diff options
author | Jeremy Evans <code@jeremyevans.net> | 2019-12-05 11:01:20 -0800 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2019-12-09 17:10:19 +0200 |
commit | f45c0dc23980d7fd8167d290ea7c354cf2cdb500 (patch) | |
tree | 66f279aadb01d932d8ce320b7f268ddc9f1dc67a /test | |
parent | c2dc27d6435f40ff24f553cf47816a1c696bbbba (diff) |
Add Proc#ruby2_keywords
This allows passing keywords through a normal argument splat in a
Proc. While needing ruby2_keywords support for methods is more
common, there is code that delegates keywords through normal
argument splats in procs, including code in Rails. For that
reason, it makes sense to expose this for procs as well.
Internally, ruby2_keywords is not tied to methods, but iseqs,
so this just allows for setting the ruby2_keywords for the iseq
related to the proc.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2728
Diffstat (limited to 'test')
-rw-r--r-- | test/ruby/test_keyword.rb | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb index 295b499530..b0199e0c53 100644 --- a/test/ruby/test_keyword.rb +++ b/test/ruby/test_keyword.rb @@ -2684,6 +2684,45 @@ class TestKeywordArguments < Test::Unit::TestCase assert_raise(ArgumentError) { m.call(42, a: 1, **h2) } end + def test_proc_ruby2_keywords + h1 = {:a=>1} + foo = ->(*args, &block){block.call(*args)} + assert_same(foo, foo.ruby2_keywords) + + assert_equal([[1], h1], foo.call(1, :a=>1, &->(*args, **kw){[args, kw]})) + assert_equal([1, h1], foo.call(1, :a=>1, &->(*args){args})) + assert_warn(/The last argument is used as the keyword parameter/) do + assert_equal([[1], h1], foo.call(1, {:a=>1}, &->(*args, **kw){[args, kw]})) + end + assert_equal([1, h1], foo.call(1, {:a=>1}, &->(*args){args})) + assert_warn(/The keyword argument is passed as the last hash parameter/) do + assert_equal([h1, {}], foo.call(:a=>1, &->(arg, **kw){[arg, kw]})) + end + assert_equal(h1, foo.call(:a=>1, &->(arg){arg})) + + [->(){}, ->(arg){}, ->(*args, **kw){}, ->(*args, k: 1){}, ->(*args, k: ){}].each do |pr| + assert_warn(/Skipping set of ruby2_keywords flag for proc \(proc accepts keywords or proc does not accept argument splat\)/) do + pr.ruby2_keywords + end + end + + o = Object.new + def o.foo(*args) + yield *args + end + foo = o.method(:foo).to_proc + assert_warn(/Skipping set of ruby2_keywords flag for proc \(proc created from method\)/) do + foo.ruby2_keywords + end + + foo = :foo.to_proc + assert_warn(/Skipping set of ruby2_keywords flag for proc \(proc not defined in Ruby\)/) do + foo.ruby2_keywords + end + + assert_raise(FrozenError) { ->(*args){}.freeze.ruby2_keywords } + end + def test_ruby2_keywords c = Class.new do ruby2_keywords def foo(meth, *args) |