summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2022-03-30 11:03:56 -0700
committerGitHub <noreply@github.com>2022-03-30 11:03:56 -0700
commitfbaadd1cfe7fbfd1b904f193f99d7c845a6ed804 (patch)
tree298c1393d770cc229d731b43ac13c793dcd93a36 /test/ruby
parent75efbb98afe854972a1c832ec5d4d66639c41c74 (diff)
Do not autosplat array in block call just because keywords accepted
If the block only accepts a single positional argument plus keywords, then do not autosplat. Still autosplat if the block accepts more than one positional argument in addition to keywords. Autosplatting a single positional argument plus keywords made sense in Ruby 2, since a final positional hash could be used as keywords, but it does not make sense in Ruby 3. Fixes [Bug #18633]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5665 Merged-By: jeremyevans <code@jeremyevans.net>
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_keyword.rb2
-rw-r--r--test/ruby/test_proc.rb82
2 files changed, 83 insertions, 1 deletions
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 9094259bc2..0d766905bd 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -3538,7 +3538,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal(splat_expect, pr.call(a), bug8463)
pr = proc {|a, **opt| next a, opt}
- assert_equal(splat_expect.values_at(0, -1), pr.call(splat_expect), bug8463)
+ assert_equal([splat_expect, {}], pr.call(splat_expect), bug8463)
end
def req_plus_keyword(x, **h)
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index bcba3a127b..05c6e03aac 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -857,6 +857,88 @@ class TestProc < Test::Unit::TestCase
assert_equal [[1, 2], Proc, :x], (pr.call(1, 2){|x| x})
end
+ def test_proc_args_single_kw_no_autosplat
+ pr = proc {|c, a: 1| [c, a] }
+ assert_equal [nil, 1], pr.call()
+ assert_equal [1, 1], pr.call(1)
+ assert_equal [[1], 1], pr.call([1])
+ assert_equal [1, 1], pr.call(1,2)
+ assert_equal [[1, 2], 1], pr.call([1,2])
+
+ assert_equal [nil, 3], pr.call(a: 3)
+ assert_equal [1, 3], pr.call(1, a: 3)
+ assert_equal [[1], 3], pr.call([1], a: 3)
+ assert_equal [1, 3], pr.call(1,2, a: 3)
+ assert_equal [[1, 2], 3], pr.call([1,2], a: 3)
+ end
+
+ def test_proc_args_single_kwsplat_no_autosplat
+ pr = proc {|c, **kw| [c, kw] }
+ assert_equal [nil, {}], pr.call()
+ assert_equal [1, {}], pr.call(1)
+ assert_equal [[1], {}], pr.call([1])
+ assert_equal [1, {}], pr.call(1,2)
+ assert_equal [[1, 2], {}], pr.call([1,2])
+
+ assert_equal [nil, {a: 3}], pr.call(a: 3)
+ assert_equal [1, {a: 3}], pr.call(1, a: 3)
+ assert_equal [[1], {a: 3}], pr.call([1], a: 3)
+ assert_equal [1, {a: 3}], pr.call(1,2, a: 3)
+ assert_equal [[1, 2], {a: 3}], pr.call([1,2], a: 3)
+ end
+
+ def test_proc_args_multiple_kw_autosplat
+ pr = proc {|c, b, a: 1| [c, b, a] }
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c=nil, b=nil, a: 1| [c, b, a] }
+ assert_equal [nil, nil, 1], pr.call([])
+ assert_equal [1, nil, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c, b=nil, a: 1| [c, b, a] }
+ assert_equal [1, nil, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c=nil, b, a: 1| [c, b, a] }
+ assert_equal [nil, 1, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c, *b, a: 1| [c, b, a] }
+ assert_equal [1, [], 1], pr.call([1])
+ assert_equal [1, [2], 1], pr.call([1,2])
+
+ pr = proc {|*c, b, a: 1| [c, b, a] }
+ assert_equal [[], 1, 1], pr.call([1])
+ assert_equal [[1], 2, 1], pr.call([1,2])
+ end
+
+ def test_proc_args_multiple_kwsplat_autosplat
+ pr = proc {|c, b, **kw| [c, b, kw] }
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c=nil, b=nil, **kw| [c, b, kw] }
+ assert_equal [nil, nil, {}], pr.call([])
+ assert_equal [1, nil, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c, b=nil, **kw| [c, b, kw] }
+ assert_equal [1, nil, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c=nil, b, **kw| [c, b, kw] }
+ assert_equal [nil, 1, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c, *b, **kw| [c, b, kw] }
+ assert_equal [1, [], {}], pr.call([1])
+ assert_equal [1, [2], {}], pr.call([1,2])
+
+ pr = proc {|*c, b, **kw| [c, b, kw] }
+ assert_equal [[], 1, {}], pr.call([1])
+ assert_equal [[1], 2, {}], pr.call([1,2])
+ end
+
def test_proc_args_only_rest
pr = proc {|*c| c }
assert_equal [], pr.call()