diff options
Diffstat (limited to 'spec/ruby/language/delegation_spec.rb')
| -rw-r--r-- | spec/ruby/language/delegation_spec.rb | 184 |
1 files changed, 139 insertions, 45 deletions
diff --git a/spec/ruby/language/delegation_spec.rb b/spec/ruby/language/delegation_spec.rb index 8e4183cbcc..3d917993f5 100644 --- a/spec/ruby/language/delegation_spec.rb +++ b/spec/ruby/language/delegation_spec.rb @@ -1,68 +1,162 @@ require_relative '../spec_helper' require_relative 'fixtures/delegation' -ruby_version_is "2.7" do - describe "delegation with def(...)" do - it "delegates rest and kwargs" do - a = Class.new(DelegationSpecs::Target) +# Forwarding anonymous parameters +describe "delegation with def(...)" do + it "delegates rest and kwargs" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(...) + target(...) + end + RUBY + + a.new.delegate(1, b: 2).should == [[1], {b: 2}, nil] + end + + it "delegates a block literal" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate_block(...) + target_block(...) + end + RUBY + + a.new.delegate_block(1, b: 2) { |x| x }.should == [{b: 2}, [1]] + end + + it "delegates a block argument" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(...) + target(...) + end + RUBY + + block = proc {} + a.new.delegate(1, b: 2, &block).should == [[1], {b: 2}, block] + end + + it "delegates with additional arguments" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(...) + target(:first, :second, ...) + end + RUBY + a.new.delegate(1, b: 2).should == [[:first, :second, 1], {b: 2}, nil] + end + + it "parses as open endless Range when brackets are omitted" do + a = Class.new(DelegationSpecs::Target) + suppress_warning do a.class_eval(<<-RUBY) def delegate(...) - target(...) + target ... end RUBY - - a.new.delegate(1, b: 2).should == [[1], {b: 2}] end - it "delegates block" do - a = Class.new(DelegationSpecs::Target) - a.class_eval(<<-RUBY) - def delegate_block(...) - target_block(...) - end - RUBY + a.new.delegate(1, b: 2).should == Range.new([[], {}, nil], nil, true) + end +end + +describe "delegation with def(x, ...)" do + it "delegates rest and kwargs" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(x, ...) + target(...) + end + RUBY + + a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}, nil] + end + + it "delegates a block literal" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate_block(x, ...) + target_block(...) + end + RUBY + + a.new.delegate_block(0, 1, b: 2) { |x| x }.should == [{b: 2}, [1]] + end + + it "delegates a block argument" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(...) + target(...) + end + RUBY + + block = proc {} + a.new.delegate(1, b: 2, &block).should == [[1], {b: 2}, block] + end +end - a.new.delegate_block(1, b: 2) { |x| x }.should == [{b: 2}, [1]] +describe "delegation with def(*)" do + it "delegates rest" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(*) + target(*) end + RUBY - it "parses as open endless Range when brackets are omitted" do - a = Class.new(DelegationSpecs::Target) - suppress_warning do - a.class_eval(<<-RUBY) - def delegate(...) - target ... - end - RUBY - end - - a.new.delegate(1, b: 2).should == Range.new([[], {}], nil, true) + a.new.delegate(0, 1).should == [[0, 1], {}, nil] + end + + context "within a block that accepts anonymous rest within a method that accepts anonymous rest" do + it "does not allow delegating rest" do + -> { + eval "def m(*); proc { |*| n(*) } end" + }.should.raise(SyntaxError, /anonymous rest parameter is also used within block/) end end end -ruby_version_is "2.7.3" do - describe "delegation with def(x, ...)" do - it "delegates rest and kwargs" do - a = Class.new(DelegationSpecs::Target) - a.class_eval(<<-RUBY) - def delegate(x, ...) - target(...) - end - RUBY - - a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}] +describe "delegation with def(**)" do + it "delegates kwargs" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(**) + target(**) end + RUBY - it "delegates block" do - a = Class.new(DelegationSpecs::Target) - a.class_eval(<<-RUBY) - def delegate_block(x, ...) - target_block(...) - end - RUBY + a.new.delegate(a: 1) { |x| x }.should == [[], {a: 1}, nil] + end - a.new.delegate_block(0, 1, b: 2) { |x| x }.should == [{b: 2}, [1]] + context "within a block that accepts anonymous kwargs within a method that accepts anonymous kwargs" do + it "does not allow delegating kwargs" do + -> { + eval "def m(**); proc { |**| n(**) } end" + }.should.raise(SyntaxError, /anonymous keyword rest parameter is also used within block/) end + end +end +describe "delegation with def(&)" do + it "delegates an anonymous block parameter" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(&) + target(&) + end + RUBY + + block = proc {} + a.new.delegate(&block).should == [[], {}, block] + end + + context "within a block that accepts anonymous block within a method that accepts anonymous block" do + it "does not allow delegating a block" do + -> { + eval "def m(&); proc { |&| n(&) } end" + }.should.raise(SyntaxError, /anonymous block parameter is also used within block/) + end end end |
