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
|
require_relative '../../array/shared/iterable_and_tolerating_size_increasing'
describe :enumerable_inject, shared: true do
it "with argument takes a block with an accumulator (with argument as initial value) and the current element. Value of block becomes new accumulator" do
a = []
EnumerableSpecs::Numerous.new.send(@method, 0) { |memo, i| a << [memo, i]; i }
a.should == [[0, 2], [2, 5], [5, 3], [3, 6], [6, 1], [1, 4]]
EnumerableSpecs::EachDefiner.new(true, true, true).send(@method, nil) {|result, i| i && result}.should == nil
end
it "produces an array of the accumulator and the argument when given a block with a *arg" do
a = []
[1,2].send(@method, 0) {|*args| a << args; args[0] + args[1]}
a.should == [[0, 1], [1, 2]]
end
it "can take two argument" do
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-).should == 4
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, "-").should == 4
[1, 2, 3].send(@method, 10, :-).should == 4
[1, 2, 3].send(@method, 10, "-").should == 4
end
it "converts non-Symbol method name argument to String with #to_str if two arguments" do
name = Object.new
def name.to_str; "-"; end
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, name).should == 4
[1, 2, 3].send(@method, 10, name).should == 4
end
it "raises TypeError when the second argument is not Symbol or String and it cannot be converted to String if two arguments" do
-> { EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
-> { [1, 2, 3].send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
end
it "ignores the block if two arguments" do
-> {
EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4
}.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
-> {
[1, 2, 3].send(@method, 10, :-) { raise "we never get here"}.should == 4
}.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
end
it "does not warn when given a Symbol with $VERBOSE true" do
-> {
[1, 2].send(@method, 0, :+)
[1, 2].send(@method, :+)
EnumerableSpecs::Numerous.new(1, 2).send(@method, 0, :+)
EnumerableSpecs::Numerous.new(1, 2).send(@method, :+)
}.should_not complain(verbose: true)
end
it "can take a symbol argument" do
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, :-).should == 4
[10, 1, 2, 3].send(@method, :-).should == 4
end
it "can take a String argument" do
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, "-").should == 4
[10, 1, 2, 3].send(@method, "-").should == 4
end
it "converts non-Symbol method name argument to String with #to_str" do
name = Object.new
def name.to_str; "-"; end
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, name).should == 4
[10, 1, 2, 3].send(@method, name).should == 4
end
it "raises TypeError when passed not Symbol or String method name argument and it cannot be converted to String" do
-> { EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
-> { [10, 1, 2, 3].send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
end
it "without argument takes a block with an accumulator (with first element as initial value) and the current element. Value of block becomes new accumulator" do
a = []
EnumerableSpecs::Numerous.new.send(@method) { |memo, i| a << [memo, i]; i }
a.should == [[2, 5], [5, 3], [3, 6], [6, 1], [1, 4]]
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
it "with inject arguments(legacy rubycon)" do
# with inject argument
EnumerableSpecs::EachDefiner.new().send(@method, 1) {|acc,x| 999 }.should == 1
EnumerableSpecs::EachDefiner.new(2).send(@method, 1) {|acc,x| 999 }.should == 999
EnumerableSpecs::EachDefiner.new(2).send(@method, 1) {|acc,x| acc }.should == 1
EnumerableSpecs::EachDefiner.new(2).send(@method, 1) {|acc,x| x }.should == 2
EnumerableSpecs::EachDefiner.new(1,2,3,4).send(@method, 100) {|acc,x| acc + x }.should == 110
EnumerableSpecs::EachDefiner.new(1,2,3,4).send(@method, 100) {|acc,x| acc * x }.should == 2400
EnumerableSpecs::EachDefiner.new('a','b','c').send(@method, "z") {|result, i| i+result}.should == "cbaz"
end
it "without inject arguments(legacy rubycon)" do
# no inject argument
EnumerableSpecs::EachDefiner.new(2).send(@method) {|acc,x| 999 } .should == 2
EnumerableSpecs::EachDefiner.new(2).send(@method) {|acc,x| acc }.should == 2
EnumerableSpecs::EachDefiner.new(2).send(@method) {|acc,x| x }.should == 2
EnumerableSpecs::EachDefiner.new(1,2,3,4).send(@method) {|acc,x| acc + x }.should == 10
EnumerableSpecs::EachDefiner.new(1,2,3,4).send(@method) {|acc,x| acc * x }.should == 24
EnumerableSpecs::EachDefiner.new('a','b','c').send(@method) {|result, i| i+result}.should == "cba"
EnumerableSpecs::EachDefiner.new(3, 4, 5).send(@method) {|result, i| result*i}.should == 60
EnumerableSpecs::EachDefiner.new([1], 2, 'a','b').send(@method){|r,i| r<<i}.should == [1, 2, 'a', 'b']
end
it "returns nil when fails(legacy rubycon)" do
EnumerableSpecs::EachDefiner.new().send(@method) {|acc,x| 999 }.should == nil
end
it "tolerates increasing a collection size during iterating Array" do
array = [:a, :b, :c]
ScratchPad.record []
i = 0
array.send(@method, nil) do |_, e|
ScratchPad << e
array << i if i < 100
i += 1
end
actual = ScratchPad.recorded
expected = [:a, :b, :c] + (0..99).to_a
actual.sort_by(&:to_s).should == expected.sort_by(&:to_s)
end
it "raises an ArgumentError when no parameters or block is given" do
-> { [1,2].send(@method) }.should raise_error(ArgumentError)
-> { {one: 1, two: 2}.send(@method) }.should raise_error(ArgumentError)
end
end
|