diff options
Diffstat (limited to 'spec/ruby/language')
-rw-r--r-- | spec/ruby/language/block_spec.rb | 30 | ||||
-rw-r--r-- | spec/ruby/language/defined_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/language/delegation_spec.rb | 89 | ||||
-rw-r--r-- | spec/ruby/language/fixtures/defined.rb | 6 | ||||
-rw-r--r-- | spec/ruby/language/fixtures/delegation.rb | 4 |
5 files changed, 122 insertions, 11 deletions
diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb index cf0931b688..75c1e71bc2 100644 --- a/spec/ruby/language/block_spec.rb +++ b/spec/ruby/language/block_spec.rb @@ -999,6 +999,7 @@ describe "Post-args" do 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 @@ -1072,3 +1073,32 @@ describe "Anonymous block forwarding" do end end end + +describe "`it` calls without arguments in a block with no ordinary parameters" do + ruby_version_is "3.3"..."3.4" do + it "emits a deprecation warning" do + -> { + eval "proc { it }" + }.should complain(/warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it\(\) or self.it/) + end + + it "does not emit a deprecation warning when a block has parameters" do + -> { eval "proc { |a, b| it }" }.should_not complain + -> { eval "proc { |*rest| it }" }.should_not complain + -> { eval "proc { |*| it }" }.should_not complain + -> { eval "proc { |a:, b:| it }" }.should_not complain + -> { eval "proc { |**kw| it }" }.should_not complain + -> { eval "proc { |**| it }" }.should_not complain + -> { eval "proc { |&block| it }" }.should_not complain + -> { eval "proc { |&| it }" }.should_not complain + end + + it "does not emit a deprecation warning when `it` calls with arguments" do + -> { eval "proc { it(42) }" }.should_not complain + end + + it "does not emit a deprecation warning when `it` calls with explicit empty arguments list" do + -> { eval "proc { it() }" }.should_not complain + end + end +end diff --git a/spec/ruby/language/defined_spec.rb b/spec/ruby/language/defined_spec.rb index 34408c0190..80ad1818b1 100644 --- a/spec/ruby/language/defined_spec.rb +++ b/spec/ruby/language/defined_spec.rb @@ -900,6 +900,10 @@ describe "The defined? keyword for a scoped constant" do defined?(DefinedSpecs::Undefined).should be_nil end + it "returns nil when the constant is not defined and the outer module implements .const_missing" do + defined?(DefinedSpecs::ModuleWithConstMissing::Undefined).should be_nil + end + it "does not call .const_missing if the constant is not defined" do DefinedSpecs.should_not_receive(:const_missing) defined?(DefinedSpecs::UnknownChild).should be_nil diff --git a/spec/ruby/language/delegation_spec.rb b/spec/ruby/language/delegation_spec.rb index d780506421..b75f3f5f7c 100644 --- a/spec/ruby/language/delegation_spec.rb +++ b/spec/ruby/language/delegation_spec.rb @@ -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) @@ -10,10 +11,10 @@ describe "delegation with def(...)" do 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(...) @@ -24,6 +25,18 @@ describe "delegation with def(...)" do 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 @@ -34,7 +47,7 @@ describe "delegation with def(...)" do 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 @@ -47,10 +60,10 @@ describe "delegation with def(x, ...)" do 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, ...) @@ -60,6 +73,18 @@ describe "delegation with def(x, ...)" do 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 @@ -70,9 +95,19 @@ ruby_version_is "3.2" do 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 @@ -85,9 +120,45 @@ ruby_version_is "3.2" do 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 diff --git a/spec/ruby/language/fixtures/defined.rb b/spec/ruby/language/fixtures/defined.rb index a9552619bf..3761cfa5bd 100644 --- a/spec/ruby/language/fixtures/defined.rb +++ b/spec/ruby/language/fixtures/defined.rb @@ -285,6 +285,12 @@ module DefinedSpecs end end + module ModuleWithConstMissing + def self.const_missing(const) + const + end + end + class SuperWithIntermediateModules include IntermediateModule1 include IntermediateModule2 diff --git a/spec/ruby/language/fixtures/delegation.rb b/spec/ruby/language/fixtures/delegation.rb index 527d928390..da2b024791 100644 --- a/spec/ruby/language/fixtures/delegation.rb +++ b/spec/ruby/language/fixtures/delegation.rb @@ -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) |