diff options
Diffstat (limited to 'test/ruby/test_call.rb')
| -rw-r--r-- | test/ruby/test_call.rb | 163 |
1 files changed, 160 insertions, 3 deletions
diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb index ced1eaf5e9..dd1936c4e2 100644 --- a/test/ruby/test_call.rb +++ b/test/ruby/test_call.rb @@ -3,7 +3,24 @@ require 'test/unit' require '-test-/iter' class TestCall < Test::Unit::TestCase - def aaa(a, b=100, *rest) + # These dummy method definitions prevent warnings "the block passed to 'a'..." + def a(&) = nil + def b(&) = nil + def c(&) = nil + def d(&) = nil + def e(&) = nil + def f(&) = nil + def g(&) = nil + def h(&) = nil + def i(&) = nil + def j(&) = nil + def k(&) = nil + def l(&) = nil + def m(&) = nil + def n(&) = nil + def o(&) = nil + + def aaa(a, b=100, *rest, &) res = [a, b] res += rest if rest return res @@ -106,6 +123,25 @@ class TestCall < Test::Unit::TestCase assert_equal([1, 2, {kw: 3}], f(*a, kw: 3)) end + def test_forward_argument_init + o = Object.new + def o.simple_forward_argument_init(a=eval('b'), b=1) + [a, b] + end + + def o.complex_forward_argument_init(a=eval('b'), b=eval('kw'), kw: eval('kw2'), kw2: 3) + [a, b, kw, kw2] + end + + def o.keyword_forward_argument_init(a: eval('b'), b: eval('kw'), kw: eval('kw2'), kw2: 3) + [a, b, kw, kw2] + end + + assert_equal [nil, 1], o.simple_forward_argument_init + assert_equal [nil, nil, 3, 3], o.complex_forward_argument_init + assert_equal [nil, nil, 3, 3], o.keyword_forward_argument_init + end + def test_call_bmethod_proc pr = proc{|sym| sym} define_singleton_method(:a, &pr) @@ -303,7 +339,7 @@ class TestCall < Test::Unit::TestCase assert_syntax_error(%q{h[*a, 2, b: 5, **kw] += 1}, message) end - def test_call_splat_order + def test_call_splat_post_order bug12860 = '[ruby-core:77701] [Bug# 12860]' ary = [1, 2] assert_equal([1, 2, 1], aaa(*ary, ary.shift), bug12860) @@ -311,7 +347,7 @@ class TestCall < Test::Unit::TestCase assert_equal([0, 1, 2, 1], aaa(0, *ary, ary.shift), bug12860) end - def test_call_block_order + def test_call_splat_block_order bug16504 = '[ruby-core:96769] [Bug# 16504]' b = proc{} ary = [1, 2, b] @@ -320,6 +356,22 @@ class TestCall < Test::Unit::TestCase assert_equal([0, 1, 2, b], aaa(0, *ary, &ary.pop), bug16504) end + def test_call_splat_kw_order + b = {} + ary = [1, 2, b] + assert_equal([1, 2, b, {a: b}], aaa(*ary, a: ary.pop)) + ary = [1, 2, b] + assert_equal([0, 1, 2, b, {a: b}], aaa(0, *ary, a: ary.pop)) + end + + def test_call_splat_kw_splat_order + b = {} + ary = [1, 2, b] + assert_equal([1, 2, b], aaa(*ary, **ary.pop)) + ary = [1, 2, b] + assert_equal([0, 1, 2, b], aaa(0, *ary, **ary.pop)) + end + def test_call_args_splat_with_nonhash_keyword_splat o = Object.new def o.to_hash; {a: 1} end @@ -329,6 +381,111 @@ class TestCall < Test::Unit::TestCase assert_equal Hash, f(*[], **o).class end + def test_call_args_splat_with_pos_arg_kw_splat_is_not_mutable + o = Object.new + def o.foo(a, **h)= h[:splat_modified] = true + + a = [] + b = {splat_modified: false} + + o.foo(*a, :x, **b) + + assert_equal({splat_modified: false}, b) + end + + def test_anon_splat + r2kh = Hash.ruby2_keywords_hash(kw: 2) + r2kea = [r2kh] + r2ka = [1, r2kh] + + def self.s(*) ->(*a){a}.call(*) end + assert_equal([], s) + assert_equal([1], s(1)) + assert_equal([{kw: 2}], s(kw: 2)) + assert_equal([{kw: 2}], s(**{kw: 2})) + assert_equal([1, {kw: 2}], s(1, kw: 2)) + assert_equal([1, {kw: 2}], s(1, **{kw: 2})) + assert_equal([{kw: 2}], s(*r2kea)) + assert_equal([1, {kw: 2}], s(*r2ka)) + + singleton_class.remove_method(:s) + def self.s(*, kw: 0) [*->(*a){a}.call(*), kw] end + assert_equal([0], s) + assert_equal([1, 0], s(1)) + assert_equal([2], s(kw: 2)) + assert_equal([2], s(**{kw: 2})) + assert_equal([1, 2], s(1, kw: 2)) + assert_equal([1, 2], s(1, **{kw: 2})) + assert_equal([2], s(*r2kea)) + assert_equal([1, 2], s(*r2ka)) + + singleton_class.remove_method(:s) + def self.s(*, **kw) [*->(*a){a}.call(*), kw] end + assert_equal([{}], s) + assert_equal([1, {}], s(1)) + assert_equal([{kw: 2}], s(kw: 2)) + assert_equal([{kw: 2}], s(**{kw: 2})) + assert_equal([1, {kw: 2}], s(1, kw: 2)) + assert_equal([1, {kw: 2}], s(1, **{kw: 2})) + assert_equal([{kw: 2}], s(*r2kea)) + assert_equal([1, {kw: 2}], s(*r2ka)) + + singleton_class.remove_method(:s) + def self.s(*, kw: 0, **kws) [*->(*a){a}.call(*), kw, kws] end + assert_equal([0, {}], s) + assert_equal([1, 0, {}], s(1)) + assert_equal([2, {}], s(kw: 2)) + assert_equal([2, {}], s(**{kw: 2})) + assert_equal([1, 2, {}], s(1, kw: 2)) + assert_equal([1, 2, {}], s(1, **{kw: 2})) + assert_equal([2, {}], s(*r2kea)) + assert_equal([1, 2, {}], s(*r2ka)) + end + + def test_anon_splat_mutated_bug_21757 + args = [1, 2] + kw = {bug: true} + + def self.m(*); end + m(*args, bug: true) + assert_equal(2, args.length) + + proc = ->(*) { } + proc.(*args, bug: true) + assert_equal(2, args.length) + + def self.m2(*); end + m2(*args, **kw) + assert_equal(2, args.length) + + proc = ->(*) { } + proc.(*args, **kw) + assert_equal(2, args.length) + + def self.m3(*, **nil); end + assert_raise(ArgumentError) { m3(*args, bug: true) } + assert_equal(2, args.length) + + proc = ->(*, **nil) { } + assert_raise(ArgumentError) { proc.(*args, bug: true) } + assert_equal(2, args.length) + end + + def test_kwsplat_block_eval_order + def self.t(**kw, &b) [kw, b] end + + pr = ->{} + h = {a: pr} + a = [] + + ary = t(**h, &h.delete(:a)) + assert_equal([{a: pr}, pr], ary) + + h = {a: pr} + ary = t(*a, **h, &h.delete(:a)) + assert_equal([{a: pr}, pr], ary) + end + def test_kwsplat_block_order o = Object.new ary = [] |
