summaryrefslogtreecommitdiff
path: root/test/ruby/test_call.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_call.rb')
-rw-r--r--test/ruby/test_call.rb131
1 files changed, 130 insertions, 1 deletions
diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb
index 14847bf629..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)
@@ -357,6 +393,99 @@ class TestCall < Test::Unit::TestCase
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 = []