diff options
Diffstat (limited to 'spec/ruby/core/enumerable/shared')
| -rw-r--r-- | spec/ruby/core/enumerable/shared/collect.rb | 79 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/collect_concat.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/entries.rb | 8 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/find.rb | 18 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/find_all.rb | 4 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/include.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/inject.rb | 87 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/take.rb | 8 | ||||
| -rw-r--r-- | spec/ruby/core/enumerable/shared/value_packing.rb | 26 |
10 files changed, 205 insertions, 35 deletions
diff --git a/spec/ruby/core/enumerable/shared/collect.rb b/spec/ruby/core/enumerable/shared/collect.rb index f66c539904..4696d32454 100644 --- a/spec/ruby/core/enumerable/shared/collect.rb +++ b/spec/ruby/core/enumerable/shared/collect.rb @@ -1,4 +1,4 @@ -require File.expand_path('../enumerable_enumeratorized', __FILE__) +require_relative 'enumerable_enumeratorized' describe :enumerable_collect, shared: true do before :each do @@ -22,11 +22,86 @@ describe :enumerable_collect, shared: true do 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.should.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(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 index 54e10692eb..1694e3fdce 100644 --- a/spec/ruby/core/enumerable/shared/collect_concat.rb +++ b/spec/ruby/core/enumerable/shared/collect_concat.rb @@ -1,4 +1,4 @@ -require File.expand_path('../enumerable_enumeratorized', __FILE__) +require_relative 'enumerable_enumeratorized' describe :enumerable_collect_concat, shared: true do it "yields elements to the block and flattens one level" do @@ -41,12 +41,12 @@ describe :enumerable_collect_concat, shared: true do obj = mock("to_ary defined") obj.should_receive(:to_ary).and_return("array") - lambda { [1, obj, 3].send(@method) { |i| i } }.should raise_error(TypeError) + -> { [1, obj, 3].send(@method) { |i| i } }.should.raise(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.should.instance_of?(Enumerator) enum.each{ |i| [i] * i }.should == [1, 2, 2] end diff --git a/spec/ruby/core/enumerable/shared/entries.rb b/spec/ruby/core/enumerable/shared/entries.rb index f52844cb45..e32eb23d2a 100644 --- a/spec/ruby/core/enumerable/shared/entries.rb +++ b/spec/ruby/core/enumerable/shared/entries.rb @@ -13,12 +13,4 @@ describe :enumerable_entries, shared: true do count.send(@method, :hello, "world").should == [1, 2, 3] count.arguments_passed.should == [:hello, "world"] end - - it "returns a tainted array if self is tainted" do - EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true - end - - it "returns an untrusted array if self is untrusted" do - EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true - end end diff --git a/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb index b03ce9ed4e..e2bbe18eda 100644 --- a/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb +++ b/spec/ruby/core/enumerable/shared/enumerable_enumeratorized.rb @@ -1,4 +1,4 @@ -require File.expand_path('../enumeratorized', __FILE__) +require_relative 'enumeratorized' describe :enumerable_enumeratorized_with_unknown_size, shared: true do describe "Enumerable with size" do diff --git a/spec/ruby/core/enumerable/shared/find.rb b/spec/ruby/core/enumerable/shared/find.rb index 4cbbf07be0..cdff640415 100644 --- a/spec/ruby/core/enumerable/shared/find.rb +++ b/spec/ruby/core/enumerable/shared/find.rb @@ -1,4 +1,4 @@ -require File.expand_path('../enumerable_enumeratorized', __FILE__) +require_relative 'enumerable_enumeratorized' describe :enumerable_find, shared: true do # #detect and #find are aliases, so we only need one function @@ -29,38 +29,42 @@ describe :enumerable_find, shared: true do end it "returns the value of the ifnone proc if the block is false" do - fail_proc = lambda { "cheeseburgers" } + 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 = lambda { raise "This shouldn't have been called" } + 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 = lambda { times += 1; raise if times > 1; "cheeseburgers" } + 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 = lambda { "yay" } + 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) + @numerous.send(@method).should.instance_of?(Enumerator) end it "passes the ifnone proc to the enumerator" do times = 0 - fail_proc = lambda { times += 1; raise if times > 1; "cheeseburgers" } + fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" } @numerous.send(@method, fail_proc).each {|e| false }.should == "cheeseburgers" end diff --git a/spec/ruby/core/enumerable/shared/find_all.rb b/spec/ruby/core/enumerable/shared/find_all.rb index 3e15c68e9f..27f01de6e0 100644 --- a/spec/ruby/core/enumerable/shared/find_all.rb +++ b/spec/ruby/core/enumerable/shared/find_all.rb @@ -1,4 +1,4 @@ -require File.expand_path('../enumerable_enumeratorized', __FILE__) +require_relative 'enumerable_enumeratorized' describe :enumerable_find_all, shared: true do before :each do @@ -14,7 +14,7 @@ describe :enumerable_find_all, shared: true do end it "returns an enumerator when no block given" do - @numerous.send(@method).should be_an_instance_of(Enumerator) + @numerous.send(@method).should.instance_of?(Enumerator) end it "passes through the values yielded by #each_with_index" do diff --git a/spec/ruby/core/enumerable/shared/include.rb b/spec/ruby/core/enumerable/shared/include.rb index 569f350fd5..ea250f032b 100644 --- a/spec/ruby/core/enumerable/shared/include.rb +++ b/spec/ruby/core/enumerable/shared/include.rb @@ -28,7 +28,7 @@ describe :enumerable_include, shared: true do it "gathers whole arrays as elements when each yields multiple" do multi = EnumerableSpecs::YieldsMulti.new - multi.send(@method, [1,2]).should be_true + multi.send(@method, [1,2]).should == true end end diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb index 12e0665dda..7da4f0ca99 100644 --- a/spec/ruby/core/enumerable/shared/inject.rb +++ b/spec/ruby/core/enumerable/shared/inject.rb @@ -1,3 +1,5 @@ +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 = [] @@ -14,14 +16,65 @@ describe :enumerable_inject, shared: true do 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(TypeError, /is not a symbol nor a string/) + -> { [1, 2, 3].send(@method, 10, Object.new) }.should.raise(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 + -> { + 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(TypeError, /is not a symbol nor a string/) + -> { [10, 1, 2, 3].send(@method, Object.new) }.should.raise(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 @@ -30,10 +83,10 @@ describe :enumerable_inject, shared: true do 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 "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 @@ -50,7 +103,7 @@ describe :enumerable_inject, shared: true do 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| 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 @@ -60,10 +113,30 @@ describe :enumerable_inject, shared: true do 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(ArgumentError) + -> { {one: 1, two: 2}.send(@method) }.should.raise(ArgumentError) + end end diff --git a/spec/ruby/core/enumerable/shared/take.rb b/spec/ruby/core/enumerable/shared/take.rb index bf2536acda..a6da06325f 100644 --- a/spec/ruby/core/enumerable/shared/take.rb +++ b/spec/ruby/core/enumerable/shared/take.rb @@ -25,7 +25,7 @@ describe :enumerable_take, shared: true do end it "raises an ArgumentError when count is negative" do - lambda { @enum.send(@method, -1) }.should raise_error(ArgumentError) + -> { @enum.send(@method, -1) }.should.raise(ArgumentError) end it "returns the entire array when count > length" do @@ -40,11 +40,11 @@ describe :enumerable_take, shared: true do end it "raises a TypeError if the passed argument is not numeric" do - lambda { @enum.send(@method, nil) }.should raise_error(TypeError) - lambda { @enum.send(@method, "a") }.should raise_error(TypeError) + -> { @enum.send(@method, nil) }.should.raise(TypeError) + -> { @enum.send(@method, "a") }.should.raise(TypeError) obj = mock("nonnumeric") - lambda { @enum.send(@method, obj) }.should raise_error(TypeError) + -> { @enum.send(@method, obj) }.should.raise(TypeError) end it "gathers whole arrays as elements when each yields multiple" do diff --git a/spec/ruby/core/enumerable/shared/value_packing.rb b/spec/ruby/core/enumerable/shared/value_packing.rb new file mode 100644 index 0000000000..ff77f45cdf --- /dev/null +++ b/spec/ruby/core/enumerable/shared/value_packing.rb @@ -0,0 +1,26 @@ +# This is the behavior of rb_enum_values_pack() in CRuby +describe :enumerable_value_packing, shared: true do + # @take must be set to a Proc that returns the take-result whose #each + # yields packed values (e.g. -> e { e.take(1) } or -> e { e.lazy.take(1) }). + + it "yields a single nil for a zero-argument source yield" do + e = Enumerator.new { |y| y.yield } + args = nil + @take.call(e).each { |*a| args = a } + args.should == [nil] + end + + it "yields the value for a single-argument source yield" do + e = Enumerator.new { |y| y.yield :v } + args = nil + @take.call(e).each { |*a| args = a } + args.should == [:v] + end + + it "yields a packed Array for a multi-argument source yield" do + e = Enumerator.new { |y| y.yield 1, 2 } + args = nil + @take.call(e).each { |*a| args = a } + args.should == [[1, 2]] + end +end |
