diff options
Diffstat (limited to 'spec/ruby/core/enumerable/shared')
| -rw-r--r-- | spec/ruby/core/enumerable/shared/collect.rb | 107 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/collect_concat.rb | 54 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/entries.rb | 16 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb | 33 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/enumeratorized.rb | 42 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/find.rb | 77 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/find_all.rb | 31 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/include.rb | 34 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/inject.rb | 142 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/take.rb | 63 |
10 files changed, 599 insertions, 0 deletions
diff --git a/spec/ruby/core/enumerable/shared/collect.rb b/spec/ruby/core/enumerable/shared/collect.rb new file mode 100644 index 0000000000..6df1a616eb --- /dev/null +++ b/spec/ruby/core/enumerable/shared/collect.rb @@ -0,0 +1,107 @@ +require_relative 'enumerable_enumeratorized' + +describe :enumerable_collect, shared: true do + before :each do + ScratchPad.record [] + end + + it "returns a new array with the results of passing each element to block" do + entries = [0, 1, 3, 4, 5, 6] + numerous = EnumerableSpecs::Numerous.new(*entries) + numerous.send(@method) { |i| i % 2 }.should == [0, 1, 1, 0, 1, 0] + numerous.send(@method) { |i| i }.should == entries + end + + it "passes through the values yielded by #each_with_index" do + [:a, :b].each_with_index.send(@method) { |x, i| ScratchPad << [x, i]; nil } + ScratchPad.recorded.should == [[:a, 0], [:b, 1]] + end + + it "gathers initial args as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method) {|e| e}.should == [1,3,6] + end + + it "only yields increasing values for a Range" do + (1..0).send(@method) { |x| x }.should == [] + (1..1).send(@method) { |x| x }.should == [1] + (1..2).send(@method) { |x| x }.should == [1, 2] + end + + it "returns an enumerator when no block given" do + enum = EnumerableSpecs::Numerous.new.send(@method) + enum.should be_an_instance_of(Enumerator) + enum.each { |i| -i }.should == [-2, -5, -3, -6, -1, -4] + end + + it "reports the same arity as the given block" do + entries = [0, 1, 3, 4, 5, 6] + numerous = EnumerableSpecs::Numerous.new(*entries) + + def numerous.each(&block) + ScratchPad << block.arity + super + end + + numerous.send(@method) { |a, b| a % 2 }.should == [0, 1, 1, 0, 1, 0] + ScratchPad.recorded.should == [2] + ScratchPad.clear + ScratchPad.record [] + numerous.send(@method) { |i| i }.should == entries + ScratchPad.recorded.should == [1] + end + + it "yields an Array of 2 elements for a Hash when block arity is 1" do + c = Class.new do + def register(a) + ScratchPad << a + end + end + m = c.new.method(:register) + + ScratchPad.record [] + { 1 => 'a', 2 => 'b' }.map(&m) + ScratchPad.recorded.should == [[1, 'a'], [2, 'b']] + end + + it "yields 2 arguments for a Hash when block arity is 2" do + c = Class.new do + def register(a, b) + ScratchPad << [a, b] + end + end + m = c.new.method(:register) + + ScratchPad.record [] + { 1 => 'a', 2 => 'b' }.map(&m) + ScratchPad.recorded.should == [[1, 'a'], [2, 'b']] + end + + it "raises an error for a Hash when an arity enforcing block of arity >2 is passed in" do + c = Class.new do + def register(a, b, c) + end + end + m = c.new.method(:register) + + -> do + { 1 => 'a', 2 => 'b' }.map(&m) + end.should raise_error(ArgumentError) + end + + it "calls the each method on sub-classes" do + c = Class.new(Hash) do + def each + ScratchPad << 'in each' + super + end + end + h = c.new + h[1] = 'a' + ScratchPad.record [] + h.send(@method) { |k,v| v } + ScratchPad.recorded.should == ['in each'] + end + + it_should_behave_like :enumerable_enumeratorized_with_origin_size +end diff --git a/spec/ruby/core/enumerable/shared/collect_concat.rb b/spec/ruby/core/enumerable/shared/collect_concat.rb new file mode 100644 index 0000000000..ddd431baeb --- /dev/null +++ b/spec/ruby/core/enumerable/shared/collect_concat.rb @@ -0,0 +1,54 @@ +require_relative 'enumerable_enumeratorized' + +describe :enumerable_collect_concat, shared: true do + it "yields elements to the block and flattens one level" do + numerous = EnumerableSpecs::Numerous.new(1, [2, 3], [4, [5, 6]], {foo: :bar}) + numerous.send(@method) { |i| i }.should == [1, 2, 3, 4, [5, 6], {foo: :bar}] + end + + it "appends non-Array elements that do not define #to_ary" do + obj = mock("to_ary undefined") + + numerous = EnumerableSpecs::Numerous.new(1, obj, 2) + numerous.send(@method) { |i| i }.should == [1, obj, 2] + end + + it "concatenates the result of calling #to_ary if it returns an Array" do + obj = mock("to_ary defined") + obj.should_receive(:to_ary).and_return([:a, :b]) + + numerous = EnumerableSpecs::Numerous.new(1, obj, 2) + numerous.send(@method) { |i| i }.should == [1, :a, :b, 2] + end + + it "does not call #to_a" do + obj = mock("to_ary undefined") + obj.should_not_receive(:to_a) + + numerous = EnumerableSpecs::Numerous.new(1, obj, 2) + numerous.send(@method) { |i| i }.should == [1, obj, 2] + end + + it "appends an element that defines #to_ary that returns nil" do + obj = mock("to_ary defined") + obj.should_receive(:to_ary).and_return(nil) + + numerous = EnumerableSpecs::Numerous.new(1, obj, 2) + numerous.send(@method) { |i| i }.should == [1, obj, 2] + end + + it "raises a TypeError if an element defining #to_ary does not return an Array or nil" do + obj = mock("to_ary defined") + obj.should_receive(:to_ary).and_return("array") + + -> { [1, obj, 3].send(@method) { |i| i } }.should raise_error(TypeError) + end + + it "returns an enumerator when no block given" do + enum = EnumerableSpecs::Numerous.new(1, 2).send(@method) + enum.should be_an_instance_of(Enumerator) + enum.each{ |i| [i] * i }.should == [1, 2, 2] + end + + it_should_behave_like :enumerable_enumeratorized_with_origin_size +end diff --git a/spec/ruby/core/enumerable/shared/entries.rb b/spec/ruby/core/enumerable/shared/entries.rb new file mode 100644 index 0000000000..e32eb23d2a --- /dev/null +++ b/spec/ruby/core/enumerable/shared/entries.rb @@ -0,0 +1,16 @@ +describe :enumerable_entries, shared: true do + it "returns an array containing the elements" do + numerous = EnumerableSpecs::Numerous.new(1, nil, 'a', 2, false, true) + numerous.send(@method).should == [1, nil, "a", 2, false, true] + end + + it "passes through the values yielded by #each_with_index" do + [:a, :b].each_with_index.send(@method).should == [[:a, 0], [:b, 1]] + end + + it "passes arguments to each" do + count = EnumerableSpecs::EachCounter.new(1, 2, 3) + count.send(@method, :hello, "world").should == [1, 2, 3] + count.arguments_passed.should == [:hello, "world"] + end +end diff --git a/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb new file mode 100644 index 0000000000..e2bbe18eda --- /dev/null +++ b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb @@ -0,0 +1,33 @@ +require_relative 'enumeratorized' + +describe :enumerable_enumeratorized_with_unknown_size, shared: true do + describe "Enumerable with size" do + before :all do + @object = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 4) + end + it_should_behave_like :enumeratorized_with_unknown_size + end + + describe "Enumerable with no size" do + before :all do + @object = EnumerableSpecs::Numerous.new(1, 2, 3, 4) + end + it_should_behave_like :enumeratorized_with_unknown_size + end +end + +describe :enumerable_enumeratorized_with_origin_size, shared: true do + describe "Enumerable with size" do + before :all do + @object = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 4) + end + it_should_behave_like :enumeratorized_with_origin_size + end + + describe "Enumerable with no size" do + before :all do + @object = EnumerableSpecs::Numerous.new(1, 2, 3, 4) + end + it_should_behave_like :enumeratorized_with_unknown_size + end +end diff --git a/spec/ruby/core/enumerable/shared/enumeratorized.rb b/spec/ruby/core/enumerable/shared/enumeratorized.rb new file mode 100644 index 0000000000..05d27b5783 --- /dev/null +++ b/spec/ruby/core/enumerable/shared/enumeratorized.rb @@ -0,0 +1,42 @@ +describe :enumeratorized_with_unknown_size, shared: true do + describe "when no block is given" do + describe "returned Enumerator" do + it "size returns nil" do + @object.send(*@method).size.should == nil + end + end + end +end + +describe :enumeratorized_with_origin_size, shared: true do + describe "when no block is given" do + describe "returned Enumerator" do + it "size returns the enumerable size" do + @object.send(*@method).size.should == @object.size + end + end + end +end + +describe :enumeratorized_with_cycle_size, shared: true do + describe "when no block is given" do + describe "returned Enumerator" do + describe "size" do + it "should be the result of multiplying the enumerable size by the argument passed" do + @object.cycle(2).size.should == @object.size * 2 + @object.cycle(7).size.should == @object.size * 7 + @object.cycle(0).size.should == 0 + @empty_object.cycle(2).size.should == 0 + end + + it "should be zero when the argument passed is 0 or less" do + @object.cycle(-1).size.should == 0 + end + + it "should be Float::INFINITY when no argument is passed" do + @object.cycle.size.should == Float::INFINITY + end + end + end + end +end diff --git a/spec/ruby/core/enumerable/shared/find.rb b/spec/ruby/core/enumerable/shared/find.rb new file mode 100644 index 0000000000..61d63ba3d5 --- /dev/null +++ b/spec/ruby/core/enumerable/shared/find.rb @@ -0,0 +1,77 @@ +require_relative 'enumerable_enumeratorized' + +describe :enumerable_find, shared: true do + # #detect and #find are aliases, so we only need one function + before :each do + ScratchPad.record [] + @elements = [2, 4, 6, 8, 10] + @numerous = EnumerableSpecs::Numerous.new(*@elements) + @empty = [] + end + + it "passes each entry in enum to block while block when block is false" do + visited_elements = [] + @numerous.send(@method) do |element| + visited_elements << element + false + end + visited_elements.should == @elements + end + + it "returns nil when the block is false and there is no ifnone proc given" do + @numerous.send(@method) {|e| false }.should == nil + end + + it "returns the first element for which the block is not false" do + @elements.each do |element| + @numerous.send(@method) {|e| e > element - 1 }.should == element + end + end + + it "returns the value of the ifnone proc if the block is false" do + fail_proc = -> { "cheeseburgers" } + @numerous.send(@method, fail_proc) {|e| false }.should == "cheeseburgers" + end + + it "doesn't call the ifnone proc if an element is found" do + fail_proc = -> { raise "This shouldn't have been called" } + @numerous.send(@method, fail_proc) {|e| e == @elements.first }.should == 2 + end + + it "calls the ifnone proc only once when the block is false" do + times = 0 + fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" } + @numerous.send(@method, fail_proc) {|e| false }.should == "cheeseburgers" + end + + it "calls the ifnone proc when there are no elements" do + fail_proc = -> { "yay" } + @empty.send(@method, fail_proc) {|e| true}.should == "yay" + end + + it "ignores the ifnone argument when nil" do + @numerous.send(@method, nil) {|e| false }.should == nil + end + + it "passes through the values yielded by #each_with_index" do + [:a, :b].each_with_index.send(@method) { |x, i| ScratchPad << [x, i]; nil } + ScratchPad.recorded.should == [[:a, 0], [:b, 1]] + end + + it "returns an enumerator when no block given" do + @numerous.send(@method).should be_an_instance_of(Enumerator) + end + + it "passes the ifnone proc to the enumerator" do + times = 0 + fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" } + @numerous.send(@method, fail_proc).each {|e| false }.should == "cheeseburgers" + end + + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method) {|e| e == [1, 2] }.should == [1, 2] + end + + it_should_behave_like :enumerable_enumeratorized_with_unknown_size +end diff --git a/spec/ruby/core/enumerable/shared/find_all.rb b/spec/ruby/core/enumerable/shared/find_all.rb new file mode 100644 index 0000000000..1bbe71f372 --- /dev/null +++ b/spec/ruby/core/enumerable/shared/find_all.rb @@ -0,0 +1,31 @@ +require_relative 'enumerable_enumeratorized' + +describe :enumerable_find_all, shared: true do + before :each do + ScratchPad.record [] + @elements = (1..10).to_a + @numerous = EnumerableSpecs::Numerous.new(*@elements) + end + + it "returns all elements for which the block is not false" do + @numerous.send(@method) {|i| i % 3 == 0 }.should == [3, 6, 9] + @numerous.send(@method) {|i| true }.should == @elements + @numerous.send(@method) {|i| false }.should == [] + end + + it "returns an enumerator when no block given" do + @numerous.send(@method).should be_an_instance_of(Enumerator) + end + + it "passes through the values yielded by #each_with_index" do + [:a, :b].each_with_index.send(@method) { |x, i| ScratchPad << [x, i] } + ScratchPad.recorded.should == [[:a, 0], [:b, 1]] + end + + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method) {|e| e == [3, 4, 5] }.should == [[3, 4, 5]] + end + + it_should_behave_like :enumerable_enumeratorized_with_origin_size +end diff --git a/spec/ruby/core/enumerable/shared/include.rb b/spec/ruby/core/enumerable/shared/include.rb new file mode 100644 index 0000000000..569f350fd5 --- /dev/null +++ b/spec/ruby/core/enumerable/shared/include.rb @@ -0,0 +1,34 @@ +describe :enumerable_include, shared: true do + it "returns true if any element == argument for numbers" do + class EnumerableSpecIncludeP; def ==(obj) obj == 5; end; end + + elements = (0..5).to_a + EnumerableSpecs::Numerous.new(*elements).send(@method,5).should == true + EnumerableSpecs::Numerous.new(*elements).send(@method,10).should == false + EnumerableSpecs::Numerous.new(*elements).send(@method,EnumerableSpecIncludeP.new).should == true + end + + it "returns true if any element == argument for other objects" do + class EnumerableSpecIncludeP11; def ==(obj); obj == '11'; end; end + + elements = ('0'..'5').to_a + [EnumerableSpecIncludeP11.new] + EnumerableSpecs::Numerous.new(*elements).send(@method,'5').should == true + EnumerableSpecs::Numerous.new(*elements).send(@method,'10').should == false + EnumerableSpecs::Numerous.new(*elements).send(@method,EnumerableSpecIncludeP11.new).should == true + EnumerableSpecs::Numerous.new(*elements).send(@method,'11').should == true + end + + + it "returns true if any member of enum equals obj when == compare different classes (legacy rubycon)" do + # equality is tested with == + EnumerableSpecs::Numerous.new(2,4,6,8,10).send(@method, 2.0).should == true + EnumerableSpecs::Numerous.new(2,4,[6,8],10).send(@method, [6, 8]).should == true + EnumerableSpecs::Numerous.new(2,4,[6,8],10).send(@method, [6.0, 8.0]).should == true + end + + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method, [1,2]).should be_true + end + +end diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb new file mode 100644 index 0000000000..8fb7e98c2b --- /dev/null +++ b/spec/ruby/core/enumerable/shared/inject.rb @@ -0,0 +1,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 diff --git a/spec/ruby/core/enumerable/shared/take.rb b/spec/ruby/core/enumerable/shared/take.rb new file mode 100644 index 0000000000..ce2ace20fa --- /dev/null +++ b/spec/ruby/core/enumerable/shared/take.rb @@ -0,0 +1,63 @@ +describe :enumerable_take, shared: true do + before :each do + @values = [4,3,2,1,0,-1] + @enum = EnumerableSpecs::Numerous.new(*@values) + end + + it "returns the first count elements if given a count" do + @enum.send(@method, 2).should == [4, 3] + @enum.send(@method, 4).should == [4, 3, 2, 1] # See redmine #1686 ! + end + + it "returns an empty array when passed count on an empty array" do + empty = EnumerableSpecs::Empty.new + empty.send(@method, 0).should == [] + empty.send(@method, 1).should == [] + empty.send(@method, 2).should == [] + end + + it "returns an empty array when passed count == 0" do + @enum.send(@method, 0).should == [] + end + + it "returns an array containing the first element when passed count == 1" do + @enum.send(@method, 1).should == [4] + end + + it "raises an ArgumentError when count is negative" do + -> { @enum.send(@method, -1) }.should raise_error(ArgumentError) + end + + it "returns the entire array when count > length" do + @enum.send(@method, 100).should == @values + @enum.send(@method, 8).should == @values # See redmine #1686 ! + end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(3).at_most(:twice) # called twice, no apparent reason. See redmine #1554 + @enum.send(@method, obj).should == [4, 3, 2] + end + + it "raises a TypeError if the passed argument is not numeric" do + -> { @enum.send(@method, nil) }.should raise_error(TypeError) + -> { @enum.send(@method, "a") }.should raise_error(TypeError) + + obj = mock("nonnumeric") + -> { @enum.send(@method, obj) }.should raise_error(TypeError) + end + + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method, 1).should == [[1, 2]] + end + + it "consumes only what is needed" do + thrower = EnumerableSpecs::ThrowingEach.new + thrower.send(@method, 0).should == [] + counter = EnumerableSpecs::EachCounter.new(1,2,3,4) + counter.send(@method, 2).should == [1,2] + counter.times_called.should == 1 + counter.times_yielded.should == 2 + end +end |
