-
-
Notifications
You must be signed in to change notification settings - Fork 399
Expand file tree
/
Copy pathnumbered_parameters_spec.rb
More file actions
147 lines (120 loc) · 5.04 KB
/
Copy pathnumbered_parameters_spec.rb
File metadata and controls
147 lines (120 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
require_relative '../spec_helper'
describe "Numbered parameters" do
it "provides default parameters _1, _2, ... in a block" do
-> { _1 }.call("a").should == "a"
proc { _1 }.call("a").should == "a"
lambda { _1 }.call("a").should == "a"
["a"].map { _1 }.should == ["a"]
end
it "assigns nil to not passed parameters" do
proc { [_1, _2] }.call("a").should == ["a", nil]
proc { [_1, _2] }.call("a", "b").should == ["a", "b"]
end
it "supports variables _1-_9 only for the first 9 passed parameters" do
block = proc { [_1, _2, _3, _4, _5, _6, _7, _8, _9] }
result = block.call(1, 2, 3, 4, 5, 6, 7, 8, 9)
result.should == [1, 2, 3, 4, 5, 6, 7, 8, 9]
end
it "does not support more than 9 parameters" do
-> {
proc { [_10] }.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
}.should.raise(NameError, /undefined local variable or method [`']_10'/)
end
it "can not be used in both outer and nested blocks at the same time" do
-> {
eval("-> { _1; -> { _2 } }")
}.should.raise(SyntaxError, /numbered parameter is already used in/m)
end
it "cannot be overwritten with local variable" do
-> {
eval <<~CODE
_1 = 0
proc { _1 }.call("a").should == 0
CODE
}.should.raise(SyntaxError, /_1 is reserved for numbered parameter/)
end
it "errors when numbered parameter is overwritten with local variable" do
-> {
eval("_1 = 0")
}.should.raise(SyntaxError, /_1 is reserved for numbered parameter/)
end
it "raises SyntaxError when block parameters are specified explicitly" do
-> { eval("-> () { _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("-> (x) { _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("proc { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("proc { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("lambda { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("lambda { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("['a'].map { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
-> { eval("['a'].map { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/)
end
describe "assigning to a numbered parameter" do
it "raises SyntaxError" do
-> { eval("proc { _1 = 0 }") }.should.raise(SyntaxError, /_1 is reserved for numbered parameter/)
end
end
it "affects block arity" do
-> { _1 }.arity.should == 1
-> { _2 }.arity.should == 2
-> { _3 }.arity.should == 3
-> { _4 }.arity.should == 4
-> { _5 }.arity.should == 5
-> { _6 }.arity.should == 6
-> { _7 }.arity.should == 7
-> { _8 }.arity.should == 8
-> { _9 }.arity.should == 9
-> { _9 }.arity.should == 9
proc { _9 }.arity.should == 9
lambda { _9 }.arity.should == 9
end
it "affects block parameters" do
-> { _1 }.parameters.should == [[:req, :_1]]
-> { _2 }.parameters.should == [[:req, :_1], [:req, :_2]]
proc { _1 }.parameters.should == [[:opt, :_1]]
proc { _2 }.parameters.should == [[:opt, :_1], [:opt, :_2]]
end
ruby_version_is ""..."4.0" do
it "affects binding local variables" do
-> { _1; binding.local_variables }.call("a").should == [:_1]
-> { _2; binding.local_variables }.call("a", "b").should == [:_1, :_2]
end
it "affects binding local variables getting" do
-> { _1; binding.local_variable_get(:_1) }.call("a").should == "a"
end
it "affects binding local variables setting" do
-> { _1; binding.local_variable_set(:_1, "b"); _1 }.call("a").should == "b"
end
it "affects binding local variables definition check" do
-> { _1; binding.local_variable_defined?(:_1) }.call("a").should == true
end
end
ruby_version_is "4.0" do
it "does not affect binding local variables" do
-> { _1; binding.local_variables }.call("a").should == []
-> { _2; binding.local_variables }.call("a", "b").should == []
end
it "does not affect binding local variables getting" do
proc {
_1; binding.local_variable_get(:_1)
}.should.raise(NameError, "numbered parameter '_1' is not a local variable")
end
it "does not affect binding local variables setting" do
proc {
_1; binding.local_variable_set(:_1, "b")
}.should.raise(NameError, "numbered parameter '_1' is not a local variable")
end
it "does not affect binding local variables definition check" do
proc {
_1; binding.local_variable_defined?(:_1)
}.should.raise(NameError, "numbered parameter '_1' is not a local variable")
end
end
it "does not work in methods" do
obj = Object.new
def obj.foo; _1 end
-> { obj.foo("a") }.should.raise(ArgumentError, /wrong number of arguments/)
end
it "cannot be accessed using eval()" do
-> { proc { binding.eval('_1') }.call(1) }.should.raise(NameError, /undefined local variable or method ._1'/)
end
end