summaryrefslogtreecommitdiff
path: root/spec/ruby/language/it_parameter_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language/it_parameter_spec.rb')
-rw-r--r--spec/ruby/language/it_parameter_spec.rb108
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