Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions language/block_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@ def a; 1; end
end
end

# tested more thoroughly in language/delegation_spec.rb
describe "Anonymous block forwarding" do
ruby_version_is "3.1" do
it "forwards blocks to other method that formally declares anonymous block" do
Expand Down
89 changes: 80 additions & 9 deletions language/delegation_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require_relative '../spec_helper'
require_relative 'fixtures/delegation'

# Forwarding anonymous parameters
describe "delegation with def(...)" do
it "delegates rest and kwargs" do
a = Class.new(DelegationSpecs::Target)
Expand All @@ -10,10 +11,10 @@ def delegate(...)
end
RUBY

a.new.delegate(1, b: 2).should == [[1], {b: 2}]
a.new.delegate(1, b: 2).should == [[1], {b: 2}, nil]
end

it "delegates block" do
it "delegates a block literal" do
a = Class.new(DelegationSpecs::Target)
a.class_eval(<<-RUBY)
def delegate_block(...)
Expand All @@ -24,6 +25,18 @@ def delegate_block(...)
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 "parses as open endless Range when brackets are omitted" do
a = Class.new(DelegationSpecs::Target)
suppress_warning do
Expand All @@ -34,7 +47,7 @@ def delegate(...)
RUBY
end

a.new.delegate(1, b: 2).should == Range.new([[], {}], nil, true)
a.new.delegate(1, b: 2).should == Range.new([[], {}, nil], nil, true)
end
end

Expand All @@ -47,10 +60,10 @@ def delegate(x, ...)
end
RUBY

a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}]
a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}, nil]
end

it "delegates block" do
it "delegates a block literal" do
a = Class.new(DelegationSpecs::Target)
a.class_eval(<<-RUBY)
def delegate_block(x, ...)
Expand All @@ -60,6 +73,18 @@ def delegate_block(x, ...)

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

ruby_version_is "3.2" do
Expand All @@ -70,9 +95,19 @@ def delegate_block(x, ...)
def delegate(*)
target(*)
end
RUBY
RUBY

a.new.delegate(0, 1).should == [[0, 1], {}]
a.new.delegate(0, 1).should == [[0, 1], {}, nil]
end

ruby_version_is "3.3" do
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_error(SyntaxError, /anonymous rest parameter is also used within block/)
end
end
end
end
end
Expand All @@ -85,9 +120,45 @@ def delegate(*)
def delegate(**)
target(**)
end
RUBY
RUBY

a.new.delegate(a: 1) { |x| x }.should == [[], {a: 1}, nil]
end

a.new.delegate(a: 1) { |x| x }.should == [[], {a: 1}]
ruby_version_is "3.3" do
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_error(SyntaxError, /anonymous keyword rest parameter is also used within block/)
end
end
end
end
end

ruby_version_is "3.1" do
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

ruby_version_is "3.3" do
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_error(SyntaxError, /anonymous block parameter is also used within block/)
end
end
end
end
end
4 changes: 2 additions & 2 deletions language/fixtures/delegation.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module DelegationSpecs
class Target
def target(*args, **kwargs)
[args, kwargs]
def target(*args, **kwargs, &block)
[args, kwargs, block]
end

def target_block(*args, **kwargs)
Expand Down