diff options
Diffstat (limited to 'spec/ruby/language/it_parameter_spec.rb')
| -rw-r--r-- | spec/ruby/language/it_parameter_spec.rb | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/spec/ruby/language/it_parameter_spec.rb b/spec/ruby/language/it_parameter_spec.rb new file mode 100644 index 0000000000..6ba67cbb4f --- /dev/null +++ b/spec/ruby/language/it_parameter_spec.rb @@ -0,0 +1,108 @@ +require_relative '../spec_helper' + +ruby_version_is "3.4" do + eval <<-RUBY # use eval to avoid warnings on Ruby 3.3 + describe "The `it` parameter" do + it "provides it in a block" do + -> { it }.call("a").should == "a" + proc { it }.call("a").should == "a" + lambda { it }.call("a").should == "a" + ["a"].map { it }.should == ["a"] + end + + it "assigns nil to not passed parameters" do + proc { it }.call().should == nil + end + + it "can be used in both outer and nested blocks at the same time" do + -> { it + -> { it * it }.call(2) }.call(3).should == 7 + end + + it "can be reassigned to act as a local variable" do + proc { tmp = it; it = tmp * 2; it }.call(21).should == 42 + end + + it "is a regular local variable if there is already a 'it' local variable" do + it = 0 + proc { it }.call("a").should == 0 + end + + it "is a regular local variable if there is a method `it` defined" do + o = Object.new + def o.it + 21 + end + + o.instance_eval("proc { it * 2 }").call(1).should == 2 + end + + it "is not shadowed by an reassignment in a block" do + a = nil + proc { a = it; it = 42 }.call(0) + a.should == 0 # if `it` were shadowed its value would be nil + end + + it "raises SyntaxError when block parameters are specified explicitly" do + -> { eval("-> () { it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("-> (x) { it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("proc { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("proc { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("lambda { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("lambda { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("['a'].map { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("['a'].map { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + end + + it "cannot be mixed with numbered parameters" do + -> { + eval("proc { it + _1 }") + }.should.raise(SyntaxError, /numbered parameters are not allowed when 'it' is already used|'it' is already used in/) + + -> { + eval("proc { _1 + it }") + }.should.raise(SyntaxError, /numbered parameter is already used in|'it' is not allowed when a numbered parameter is already used/) + end + + it "affects block arity" do + -> {}.arity.should == 0 + -> { it }.arity.should == 1 + end + + it "affects block parameters" do + -> { it }.parameters.should == [[:req]] + + ruby_version_is ""..."4.0" do + proc { it }.parameters.should == [[:opt, nil]] + end + ruby_version_is "4.0" do + proc { it }.parameters.should == [[:opt]] + end + end + + it "does not affect binding local variables" do + -> { it; binding.local_variables }.call("a").should == [] + end + + it "does not work in methods" do + obj = Object.new + def obj.foo; it; end + + -> { obj.foo("a") }.should.raise(ArgumentError, /wrong number of arguments/) + end + + context "given multiple arguments" do + it "provides it in a block and assigns the first argument for a block" do + proc { it }.call("a", "b").should == "a" + end + + it "raises ArgumentError for a proc" do + -> { -> { it }.call("a", "b") }.should.raise(ArgumentError, "wrong number of arguments (given 2, expected 1)") + -> { lambda { it }.call("a", "b") }.should.raise(ArgumentError, "wrong number of arguments (given 2, expected 1)") + end + end + end + RUBY +end |
