summaryrefslogtreecommitdiff
path: root/test/fiddle
diff options
context:
space:
mode:
Diffstat (limited to 'test/fiddle')
-rw-r--r--test/fiddle/helper.rb178
-rw-r--r--test/fiddle/test_c_struct_builder.rb69
-rw-r--r--test/fiddle/test_c_struct_entry.rb165
-rw-r--r--test/fiddle/test_c_union_entity.rb36
-rw-r--r--test/fiddle/test_closure.rb110
-rw-r--r--test/fiddle/test_cparser.rb374
-rw-r--r--test/fiddle/test_fiddle.rb17
-rw-r--r--test/fiddle/test_func.rb139
-rw-r--r--test/fiddle/test_function.rb227
-rw-r--r--test/fiddle/test_handle.rb208
-rw-r--r--test/fiddle/test_import.rb479
-rw-r--r--test/fiddle/test_memory_view.rb143
-rw-r--r--test/fiddle/test_pinned.rb28
-rw-r--r--test/fiddle/test_pointer.rb287
14 files changed, 0 insertions, 2460 deletions
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
deleted file mode 100644
index 0ea3bf57f4..0000000000
--- a/test/fiddle/helper.rb
+++ /dev/null
@@ -1,178 +0,0 @@
-# frozen_string_literal: true
-
-require 'rbconfig/sizeof'
-require 'test/unit'
-require 'fiddle'
-
-# FIXME: this is stolen from DL and needs to be refactored.
-
-libc_so = libm_so = nil
-
-case RUBY_PLATFORM
-when /cygwin/
- libc_so = "cygwin1.dll"
- libm_so = "cygwin1.dll"
-when /android/
- libdir = '/system/lib'
- if [0].pack('L!').size == 8
- libdir = '/system/lib64'
- end
- libc_so = File.join(libdir, "libc.so")
- libm_so = File.join(libdir, "libm.so")
-when /linux-musl/
- Dir.glob('/lib/ld-musl-*.so.1') do |ld|
- libc_so = libm_so = ld
- end
-when /linux/
- libdir = '/lib'
- case RbConfig::SIZEOF['void*']
- when 4
- # 32-bit ruby
- case RUBY_PLATFORM
- when /armv\w+-linux/
- # In the ARM 32-bit libc package such as libc6:armhf libc6:armel,
- # libc.so and libm.so are installed to /lib/arm-linux-gnu*.
- # It's not installed to /lib32.
- dir, = Dir.glob('/lib/arm-linux-gnu*')
- libdir = dir if dir && File.directory?(dir)
- else
- libdir = '/lib32' if File.directory? '/lib32'
- end
- when 8
- # 64-bit ruby
- libdir = '/lib64' if File.directory? '/lib64'
- end
-
- # Handle musl libc
- libc_so, = Dir.glob(File.join(libdir, "libc.musl*.so*"))
- if libc_so
- libm_so = libc_so
- else
- # glibc
- libc_so = "libc.so.6"
- libm_so = "libm.so.6"
- end
-when /mingw/, /mswin/
- require "rbconfig"
- crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'
- libc_so = libm_so = "#{crtname}.dll"
-when /darwin/
- libc_so = libm_so = "/usr/lib/libSystem.B.dylib"
- # macOS 11.0+ removed libSystem.B.dylib from /usr/lib. But It works with dlopen.
- rigid_path = true
-when /kfreebsd/
- libc_so = "/lib/libc.so.0.1"
- libm_so = "/lib/libm.so.1"
-when /gnu/ #GNU/Hurd
- libc_so = "/lib/libc.so.0.3"
- libm_so = "/lib/libm.so.6"
-when /mirbsd/
- libc_so = "/usr/lib/libc.so.41.10"
- libm_so = "/usr/lib/libm.so.7.0"
-when /freebsd/
- libc_so = "/lib/libc.so.7"
- libm_so = "/lib/libm.so.5"
-when /bsd|dragonfly/
- libc_so = "/usr/lib/libc.so"
- libm_so = "/usr/lib/libm.so"
-when /solaris/
- libdir = '/lib'
- case RbConfig::SIZEOF['void*']
- when 4
- # 32-bit ruby
- libdir = '/lib' if File.directory? '/lib'
- when 8
- # 64-bit ruby
- libdir = '/lib/64' if File.directory? '/lib/64'
- end
- libc_so = File.join(libdir, "libc.so")
- libm_so = File.join(libdir, "libm.so")
-when /aix/
- pwd=Dir.pwd
- libc_so = libm_so = "#{pwd}/libaixdltest.so"
- unless File.exist? libc_so
- cobjs=%w!strcpy.o!
- mobjs=%w!floats.o sin.o!
- funcs=%w!sin sinf strcpy strncpy!
- expfile='dltest.exp'
- require 'tmpdir'
- Dir.mktmpdir do |_dir|
- begin
- Dir.chdir _dir
- %x!/usr/bin/ar x /usr/lib/libc.a #{cobjs.join(' ')}!
- %x!/usr/bin/ar x /usr/lib/libm.a #{mobjs.join(' ')}!
- %x!echo "#{funcs.join("\n")}\n" > #{expfile}!
- require 'rbconfig'
- if RbConfig::CONFIG["GCC"] = 'yes'
- lflag='-Wl,'
- else
- lflag=''
- end
- flags="#{lflag}-bE:#{expfile} #{lflag}-bnoentry -lm"
- %x!#{RbConfig::CONFIG["LDSHARED"]} -o #{libc_so} #{(cobjs+mobjs).join(' ')} #{flags}!
- ensure
- Dir.chdir pwd
- end
- end
- end
-when /haiku/
- libdir = '/system/lib'
- case [0].pack('L!').size
- when 4
- # 32-bit ruby
- libdir = '/system/lib/x86' if File.directory? '/system/lib/x86'
- when 8
- # 64-bit ruby
- libdir = '/system/lib/' if File.directory? '/system/lib/'
- end
- libc_so = File.join(libdir, "libroot.so")
- libm_so = File.join(libdir, "libroot.so")
-else
- libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
- libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
- if( !(libc_so && libm_so) )
- $stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
- end
-end
-
-unless rigid_path
- libc_so = nil if libc_so && libc_so[0] == ?/ && !File.file?(libc_so)
- libm_so = nil if libm_so && libm_so[0] == ?/ && !File.file?(libm_so)
-end
-
-if !libc_so || !libm_so
- ruby = EnvUtil.rubybin
- # When the ruby binary is 32-bit and the host is 64-bit,
- # `ldd ruby` outputs "not a dynamic executable" message.
- # libc_so and libm_so are not set.
- ldd = `ldd #{ruby}`
- #puts ldd
- libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
- libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
- #p [libc_so, libm_so]
-end
-
-Fiddle::LIBC_SO = libc_so
-Fiddle::LIBM_SO = libm_so
-
-module Fiddle
- class TestCase < Test::Unit::TestCase
- def setup
- @libc = Fiddle.dlopen(LIBC_SO)
- @libm = Fiddle.dlopen(LIBM_SO)
- end
-
- def teardown
- if /linux/ =~ RUBY_PLATFORM
- GC.start
- end
- end
-
- def under_gc_stress
- stress, GC.stress = GC.stress, true
- yield
- ensure
- GC.stress = stress
- end
- end
-end
diff --git a/test/fiddle/test_c_struct_builder.rb b/test/fiddle/test_c_struct_builder.rb
deleted file mode 100644
index ca44c6cf7a..0000000000
--- a/test/fiddle/test_c_struct_builder.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/struct'
- require 'fiddle/cparser'
- require 'fiddle/import'
-rescue LoadError
-end
-
-module Fiddle
- class TestCStructBuilder < TestCase
- include Fiddle::CParser
- extend Fiddle::Importer
-
- RBasic = struct ['void * flags',
- 'void * klass' ]
-
-
- RObject = struct [
- { 'basic' => RBasic },
- { 'as' => union([
- { 'heap'=> struct([ 'uint32_t numiv',
- 'void * ivptr',
- 'void * iv_index_tbl' ]) },
- 'void *ary[3]' ])}
- ]
-
-
- def test_basic_embedded_members
- assert_equal 0, RObject.offsetof("basic.flags")
- assert_equal Fiddle::SIZEOF_VOIDP, RObject.offsetof("basic.klass")
- end
-
- def test_embedded_union_members
- assert_equal 2 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as")
- assert_equal 2 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as.heap")
- assert_equal 2 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as.heap.numiv")
- assert_equal 3 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as.heap.ivptr")
- assert_equal 4 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as.heap.iv_index_tbl")
- end
-
- def test_as_ary
- assert_equal 2 * Fiddle::SIZEOF_VOIDP, RObject.offsetof("as.ary")
- end
-
- def test_offsetof
- types, members = parse_struct_signature(['int64_t i','char c'])
- my_struct = Fiddle::CStructBuilder.create(Fiddle::CStruct, types, members)
- assert_equal 0, my_struct.offsetof("i")
- assert_equal Fiddle::SIZEOF_INT64_T, my_struct.offsetof("c")
- end
-
- def test_offset_with_gap
- types, members = parse_struct_signature(['void *p', 'char c', 'long x'])
- my_struct = Fiddle::CStructBuilder.create(Fiddle::CStruct, types, members)
-
- assert_equal PackInfo.align(0, ALIGN_VOIDP), my_struct.offsetof("p")
- assert_equal PackInfo.align(SIZEOF_VOIDP, ALIGN_CHAR), my_struct.offsetof("c")
- assert_equal SIZEOF_VOIDP + PackInfo.align(SIZEOF_CHAR, ALIGN_LONG), my_struct.offsetof("x")
- end
-
- def test_union_offsetof
- types, members = parse_struct_signature(['int64_t i','char c'])
- my_struct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members)
- assert_equal 0, my_struct.offsetof("i")
- assert_equal 0, my_struct.offsetof("c")
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_c_struct_entry.rb b/test/fiddle/test_c_struct_entry.rb
deleted file mode 100644
index 9fd16d7101..0000000000
--- a/test/fiddle/test_c_struct_entry.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/struct'
-rescue LoadError
-end
-
-module Fiddle
- class TestCStructEntity < TestCase
- def test_class_size
- types = [TYPE_DOUBLE, TYPE_CHAR]
-
- size = CStructEntity.size types
-
- alignments = types.map { |type| PackInfo::ALIGN_MAP[type] }
-
- expected = PackInfo.align 0, alignments[0]
- expected += PackInfo::SIZE_MAP[TYPE_DOUBLE]
-
- expected = PackInfo.align expected, alignments[1]
- expected += PackInfo::SIZE_MAP[TYPE_CHAR]
-
- expected = PackInfo.align expected, alignments.max
-
- assert_equal expected, size
- end
-
- def test_class_size_with_count
- size = CStructEntity.size([[TYPE_DOUBLE, 2], [TYPE_CHAR, 20]])
-
- types = [TYPE_DOUBLE, TYPE_CHAR]
- alignments = types.map { |type| PackInfo::ALIGN_MAP[type] }
-
- expected = PackInfo.align 0, alignments[0]
- expected += PackInfo::SIZE_MAP[TYPE_DOUBLE] * 2
-
- expected = PackInfo.align expected, alignments[1]
- expected += PackInfo::SIZE_MAP[TYPE_CHAR] * 20
-
- expected = PackInfo.align expected, alignments.max
-
- assert_equal expected, size
- end
-
- def test_set_ctypes
- CStructEntity.malloc([TYPE_INT, TYPE_LONG], Fiddle::RUBY_FREE) do |struct|
- struct.assign_names %w[int long]
-
- # this test is roundabout because the stored ctypes are not accessible
- struct['long'] = 1
- struct['int'] = 2
-
- assert_equal 1, struct['long']
- assert_equal 2, struct['int']
- end
- end
-
- def test_aref_pointer_array
- CStructEntity.malloc([[TYPE_VOIDP, 2]], Fiddle::RUBY_FREE) do |team|
- team.assign_names(["names"])
- Fiddle::Pointer.malloc(6, Fiddle::RUBY_FREE) do |alice|
- alice[0, 6] = "Alice\0"
- Fiddle::Pointer.malloc(4, Fiddle::RUBY_FREE) do |bob|
- bob[0, 4] = "Bob\0"
- team["names"] = [alice, bob]
- assert_equal(["Alice", "Bob"], team["names"].map(&:to_s))
- end
- end
- end
- end
-
- def test_aref_pointer
- CStructEntity.malloc([TYPE_VOIDP], Fiddle::RUBY_FREE) do |user|
- user.assign_names(["name"])
- Fiddle::Pointer.malloc(6, Fiddle::RUBY_FREE) do |alice|
- alice[0, 6] = "Alice\0"
- user["name"] = alice
- assert_equal("Alice", user["name"].to_s)
- end
- end
- end
-
- def test_new_double_free
- types = [TYPE_INT]
- Pointer.malloc(CStructEntity.size(types), Fiddle::RUBY_FREE) do |pointer|
- assert_raise ArgumentError do
- CStructEntity.new(pointer, types, Fiddle::RUBY_FREE)
- end
- end
- end
-
- def test_malloc_block
- escaped_struct = nil
- returned = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
- assert_equal Fiddle::SIZEOF_INT, struct.size
- assert_equal Fiddle::RUBY_FREE, struct.free.to_i
- escaped_struct = struct
- :returned
- end
- assert_equal :returned, returned
- assert escaped_struct.freed?
- end
-
- def test_malloc_block_no_free
- assert_raise ArgumentError do
- CStructEntity.malloc([TYPE_INT]) { |struct| }
- end
- end
-
- def test_free
- struct = CStructEntity.malloc([TYPE_INT])
- begin
- assert_nil struct.free
- ensure
- Fiddle.free struct
- end
- end
-
- def test_free_with_func
- struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
- refute struct.freed?
- struct.call_free
- assert struct.freed?
- struct.call_free # you can safely run it again
- assert struct.freed?
- GC.start # you can safely run the GC routine
- assert struct.freed?
- end
-
- def test_free_with_no_func
- struct = CStructEntity.malloc([TYPE_INT])
- refute struct.freed?
- struct.call_free
- refute struct.freed?
- struct.call_free # you can safely run it again
- refute struct.freed?
- end
-
- def test_freed?
- struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
- refute struct.freed?
- struct.call_free
- assert struct.freed?
- end
-
- def test_null?
- struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
- refute struct.null?
- end
-
- def test_size
- CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
- assert_equal Fiddle::SIZEOF_INT, struct.size
- end
- end
-
- def test_size=
- CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
- assert_raise NoMethodError do
- struct.size = 1
- end
- end
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_c_union_entity.rb b/test/fiddle/test_c_union_entity.rb
deleted file mode 100644
index e0a3757562..0000000000
--- a/test/fiddle/test_c_union_entity.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/struct'
-rescue LoadError
-end
-
-
-module Fiddle
- class TestCUnionEntity < TestCase
- def test_class_size
- size = CUnionEntity.size([TYPE_DOUBLE, TYPE_CHAR])
-
- assert_equal SIZEOF_DOUBLE, size
- end
-
- def test_class_size_with_count
- size = CUnionEntity.size([[TYPE_DOUBLE, 2], [TYPE_CHAR, 20]])
-
- assert_equal SIZEOF_CHAR * 20, size
- end
-
- def test_set_ctypes
- CUnionEntity.malloc([TYPE_INT, TYPE_LONG], Fiddle::RUBY_FREE) do |union|
- union.assign_names %w[int long]
-
- # this test is roundabout because the stored ctypes are not accessible
- union['long'] = 1
- assert_equal 1, union['long']
-
- union['int'] = 1
- assert_equal 1, union['int']
- end
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb
deleted file mode 100644
index 9e748bf5ee..0000000000
--- a/test/fiddle/test_closure.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-module Fiddle
- class TestClosure < Fiddle::TestCase
- def test_argument_errors
- assert_raise(TypeError) do
- Closure.new(TYPE_INT, TYPE_INT)
- end
-
- assert_raise(TypeError) do
- Closure.new('foo', [TYPE_INT])
- end
-
- assert_raise(TypeError) do
- Closure.new(TYPE_INT, ['meow!'])
- end
- end
-
- def test_type_symbol
- closure = Closure.new(:int, [:void])
- assert_equal([
- TYPE_INT,
- [TYPE_VOID],
- ],
- [
- closure.instance_variable_get(:@ctype),
- closure.instance_variable_get(:@args),
- ])
- end
-
- def test_call
- closure = Class.new(Closure) {
- def call
- 10
- end
- }.new(TYPE_INT, [])
-
- func = Function.new(closure, [], TYPE_INT)
- assert_equal 10, func.call
- end
-
- def test_returner
- closure = Class.new(Closure) {
- def call thing
- thing
- end
- }.new(TYPE_INT, [TYPE_INT])
-
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
- assert_equal 10, func.call(10)
- end
-
- def test_const_string
- closure_class = Class.new(Closure) do
- def call(string)
- @return_string = "Hello! #{string}"
- @return_string
- end
- end
- closure = closure_class.new(:const_string, [:const_string])
-
- func = Function.new(closure, [:const_string], :const_string)
- assert_equal("Hello! World!", func.call("World!"))
- end
-
- def test_block_caller
- cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
- one
- end
- func = Function.new(cb, [TYPE_INT], TYPE_INT)
- assert_equal 11, func.call(11)
- end
-
- def test_memsize
- require 'objspace'
- bug = '[ruby-dev:42480]'
- n = 10000
- assert_equal(n, n.times {ObjectSpace.memsize_of(Closure.allocate)}, bug)
- end
-
- %w[INT SHORT CHAR LONG LONG_LONG].each do |name|
- type = Fiddle.const_get("TYPE_#{name}") rescue next
- size = Fiddle.const_get("SIZEOF_#{name}")
- [[type, size-1, name], [-type, size, "unsigned_"+name]].each do |t, s, n|
- define_method("test_conversion_#{n.downcase}") do
- arg = nil
-
- clos = Class.new(Closure) do
- define_method(:call) {|x| arg = x}
- end.new(t, [t])
-
- v = ~(~0 << (8*s))
-
- arg = nil
- assert_equal(v, clos.call(v))
- assert_equal(arg, v, n)
-
- arg = nil
- func = Function.new(clos, [t], t)
- assert_equal(v, func.call(v))
- assert_equal(arg, v, n)
- end
- end
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_cparser.rb b/test/fiddle/test_cparser.rb
deleted file mode 100644
index ae319197a4..0000000000
--- a/test/fiddle/test_cparser.rb
+++ /dev/null
@@ -1,374 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/cparser'
- require 'fiddle/import'
-rescue LoadError
-end
-
-module Fiddle
- class TestCParser < TestCase
- include CParser
-
- def test_char_ctype
- assert_equal(TYPE_CHAR, parse_ctype('char'))
- assert_equal(TYPE_CHAR, parse_ctype('const char'))
- assert_equal(TYPE_CHAR, parse_ctype('signed char'))
- assert_equal(TYPE_CHAR, parse_ctype('const signed char'))
- assert_equal(-TYPE_CHAR, parse_ctype('unsigned char'))
- assert_equal(-TYPE_CHAR, parse_ctype('const unsigned char'))
- end
-
- def test_short_ctype
- assert_equal(TYPE_SHORT, parse_ctype('short'))
- assert_equal(TYPE_SHORT, parse_ctype('const short'))
- assert_equal(TYPE_SHORT, parse_ctype('short int'))
- assert_equal(TYPE_SHORT, parse_ctype('const short int'))
- assert_equal(TYPE_SHORT, parse_ctype('signed short'))
- assert_equal(TYPE_SHORT, parse_ctype('const signed short'))
- assert_equal(TYPE_SHORT, parse_ctype('signed short int'))
- assert_equal(TYPE_SHORT, parse_ctype('const signed short int'))
- assert_equal(-TYPE_SHORT, parse_ctype('unsigned short'))
- assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short'))
- assert_equal(-TYPE_SHORT, parse_ctype('unsigned short int'))
- assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short int'))
- end
-
- def test_int_ctype
- assert_equal(TYPE_INT, parse_ctype('int'))
- assert_equal(TYPE_INT, parse_ctype('const int'))
- assert_equal(TYPE_INT, parse_ctype('signed int'))
- assert_equal(TYPE_INT, parse_ctype('const signed int'))
- assert_equal(-TYPE_INT, parse_ctype('uint'))
- assert_equal(-TYPE_INT, parse_ctype('const uint'))
- assert_equal(-TYPE_INT, parse_ctype('unsigned int'))
- assert_equal(-TYPE_INT, parse_ctype('const unsigned int'))
- end
-
- def test_long_ctype
- assert_equal(TYPE_LONG, parse_ctype('long'))
- assert_equal(TYPE_LONG, parse_ctype('const long'))
- assert_equal(TYPE_LONG, parse_ctype('long int'))
- assert_equal(TYPE_LONG, parse_ctype('const long int'))
- assert_equal(TYPE_LONG, parse_ctype('signed long'))
- assert_equal(TYPE_LONG, parse_ctype('const signed long'))
- assert_equal(TYPE_LONG, parse_ctype('signed long int'))
- assert_equal(TYPE_LONG, parse_ctype('const signed long int'))
- assert_equal(-TYPE_LONG, parse_ctype('unsigned long'))
- assert_equal(-TYPE_LONG, parse_ctype('const unsigned long'))
- assert_equal(-TYPE_LONG, parse_ctype('unsigned long int'))
- assert_equal(-TYPE_LONG, parse_ctype('const unsigned long int'))
- end
-
- def test_size_t_ctype
- assert_equal(TYPE_SIZE_T, parse_ctype("size_t"))
- assert_equal(TYPE_SIZE_T, parse_ctype("const size_t"))
- end
-
- def test_ssize_t_ctype
- assert_equal(TYPE_SSIZE_T, parse_ctype("ssize_t"))
- assert_equal(TYPE_SSIZE_T, parse_ctype("const ssize_t"))
- end
-
- def test_ptrdiff_t_ctype
- assert_equal(TYPE_PTRDIFF_T, parse_ctype("ptrdiff_t"))
- assert_equal(TYPE_PTRDIFF_T, parse_ctype("const ptrdiff_t"))
- end
-
- def test_intptr_t_ctype
- assert_equal(TYPE_INTPTR_T, parse_ctype("intptr_t"))
- assert_equal(TYPE_INTPTR_T, parse_ctype("const intptr_t"))
- end
-
- def test_uintptr_t_ctype
- assert_equal(TYPE_UINTPTR_T, parse_ctype("uintptr_t"))
- assert_equal(TYPE_UINTPTR_T, parse_ctype("const uintptr_t"))
- end
-
- def test_undefined_ctype
- assert_raise(DLError) { parse_ctype('DWORD') }
- end
-
- def test_undefined_ctype_with_type_alias
- assert_equal(-TYPE_LONG,
- parse_ctype('DWORD', {"DWORD" => "unsigned long"}))
- assert_equal(-TYPE_LONG,
- parse_ctype('const DWORD', {"DWORD" => "unsigned long"}))
- end
-
- def expand_struct_types(types)
- types.collect do |type|
- case type
- when Class
- [expand_struct_types(type.types)]
- when Array
- [expand_struct_types([type[0]])[0][0], type[1]]
- else
- type
- end
- end
- end
-
- def test_struct_basic
- assert_equal([[TYPE_INT, TYPE_CHAR], ['i', 'c']],
- parse_struct_signature(['int i', 'char c']))
- assert_equal([[TYPE_INT, TYPE_CHAR], ['i', 'c']],
- parse_struct_signature(['const int i', 'const char c']))
- end
-
- def test_struct_array
- assert_equal([[[TYPE_CHAR, 80], [TYPE_INT, 5]],
- ['buffer', 'x']],
- parse_struct_signature(['char buffer[80]',
- 'int[5] x']))
- assert_equal([[[TYPE_CHAR, 80], [TYPE_INT, 5]],
- ['buffer', 'x']],
- parse_struct_signature(['const char buffer[80]',
- 'const int[5] x']))
- end
-
- def test_struct_nested_struct
- types, members = parse_struct_signature([
- 'int x',
- {inner: ['int i', 'char c']},
- ])
- assert_equal([[TYPE_INT, [[TYPE_INT, TYPE_CHAR]]],
- ['x', ['inner', ['i', 'c']]]],
- [expand_struct_types(types),
- members])
- end
-
- def test_struct_nested_defined_struct
- inner = Fiddle::Importer.struct(['int i', 'char c'])
- assert_equal([[TYPE_INT, inner],
- ['x', ['inner', ['i', 'c']]]],
- parse_struct_signature([
- 'int x',
- {inner: inner},
- ]))
- end
-
- def test_struct_double_nested_struct
- types, members = parse_struct_signature([
- 'int x',
- {
- outer: [
- 'int y',
- {inner: ['int i', 'char c']},
- ],
- },
- ])
- assert_equal([[TYPE_INT, [[TYPE_INT, [[TYPE_INT, TYPE_CHAR]]]]],
- ['x', ['outer', ['y', ['inner', ['i', 'c']]]]]],
- [expand_struct_types(types),
- members])
- end
-
- def test_struct_nested_struct_array
- types, members = parse_struct_signature([
- 'int x',
- {
- 'inner[2]' => [
- 'int i',
- 'char c',
- ],
- },
- ])
- assert_equal([[TYPE_INT, [[TYPE_INT, TYPE_CHAR], 2]],
- ['x', ['inner', ['i', 'c']]]],
- [expand_struct_types(types),
- members])
- end
-
- def test_struct_double_nested_struct_inner_array
- types, members = parse_struct_signature(outer: [
- 'int x',
- {
- 'inner[2]' => [
- 'int i',
- 'char c',
- ],
- },
- ])
- assert_equal([[[[TYPE_INT, [[TYPE_INT, TYPE_CHAR], 2]]]],
- [['outer', ['x', ['inner', ['i', 'c']]]]]],
- [expand_struct_types(types),
- members])
- end
-
- def test_struct_double_nested_struct_outer_array
- types, members = parse_struct_signature([
- 'int x',
- {
- 'outer[2]' => {
- inner: [
- 'int i',
- 'char c',
- ],
- },
- },
- ])
- assert_equal([[TYPE_INT, [[[[TYPE_INT, TYPE_CHAR]]], 2]],
- ['x', ['outer', [['inner', ['i', 'c']]]]]],
- [expand_struct_types(types),
- members])
- end
-
- def test_struct_array_str
- assert_equal([[[TYPE_CHAR, 80], [TYPE_INT, 5]],
- ['buffer', 'x']],
- parse_struct_signature('char buffer[80], int[5] x'))
- assert_equal([[[TYPE_CHAR, 80], [TYPE_INT, 5]],
- ['buffer', 'x']],
- parse_struct_signature('const char buffer[80], const int[5] x'))
- end
-
- def test_struct_function_pointer
- assert_equal([[TYPE_VOIDP], ['cb']],
- parse_struct_signature(['void (*cb)(const char*)']))
- end
-
- def test_struct_function_pointer_str
- assert_equal([[TYPE_VOIDP, TYPE_VOIDP], ['cb', 'data']],
- parse_struct_signature('void (*cb)(const char*), const char* data'))
- end
-
- def test_struct_string
- assert_equal [[TYPE_INT,TYPE_VOIDP,TYPE_VOIDP], ['x', 'cb', 'name']], parse_struct_signature('int x; void (*cb)(); const char* name')
- end
-
- def test_struct_undefined
- assert_raise(DLError) { parse_struct_signature(['int i', 'DWORD cb']) }
- end
-
- def test_struct_undefined_with_type_alias
- assert_equal [[TYPE_INT,-TYPE_LONG], ['i', 'cb']], parse_struct_signature(['int i', 'DWORD cb'], {"DWORD" => "unsigned long"})
- end
-
- def test_signature_basic
- func, ret, args = parse_signature('void func()')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [], args
- end
-
- def test_signature_semi
- func, ret, args = parse_signature('void func();')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [], args
- end
-
- def test_signature_void_arg
- func, ret, args = parse_signature('void func(void)')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [], args
- end
-
- def test_signature_type_args
- types = [
- 'char', 'unsigned char',
- 'short', 'unsigned short',
- 'int', 'unsigned int',
- 'long', 'unsigned long',
- defined?(TYPE_LONG_LONG) && \
- [
- 'long long', 'unsigned long long',
- ],
- 'float', 'double',
- 'const char*', 'void*',
- ].flatten.compact
- func, ret, args = parse_signature("void func(#{types.join(',')})")
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [
- TYPE_CHAR, -TYPE_CHAR,
- TYPE_SHORT, -TYPE_SHORT,
- TYPE_INT, -TYPE_INT,
- TYPE_LONG, -TYPE_LONG,
- defined?(TYPE_LONG_LONG) && \
- [
- TYPE_LONG_LONG, -TYPE_LONG_LONG,
- ],
- TYPE_FLOAT, TYPE_DOUBLE,
- TYPE_VOIDP, TYPE_VOIDP,
- ].flatten.compact, args
- end
-
- def test_signature_single_variable
- func, ret, args = parse_signature('void func(int x)')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [TYPE_INT], args
- end
-
- def test_signature_multiple_variables
- func, ret, args = parse_signature('void func(int x, const char* s)')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [TYPE_INT, TYPE_VOIDP], args
- end
-
- def test_signature_array_variable
- func, ret, args = parse_signature('void func(int x[], int y[40])')
- assert_equal 'func', func
- assert_equal TYPE_VOID, ret
- assert_equal [TYPE_VOIDP, TYPE_VOIDP], args
- end
-
- def test_signature_function_pointer
- func, ret, args = parse_signature('int func(int (*sum)(int x, int y), int x, int y)')
- assert_equal 'func', func
- assert_equal TYPE_INT, ret
- assert_equal [TYPE_VOIDP, TYPE_INT, TYPE_INT], args
- end
-
- def test_signature_variadic_arguments
- unless Fiddle.const_defined?("TYPE_VARIADIC")
- omit "libffi doesn't support variadic arguments"
- end
- assert_equal([
- "printf",
- TYPE_INT,
- [TYPE_VOIDP, TYPE_VARIADIC],
- ],
- parse_signature('int printf(const char *format, ...)'))
- end
-
- def test_signature_return_pointer
- func, ret, args = parse_signature('void* malloc(size_t)')
- assert_equal 'malloc', func
- assert_equal TYPE_VOIDP, ret
- assert_equal [TYPE_SIZE_T], args
- end
-
- def test_signature_return_array
- func, ret, args = parse_signature('int (*func())[32]')
- assert_equal 'func', func
- assert_equal TYPE_VOIDP, ret
- assert_equal [], args
- end
-
- def test_signature_return_array_with_args
- func, ret, args = parse_signature('int (*func(const char* s))[]')
- assert_equal 'func', func
- assert_equal TYPE_VOIDP, ret
- assert_equal [TYPE_VOIDP], args
- end
-
- def test_signature_return_function_pointer
- func, ret, args = parse_signature('int (*func())(int x, int y)')
- assert_equal 'func', func
- assert_equal TYPE_VOIDP, ret
- assert_equal [], args
- end
-
- def test_signature_return_function_pointer_with_args
- func, ret, args = parse_signature('int (*func(int z))(int x, int y)')
- assert_equal 'func', func
- assert_equal TYPE_VOIDP, ret
- assert_equal [TYPE_INT], args
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_fiddle.rb b/test/fiddle/test_fiddle.rb
deleted file mode 100644
index 8751d96920..0000000000
--- a/test/fiddle/test_fiddle.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-class TestFiddle < Fiddle::TestCase
- def test_windows_constant
- require 'rbconfig'
- if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
- assert Fiddle::WINDOWS, "Fiddle::WINDOWS should be 'true' on Windows platforms"
- else
- refute Fiddle::WINDOWS, "Fiddle::WINDOWS should be 'false' on non-Windows platforms"
- end
- end
-
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_func.rb b/test/fiddle/test_func.rb
deleted file mode 100644
index 44893017e8..0000000000
--- a/test/fiddle/test_func.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-module Fiddle
- class TestFunc < TestCase
- def test_random
- f = Function.new(@libc['srand'], [-TYPE_LONG], TYPE_VOID)
- assert_nil f.call(10)
- end
-
- def test_sinf
- begin
- f = Function.new(@libm['sinf'], [TYPE_FLOAT], TYPE_FLOAT)
- rescue Fiddle::DLError
- omit "libm may not have sinf()"
- end
- assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
- end
-
- def test_sin
- f = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
- assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
- end
-
- def test_string
- under_gc_stress do
- f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
- buff = +"000"
- str = f.call(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
- end
-
- def test_isdigit
- f = Function.new(@libc['isdigit'], [TYPE_INT], TYPE_INT)
- r1 = f.call(?1.ord)
- r2 = f.call(?2.ord)
- rr = f.call(?r.ord)
- assert_operator r1, :>, 0
- assert_operator r2, :>, 0
- assert_equal 0, rr
- end
-
- def test_atof
- f = Function.new(@libc['atof'], [TYPE_VOIDP], TYPE_DOUBLE)
- r = f.call("12.34")
- assert_includes(12.00..13.00, r)
- end
-
- def test_strtod
- f = Function.new(@libc['strtod'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_DOUBLE)
- buff1 = Pointer["12.34"]
- buff2 = buff1 + 4
- r = f.call(buff1, - buff2)
- assert_in_delta(12.34, r, 0.001)
- end
-
- def test_qsort1
- cb = Class.new(Closure) {
- def call(x, y)
- Pointer.new(x)[0] <=> Pointer.new(y)[0]
- end
- }.new(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP])
-
- qsort = Function.new(@libc['qsort'],
- [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
- TYPE_VOID)
- buff = "9341"
- qsort.call(buff, buff.size, 1, cb)
- assert_equal("1349", buff)
-
- bug4929 = '[ruby-core:37395]'
- buff = "9341"
- under_gc_stress do
- qsort.call(buff, buff.size, 1, cb)
- end
- assert_equal("1349", buff, bug4929)
- end
-
- def test_snprintf
- unless Fiddle.const_defined?("TYPE_VARIADIC")
- omit "libffi doesn't support variadic arguments"
- end
- if Fiddle::WINDOWS
- snprintf_name = "_snprintf"
- else
- snprintf_name = "snprintf"
- end
- begin
- snprintf_pointer = @libc[snprintf_name]
- rescue Fiddle::DLError
- omit "Can't find #{snprintf_name}: #{$!.message}"
- end
- snprintf = Function.new(snprintf_pointer,
- [
- :voidp,
- :size_t,
- :const_string,
- :variadic,
- ],
- :int)
- output_buffer = " " * 1024
- output = Pointer[output_buffer]
-
- written = snprintf.call(output,
- output.size,
- "int: %d, string: %.*s, const string: %s\n",
- :int, -29,
- :int, 4,
- :voidp, "Hello",
- :const_string, "World")
- assert_equal("int: -29, string: Hell, const string: World\n",
- output_buffer[0, written])
-
- string_like_class = Class.new do
- def initialize(string)
- @string = string
- end
-
- def to_str
- @string
- end
- end
- written = snprintf.call(output,
- output.size,
- "string: %.*s, const string: %s, uint: %u\n",
- :int, 2,
- :voidp, "Hello",
- :const_string, string_like_class.new("World"),
- :int, 29)
- assert_equal("string: He, const string: World, uint: 29\n",
- output_buffer[0, written])
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb
deleted file mode 100644
index 8ac4f60aa3..0000000000
--- a/test/fiddle/test_function.rb
+++ /dev/null
@@ -1,227 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-module Fiddle
- class TestFunction < Fiddle::TestCase
- def setup
- super
- Fiddle.last_error = nil
- if WINDOWS
- Fiddle.win32_last_error = nil
- Fiddle.win32_last_socket_error = nil
- end
- end
-
- def test_default_abi
- func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
- assert_equal Function::DEFAULT, func.abi
- end
-
- def test_name
- func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE, name: 'sin')
- assert_equal 'sin', func.name
- end
-
- def test_need_gvl?
- libruby = Fiddle.dlopen(nil)
- rb_str_dup = Function.new(libruby['rb_str_dup'],
- [:voidp],
- :voidp,
- need_gvl: true)
- assert(rb_str_dup.need_gvl?)
- assert_equal('Hello',
- Fiddle.dlunwrap(rb_str_dup.call(Fiddle.dlwrap('Hello'))))
- end
-
- def test_argument_errors
- assert_raise(TypeError) do
- Function.new(@libm['sin'], TYPE_DOUBLE, TYPE_DOUBLE)
- end
-
- assert_raise(TypeError) do
- Function.new(@libm['sin'], ['foo'], TYPE_DOUBLE)
- end
-
- assert_raise(TypeError) do
- Function.new(@libm['sin'], [TYPE_DOUBLE], 'foo')
- end
- end
-
- def test_argument_type_conversion
- type = Struct.new(:int, :call_count) do
- def initialize(int)
- super(int, 0)
- end
- def to_int
- raise "exhausted" if (self.call_count += 1) > 1
- self.int
- end
- end
- type_arg = type.new(TYPE_DOUBLE)
- type_result = type.new(TYPE_DOUBLE)
- assert_nothing_raised(RuntimeError) do
- Function.new(@libm['sin'], [type_arg], type_result)
- end
- assert_equal(1, type_arg.call_count)
- assert_equal(1, type_result.call_count)
- end
-
- def test_call
- func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
- assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001
- end
-
- def test_argument_count
- closure = Class.new(Closure) {
- def call one
- 10 + one
- end
- }.new(TYPE_INT, [TYPE_INT])
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
-
- assert_raise(ArgumentError) do
- func.call(1,2,3)
- end
- assert_raise(ArgumentError) do
- func.call
- end
- end
-
- def test_last_error
- func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
-
- assert_nil Fiddle.last_error
- func.call(+"000", "123")
- refute_nil Fiddle.last_error
- end
-
- if WINDOWS
- def test_win32_last_error
- kernel32 = Fiddle.dlopen("kernel32")
- args = [kernel32["SetLastError"], [-TYPE_LONG], TYPE_VOID]
- args << Function::STDCALL if Function.const_defined?(:STDCALL)
- set_last_error = Function.new(*args)
- assert_nil(Fiddle.win32_last_error)
- n = 1 << 29 | 1
- set_last_error.call(n)
- assert_equal(n, Fiddle.win32_last_error)
- end
-
- def test_win32_last_socket_error
- ws2_32 = Fiddle.dlopen("ws2_32")
- args = [ws2_32["WSASetLastError"], [TYPE_INT], TYPE_VOID]
- args << Function::STDCALL if Function.const_defined?(:STDCALL)
- wsa_set_last_error = Function.new(*args)
- assert_nil(Fiddle.win32_last_socket_error)
- n = 1 << 29 | 1
- wsa_set_last_error.call(n)
- assert_equal(n, Fiddle.win32_last_socket_error)
- end
- end
-
- def test_strcpy
- f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
- buff = +"000"
- str = f.call(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def call_proc(string_to_copy)
- buff = +"000"
- str = yield(buff, string_to_copy)
- [buff, str]
- end
-
- def test_function_as_proc
- f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
- buff, str = call_proc("123", &f)
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_function_as_method
- f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
- klass = Class.new do
- define_singleton_method(:strcpy, &f)
- end
- buff = +"000"
- str = klass.strcpy(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_nogvl_poll
- # XXX hack to quiet down CI errors on EINTR from r64353
- # [ruby-core:88360] [Misc #14937]
- # Making pipes (and sockets) non-blocking by default would allow
- # us to get rid of POSIX timers / timer pthread
- # https://bugs.ruby-lang.org/issues/14968
- IO.pipe { |r,w| IO.select([r], [w]) }
- begin
- poll = @libc['poll']
- rescue Fiddle::DLError
- omit 'poll(2) not available'
- end
- f = Function.new(poll, [TYPE_VOIDP, TYPE_INT, TYPE_INT], TYPE_INT)
-
- msec = 200
- t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
- th = Thread.new { f.call(nil, 0, msec) }
- n1 = f.call(nil, 0, msec)
- n2 = th.value
- t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
- assert_in_delta(msec, t1 - t0, 180, 'slept amount of time')
- assert_equal(0, n1, perror("poll(2) in main-thread"))
- assert_equal(0, n2, perror("poll(2) in sub-thread"))
- end
-
- def test_no_memory_leak
- if respond_to?(:assert_nothing_leaked_memory)
- rb_obj_frozen_p_symbol = Fiddle.dlopen(nil)["rb_obj_frozen_p"]
- rb_obj_frozen_p = Fiddle::Function.new(rb_obj_frozen_p_symbol,
- [Fiddle::TYPE_UINTPTR_T],
- Fiddle::TYPE_UINTPTR_T)
- a = "a"
- n_tries = 100_000
- n_tries.times do
- begin
- a + 1
- rescue TypeError
- end
- end
- n_arguments = 1
- sizeof_fiddle_generic = Fiddle::SIZEOF_VOIDP # Rough
- size_per_try =
- (sizeof_fiddle_generic * n_arguments) +
- (Fiddle::SIZEOF_VOIDP * (n_arguments + 1))
- assert_nothing_leaked_memory(size_per_try * n_tries) do
- n_tries.times do
- begin
- rb_obj_frozen_p.call(a)
- rescue TypeError
- end
- end
- end
- else
- prep = 'r = Fiddle::Function.new(Fiddle.dlopen(nil)["rb_obj_frozen_p"], [Fiddle::TYPE_UINTPTR_T], Fiddle::TYPE_UINTPTR_T); a = "a"'
- code = 'begin r.call(a); rescue TypeError; end'
- assert_no_memory_leak(%w[-W0 -rfiddle], "#{prep}\n1000.times{#{code}}", "10_000.times {#{code}}", limit: 1.2)
- end
- end
-
- private
-
- def perror(m)
- proc do
- if e = Fiddle.last_error
- m = "#{m}: #{SystemCallError.new(e).message}"
- end
- m
- end
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb
deleted file mode 100644
index 7e3ff9d844..0000000000
--- a/test/fiddle/test_handle.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-module Fiddle
- class TestHandle < TestCase
- include Fiddle
-
- def test_to_i
- handle = Fiddle::Handle.new(LIBC_SO)
- assert_kind_of Integer, handle.to_i
- end
-
- def test_to_ptr
- handle = Fiddle::Handle.new(LIBC_SO)
- ptr = handle.to_ptr
- assert_equal ptr.to_i, handle.to_i
- end
-
- def test_static_sym_unknown
- assert_raise(DLError) { Fiddle::Handle.sym('fooo') }
- assert_raise(DLError) { Fiddle::Handle['fooo'] }
- end
-
- def test_static_sym
- begin
- # Linux / Darwin / FreeBSD
- refute_nil Fiddle::Handle.sym('dlopen')
- assert_equal Fiddle::Handle.sym('dlopen'), Fiddle::Handle['dlopen']
- return
- rescue
- end
-
- begin
- # NetBSD
- require '-test-/dln/empty'
- refute_nil Fiddle::Handle.sym('Init_empty')
- assert_equal Fiddle::Handle.sym('Init_empty'), Fiddle::Handle['Init_empty']
- return
- rescue
- end
- end unless /mswin|mingw/ =~ RUBY_PLATFORM
-
- def test_sym_closed_handle
- handle = Fiddle::Handle.new(LIBC_SO)
- handle.close
- assert_raise(DLError) { handle.sym("calloc") }
- assert_raise(DLError) { handle["calloc"] }
- end
-
- def test_sym_unknown
- handle = Fiddle::Handle.new(LIBC_SO)
- assert_raise(DLError) { handle.sym('fooo') }
- assert_raise(DLError) { handle['fooo'] }
- end
-
- def test_sym_with_bad_args
- handle = Handle.new(LIBC_SO)
- assert_raise(TypeError) { handle.sym(nil) }
- assert_raise(TypeError) { handle[nil] }
- end
-
- def test_sym
- handle = Handle.new(LIBC_SO)
- refute_nil handle.sym('calloc')
- refute_nil handle['calloc']
- end
-
- def test_handle_close
- handle = Handle.new(LIBC_SO)
- assert_equal 0, handle.close
- end
-
- def test_handle_close_twice
- handle = Handle.new(LIBC_SO)
- handle.close
- assert_raise(DLError) do
- handle.close
- end
- end
-
- def test_dlopen_returns_handle
- assert_instance_of Handle, dlopen(LIBC_SO)
- end
-
- def test_initialize_noargs
- handle = Handle.new
- refute_nil handle['rb_str_new']
- end
-
- def test_initialize_flags
- handle = Handle.new(LIBC_SO, RTLD_LAZY | RTLD_GLOBAL)
- refute_nil handle['calloc']
- end
-
- def test_enable_close
- handle = Handle.new(LIBC_SO)
- assert !handle.close_enabled?, 'close is enabled'
-
- handle.enable_close
- assert handle.close_enabled?, 'close is not enabled'
- end
-
- def test_disable_close
- handle = Handle.new(LIBC_SO)
-
- handle.enable_close
- assert handle.close_enabled?, 'close is enabled'
- handle.disable_close
- assert !handle.close_enabled?, 'close is enabled'
- end
-
- def test_file_name
- file_name = Handle.new(LIBC_SO).file_name
- if file_name
- assert_kind_of String, file_name
- expected = [File.basename(LIBC_SO)]
- begin
- expected << File.basename(File.realpath(LIBC_SO, File.dirname(file_name)))
- rescue Errno::ENOENT
- end
- basename = File.basename(file_name)
- unless File::FNM_SYSCASE.zero?
- basename.downcase!
- expected.each(&:downcase!)
- end
- assert_include expected, basename
- end
- end
-
- def test_NEXT
- begin
- # Linux / Darwin
- #
- # There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find
- # the first occurrence of the desired symbol using the default library search order. The
- # latter will find the next occurrence of a function in the search order after the current
- # library. This allows one to provide a wrapper around a function in another shared
- # library.
- # --- Ubuntu Linux 8.04 dlsym(3)
- handle = Handle::NEXT
- refute_nil handle['malloc']
- return
- rescue
- end
-
- begin
- # BSD
- #
- # If dlsym() is called with the special handle RTLD_NEXT, then the search
- # for the symbol is limited to the shared objects which were loaded after
- # the one issuing the call to dlsym(). Thus, if the function is called
- # from the main program, all the shared libraries are searched. If it is
- # called from a shared library, all subsequent shared libraries are
- # searched. RTLD_NEXT is useful for implementing wrappers around library
- # functions. For example, a wrapper function getpid() could access the
- # "real" getpid() with dlsym(RTLD_NEXT, "getpid"). (Actually, the dlfunc()
- # interface, below, should be used, since getpid() is a function and not a
- # data object.)
- # --- FreeBSD 8.0 dlsym(3)
- require '-test-/dln/empty'
- handle = Handle::NEXT
- refute_nil handle['Init_empty']
- return
- rescue
- end
- end unless /mswin|mingw/ =~ RUBY_PLATFORM
-
- def test_DEFAULT
- handle = Handle::DEFAULT
- refute_nil handle['malloc']
- end unless /mswin|mingw/ =~ RUBY_PLATFORM
-
- def test_dlerror
- # FreeBSD (at least 7.2 to 7.2) calls nsdispatch(3) when it calls
- # getaddrinfo(3). And nsdispatch(3) doesn't call dlerror(3) even if
- # it calls _nss_cache_cycle_prevention_function with dlsym(3).
- # So our Fiddle::Handle#sym must call dlerror(3) before call dlsym.
- # In general uses of dlerror(3) should call it before use it.
- require 'socket'
- Socket.gethostbyname("localhost")
- Fiddle.dlopen("/lib/libc.so.7").sym('strcpy')
- end if /freebsd/=~ RUBY_PLATFORM
-
- def test_no_memory_leak
- if respond_to?(:assert_nothing_leaked_memory)
- n_tries = 100_000
- assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do
- n_tries.times do
- Fiddle::Handle.allocate
- end
- end
- else
- assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Handle.allocate}; GC.start', rss: true)
- end
- end
-
- if /cygwin|mingw|mswin/ =~ RUBY_PLATFORM
- def test_fallback_to_ansi
- k = Fiddle::Handle.new("kernel32.dll")
- ansi = k["GetFileAttributesA"]
- assert_equal(ansi, k["GetFileAttributes"], "should fallback to ANSI version")
- end
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb
deleted file mode 100644
index afa8df9e00..0000000000
--- a/test/fiddle/test_import.rb
+++ /dev/null
@@ -1,479 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/import'
-rescue LoadError
-end
-
-module Fiddle
- module LIBC
- extend Importer
- dlload LIBC_SO, LIBM_SO
-
- typealias 'string', 'char*'
- typealias 'FILE*', 'void*'
-
- extern "void *strcpy(char*, char*)"
- extern "int isdigit(int)"
- extern "double atof(string)"
- extern "unsigned long strtoul(char*, char **, int)"
- extern "int qsort(void*, unsigned long, unsigned long, void*)"
- extern "int fprintf(FILE*, char*)" rescue nil
- extern "int gettimeofday(timeval*, timezone*)" rescue nil
-
- BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
- Timeval = struct [
- "long tv_sec",
- "long tv_usec",
- ]
- Timezone = struct [
- "int tz_minuteswest",
- "int tz_dsttime",
- ]
- MyStruct = struct [
- "short num[5]",
- "char c",
- "unsigned char buff[7]",
- ]
- StructNestedStruct = struct [
- {
- "vertices[2]" => {
- position: ["float x", "float y", "float z"],
- texcoord: ["float u", "float v"]
- },
- object: ["int id", "void *user_data"],
- },
- "int id"
- ]
- UnionNestedStruct = union [
- {
- keyboard: [
- 'unsigned int state',
- 'char key'
- ],
- mouse: [
- 'unsigned int button',
- 'unsigned short x',
- 'unsigned short y'
- ]
- }
- ]
-
- CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2|
- f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID)
- f.call(ptr2)
- }
- end
-
- class TestImport < TestCase
- def test_ensure_call_dlload
- err = assert_raise(RuntimeError) do
- Class.new do
- extend Importer
- extern "void *strcpy(char*, char*)"
- end
- end
- assert_match(/call dlload before/, err.message)
- end
-
- def test_struct_memory_access()
- # check memory operations performed directly on struct
- Fiddle::Importer.struct(['int id']).malloc(Fiddle::RUBY_FREE) do |my_struct|
- my_struct[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
- assert_equal 0x01010101, my_struct.id
-
- my_struct.id = 0
- assert_equal "\x00".b * Fiddle::SIZEOF_INT, my_struct[0, Fiddle::SIZEOF_INT]
- end
- end
-
- def test_struct_ptr_array_subscript_multiarg()
- # check memory operations performed on struct#to_ptr
- Fiddle::Importer.struct([ 'int x' ]).malloc(Fiddle::RUBY_FREE) do |struct|
- ptr = struct.to_ptr
-
- struct.x = 0x02020202
- assert_equal("\x02".b * Fiddle::SIZEOF_INT, ptr[0, Fiddle::SIZEOF_INT])
-
- ptr[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
- assert_equal 0x01010101, struct.x
- end
- end
-
- def test_malloc()
- LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s1|
- LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s2|
- refute_equal(s1.to_ptr.to_i, s2.to_ptr.to_i)
- end
- end
- end
-
- def test_sizeof()
- assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
- assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
- LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |my_struct|
- assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(my_struct))
- end
- assert_equal(SIZEOF_LONG_LONG, LIBC.sizeof("long long")) if defined?(SIZEOF_LONG_LONG)
- assert_equal(LIBC::StructNestedStruct.size(), LIBC.sizeof(LIBC::StructNestedStruct))
- end
-
- Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(.*)/) do
- type = $&
- const_type_name = $1
- size = Fiddle.const_get("SIZEOF_#{const_type_name}")
- if const_type_name == "CONST_STRING"
- name = "const_string"
- type_name = "const char*"
- else
- name = $1.sub(/P\z/,"*").gsub(/_(?!T\z)/, " ").downcase
- type_name = name
- end
- define_method("test_sizeof_#{name}") do
- assert_equal(size, Fiddle::Importer.sizeof(type_name), type)
- end
- end
-
- def test_unsigned_result()
- d = (2 ** 31) + 1
-
- r = LIBC.strtoul(d.to_s, 0, 0)
- assert_equal(d, r)
- end
-
- def test_io()
- if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM ) || !defined?(LIBC.fprintf)
- return
- end
- io_in,io_out = IO.pipe()
- LIBC.fprintf(io_out, "hello")
- io_out.flush()
- io_out.close()
- str = io_in.read()
- io_in.close()
- assert_equal("hello", str)
- end
-
- def test_value()
- i = LIBC.value('int', 2)
- assert_equal(2, i.value)
-
- d = LIBC.value('double', 2.0)
- assert_equal(2.0, d.value)
-
- ary = LIBC.value('int[3]', [0,1,2])
- assert_equal([0,1,2], ary.value)
- end
-
- def test_struct_array_assignment()
- Fiddle::Importer.struct(["unsigned int stages[3]"]).malloc(Fiddle::RUBY_FREE) do |instance|
- instance.stages[0] = 1024
- instance.stages[1] = 10
- instance.stages[2] = 100
- assert_equal 1024, instance.stages[0]
- assert_equal 10, instance.stages[1]
- assert_equal 100, instance.stages[2]
- assert_equal [1024, 10, 100].pack(Fiddle::PackInfo::PACK_MAP[-Fiddle::TYPE_INT] * 3),
- instance.to_ptr[0, 3 * Fiddle::SIZEOF_INT]
- assert_raise(IndexError) { instance.stages[-1] = 5 }
- assert_raise(IndexError) { instance.stages[3] = 5 }
- end
- end
-
- def test_nested_struct_reusing_other_structs()
- position_struct = Fiddle::Importer.struct(['float x', 'float y', 'float z'])
- texcoord_struct = Fiddle::Importer.struct(['float u', 'float v'])
- vertex_struct = Fiddle::Importer.struct(position: position_struct, texcoord: texcoord_struct)
- mesh_struct = Fiddle::Importer.struct([
- {
- "vertices[2]" => vertex_struct,
- object: [
- "int id",
- "void *user_data",
- ],
- },
- "int id",
- ])
- assert_equal LIBC::StructNestedStruct.size, mesh_struct.size
-
-
- keyboard_event_struct = Fiddle::Importer.struct(['unsigned int state', 'char key'])
- mouse_event_struct = Fiddle::Importer.struct(['unsigned int button', 'unsigned short x', 'unsigned short y'])
- event_union = Fiddle::Importer.union([{ keboard: keyboard_event_struct, mouse: mouse_event_struct}])
- assert_equal LIBC::UnionNestedStruct.size, event_union.size
- end
-
- def test_nested_struct_alignment_is_not_its_size()
- inner = Fiddle::Importer.struct(['int x', 'int y', 'int z', 'int w'])
- outer = Fiddle::Importer.struct(['char a', { 'nested' => inner }, 'char b'])
- outer.malloc(Fiddle::RUBY_FREE) do |instance|
- offset = instance.to_ptr.instance_variable_get(:"@offset")
- assert_equal Fiddle::SIZEOF_INT * 5, offset.last
- assert_equal Fiddle::SIZEOF_INT * 6, outer.size
- assert_equal instance.to_ptr.size, outer.size
- end
- end
-
- def test_struct_nested_struct_members()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- Fiddle::Pointer.malloc(24, Fiddle::RUBY_FREE) do |user_data|
- s.vertices[0].position.x = 1
- s.vertices[0].position.y = 2
- s.vertices[0].position.z = 3
- s.vertices[0].texcoord.u = 4
- s.vertices[0].texcoord.v = 5
- s.vertices[1].position.x = 6
- s.vertices[1].position.y = 7
- s.vertices[1].position.z = 8
- s.vertices[1].texcoord.u = 9
- s.vertices[1].texcoord.v = 10
- s.object.id = 100
- s.object.user_data = user_data
- s.id = 101
- assert_equal({
- "vertices" => [
- {
- "position" => {
- "x" => 1,
- "y" => 2,
- "z" => 3,
- },
- "texcoord" => {
- "u" => 4,
- "v" => 5,
- },
- },
- {
- "position" => {
- "x" => 6,
- "y" => 7,
- "z" => 8,
- },
- "texcoord" => {
- "u" => 9,
- "v" => 10,
- },
- },
- ],
- "object" => {
- "id" => 100,
- "user_data" => user_data,
- },
- "id" => 101,
- },
- s.to_h)
- end
- end
- end
-
- def test_union_nested_struct_members()
- LIBC::UnionNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- s.keyboard.state = 100
- s.keyboard.key = 101
- assert_equal(100, s.mouse.button)
- refute_equal( 0, s.mouse.x)
- end
- end
-
- def test_struct_nested_struct_replace_array_element()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- s.vertices[0].position.x = 5
-
- vertex_struct = Fiddle::Importer.struct [{
- position: ["float x", "float y", "float z"],
- texcoord: ["float u", "float v"]
- }]
- vertex_struct.malloc(Fiddle::RUBY_FREE) do |vertex|
- vertex.position.x = 100
- s.vertices[0] = vertex
-
- # make sure element was copied by value, but things like memory address
- # should not be changed
- assert_equal(100, s.vertices[0].position.x)
- refute_equal(vertex.object_id, s.vertices[0].object_id)
- refute_equal(vertex.to_ptr, s.vertices[0].to_ptr)
- end
- end
- end
-
- def test_struct_nested_struct_replace_array_element_nil()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- s.vertices[0].position.x = 5
- s.vertices[0] = nil
- assert_equal({
- "position" => {
- "x" => 0.0,
- "y" => 0.0,
- "z" => 0.0,
- },
- "texcoord" => {
- "u" => 0.0,
- "v" => 0.0,
- },
- },
- s.vertices[0].to_h)
- end
- end
-
- def test_struct_nested_struct_replace_array_element_hash()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- s.vertices[0] = {
- position: {
- x: 10,
- y: 100,
- }
- }
- assert_equal({
- "position" => {
- "x" => 10.0,
- "y" => 100.0,
- "z" => 0.0,
- },
- "texcoord" => {
- "u" => 0.0,
- "v" => 0.0,
- },
- },
- s.vertices[0].to_h)
- end
- end
-
- def test_struct_nested_struct_replace_entire_array()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- vertex_struct = Fiddle::Importer.struct [{
- position: ["float x", "float y", "float z"],
- texcoord: ["float u", "float v"]
- }]
-
- vertex_struct.malloc(Fiddle::RUBY_FREE) do |same0|
- vertex_struct.malloc(Fiddle::RUBY_FREE) do |same1|
- same = [same0, same1]
- same[0].position.x = 1; same[1].position.x = 6
- same[0].position.y = 2; same[1].position.y = 7
- same[0].position.z = 3; same[1].position.z = 8
- same[0].texcoord.u = 4; same[1].texcoord.u = 9
- same[0].texcoord.v = 5; same[1].texcoord.v = 10
- s.vertices = same
- assert_equal([
- {
- "position" => {
- "x" => 1.0,
- "y" => 2.0,
- "z" => 3.0,
- },
- "texcoord" => {
- "u" => 4.0,
- "v" => 5.0,
- },
- },
- {
- "position" => {
- "x" => 6.0,
- "y" => 7.0,
- "z" => 8.0,
- },
- "texcoord" => {
- "u" => 9.0,
- "v" => 10.0,
- },
- }
- ],
- s.vertices.collect(&:to_h))
- end
- end
- end
- end
-
- def test_struct_nested_struct_replace_entire_array_with_different_struct()
- LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s|
- different_struct_same_size = Fiddle::Importer.struct [{
- a: ['float i', 'float j', 'float k'],
- b: ['float l', 'float m']
- }]
-
- different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different0|
- different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different1|
- different = [different0, different1]
- different[0].a.i = 11; different[1].a.i = 16
- different[0].a.j = 12; different[1].a.j = 17
- different[0].a.k = 13; different[1].a.k = 18
- different[0].b.l = 14; different[1].b.l = 19
- different[0].b.m = 15; different[1].b.m = 20
- s.vertices[0][0, s.vertices[0].class.size] = different[0].to_ptr
- s.vertices[1][0, s.vertices[1].class.size] = different[1].to_ptr
- assert_equal([
- {
- "position" => {
- "x" => 11.0,
- "y" => 12.0,
- "z" => 13.0,
- },
- "texcoord" => {
- "u" => 14.0,
- "v" => 15.0,
- },
- },
- {
- "position" => {
- "x" => 16.0,
- "y" => 17.0,
- "z" => 18.0,
- },
- "texcoord" => {
- "u" => 19.0,
- "v" => 20.0,
- },
- }
- ],
- s.vertices.collect(&:to_h))
- end
- end
- end
- end
-
- def test_struct()
- LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |s|
- s.num = [0,1,2,3,4]
- s.c = ?a.ord
- s.buff = "012345\377"
- assert_equal([0,1,2,3,4], s.num)
- assert_equal(?a.ord, s.c)
- assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff)
- end
- end
-
- def test_gettimeofday()
- if( defined?(LIBC.gettimeofday) )
- LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |timeval|
- LIBC::Timezone.malloc(Fiddle::RUBY_FREE) do |timezone|
- LIBC.gettimeofday(timeval, timezone)
- end
- cur = Time.now()
- assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
- end
- end
- end
-
- def test_strcpy()
- buff = +"000"
- str = LIBC.strcpy(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_isdigit
- r1 = LIBC.isdigit(?1.ord)
- r2 = LIBC.isdigit(?2.ord)
- rr = LIBC.isdigit(?r.ord)
- assert_operator(r1, :>, 0)
- assert_operator(r2, :>, 0)
- assert_equal(0, rr)
- end
-
- def test_atof
- r = LIBC.atof("12.34")
- assert_includes(12.00..13.00, r)
- end
- end
-end if defined?(Fiddle)
diff --git a/test/fiddle/test_memory_view.rb b/test/fiddle/test_memory_view.rb
deleted file mode 100644
index 240cda37df..0000000000
--- a/test/fiddle/test_memory_view.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
- return
-end
-
-begin
- require '-test-/memory_view'
-rescue LoadError
- return
-end
-
-module Fiddle
- class TestMemoryView < TestCase
- def setup
- omit "MemoryView is unavailable" unless defined? Fiddle::MemoryView
- end
-
- def test_null_ptr
- assert_raise(ArgumentError) do
- MemoryView.new(Fiddle::NULL)
- end
- end
-
- def test_memory_view_from_unsupported_obj
- obj = Object.new
- assert_raise(ArgumentError) do
- MemoryView.new(obj)
- end
- end
-
- def test_memory_view_from_pointer
- str = Marshal.load(Marshal.dump("hello world"))
- ptr = Pointer[str]
- mview = MemoryView.new(ptr)
- assert_same(ptr, mview.obj)
- assert_equal(str.bytesize, mview.byte_size)
- assert_equal(true, mview.readonly?)
- assert_equal(nil, mview.format)
- assert_equal(1, mview.item_size)
- assert_equal(1, mview.ndim)
- assert_equal(nil, mview.shape)
- assert_equal(nil, mview.strides)
- assert_equal(nil, mview.sub_offsets)
-
- codes = str.codepoints
- assert_equal(codes, (0...str.bytesize).map {|i| mview[i] })
- end
-
- def test_memory_view_multi_dimensional
- omit "MemoryViewTestUtils is unavailable" unless defined? MemoryViewTestUtils
-
- buf = [ 1, 2, 3, 4,
- 5, 6, 7, 8,
- 9, 10, 11, 12 ].pack("l!*")
- shape = [3, 4]
- md = MemoryViewTestUtils::MultiDimensionalView.new(buf, "l!", shape, nil)
- mview = Fiddle::MemoryView.new(md)
- assert_equal(buf.bytesize, mview.byte_size)
- assert_equal("l!", mview.format)
- assert_equal(Fiddle::SIZEOF_LONG, mview.item_size)
- assert_equal(2, mview.ndim)
- assert_equal(shape, mview.shape)
- assert_equal([Fiddle::SIZEOF_LONG*4, Fiddle::SIZEOF_LONG], mview.strides)
- assert_equal(nil, mview.sub_offsets)
- assert_equal(1, mview[0, 0])
- assert_equal(4, mview[0, 3])
- assert_equal(6, mview[1, 1])
- assert_equal(10, mview[2, 1])
- end
-
- def test_memory_view_multi_dimensional_with_strides
- omit "MemoryViewTestUtils is unavailable" unless defined? MemoryViewTestUtils
-
- buf = [ 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16 ].pack("l!*")
- shape = [2, 8]
- strides = [4*Fiddle::SIZEOF_LONG*2, Fiddle::SIZEOF_LONG*2]
- md = MemoryViewTestUtils::MultiDimensionalView.new(buf, "l!", shape, strides)
- mview = Fiddle::MemoryView.new(md)
- assert_equal("l!", mview.format)
- assert_equal(Fiddle::SIZEOF_LONG, mview.item_size)
- assert_equal(buf.bytesize, mview.byte_size)
- assert_equal(2, mview.ndim)
- assert_equal(shape, mview.shape)
- assert_equal(strides, mview.strides)
- assert_equal(nil, mview.sub_offsets)
- assert_equal(1, mview[0, 0])
- assert_equal(5, mview[0, 2])
- assert_equal(9, mview[1, 0])
- assert_equal(15, mview[1, 3])
- end
-
- def test_memory_view_multi_dimensional_with_multiple_members
- omit "MemoryViewTestUtils is unavailable" unless defined? MemoryViewTestUtils
-
- buf = [ 1, 2, 3, 4, 5, 6, 7, 8,
- -1, -2, -3, -4, -5, -6, -7, -8].pack("s*")
- shape = [2, 4]
- strides = [4*Fiddle::SIZEOF_SHORT*2, Fiddle::SIZEOF_SHORT*2]
- md = MemoryViewTestUtils::MultiDimensionalView.new(buf, "ss", shape, strides)
- mview = Fiddle::MemoryView.new(md)
- assert_equal("ss", mview.format)
- assert_equal(Fiddle::SIZEOF_SHORT*2, mview.item_size)
- assert_equal(buf.bytesize, mview.byte_size)
- assert_equal(2, mview.ndim)
- assert_equal(shape, mview.shape)
- assert_equal(strides, mview.strides)
- assert_equal(nil, mview.sub_offsets)
- assert_equal([1, 2], mview[0, 0])
- assert_equal([5, 6], mview[0, 2])
- assert_equal([-1, -2], mview[1, 0])
- assert_equal([-7, -8], mview[1, 3])
- end
-
- def test_export
- str = "hello world"
- mview_str = MemoryView.export(Pointer[str]) do |mview|
- mview.to_s
- end
- assert_equal(str, mview_str)
- end
-
- def test_release
- ptr = Pointer["hello world"]
- mview = MemoryView.new(ptr)
- assert_same(ptr, mview.obj)
- mview.release
- assert_nil(mview.obj)
- end
-
- def test_to_s
- # U+3042 HIRAGANA LETTER A
- data = "\u{3042}"
- ptr = Pointer[data]
- mview = MemoryView.new(ptr)
- string = mview.to_s
- assert_equal([data.b, true],
- [string, string.frozen?])
- end
- end
-end
diff --git a/test/fiddle/test_pinned.rb b/test/fiddle/test_pinned.rb
deleted file mode 100644
index f0d375b1cc..0000000000
--- a/test/fiddle/test_pinned.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
- return
-end
-
-module Fiddle
- class TestPinned < Fiddle::TestCase
- def test_pin_object
- x = Object.new
- pinner = Pinned.new x
- assert_same x, pinner.ref
- end
-
- def test_clear
- pinner = Pinned.new Object.new
- refute pinner.cleared?
- pinner.clear
- assert pinner.cleared?
- ex = assert_raise(Fiddle::ClearedReferenceError) do
- pinner.ref
- end
- assert_match "called on", ex.message
- end
- end
-end
-
diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb
deleted file mode 100644
index 7d708ee417..0000000000
--- a/test/fiddle/test_pointer.rb
+++ /dev/null
@@ -1,287 +0,0 @@
-# frozen_string_literal: true
-begin
- require_relative 'helper'
-rescue LoadError
-end
-
-module Fiddle
- class TestPointer < TestCase
- def dlwrap arg
- Fiddle.dlwrap arg
- end
-
- def test_cptr_to_int
- null = Fiddle::NULL
- assert_equal(null.to_i, null.to_int)
- end
-
- def test_malloc_free_func_int
- free = Fiddle::Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID)
- assert_equal free.to_i, Fiddle::RUBY_FREE.to_i
-
- ptr = Pointer.malloc(10, free.to_i)
- assert_equal 10, ptr.size
- assert_equal free.to_i, ptr.free.to_i
- end
-
- def test_malloc_free_func
- free = Fiddle::Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID)
-
- ptr = Pointer.malloc(10, free)
- assert_equal 10, ptr.size
- assert_equal free.to_i, ptr.free.to_i
- end
-
- def test_malloc_block
- escaped_ptr = nil
- returned = Pointer.malloc(10, Fiddle::RUBY_FREE) do |ptr|
- assert_equal 10, ptr.size
- assert_equal Fiddle::RUBY_FREE, ptr.free.to_i
- escaped_ptr = ptr
- :returned
- end
- assert_equal :returned, returned
- assert escaped_ptr.freed?
- end
-
- def test_malloc_block_no_free
- assert_raise ArgumentError do
- Pointer.malloc(10) { |ptr| }
- end
- end
-
- def test_malloc_subclass
- subclass = Class.new(Pointer)
- subclass.malloc(10, Fiddle::RUBY_FREE) do |ptr|
- assert ptr.is_a?(subclass)
- end
- end
-
- def test_to_str
- str = Marshal.load(Marshal.dump("hello world"))
- ptr = Pointer[str]
-
- assert_equal 3, ptr.to_str(3).length
- assert_equal str, ptr.to_str
-
- ptr[5] = 0
- assert_equal "hello\0world", ptr.to_str
- end
-
- def test_to_s
- str = Marshal.load(Marshal.dump("hello world"))
- ptr = Pointer[str]
-
- assert_equal 3, ptr.to_s(3).length
- assert_equal str, ptr.to_s
-
- ptr[5] = 0
- assert_equal 'hello', ptr.to_s
- end
-
- def test_minus
- str = "hello world"
- ptr = Pointer[str]
- assert_equal ptr.to_s, (ptr + 3 - 3).to_s
- end
-
- # TODO: what if the pointer size is 0? raise an exception? do we care?
- def test_plus
- str = "hello world"
- ptr = Pointer[str]
- new_str = ptr + 3
- assert_equal 'lo world', new_str.to_s
- end
-
- def test_inspect
- ptr = Pointer.new(0)
- inspect = ptr.inspect
- assert_match(/size=#{ptr.size}/, inspect)
- assert_match(/free=#{sprintf("%#x", ptr.free.to_i)}/, inspect)
- assert_match(/ptr=#{sprintf("%#x", ptr.to_i)}/, inspect)
- end
-
- def test_to_ptr_string
- str = "hello world"
- ptr = Pointer[str]
- assert_equal str.length, ptr.size
- assert_equal 'hello', ptr[0,5]
- end
-
- def test_to_ptr_io
- Pointer.malloc(10, Fiddle::RUBY_FREE) do |buf|
- File.open(__FILE__, 'r') do |f|
- ptr = Pointer.to_ptr f
- fread = Function.new(@libc['fread'],
- [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP],
- TYPE_INT)
- fread.call(buf.to_i, Fiddle::SIZEOF_CHAR, buf.size - 1, ptr.to_i)
- end
-
- File.open(__FILE__, 'r') do |f|
- assert_equal f.read(9), buf.to_s
- end
- end
- end
-
- def test_to_ptr_with_ptr
- ptr = Pointer.new 0
- ptr2 = Pointer.to_ptr Struct.new(:to_ptr).new(ptr)
- assert_equal ptr, ptr2
-
- assert_raise(Fiddle::DLError) do
- Pointer.to_ptr Struct.new(:to_ptr).new(nil)
- end
- end
-
- def test_to_ptr_with_num
- ptr = Pointer.new 0
- assert_equal ptr, Pointer[0]
- end
-
- def test_equals
- ptr = Pointer.new 0
- ptr2 = Pointer.new 0
- assert_equal ptr2, ptr
- end
-
- def test_not_equals
- ptr = Pointer.new 0
- refute_equal 10, ptr, '10 should not equal the pointer'
- end
-
- def test_cmp
- ptr = Pointer.new 0
- assert_nil(ptr <=> 10, '10 should not be comparable')
- end
-
- def test_ref_ptr
- ary = [0,1,2,4,5]
- addr = Pointer.new(dlwrap(ary))
- assert_equal addr.to_i, addr.ref.ptr.to_i
-
- assert_equal addr.to_i, (+ (- addr)).to_i
- end
-
- def test_to_value
- ary = [0,1,2,4,5]
- addr = Pointer.new(dlwrap(ary))
- assert_equal ary, addr.to_value
- end
-
- def test_free
- ptr = Pointer.malloc(4)
- begin
- assert_nil ptr.free
- ensure
- Fiddle.free ptr
- end
- end
-
- def test_free=
- free = Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID)
- ptr = Pointer.malloc(4)
- ptr.free = free
-
- assert_equal free.ptr, ptr.free.ptr
- end
-
- def test_free_with_func
- ptr = Pointer.malloc(4, Fiddle::RUBY_FREE)
- refute ptr.freed?
- ptr.call_free
- assert ptr.freed?
- ptr.call_free # you can safely run it again
- assert ptr.freed?
- GC.start # you can safely run the GC routine
- assert ptr.freed?
- end
-
- def test_free_with_no_func
- ptr = Pointer.malloc(4)
- refute ptr.freed?
- ptr.call_free
- refute ptr.freed?
- ptr.call_free # you can safely run it again
- refute ptr.freed?
- end
-
- def test_freed?
- ptr = Pointer.malloc(4, Fiddle::RUBY_FREE)
- refute ptr.freed?
- ptr.call_free
- assert ptr.freed?
- end
-
- def test_null?
- ptr = Pointer.new(0)
- assert ptr.null?
- end
-
- def test_size
- Pointer.malloc(4, Fiddle::RUBY_FREE) do |ptr|
- assert_equal 4, ptr.size
- end
- end
-
- def test_size=
- Pointer.malloc(4, Fiddle::RUBY_FREE) do |ptr|
- ptr.size = 10
- assert_equal 10, ptr.size
- end
- end
-
- def test_aref_aset
- check = Proc.new{|str,ptr|
- assert_equal(str.size(), ptr.size())
- assert_equal(str, ptr.to_s())
- assert_equal(str[0,2], ptr.to_s(2))
- assert_equal(str[0,2], ptr[0,2])
- assert_equal(str[1,2], ptr[1,2])
- assert_equal(str[1,0], ptr[1,0])
- assert_equal(str[0].ord, ptr[0])
- assert_equal(str[1].ord, ptr[1])
- }
- str = Marshal.load(Marshal.dump('abc'))
- ptr = Pointer[str]
- check.call(str, ptr)
-
- str[0] = "c"
- assert_equal 'c'.ord, ptr[0] = "c".ord
- check.call(str, ptr)
-
- str[0,2] = "aa"
- assert_equal 'aa', ptr[0,2] = "aa"
- check.call(str, ptr)
-
- ptr2 = Pointer['cdeeee']
- str[0,2] = "cd"
- assert_equal ptr2, ptr[0,2] = ptr2
- check.call(str, ptr)
-
- ptr3 = Pointer['vvvv']
- str[0,2] = "vv"
- assert_equal ptr3.to_i, ptr[0,2] = ptr3.to_i
- check.call(str, ptr)
- end
-
- def test_null_pointer
- nullpo = Pointer.new(0)
- assert_raise(DLError) {nullpo[0]}
- assert_raise(DLError) {nullpo[0] = 1}
- end
-
- def test_no_memory_leak
- if respond_to?(:assert_nothing_leaked_memory)
- n_tries = 100_000
- assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do
- n_tries.times do
- Fiddle::Pointer.allocate
- end
- end
- else
- assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Pointer.allocate}', rss: true)
- end
- end
- end
-end if defined?(Fiddle)