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
|
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
ruby_bug '#18635', ''...'3.2' do
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
end
|