diff options
Diffstat (limited to 'test/fiddle/test_closure.rb')
-rw-r--r-- | test/fiddle/test_closure.rb | 123 |
1 files changed, 83 insertions, 40 deletions
diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb index 9e748bf5ee..abb6bdbd32 100644 --- a/test/fiddle/test_closure.rb +++ b/test/fiddle/test_closure.rb @@ -6,6 +6,17 @@ end module Fiddle class TestClosure < Fiddle::TestCase + def teardown + super + # Ensure freeing all closures. + # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 . + not_freed_closures = [] + ObjectSpace.each_object(Fiddle::Closure) do |closure| + not_freed_closures << closure unless closure.freed? + end + assert_equal([], not_freed_closures) + end + def test_argument_errors assert_raise(TypeError) do Closure.new(TYPE_INT, TYPE_INT) @@ -21,37 +32,40 @@ module Fiddle 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), - ]) + Closure.create(:int, [:void]) do |closure| + assert_equal([ + TYPE_INT, + [TYPE_VOID], + ], + [ + closure.instance_variable_get(:@ctype), + closure.instance_variable_get(:@args), + ]) + end end def test_call - closure = Class.new(Closure) { + closure_class = Class.new(Closure) do def call 10 end - }.new(TYPE_INT, []) - - func = Function.new(closure, [], TYPE_INT) - assert_equal 10, func.call + end + closure_class.create(TYPE_INT, []) do |closure| + func = Function.new(closure, [], TYPE_INT) + assert_equal 10, func.call + end end def test_returner - closure = Class.new(Closure) { + closure_class = Class.new(Closure) do 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 + closure_class.create(TYPE_INT, [TYPE_INT]) do |closure| + func = Function.new(closure, [TYPE_INT], TYPE_INT) + assert_equal 10, func.call(10) + end end def test_const_string @@ -61,25 +75,53 @@ module Fiddle @return_string end end - closure = closure_class.new(:const_string, [:const_string]) + closure_class.create(:const_string, [:const_string]) do |closure| + func = Function.new(closure, [:const_string], :const_string) + assert_equal("Hello! World!", func.call("World!")) + end + end - func = Function.new(closure, [:const_string], :const_string) - assert_equal("Hello! World!", func.call("World!")) + def test_bool + closure_class = Class.new(Closure) do + def call(bool) + not bool + end + end + closure_class.create(:bool, [:bool]) do |closure| + func = Function.new(closure, [:bool], :bool) + assert_equal(false, func.call(true)) + end + end + + def test_free + Closure.create(:int, [:void]) do |closure| + assert(!closure.freed?) + closure.free + assert(closure.freed?) + closure.free + end 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) + begin + func = Function.new(cb, [TYPE_INT], TYPE_INT) + assert_equal 11, func.call(11) + ensure + cb.free + end end - def test_memsize + def test_memsize_ruby_dev_42480 require 'objspace' - bug = '[ruby-dev:42480]' n = 10000 - assert_equal(n, n.times {ObjectSpace.memsize_of(Closure.allocate)}, bug) + n.times do + Closure.create(:int, [:void]) do |closure| + ObjectSpace.memsize_of(closure) + end + end end %w[INT SHORT CHAR LONG LONG_LONG].each do |name| @@ -89,20 +131,21 @@ module Fiddle define_method("test_conversion_#{n.downcase}") do arg = nil - clos = Class.new(Closure) do + closure_class = 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 + closure_class.create(t, [t]) do |closure| + v = ~(~0 << (8*s)) + + arg = nil + assert_equal(v, closure.call(v)) + assert_equal(arg, v, n) + + arg = nil + func = Function.new(closure, [t], t) + assert_equal(v, func.call(v)) + assert_equal(arg, v, n) + end end end end |