diff options
Diffstat (limited to 'test/ruby/test_method.rb')
| -rw-r--r-- | test/ruby/test_method.rb | 144 |
1 files changed, 139 insertions, 5 deletions
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index ebe711ddb4..8561f841a8 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -209,6 +209,27 @@ class TestMethod < Test::Unit::TestCase assert_kind_of(String, o.method(:foo).hash.to_s) end + def test_hash_does_not_change_after_compaction + omit "compaction is not supported on this platform" unless GC.respond_to?(:compact) + + # iseq backed method + assert_separately([], <<~RUBY) + def a; end + + # Need this method here because otherwise the iseq may be on the C stack + # which would get pinned and not move during compaction + def get_hash + method(:a).hash + end + + hash = get_hash + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + assert_equal(hash, get_hash) + RUBY + end + def test_owner c = Class.new do def foo; end @@ -263,8 +284,10 @@ class TestMethod < Test::Unit::TestCase assert_raise(TypeError) { m.bind(Object.new) } cx = EnvUtil.labeled_class("X\u{1f431}") - assert_raise_with_message(TypeError, /X\u{1f431}/) do - o.method(cx) + EnvUtil.with_default_internal(Encoding::UTF_8) do + assert_raise_with_message(TypeError, /X\u{1f431}/) do + o.method(cx) + end end end @@ -294,9 +317,12 @@ class TestMethod < Test::Unit::TestCase assert_raise(TypeError) do Class.new.class_eval { define_method(:bar, o.method(:bar)) } end + cx = EnvUtil.labeled_class("X\u{1f431}") - assert_raise_with_message(TypeError, /X\u{1F431}/) do - Class.new {define_method(cx) {}} + EnvUtil.with_default_internal(Encoding::UTF_8) do + assert_raise_with_message(TypeError, /X\u{1F431}/) do + Class.new {define_method(cx) {}} + end end end @@ -1418,6 +1444,46 @@ class TestMethod < Test::Unit::TestCase def foo a = b = c = a = b = c = 12345 end + + def binding_noarg + a = a = 12345 + binding + end + + def binding_one_arg(x) + a = a = 12345 + binding + end + + def binding_optargs(x, y=42) + a = a = 12345 + binding + end + + def binding_anyargs(*x) + a = a = 12345 + binding + end + + def binding_keywords(x: 42) + a = a = 12345 + binding + end + + def binding_anykeywords(**x) + a = a = 12345 + binding + end + + def binding_forwarding(...) + a = a = 12345 + binding + end + + def binding_forwarding1(x, ...) + a = a = 12345 + binding + end end def test_to_proc_binding @@ -1436,6 +1502,66 @@ class TestMethod < Test::Unit::TestCase assert_equal([:bar, :foo], b.local_variables.sort, bug11012) end + def test_method_binding + c = C.new + + b = c.binding_noarg + assert_equal(12345, b.local_variable_get(:a)) + + b = c.binding_one_arg(0) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(0, b.local_variable_get(:x)) + + b = c.binding_anyargs() + assert_equal(12345, b.local_variable_get(:a)) + assert_equal([], b.local_variable_get(:x)) + b = c.binding_anyargs(0) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal([0], b.local_variable_get(:x)) + b = c.binding_anyargs(0, 1) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal([0, 1], b.local_variable_get(:x)) + + b = c.binding_optargs(0) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(0, b.local_variable_get(:x)) + assert_equal(42, b.local_variable_get(:y)) + b = c.binding_optargs(0, 1) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(0, b.local_variable_get(:x)) + assert_equal(1, b.local_variable_get(:y)) + + b = c.binding_keywords() + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(42, b.local_variable_get(:x)) + b = c.binding_keywords(x: 102) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(102, b.local_variable_get(:x)) + + b = c.binding_anykeywords() + assert_equal(12345, b.local_variable_get(:a)) + assert_equal({}, b.local_variable_get(:x)) + b = c.binding_anykeywords(foo: 999) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal({foo: 999}, b.local_variable_get(:x)) + + b = c.binding_forwarding() + assert_equal(12345, b.local_variable_get(:a)) + b = c.binding_forwarding(0) + assert_equal(12345, b.local_variable_get(:a)) + b = c.binding_forwarding(0, 1) + assert_equal(12345, b.local_variable_get(:a)) + b = c.binding_forwarding(foo: 42) + assert_equal(12345, b.local_variable_get(:a)) + + b = c.binding_forwarding1(987) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(987, b.local_variable_get(:x)) + b = c.binding_forwarding1(987, 654) + assert_equal(12345, b.local_variable_get(:a)) + assert_equal(987, b.local_variable_get(:x)) + end + MethodInMethodClass_Setup = -> do remove_const :MethodInMethodClass if defined? MethodInMethodClass @@ -1491,7 +1617,7 @@ class TestMethod < Test::Unit::TestCase begin foo(1) rescue ArgumentError => e - assert_equal "main.rb:#{$line_method}:in 'foo'", e.backtrace.first + assert_equal "main.rb:#{$line_method}:in 'Object#foo'", e.backtrace.first end EOS END_OF_BODY @@ -1755,5 +1881,13 @@ class TestMethod < Test::Unit::TestCase RUBY assert_equal 0, err.size, err.join("\n") end + + assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status| + def foo(*, &block) = block + def bar(buz, ...) = foo(buz, ...) + bar(:test) {} # do not warn because of forwarding + RUBY + assert_equal 0, err.size, err.join("\n") + end end end |
