1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Move spec/rubyspec to spec/ruby for consistency

* Other ruby implementations use the spec/ruby directory.
  [Misc #13792] [ruby-core:82287]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-09-20 20:18:52 +00:00
parent 75bfc6440d
commit 1d15d5f080
4370 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,121 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#all?" do
before :each do
@enum = EnumerableSpecs::Numerous.new
@empty = EnumerableSpecs::Empty.new()
@enum1 = [0, 1, 2, -1]
@enum2 = [nil, false, true]
end
it "always returns true on empty enumeration" do
@empty.all?.should == true
@empty.all? { nil }.should == true
[].all?.should == true
[].all? { false }.should == true
{}.all?.should == true
{}.all? { nil }.should == true
end
it "does not hide exceptions out of #each" do
lambda {
EnumerableSpecs::ThrowingEach.new.all?
}.should raise_error(RuntimeError)
lambda {
EnumerableSpecs::ThrowingEach.new.all? { false }
}.should raise_error(RuntimeError)
end
describe "with no block" do
it "returns true if no elements are false or nil" do
@enum.all?.should == true
@enum1.all?.should == true
@enum2.all?.should == false
EnumerableSpecs::Numerous.new('a','b','c').all?.should == true
EnumerableSpecs::Numerous.new(0, "x", true).all?.should == true
end
it "returns false if there are false or nil elements" do
EnumerableSpecs::Numerous.new(false).all?.should == false
EnumerableSpecs::Numerous.new(false, false).all?.should == false
EnumerableSpecs::Numerous.new(nil).all?.should == false
EnumerableSpecs::Numerous.new(nil, nil).all?.should == false
EnumerableSpecs::Numerous.new(1, nil, 2).all?.should == false
EnumerableSpecs::Numerous.new(0, "x", false, true).all?.should == false
@enum2.all?.should == false
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.all?.should be_true
end
end
describe "with block" do
it "returns true if the block never returns false or nil" do
@enum.all? { true }.should == true
@enum1.all?{ |o| o < 5 }.should == true
@enum1.all?{ |o| 5 }.should == true
end
it "returns false if the block ever returns false or nil" do
@enum.all? { false }.should == false
@enum.all? { nil }.should == false
@enum1.all?{ |o| o > 2 }.should == false
EnumerableSpecs::Numerous.new.all? { |i| i > 5 }.should == false
EnumerableSpecs::Numerous.new.all? { |i| i == 3 ? nil : true }.should == false
end
it "stops iterating once the return value is determined" do
yielded = []
EnumerableSpecs::Numerous.new(:one, :two, :three).all? do |e|
yielded << e
false
end.should == false
yielded.should == [:one]
yielded = []
EnumerableSpecs::Numerous.new(true, true, false, true).all? do |e|
yielded << e
e
end.should == false
yielded.should == [true, true, false]
yielded = []
EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).all? do |e|
yielded << e
e
end.should == true
yielded.should == [1, 2, 3, 4, 5]
end
it "does not hide exceptions out of the block" do
lambda {
@enum.all? { raise "from block" }
}.should raise_error(RuntimeError)
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.all? {|e| !(Array === e) }.should be_true
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
multi.all? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4], [6, 7]]
end
end
end

View file

@ -0,0 +1,141 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#any?" do
before :each do
@enum = EnumerableSpecs::Numerous.new
@empty = EnumerableSpecs::Empty.new()
@enum1 = [0, 1, 2, -1]
@enum2 = [nil, false, true]
end
it "always returns false on empty enumeration" do
@empty.any?.should == false
@empty.any? { nil }.should == false
[].any?.should == false
[].any? { false }.should == false
{}.any?.should == false
{}.any? { nil }.should == false
end
it "raises an ArgumentError when any arguments provided" do
lambda { @enum.any?(Proc.new {}) }.should raise_error(ArgumentError)
lambda { @enum.any?(nil) }.should raise_error(ArgumentError)
lambda { @empty.any?(1) }.should raise_error(ArgumentError)
lambda { @enum1.any?(1) {} }.should raise_error(ArgumentError)
lambda { @enum2.any?(1, 2, 3) {} }.should raise_error(ArgumentError)
end
it "does not hide exceptions out of #each" do
lambda {
EnumerableSpecs::ThrowingEach.new.any?
}.should raise_error(RuntimeError)
lambda {
EnumerableSpecs::ThrowingEach.new.any? { false }
}.should raise_error(RuntimeError)
end
describe "with no block" do
it "returns true if any element is not false or nil" do
@enum.any?.should == true
@enum1.any?.should == true
@enum2.any?.should == true
EnumerableSpecs::Numerous.new(true).any?.should == true
EnumerableSpecs::Numerous.new('a','b','c').any?.should == true
EnumerableSpecs::Numerous.new('a','b','c', nil).any?.should == true
EnumerableSpecs::Numerous.new(1, nil, 2).any?.should == true
EnumerableSpecs::Numerous.new(1, false).any?.should == true
EnumerableSpecs::Numerous.new(false, nil, 1, false).any?.should == true
EnumerableSpecs::Numerous.new(false, 0, nil).any?.should == true
end
it "returns false if all elements are false or nil" do
EnumerableSpecs::Numerous.new(false).any?.should == false
EnumerableSpecs::Numerous.new(false, false).any?.should == false
EnumerableSpecs::Numerous.new(nil).any?.should == false
EnumerableSpecs::Numerous.new(nil, nil).any?.should == false
EnumerableSpecs::Numerous.new(nil, false, nil).any?.should == false
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.any?.should be_true
end
end
describe "with block" do
it "returns true if the block ever returns other than false or nil" do
@enum.any? { true } == true
@enum.any? { 0 } == true
@enum.any? { 1 } == true
@enum1.any? { Object.new } == true
@enum1.any?{ |o| o < 1 }.should == true
@enum1.any?{ |o| 5 }.should == true
@enum2.any? { |i| i == nil }.should == true
end
it "any? should return false if the block never returns other than false or nil" do
@enum.any? { false }.should == false
@enum.any? { nil }.should == false
@enum1.any?{ |o| o < -10 }.should == false
@enum1.any?{ |o| nil }.should == false
@enum2.any? { |i| i == :stuff }.should == false
end
it "stops iterating once the return value is determined" do
yielded = []
EnumerableSpecs::Numerous.new(:one, :two, :three).any? do |e|
yielded << e
false
end.should == false
yielded.should == [:one, :two, :three]
yielded = []
EnumerableSpecs::Numerous.new(true, true, false, true).any? do |e|
yielded << e
e
end.should == true
yielded.should == [true]
yielded = []
EnumerableSpecs::Numerous.new(false, nil, false, true, false).any? do |e|
yielded << e
e
end.should == true
yielded.should == [false, nil, false, true]
yielded = []
EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).any? do |e|
yielded << e
e
end.should == true
yielded.should == [1]
end
it "does not hide exceptions out of the block" do
lambda {
@enum.any? { raise "from block" }
}.should raise_error(RuntimeError)
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.any? {|e| e == 1 }.should be_true
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
multi.any? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2]]
end
end
end

View file

@ -0,0 +1,100 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#chunk" do
before do
ScratchPad.record []
end
ruby_version_is ""..."2.4" do
it "raises an ArgumentError if called without a block" do
lambda do
EnumerableSpecs::Numerous.new.chunk
end.should raise_error(ArgumentError)
end
end
ruby_version_is "2.4" do
it "returns an Enumerator if called without a block" do
chunk = EnumerableSpecs::Numerous.new(1, 2, 3, 1, 2).chunk
chunk.should be_an_instance_of(Enumerator)
result = chunk.with_index {|elt, i| elt - i }.to_a
result.should == [[1, [1, 2, 3]], [-2, [1, 2]]]
end
end
it "returns an Enumerator if given a block" do
EnumerableSpecs::Numerous.new.chunk {}.should be_an_instance_of(Enumerator)
end
it "yields the current element and the current chunk to the block" do
e = EnumerableSpecs::Numerous.new(1, 2, 3)
e.chunk { |x| ScratchPad << x }.to_a
ScratchPad.recorded.should == [1, 2, 3]
end
it "returns elements of the Enumerable in an Array of Arrays, [v, ary], where 'ary' contains the consecutive elements for which the block returned the value 'v'" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 3, 2, 1)
result = e.chunk { |x| x < 3 && 1 || 0 }.to_a
result.should == [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]]
end
it "returns elements for which the block returns :_alone in separate Arrays" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
result = e.chunk { |x| x < 2 && :_alone }.to_a
result.should == [[:_alone, [1]], [false, [2, 3, 2]], [:_alone, [1]]]
end
it "does not return elements for which the block returns :_separator" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 3, 2, 1)
result = e.chunk { |x| x == 2 ? :_separator : 1 }.to_a
result.should == [[1, [1]], [1, [3, 3]], [1, [1]]]
end
it "does not return elements for which the block returns nil" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
result = e.chunk { |x| x == 2 ? nil : 1 }.to_a
result.should == [[1, [1]], [1, [3]], [1, [1]]]
end
it "raises a RuntimeError if the block returns a Symbol starting with an underscore other than :_alone or :_separator" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
lambda { e.chunk { |x| :_arbitrary }.to_a }.should raise_error(RuntimeError)
end
ruby_version_is ""..."2.3" do
describe "with [initial_state]" do
it "yields an element and an object value-equal but not identical to the object passed to #chunk" do
e = EnumerableSpecs::Numerous.new(1)
value = "value"
e.chunk(value) do |x, v|
x.should == 1
v.should == value
v.should_not equal(value)
end.to_a
end
it "does not yield the object passed to #chunk if it is nil" do
e = EnumerableSpecs::Numerous.new(1)
e.chunk(nil) { |*x| ScratchPad << x }.to_a
ScratchPad.recorded.should == [[1]]
end
end
end
ruby_version_is "2.3" do
it "does not accept arguments" do
e = EnumerableSpecs::Numerous.new(1, 2, 3)
lambda {
e.chunk(1) {}
}.should raise_error(ArgumentError)
end
end
it 'returned Enumerator size returns nil' do
e = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 2, 1)
enum = e.chunk { |x| true }
enum.size.should == nil
end
end

View file

@ -0,0 +1,44 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
ruby_version_is "2.3" do
describe "Enumerable#chunk_while" do
before :each do
ary = [10, 9, 7, 6, 4, 3, 2, 1]
@enum = EnumerableSpecs::Numerous.new(*ary)
@result = @enum.chunk_while { |i, j| i - 1 == j }
@enum_length = ary.length
end
context "when given a block" do
it "returns an enumerator" do
@result.should be_an_instance_of(Enumerator)
end
it "splits chunks between adjacent elements i and j where the block returns false" do
@result.to_a.should == [[10, 9], [7, 6], [4, 3, 2, 1]]
end
it "calls the block for length of the receiver enumerable minus one times" do
times_called = 0
@enum.chunk_while do |i, j|
times_called += 1
i - 1 == j
end.to_a
times_called.should == (@enum_length - 1)
end
end
context "when not given a block" do
it "raises an ArgumentError" do
lambda { @enum.chunk_while }.should raise_error(ArgumentError)
end
end
context "on a single-element array" do
it "ignores the block and returns an enumerator that yields [element]" do
[1].chunk_while {|x| x.even?}.to_a.should == [[1]]
end
end
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/collect_concat', __FILE__)
describe "Enumerable#collect_concat" do
it_behaves_like(:enumerable_collect_concat , :collect_concat)
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/collect', __FILE__)
describe "Enumerable#collect" do
it_behaves_like(:enumerable_collect , :collect)
end

View file

@ -0,0 +1,59 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#count" do
before :each do
@elements = [1, 2, 4, 2]
@numerous = EnumerableSpecs::Numerous.new(*@elements)
end
describe "when no argument or a block" do
it "returns size" do
@numerous.count.should == 4
end
describe "with a custom size method" do
before :each do
class << @numerous
def size
:any_object
end
end
end
it "ignores the custom size method" do
@numerous.count.should == 4
end
end
end
it "counts nils if given nil as an argument" do
EnumerableSpecs::Numerous.new(nil, nil, nil, false).count(nil).should == 3
end
it "accepts an argument for comparison using ==" do
@numerous.count(2).should == 2
end
it "uses a block for comparison" do
@numerous.count{|x| x%2==0 }.should == 3
end
it "ignores the block when given an argument" do
-> {
@numerous.count(4){|x| x%2==0 }.should == 1
}.should complain(/given block not used/)
end
describe "when each yields multiple values" do
it "gathers initial args as elements" do
multi = EnumerableSpecs::YieldsMulti.new
multi.count {|e| e == 1 }.should == 1
end
it "accepts an argument for comparison using ==" do
multi = EnumerableSpecs::YieldsMulti.new
multi.count([1, 2]).should == 1
end
end
end

View file

@ -0,0 +1,104 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumeratorized', __FILE__)
describe "Enumerable#cycle" do
describe "passed no argument or nil" do
it "loops indefinitely" do
[[],[nil]].each do |args|
bomb = 10
EnumerableSpecs::Numerous.new.cycle(*args) do
bomb -= 1
break 42 if bomb <= 0
end.should == 42
bomb.should == 0
end
end
it "returns nil if there are no elements" do
out = EnumerableSpecs::Empty.new.cycle { break :nope }
out.should be_nil
end
it "yields successive elements of the array repeatedly" do
b = []
EnumerableSpecs::Numerous.new(1,2,3).cycle do |elem|
b << elem
break if b.size == 7
end
b.should == [1,2,3,1,2,3,1]
end
it "calls each at most once" do
enum = EnumerableSpecs::EachCounter.new(1, 2)
enum.cycle.first(6).should == [1,2,1,2,1,2]
enum.times_called.should == 1
end
it "yields only when necessary" do
enum = EnumerableSpecs::EachCounter.new(10, 20, 30)
enum.cycle { |x| break if x == 20}
enum.times_yielded.should == 2
end
end
describe "passed a number n as an argument" do
it "returns nil and does nothing for non positive n" do
EnumerableSpecs::ThrowingEach.new.cycle(0) {}.should be_nil
EnumerableSpecs::NoEach.new.cycle(-22) {}.should be_nil
end
it "calls each at most once" do
enum = EnumerableSpecs::EachCounter.new(1, 2)
enum.cycle(3).to_a.should == [1,2,1,2,1,2]
enum.times_called.should == 1
end
it "yields only when necessary" do
enum = EnumerableSpecs::EachCounter.new(10, 20, 30)
enum.cycle(3) { |x| break if x == 20}
enum.times_yielded.should == 2
end
it "tries to convert n to an Integer using #to_int" do
enum = EnumerableSpecs::Numerous.new(3, 2, 1)
enum.cycle(2.3).to_a.should == [3, 2, 1, 3, 2, 1]
obj = mock('to_int')
obj.should_receive(:to_int).and_return(2)
enum.cycle(obj).to_a.should == [3, 2, 1, 3, 2, 1]
end
it "raises a TypeError when the passed n can be coerced to Integer" do
enum = EnumerableSpecs::Numerous.new
lambda{ enum.cycle("cat"){} }.should raise_error(TypeError)
end
it "raises an ArgumentError if more arguments are passed" do
enum = EnumerableSpecs::Numerous.new
lambda{ enum.cycle(1, 2) {} }.should raise_error(ArgumentError)
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.cycle(2).to_a.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9], [1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
end
describe "Enumerable with size" do
before :all do
@object = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 4)
@empty_object = EnumerableSpecs::EmptyWithSize.new
end
it_should_behave_like :enumeratorized_with_cycle_size
end
describe "Enumerable with no size" do
before :all do
@object = EnumerableSpecs::Numerous.new(1, 2, 3, 4)
@method = :cycle
end
it_should_behave_like :enumeratorized_with_unknown_size
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/find', __FILE__)
describe "Enumerable#detect" do
it_behaves_like(:enumerable_find , :detect)
end

View file

@ -0,0 +1,43 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#drop" do
before :each do
@enum = EnumerableSpecs::Numerous.new(3, 2, 1, :go)
end
it "requires exactly one argument" do
lambda{ @enum.drop{} }.should raise_error(ArgumentError)
lambda{ @enum.drop(1, 2){} }.should raise_error(ArgumentError)
end
describe "passed a number n as an argument" do
it "raises ArgumentError if n < 0" do
lambda{ @enum.drop(-1) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
@enum.drop(2.3).should == [1, :go]
obj = mock('to_int')
obj.should_receive(:to_int).and_return(2)
@enum.drop(obj).should == [1, :go]
end
it "returns [] for empty enumerables" do
EnumerableSpecs::Empty.new.drop(0).should == []
EnumerableSpecs::Empty.new.drop(2).should == []
end
it "returns [] if dropping all" do
@enum.drop(5).should == []
EnumerableSpecs::Numerous.new(3, 2, 1, :go).drop(4).should == []
end
it "raises a TypeError when the passed n can be coerced to Integer" do
lambda{ @enum.drop("hat") }.should raise_error(TypeError)
lambda{ @enum.drop(nil) }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,50 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#drop_while" do
before :each do
@enum = EnumerableSpecs::Numerous.new(3, 2, 1, :go)
end
it "returns an Enumerator if no block given" do
@enum.drop_while.should be_an_instance_of(Enumerator)
end
it "returns no/all elements for {true/false} block" do
@enum.drop_while{true}.should == []
@enum.drop_while{false}.should == @enum.to_a
end
it "accepts returns other than true/false" do
@enum.drop_while{1}.should == []
@enum.drop_while{nil}.should == @enum.to_a
end
it "passes elements to the block until the first false" do
a = []
@enum.drop_while{|obj| (a << obj).size < 3}.should == [1, :go]
a.should == [3, 2, 1]
end
it "will only go through what's needed" do
enum = EnumerableSpecs::EachCounter.new(1,2,3,4)
enum.drop_while { |x|
break 42 if x == 3
true
}.should == 42
enum.times_yielded.should == 3
end
it "doesn't return self when it could" do
a = [1,2,3]
a.drop_while{false}.should_not equal(a)
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.drop_while {|e| e != [6, 7, 8, 9] }.should == [[6, 7, 8, 9]]
end
it_behaves_like :enumerable_enumeratorized_with_unknown_size, :drop_while
end

View file

@ -0,0 +1,99 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumeratorized', __FILE__)
describe "Enumerable#each_cons" do
before :each do
@enum = EnumerableSpecs::Numerous.new(4,3,2,1)
@in_threes = [[4,3,2],[3,2,1]]
end
it "passes element groups to the block" do
acc = []
@enum.each_cons(3){|g| acc << g}.should be_nil
acc.should == @in_threes
end
it "raises an ArgumentError if there is not a single parameter > 0" do
lambda{ @enum.each_cons(0){} }.should raise_error(ArgumentError)
lambda{ @enum.each_cons(-2){} }.should raise_error(ArgumentError)
lambda{ @enum.each_cons{} }.should raise_error(ArgumentError)
lambda{ @enum.each_cons(2,2){} }.should raise_error(ArgumentError)
lambda{ @enum.each_cons(0) }.should raise_error(ArgumentError)
lambda{ @enum.each_cons(-2) }.should raise_error(ArgumentError)
lambda{ @enum.each_cons }.should raise_error(ArgumentError)
lambda{ @enum.each_cons(2,2) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
acc = []
@enum.each_cons(3.3){|g| acc << g}.should == nil
acc.should == @in_threes
obj = mock('to_int')
obj.should_receive(:to_int).and_return(3)
@enum.each_cons(obj){|g| break g.length}.should == 3
end
it "works when n is >= full length" do
full = @enum.to_a
acc = []
@enum.each_cons(full.length){|g| acc << g}
acc.should == [full]
acc = []
@enum.each_cons(full.length+1){|g| acc << g}
acc.should == []
end
it "yields only as much as needed" do
cnt = EnumerableSpecs::EachCounter.new(1, 2, :stop, "I said stop!", :got_it)
cnt.each_cons(2) {|g| break 42 if g[-1] == :stop }.should == 42
cnt.times_yielded.should == 3
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.each_cons(2).to_a.should == [[[1, 2], [3, 4, 5]], [[3, 4, 5], [6, 7, 8, 9]]]
end
describe "when no block is given" do
it "returns an enumerator" do
e = @enum.each_cons(3)
e.should be_an_instance_of(Enumerator)
e.to_a.should == @in_threes
end
describe "Enumerable with size" do
describe "returned Enumerator" do
describe "size" do
it "returns enum size - each_cons argument + 1" do
enum = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
enum.each_cons(10).size.should == 1
enum.each_cons(9).size.should == 2
enum.each_cons(3).size.should == 8
enum.each_cons(2).size.should == 9
enum.each_cons(1).size.should == 10
end
it "returns 0 when the argument is larger than self" do
enum = EnumerableSpecs::NumerousWithSize.new(1, 2, 3)
enum.each_cons(20).size.should == 0
end
it "returns 0 when the enum is empty" do
enum = EnumerableSpecs::EmptyWithSize.new
enum.each_cons(10).size.should == 0
end
end
end
end
describe "Enumerable with no size" do
before :all do
@object = EnumerableSpecs::Numerous.new(1, 2, 3, 4)
@method = [:each_cons, 8]
end
it_should_behave_like :enumeratorized_with_unknown_size
end
end
end

View file

@ -0,0 +1,41 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#each_entry" do
before :each do
ScratchPad.record []
@enum = EnumerableSpecs::YieldsMixed.new
@entries = [1, [2], [3,4], [5,6,7], [8,9], nil, []]
end
it "yields multiple arguments as an array" do
acc = []
@enum.each_entry {|g| acc << g}.should equal(@enum)
acc.should == @entries
end
it "returns an enumerator if no block" do
e = @enum.each_entry
e.should be_an_instance_of(Enumerator)
e.to_a.should == @entries
end
it "passes through the values yielded by #each_with_index" do
[:a, :b].each_with_index.each_entry { |x, i| ScratchPad << [x, i] }
ScratchPad.recorded.should == [[:a, 0], [:b, 1]]
end
it "raises an ArgumentError when extra arguments" do
lambda { @enum.each_entry("one").to_a }.should raise_error(ArgumentError)
lambda { @enum.each_entry("one"){}.to_a }.should raise_error(ArgumentError)
end
it "passes extra arguments to #each" do
enum = EnumerableSpecs::EachCounter.new(1, 2)
enum.each_entry(:foo, "bar").to_a.should == [1,2]
enum.arguments_passed.should == [:foo, "bar"]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :each_entry
end

View file

@ -0,0 +1,101 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumeratorized', __FILE__)
describe "Enumerable#each_slice" do
before :each do
@enum = EnumerableSpecs::Numerous.new(7,6,5,4,3,2,1)
@sliced = [[7,6,5],[4,3,2],[1]]
end
it "passes element groups to the block" do
acc = []
@enum.each_slice(3){|g| acc << g}.should be_nil
acc.should == @sliced
end
it "raises an ArgumentError if there is not a single parameter > 0" do
lambda{ @enum.each_slice(0){} }.should raise_error(ArgumentError)
lambda{ @enum.each_slice(-2){} }.should raise_error(ArgumentError)
lambda{ @enum.each_slice{} }.should raise_error(ArgumentError)
lambda{ @enum.each_slice(2,2){} }.should raise_error(ArgumentError)
lambda{ @enum.each_slice(0) }.should raise_error(ArgumentError)
lambda{ @enum.each_slice(-2) }.should raise_error(ArgumentError)
lambda{ @enum.each_slice }.should raise_error(ArgumentError)
lambda{ @enum.each_slice(2,2) }.should raise_error(ArgumentError)
end
it "tries to convert n to an Integer using #to_int" do
acc = []
@enum.each_slice(3.3){|g| acc << g}.should == nil
acc.should == @sliced
obj = mock('to_int')
obj.should_receive(:to_int).and_return(3)
@enum.each_slice(obj){|g| break g.length}.should == 3
end
it "works when n is >= full length" do
full = @enum.to_a
acc = []
@enum.each_slice(full.length){|g| acc << g}
acc.should == [full]
acc = []
@enum.each_slice(full.length+1){|g| acc << g}
acc.should == [full]
end
it "yields only as much as needed" do
cnt = EnumerableSpecs::EachCounter.new(1, 2, :stop, "I said stop!", :got_it)
cnt.each_slice(2) {|g| break 42 if g[0] == :stop }.should == 42
cnt.times_yielded.should == 4
end
it "returns an enumerator if no block" do
e = @enum.each_slice(3)
e.should be_an_instance_of(Enumerator)
e.to_a.should == @sliced
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.each_slice(2).to_a.should == [[[1, 2], [3, 4, 5]], [[6, 7, 8, 9]]]
end
describe "when no block is given" do
it "returns an enumerator" do
e = @enum.each_slice(3)
e.should be_an_instance_of(Enumerator)
e.to_a.should == @sliced
end
describe "Enumerable with size" do
describe "returned Enumerator" do
describe "size" do
it "returns the ceil of Enumerable size divided by the argument value" do
enum = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
enum.each_slice(10).size.should == 1
enum.each_slice(9).size.should == 2
enum.each_slice(3).size.should == 4
enum.each_slice(2).size.should == 5
enum.each_slice(1).size.should == 10
end
it "returns 0 when the Enumerable is empty" do
enum = EnumerableSpecs::EmptyWithSize.new
enum.each_slice(10).size.should == 0
end
end
end
end
describe "Enumerable with no size" do
before :all do
@object = EnumerableSpecs::Numerous.new(1, 2, 3, 4)
@method = [:each_slice, 8]
end
it_should_behave_like :enumeratorized_with_unknown_size
end
end
end

View file

@ -0,0 +1,53 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#each_with_index" do
before :each do
@b = EnumerableSpecs::Numerous.new(2, 5, 3, 6, 1, 4)
end
it "passes each element and its index to block" do
@a = []
@b.each_with_index { |o, i| @a << [o, i] }
@a.should == [[2, 0], [5, 1], [3, 2], [6, 3], [1, 4], [4, 5]]
end
it "provides each element to the block" do
acc = []
obj = EnumerableSpecs::EachDefiner.new()
res = obj.each_with_index {|a,i| acc << [a,i]}
acc.should == []
obj.should == res
end
it "provides each element to the block and its index" do
acc = []
res = @b.each_with_index {|a,i| acc << [a,i]}
[[2, 0], [5, 1], [3, 2], [6, 3], [1, 4], [4, 5]].should == acc
res.should eql(@b)
end
it "binds splat arguments properly" do
acc = []
res = @b.each_with_index { |*b| c,d = b; acc << c; acc << d }
[2, 0, 5, 1, 3, 2, 6, 3, 1, 4, 4, 5].should == acc
res.should eql(@b)
end
it "returns an enumerator if no block" do
e = @b.each_with_index
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[2, 0], [5, 1], [3, 2], [6, 3], [1, 4], [4, 5]]
end
it "passes extra parameters to each" do
count = EnumerableSpecs::EachCounter.new(:apple)
e = count.each_with_index(:foo, :bar)
e.to_a.should == [[:apple, 0]]
count.arguments_passed.should == [:foo, :bar]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :each_with_index
end

View file

@ -0,0 +1,41 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#each_with_object" do
before :each do
@values = [2, 5, 3, 6, 1, 4]
@enum = EnumerableSpecs::Numerous.new(*@values)
@initial = "memo"
end
it "passes each element and its argument to the block" do
acc = []
@enum.each_with_object(@initial) do |elem, obj|
obj.should equal(@initial)
obj = 42
acc << elem
end.should equal(@initial)
acc.should == @values
end
it "returns an enumerator if no block" do
acc = []
e = @enum.each_with_object(@initial)
e.each do |elem, obj|
obj.should equal(@initial)
obj = 42
acc << elem
end.should equal(@initial)
acc.should == @values
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
array = []
multi.each_with_object(array) { |elem, obj| obj << elem }
array.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, [:each_with_object, []]
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/entries', __FILE__)
describe "Enumerable#entries" do
it_behaves_like(:enumerable_entries , :entries)
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/find_all', __FILE__)
describe "Enumerable#find_all" do
it_behaves_like(:enumerable_find_all , :find_all)
end

View file

@ -0,0 +1,89 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#find_index" do
before :each do
@elements = [2, 4, 6, 8, 10]
@numerous = EnumerableSpecs::Numerous.new(*@elements)
@yieldsmixed = EnumerableSpecs::YieldsMixed2.new
end
it "passes each entry in enum to block while block when block is false" do
visited_elements = []
@numerous.find_index do |element|
visited_elements << element
false
end
visited_elements.should == @elements
end
it "returns nil when the block is false" do
@numerous.find_index {|e| false }.should == nil
end
it "returns the first index for which the block is not false" do
@elements.each_with_index do |element, index|
@numerous.find_index {|e| e > element - 1 }.should == index
end
end
it "returns the first index found" do
repeated = [10, 11, 11, 13, 11, 13, 10, 10, 13, 11]
numerous_repeat = EnumerableSpecs::Numerous.new(*repeated)
repeated.each do |element|
numerous_repeat.find_index(element).should == element - 10
end
end
it "returns nil when the element not found" do
@numerous.find_index(-1).should == nil
end
it "ignores the block if an argument is given" do
-> {
@numerous.find_index(-1) {|e| true }.should == nil
}.should complain(/given block not used/)
end
it "returns an Enumerator if no block given" do
@numerous.find_index.should be_an_instance_of(Enumerator)
end
it "uses #== for testing equality" do
[2].to_enum.find_index(2.0).should == 0
[2.0].to_enum.find_index(2).should == 0
end
describe "without block" do
it "gathers whole arrays as elements when each yields multiple" do
@yieldsmixed.find_index([0, 1, 2]).should == 3
end
end
describe "with block" do
before :each do
ScratchPad.record []
end
after :each do
ScratchPad.clear
end
describe "given a single yield parameter" do
it "passes first element to the parameter" do
@yieldsmixed.find_index {|a| ScratchPad << a; false }
ScratchPad.recorded.should == EnumerableSpecs::YieldsMixed2.first_yields
end
end
describe "given a greedy yield parameter" do
it "passes a gathered array to the parameter" do
@yieldsmixed.find_index {|*args| ScratchPad << args; false }
ScratchPad.recorded.should == EnumerableSpecs::YieldsMixed2.greedy_yields
end
end
end
it_behaves_like :enumerable_enumeratorized_with_unknown_size, :find_index
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/find', __FILE__)
describe "Enumerable#find" do
it_behaves_like(:enumerable_find , :find)
end

View file

@ -0,0 +1,28 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/take', __FILE__)
describe "Enumerable#first" do
it "returns the first element" do
EnumerableSpecs::Numerous.new.first.should == 2
EnumerableSpecs::Empty.new.first.should == nil
end
it "returns nil if self is empty" do
EnumerableSpecs::Empty.new.first.should == nil
end
it 'returns a gathered array from yield parameters' do
EnumerableSpecs::YieldsMulti.new.to_enum.first.should == [1, 2]
EnumerableSpecs::YieldsMixed2.new.to_enum.first.should == nil
end
it "raises a RangeError when passed a Bignum" do
enum = EnumerableSpecs::Empty.new
lambda { enum.first(bignum_value) }.should raise_error(RangeError)
end
describe "when passed an argument" do
it_behaves_like :enumerable_take, :first
end
end

View file

@ -0,0 +1,331 @@
module EnumerableSpecs
class Numerous
include Enumerable
def initialize(*list)
@list = list.empty? ? [2, 5, 3, 6, 1, 4] : list
end
def each
@list.each { |i| yield i }
end
end
class NumerousWithSize < Numerous
def size
@list.size
end
end
class EachCounter < Numerous
attr_reader :times_called, :times_yielded, :arguments_passed
def initialize(*list)
super(*list)
@times_yielded = @times_called = 0
end
def each(*arg)
@times_called += 1
@times_yielded = 0
@arguments_passed = arg
@list.each do |i|
@times_yielded +=1
yield i
end
end
end
class Empty
include Enumerable
def each
end
end
class EmptyWithSize
include Enumerable
def each
end
def size
0
end
end
class ThrowingEach
include Enumerable
def each
raise "from each"
end
end
class NoEach
include Enumerable
end
# (Legacy form rubycon)
class EachDefiner
include Enumerable
attr_reader :arr
def initialize(*arr)
@arr = arr
end
def each
i = 0
loop do
break if i == @arr.size
yield @arr[i]
i += 1
end
end
end
class SortByDummy
def initialize(s)
@s = s
end
def s
@s
end
end
class ComparesByVowelCount
attr_accessor :value, :vowels
def self.wrap(*args)
args.map {|element| ComparesByVowelCount.new(element)}
end
def initialize(string)
self.value = string
self.vowels = string.gsub(/[^aeiou]/, '').size
end
def <=>(other)
self.vowels <=> other.vowels
end
end
class InvalidComparable
def <=>(other)
"Not Valid"
end
end
class ArrayConvertable
attr_accessor :called
def initialize(*values)
@values = values
end
def to_a
self.called = :to_a
@values
end
def to_ary
self.called = :to_ary
@values
end
end
class EnumConvertable
attr_accessor :called
attr_accessor :sym
def initialize(delegate)
@delegate = delegate
end
def to_enum(sym)
self.called = :to_enum
self.sym = sym
@delegate.to_enum(sym)
end
def respond_to_missing?(*args)
@delegate.respond_to?(*args)
end
end
class Equals
def initialize(obj)
@obj = obj
end
def ==(other)
@obj == other
end
end
class YieldsMulti
include Enumerable
def each
yield 1,2
yield 3,4,5
yield 6,7,8,9
end
end
class YieldsMultiWithFalse
include Enumerable
def each
yield false,2
yield false,4,5
yield false,7,8,9
end
end
class YieldsMultiWithSingleTrue
include Enumerable
def each
yield false,2
yield true,4,5
yield false,7,8,9
end
end
class YieldsMixed
include Enumerable
def each
yield 1
yield [2]
yield 3,4
yield 5,6,7
yield [8,9]
yield nil
yield []
end
end
class YieldsMixed2
include Enumerable
def self.first_yields
[nil, 0, 0, 0, 0, nil, :default_arg, [], [], [0], [0, 1], [0, 1, 2]]
end
def self.gathered_yields
[nil, 0, [0, 1], [0, 1, 2], [0, 1, 2], nil, :default_arg, [], [], [0], [0, 1], [0, 1, 2]]
end
def self.gathered_yields_with_args(arg, *args)
[nil, 0, [0, 1], [0, 1, 2], [0, 1, 2], nil, arg, args, [], [0], [0, 1], [0, 1, 2]]
end
def self.greedy_yields
[[], [0], [0, 1], [0, 1, 2], [0, 1, 2], [nil], [:default_arg], [[]], [[]], [[0]], [[0, 1]], [[0, 1, 2]]]
end
def each(arg=:default_arg, *args)
yield
yield 0
yield 0, 1
yield 0, 1, 2
yield(*[0, 1, 2])
yield nil
yield arg
yield args
yield []
yield [0]
yield [0, 1]
yield [0, 1, 2]
end
end
class ReverseComparable
include Comparable
def initialize(num)
@num = num
end
attr_accessor :num
# Reverse comparison
def <=>(other)
other.num <=> @num
end
end
class ComparableWithFixnum
include Comparable
def initialize(num)
@num = num
end
def <=>(fixnum)
@num <=> fixnum
end
end
class Uncomparable
def <=>(obj)
nil
end
end
class Undupable
attr_reader :initialize_called, :initialize_dup_called
def dup
raise "Can't, sorry"
end
def clone
raise "Can't, either, sorry"
end
def initialize
@initialize_dup = true
end
def initialize_dup(arg)
@initialize_dup_called = true
end
end
class Freezy
include Enumerable
def each
yield 1
yield 2
end
def to_a
super.freeze
end
end
class MapReturnsEnumerable
include Enumerable
class EnumerableMapping
include Enumerable
def initialize(items, block)
@items = items
@block = block
end
def each
@items.each do |i|
yield @block.call(i)
end
end
end
def each
yield 1
yield 2
yield 3
end
def map(&block)
EnumerableMapping.new(self, block)
end
end
end # EnumerableSpecs utility classes

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/collect_concat', __FILE__)
describe "Enumerable#flat_map" do
it_behaves_like(:enumerable_collect_concat , :flat_map)
end

View file

@ -0,0 +1,52 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#grep" do
before :each do
@a = EnumerableSpecs::EachDefiner.new( 2, 4, 6, 8, 10)
end
it "grep without a block should return an array of all elements === pattern" do
class EnumerableSpecGrep; def ===(obj); obj == '2'; end; end
EnumerableSpecs::Numerous.new('2', 'a', 'nil', '3', false).grep(EnumerableSpecGrep.new).should == ['2']
end
it "grep with a block should return an array of elements === pattern passed through block" do
class EnumerableSpecGrep2; def ===(obj); /^ca/ =~ obj; end; end
EnumerableSpecs::Numerous.new("cat", "coat", "car", "cadr", "cost").grep(EnumerableSpecGrep2.new) { |i| i.upcase }.should == ["CAT", "CAR", "CADR"]
end
it "grep the enumerable (rubycon legacy)" do
EnumerableSpecs::EachDefiner.new().grep(1).should == []
@a.grep(3..7).should == [4,6]
@a.grep(3..7) {|a| a+1}.should == [5,7]
end
it "can use $~ in the block when used with a Regexp" do
ary = ["aba", "aba"]
ary.grep(/a(b)a/) { $1 }.should == ["b", "b"]
end
describe "with a block" do
before :each do
@numerous = EnumerableSpecs::Numerous.new(*(0..9).to_a)
def (@odd_matcher = BasicObject.new).===(obj)
obj.odd?
end
end
it "returns an Array of matched elements that mapped by the block" do
@numerous.grep(@odd_matcher) { |n| n * 2 }.should == [2, 6, 10, 14, 18]
end
it "calls the block with gathered array when yielded with multiple arguments" do
EnumerableSpecs::YieldsMixed2.new.grep(Object){ |e| e }.should == EnumerableSpecs::YieldsMixed2.gathered_yields
end
it "raises an ArgumentError when not given a pattern" do
-> { @numerous.grep { |e| e } }.should raise_error(ArgumentError)
end
end
end

View file

@ -0,0 +1,43 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
ruby_version_is "2.3" do
describe "Enumerable#grep_v" do
before :each do
@numerous = EnumerableSpecs::Numerous.new(*(0..9).to_a)
def (@odd_matcher = BasicObject.new).===(obj)
obj.odd?
end
end
describe "without block" do
it "returns an Array of matched elements" do
@numerous.grep_v(@odd_matcher).should == [0, 2, 4, 6, 8]
end
it "compares pattern with gathered array when yielded with multiple arguments" do
(unmatcher = Object.new).stub!(:===).and_return(false)
EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher).should == EnumerableSpecs::YieldsMixed2.gathered_yields
end
it "raises an ArgumentError when not given a pattern" do
-> { @numerous.grep_v }.should raise_error(ArgumentError)
end
end
describe "with block" do
it "returns an Array of matched elements that mapped by the block" do
@numerous.grep_v(@odd_matcher) { |n| n * 2 }.should == [0, 4, 8, 12, 16]
end
it "calls the block with gathered array when yielded with multiple arguments" do
(unmatcher = Object.new).stub!(:===).and_return(false)
EnumerableSpecs::YieldsMixed2.new.grep_v(unmatcher){ |e| e }.should == EnumerableSpecs::YieldsMixed2.gathered_yields
end
it "raises an ArgumentError when not given a pattern" do
-> { @numerous.grep_v { |e| e } }.should raise_error(ArgumentError)
end
end
end
end

View file

@ -0,0 +1,45 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#group_by" do
it "returns a hash with values grouped according to the block" do
e = EnumerableSpecs::Numerous.new("foo", "bar", "baz")
h = e.group_by { |word| word[0..0].to_sym }
h.should == { f: ["foo"], b: ["bar", "baz"]}
end
it "returns an empty hash for empty enumerables" do
EnumerableSpecs::Empty.new.group_by { |x| x}.should == {}
end
it "returns a hash without default_proc" do
e = EnumerableSpecs::Numerous.new("foo", "bar", "baz")
h = e.group_by { |word| word[0..0].to_sym }
h[:some].should be_nil
h.default_proc.should be_nil
h.default.should be_nil
end
it "returns an Enumerator if called without a block" do
EnumerableSpecs::Numerous.new.group_by.should be_an_instance_of(Enumerator)
end
it "gathers whole arrays as elements when each yields multiple" do
e = EnumerableSpecs::YieldsMulti.new
h = e.group_by { |i| i }
h.should == { [1, 2] => [[1, 2]],
[6, 7, 8, 9] => [[6, 7, 8, 9]],
[3, 4, 5] => [[3, 4, 5]] }
end
it "returns a tainted hash if self is tainted" do
EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true
end
it "returns an untrusted hash if self is untrusted" do
EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :group_by
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/include', __FILE__)
describe "Enumerable#include?" do
it_behaves_like(:enumerable_include, :include?)
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/inject', __FILE__)
describe "Enumerable#inject" do
it_behaves_like :enumerable_inject, :inject
end

View file

@ -0,0 +1,10 @@
# -*- encoding: us-ascii -*-
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#lazy" do
it "returns an instance of Enumerator::Lazy" do
EnumerableSpecs::Numerous.new.lazy.should be_an_instance_of(Enumerator::Lazy)
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/collect', __FILE__)
describe "Enumerable#map" do
it_behaves_like(:enumerable_collect , :map)
end

View file

@ -0,0 +1,81 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#max_by" do
it "returns an enumerator if no block" do
EnumerableSpecs::Numerous.new(42).max_by.should be_an_instance_of(Enumerator)
end
it "returns nil if #each yields no objects" do
EnumerableSpecs::Empty.new.max_by {|o| o.nonesuch }.should == nil
end
it "returns the object for whom the value returned by block is the largest" do
EnumerableSpecs::Numerous.new(*%w[1 2 3]).max_by {|obj| obj.to_i }.should == '3'
EnumerableSpecs::Numerous.new(*%w[three five]).max_by {|obj| obj.length }.should == 'three'
end
it "returns the object that appears first in #each in case of a tie" do
a, b, c = '1', '2', '2'
EnumerableSpecs::Numerous.new(a, b, c).max_by {|obj| obj.to_i }.should equal(b)
end
it "uses max.<=>(current) to determine order" do
a, b, c = (1..3).map{|n| EnumerableSpecs::ReverseComparable.new(n)}
# Just using self here to avoid additional complexity
EnumerableSpecs::Numerous.new(a, b, c).max_by {|obj| obj }.should == a
end
it "is able to return the maximum for enums that contain nils" do
enum = EnumerableSpecs::Numerous.new(nil, nil, true)
enum.max_by {|o| o.nil? ? 0 : 1 }.should == true
enum.max_by {|o| o.nil? ? 1 : 0 }.should == nil
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.max_by {|e| e.size}.should == [6, 7, 8, 9]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :max_by
context "when called with an argument n" do
before :each do
@enum = EnumerableSpecs::Numerous.new(101, 55, 1, 20, 33, 500, 60)
end
context "without a block" do
it "returns an enumerator" do
@enum.max_by(2).should be_an_instance_of(Enumerator)
end
end
context "with a block" do
it "returns an array containing the maximum n elements based on the block's value" do
result = @enum.max_by(3) { |i| i.to_s }
result.should == [60, 55, 500]
end
context "on a enumerable of length x where x < n" do
it "returns an array containing the maximum n elements of length n" do
result = @enum.max_by(500) { |i| i.to_s }
result.length.should == 7
end
end
context "when n is negative" do
it "raises an ArgumentError" do
lambda { @enum.max_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
end
end
end
context "when n is nil" do
it "returns the maximum element" do
@enum.max_by(nil) { |i| i.to_s }.should == 60
end
end
end
end

View file

@ -0,0 +1,119 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#max" do
before :each do
@e_strs = EnumerableSpecs::EachDefiner.new("333", "22", "666666", "1", "55555", "1010101010")
@e_ints = EnumerableSpecs::EachDefiner.new( 333, 22, 666666, 55555, 1010101010)
end
it "returns the maximum element" do
EnumerableSpecs::Numerous.new.max.should == 6
end
it "returns the maximum element (basics cases)" do
EnumerableSpecs::EachDefiner.new(55).max.should == 55
EnumerableSpecs::EachDefiner.new(11,99).max.should == 99
EnumerableSpecs::EachDefiner.new(99,11).max.should == 99
EnumerableSpecs::EachDefiner.new(2, 33, 4, 11).max.should == 33
EnumerableSpecs::EachDefiner.new(1,2,3,4,5).max.should == 5
EnumerableSpecs::EachDefiner.new(5,4,3,2,1).max.should == 5
EnumerableSpecs::EachDefiner.new(1,4,3,5,2).max.should == 5
EnumerableSpecs::EachDefiner.new(5,5,5,5,5).max.should == 5
EnumerableSpecs::EachDefiner.new("aa","tt").max.should == "tt"
EnumerableSpecs::EachDefiner.new("tt","aa").max.should == "tt"
EnumerableSpecs::EachDefiner.new("2","33","4","11").max.should == "4"
@e_strs.max.should == "666666"
@e_ints.max.should == 1010101010
end
it "returns nil for an empty Enumerable" do
EnumerableSpecs::EachDefiner.new.max.should == nil
end
it "raises a NoMethodError for elements without #<=>" do
lambda do
EnumerableSpecs::EachDefiner.new(BasicObject.new, BasicObject.new).max
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
lambda do
EnumerableSpecs::EachDefiner.new(11,"22").max
end.should raise_error(ArgumentError)
lambda do
EnumerableSpecs::EachDefiner.new(11,12,22,33).max{|a, b| nil}
end.should raise_error(ArgumentError)
end
context "when passed a block" do
it "returns the maximum element" do
EnumerableSpecs::EachDefiner.new("2","33","4","11").max {|a,b| a <=> b }.should == "4"
EnumerableSpecs::EachDefiner.new( 2 , 33 , 4 , 11 ).max {|a,b| a <=> b }.should == 33
EnumerableSpecs::EachDefiner.new("2","33","4","11").max {|a,b| b <=> a }.should == "11"
EnumerableSpecs::EachDefiner.new( 2 , 33 , 4 , 11 ).max {|a,b| b <=> a }.should == 2
@e_strs.max {|a,b| a.length <=> b.length }.should == "1010101010"
@e_strs.max {|a,b| a <=> b }.should == "666666"
@e_strs.max {|a,b| a.to_i <=> b.to_i }.should == "1010101010"
@e_ints.max {|a,b| a <=> b }.should == 1010101010
@e_ints.max {|a,b| a.to_s <=> b.to_s }.should == 666666
end
end
it "returns the maximum for enumerables that contain nils" do
arr = EnumerableSpecs::Numerous.new(nil, nil, true)
arr.max { |a, b|
x = a.nil? ? 1 : a ? 0 : -1
y = b.nil? ? 1 : b ? 0 : -1
x <=> y
}.should == nil
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.max.should == [6, 7, 8, 9]
end
context "when called with an argument n" do
context "without a block" do
it "returns an array containing the maximum n elements" do
result = @e_ints.max(2)
result.should == [1010101010, 666666]
end
end
context "with a block" do
it "returns an array containing the maximum n elements" do
result = @e_ints.max(2) { |a, b| a * 2 <=> b * 2 }
result.should == [1010101010, 666666]
end
end
context "on a enumerable of length x where x < n" do
it "returns an array containing the maximum n elements of length x" do
result = @e_ints.max(500)
result.length.should == 5
end
end
context "that is negative" do
it "raises an ArgumentError" do
lambda { @e_ints.max(-1) }.should raise_error(ArgumentError)
end
end
end
context "that is nil" do
it "returns the maximum element" do
@e_ints.max(nil).should == 1010101010
end
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/include', __FILE__)
describe "Enumerable#member?" do
it_behaves_like(:enumerable_include, :member?)
end

View file

@ -0,0 +1,81 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#min_by" do
it "returns an enumerator if no block" do
EnumerableSpecs::Numerous.new(42).min_by.should be_an_instance_of(Enumerator)
end
it "returns nil if #each yields no objects" do
EnumerableSpecs::Empty.new.min_by {|o| o.nonesuch }.should == nil
end
it "returns the object for whom the value returned by block is the smallest" do
EnumerableSpecs::Numerous.new(*%w[3 2 1]).min_by {|obj| obj.to_i }.should == '1'
EnumerableSpecs::Numerous.new(*%w[five three]).min_by {|obj| obj.length }.should == 'five'
end
it "returns the object that appears first in #each in case of a tie" do
a, b, c = '2', '1', '1'
EnumerableSpecs::Numerous.new(a, b, c).min_by {|obj| obj.to_i }.should equal(b)
end
it "uses min.<=>(current) to determine order" do
a, b, c = (1..3).map{|n| EnumerableSpecs::ReverseComparable.new(n)}
# Just using self here to avoid additional complexity
EnumerableSpecs::Numerous.new(a, b, c).min_by {|obj| obj }.should == c
end
it "is able to return the minimum for enums that contain nils" do
enum = EnumerableSpecs::Numerous.new(nil, nil, true)
enum.min_by {|o| o.nil? ? 0 : 1 }.should == nil
enum.min_by {|o| o.nil? ? 1 : 0 }.should == true
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.min_by {|e| e.size}.should == [1, 2]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :min_by
context "when called with an argument n" do
before :each do
@enum = EnumerableSpecs::Numerous.new(101, 55, 1, 20, 33, 500, 60)
end
context "without a block" do
it "returns an enumerator" do
@enum.min_by(2).should be_an_instance_of(Enumerator)
end
end
context "with a block" do
it "returns an array containing the minimum n elements based on the block's value" do
result = @enum.min_by(3) { |i| i.to_s }
result.should == [1, 101, 20]
end
context "on a enumerable of length x where x < n" do
it "returns an array containing the minimum n elements of length n" do
result = @enum.min_by(500) { |i| i.to_s }
result.length.should == 7
end
end
context "when n is negative" do
it "raises an ArgumentError" do
lambda { @enum.min_by(-1) { |i| i.to_s } }.should raise_error(ArgumentError)
end
end
end
context "when n is nil" do
it "returns the minimum element" do
@enum.min_by(nil) { |i| i.to_s }.should == 1
end
end
end
end

View file

@ -0,0 +1,123 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#min" do
before :each do
@e_strs = EnumerableSpecs::EachDefiner.new("333", "22", "666666", "1", "55555", "1010101010")
@e_ints = EnumerableSpecs::EachDefiner.new( 333, 22, 666666, 55555, 1010101010)
end
it "min should return the minimum element" do
EnumerableSpecs::Numerous.new.min.should == 1
end
it "returns the minimum (basic cases)" do
EnumerableSpecs::EachDefiner.new(55).min.should == 55
EnumerableSpecs::EachDefiner.new(11,99).min.should == 11
EnumerableSpecs::EachDefiner.new(99,11).min.should == 11
EnumerableSpecs::EachDefiner.new(2, 33, 4, 11).min.should == 2
EnumerableSpecs::EachDefiner.new(1,2,3,4,5).min.should == 1
EnumerableSpecs::EachDefiner.new(5,4,3,2,1).min.should == 1
EnumerableSpecs::EachDefiner.new(4,1,3,5,2).min.should == 1
EnumerableSpecs::EachDefiner.new(5,5,5,5,5).min.should == 5
EnumerableSpecs::EachDefiner.new("aa","tt").min.should == "aa"
EnumerableSpecs::EachDefiner.new("tt","aa").min.should == "aa"
EnumerableSpecs::EachDefiner.new("2","33","4","11").min.should == "11"
@e_strs.min.should == "1"
@e_ints.min.should == 22
end
it "returns nil for an empty Enumerable" do
EnumerableSpecs::EachDefiner.new.min.should be_nil
end
it "raises a NoMethodError for elements without #<=>" do
lambda do
EnumerableSpecs::EachDefiner.new(BasicObject.new, BasicObject.new).min
end.should raise_error(NoMethodError)
end
it "raises an ArgumentError for incomparable elements" do
lambda do
EnumerableSpecs::EachDefiner.new(11,"22").min
end.should raise_error(ArgumentError)
lambda do
EnumerableSpecs::EachDefiner.new(11,12,22,33).min{|a, b| nil}
end.should raise_error(ArgumentError)
end
it "returns the minimum when using a block rule" do
EnumerableSpecs::EachDefiner.new("2","33","4","11").min {|a,b| a <=> b }.should == "11"
EnumerableSpecs::EachDefiner.new( 2 , 33 , 4 , 11 ).min {|a,b| a <=> b }.should == 2
EnumerableSpecs::EachDefiner.new("2","33","4","11").min {|a,b| b <=> a }.should == "4"
EnumerableSpecs::EachDefiner.new( 2 , 33 , 4 , 11 ).min {|a,b| b <=> a }.should == 33
EnumerableSpecs::EachDefiner.new( 1, 2, 3, 4 ).min {|a,b| 15 }.should == 1
EnumerableSpecs::EachDefiner.new(11,12,22,33).min{|a, b| 2 }.should == 11
@i = -2
EnumerableSpecs::EachDefiner.new(11,12,22,33).min{|a, b| @i += 1 }.should == 12
@e_strs.min {|a,b| a.length <=> b.length }.should == "1"
@e_strs.min {|a,b| a <=> b }.should == "1"
@e_strs.min {|a,b| a.to_i <=> b.to_i }.should == "1"
@e_ints.min {|a,b| a <=> b }.should == 22
@e_ints.min {|a,b| a.to_s <=> b.to_s }.should == 1010101010
end
it "returns the minimum for enumerables that contain nils" do
arr = EnumerableSpecs::Numerous.new(nil, nil, true)
arr.min { |a, b|
x = a.nil? ? -1 : a ? 0 : 1
y = b.nil? ? -1 : b ? 0 : 1
x <=> y
}.should == nil
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.min.should == [1, 2]
end
context "when called with an argument n" do
context "without a block" do
it "returns an array containing the minimum n elements" do
result = @e_ints.min(2)
result.should == [22, 333]
end
end
context "with a block" do
it "returns an array containing the minimum n elements" do
result = @e_ints.min(2) { |a, b| a * 2 <=> b * 2 }
result.should == [22, 333]
end
end
context "on a enumerable of length x where x < n" do
it "returns an array containing the minimum n elements of length x" do
result = @e_ints.min(500)
result.length.should == 5
end
end
context "that is negative" do
it "raises an ArgumentError" do
lambda { @e_ints.min(-1) }.should raise_error(ArgumentError)
end
end
end
context "that is nil" do
it "returns the minimum element" do
@e_ints.min(nil).should == 22
end
end
end

View file

@ -0,0 +1,44 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#minmax_by" do
it "returns an enumerator if no block" do
EnumerableSpecs::Numerous.new(42).minmax_by.should be_an_instance_of(Enumerator)
end
it "returns nil if #each yields no objects" do
EnumerableSpecs::Empty.new.minmax_by {|o| o.nonesuch }.should == [nil, nil]
end
it "returns the object for whom the value returned by block is the largest" do
EnumerableSpecs::Numerous.new(*%w[1 2 3]).minmax_by {|obj| obj.to_i }.should == ['1', '3']
EnumerableSpecs::Numerous.new(*%w[three five]).minmax_by {|obj| obj.length }.should == ['five', 'three']
end
it "returns the object that appears first in #each in case of a tie" do
a, b, c, d = '1', '1', '2', '2'
mm = EnumerableSpecs::Numerous.new(a, b, c, d).minmax_by {|obj| obj.to_i }
mm[0].should equal(a)
mm[1].should equal(c)
end
it "uses min/max.<=>(current) to determine order" do
a, b, c = (1..3).map{|n| EnumerableSpecs::ReverseComparable.new(n)}
# Just using self here to avoid additional complexity
EnumerableSpecs::Numerous.new(a, b, c).minmax_by {|obj| obj }.should == [c, a]
end
it "is able to return the maximum for enums that contain nils" do
enum = EnumerableSpecs::Numerous.new(nil, nil, true)
enum.minmax_by {|o| o.nil? ? 0 : 1 }.should == [nil, true]
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.minmax_by {|e| e.size}.should == [[1, 2], [6, 7, 8, 9]]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :minmax_by
end

View file

@ -0,0 +1,44 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#minmax" do
before :each do
@enum = EnumerableSpecs::Numerous.new(6, 4, 5, 10, 8)
@strs = EnumerableSpecs::Numerous.new("333", "2", "60", "55555", "1010", "111")
end
it "min should return the minimum element" do
@enum.minmax.should == [4, 10]
@strs.minmax.should == ["1010", "60" ]
end
it "returns [nil, nil] for an empty Enumerable" do
EnumerableSpecs::Empty.new.minmax.should == [nil, nil]
end
it "raises an ArgumentError when elements are incomparable" do
lambda do
EnumerableSpecs::Numerous.new(11,"22").minmax
end.should raise_error(ArgumentError)
lambda do
EnumerableSpecs::Numerous.new(11,12,22,33).minmax{|a, b| nil}
end.should raise_error(ArgumentError)
end
it "raises a NoMethodError for elements without #<=>" do
lambda do
EnumerableSpecs::Numerous.new(BasicObject.new, BasicObject.new).minmax
end.should raise_error(NoMethodError)
end
it "returns the minimum when using a block rule" do
@enum.minmax {|a,b| b <=> a }.should == [10, 4]
@strs.minmax {|a,b| a.length <=> b.length }.should == ["2", "55555"]
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.minmax.should == [[1, 2], [6, 7, 8, 9]]
end
end

View file

@ -0,0 +1,57 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#none?" do
it "returns true if none of the elements in self are true" do
e = EnumerableSpecs::Numerous.new(false, nil, false)
e.none?.should be_true
end
it "returns false if at least one of the elements in self are true" do
e = EnumerableSpecs::Numerous.new(false, nil, true, false)
e.none?.should be_false
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.none?.should be_false
end
end
describe "Enumerable#none? with a block" do
before :each do
@e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
end
it "passes each element to the block in turn until it returns true" do
acc = []
@e.none? {|e| acc << e; false }
acc.should == [1,1,2,3,4]
end
it "stops passing elements to the block when it returns true" do
acc = []
@e.none? {|e| acc << e; e == 3 ? true : false }
acc.should == [1,1,2,3]
end
it "returns true if the block never returns true" do
@e.none? {|e| false }.should be_true
end
it "returns false if the block ever returns true" do
@e.none? {|e| e == 3 ? true : false }.should be_false
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.none? {|e| e == [1, 2] }.should be_true
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
multi.none? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2]]
end
end

View file

@ -0,0 +1,49 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#one?" do
describe "when passed a block" do
it "returns true if block returns true once" do
[:a, :b, :c].one? { |s| s == :a }.should be_true
end
it "returns false if the block returns true more than once" do
[:a, :b, :c].one? { |s| s == :a || s == :b }.should be_false
end
it "returns false if the block only returns false" do
[:a, :b, :c].one? { |s| s == :d }.should be_false
end
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.one? {|e| e == 1 }.should be_true
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
multi.one? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4]]
end
end
describe "when not passed a block" do
it "returns true if only one element evaluates to true" do
[false, nil, true].one?.should be_true
end
it "returns false if two elements evaluate to true" do
[false, :value, nil, true].one?.should be_false
end
it "returns false if all elements evaluate to false" do
[false, nil, false].one?.should be_false
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMultiWithSingleTrue.new
multi.one?.should be_false
end
end
end

View file

@ -0,0 +1,20 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#partition" do
it "returns two arrays, the first containing elements for which the block is true, the second containing the rest" do
EnumerableSpecs::Numerous.new.partition { |i| i % 2 == 0 }.should == [[2, 6, 4], [5, 3, 1]]
end
it "returns an Enumerator if called without a block" do
EnumerableSpecs::Numerous.new.partition.should be_an_instance_of(Enumerator)
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.partition {|e| e == [3, 4, 5] }.should == [[[3, 4, 5]], [[1, 2], [6, 7, 8, 9]]]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :partition
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/inject', __FILE__)
describe "Enumerable#reduce" do
it_behaves_like :enumerable_inject, :reduce
end

View file

@ -0,0 +1,25 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#reject" do
it "returns an array of the elements for which block is false" do
EnumerableSpecs::Numerous.new.reject { |i| i > 3 }.should == [2, 3, 1]
entries = (1..10).to_a
numerous = EnumerableSpecs::Numerous.new(*entries)
numerous.reject {|i| i % 2 == 0 }.should == [1,3,5,7,9]
numerous.reject {|i| true }.should == []
numerous.reject {|i| false }.should == entries
end
it "returns an Enumerator if called without a block" do
EnumerableSpecs::Numerous.new.reject.should be_an_instance_of(Enumerator)
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.reject {|e| e == [3, 4, 5] }.should == [[1, 2], [6, 7, 8, 9]]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :reject
end

View file

@ -0,0 +1,26 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#reverse_each" do
it "traverses enum in reverse order and pass each element to block" do
a=[]
EnumerableSpecs::Numerous.new.reverse_each { |i| a << i }
a.should == [4, 1, 6, 3, 5, 2]
end
it "returns an Enumerator if no block given" do
enum = EnumerableSpecs::Numerous.new.reverse_each
enum.should be_an_instance_of(Enumerator)
enum.to_a.should == [4, 1, 6, 3, 5, 2]
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
multi.reverse_each {|e| yielded << e }
yielded.should == [[6, 7, 8, 9], [3, 4, 5], [1, 2]]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :reverse_each
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/find_all', __FILE__)
describe "Enumerable#select" do
it_behaves_like(:enumerable_find_all , :select)
end

View file

@ -0,0 +1,32 @@
require File.expand_path('../enumerable_enumeratorized', __FILE__)
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 "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_should_behave_like :enumerable_enumeratorized_with_origin_size
end

View file

@ -0,0 +1,54 @@
require File.expand_path('../enumerable_enumeratorized', __FILE__)
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")
lambda { [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

View file

@ -0,0 +1,24 @@
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
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

View file

@ -0,0 +1,33 @@
require File.expand_path('../enumeratorized', __FILE__)
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

View file

@ -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

View file

@ -0,0 +1,73 @@
require File.expand_path('../enumerable_enumeratorized', __FILE__)
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 = lambda { "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" }
@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" }
@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" }
@empty.send(@method, fail_proc) {|e| true}.should == "yay"
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 = lambda { 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

View file

@ -0,0 +1,31 @@
require File.expand_path('../enumerable_enumeratorized', __FILE__)
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

View file

@ -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

View file

@ -0,0 +1,69 @@
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
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
end
it "can take a symbol argument" do
EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, :-).should == 4
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
end

View file

@ -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
lambda { @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
lambda { @enum.send(@method, nil) }.should raise_error(TypeError)
lambda { @enum.send(@method, "a") }.should raise_error(TypeError)
obj = mock("nonnumeric")
lambda { @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

View file

@ -0,0 +1,61 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#slice_after" do
before :each do
@enum = EnumerableSpecs::Numerous.new(7, 6, 5, 4, 3, 2, 1)
end
describe "when given an argument and no block" do
it "calls === on the argument to determine when to yield" do
arg = mock("filter")
arg.should_receive(:===).and_return(false, true, false, false, false, true, false)
e = @enum.slice_after(arg)
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[7, 6], [5, 4, 3, 2], [1]]
end
it "doesn't yield an empty array if the filter matches the first entry or the last entry" do
arg = mock("filter")
arg.should_receive(:===).and_return(true).exactly(7)
e = @enum.slice_after(arg)
e.to_a.should == [[7], [6], [5], [4], [3], [2], [1]]
end
it "uses standard boolean as a test" do
arg = mock("filter")
arg.should_receive(:===).and_return(false, :foo, nil, false, false, 42, false)
e = @enum.slice_after(arg)
e.to_a.should == [[7, 6], [5, 4, 3, 2], [1]]
end
end
describe "when given a block" do
describe "and no argument" do
it "calls the block to determine when to yield" do
e = @enum.slice_after{ |i| i == 6 || i == 2 }
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[7, 6], [5, 4, 3, 2], [1]]
end
end
describe "and an argument" do
it "raises an ArgumentError" do
lambda { @enum.slice_after(42) { |i| i == 6 } }.should raise_error(ArgumentError)
end
end
end
it "raises an ArgumentError when given an incorrect number of arguments" do
lambda { @enum.slice_after("one", "two") }.should raise_error(ArgumentError)
lambda { @enum.slice_after }.should raise_error(ArgumentError)
end
end
describe "when an iterator method yields more than one value" do
it "processes all yielded values" do
enum = EnumerableSpecs::YieldsMulti.new
result = enum.slice_after { |i| i == [3, 4, 5] }.to_a
result.should == [[[1, 2], [3, 4, 5]], [[6, 7, 8, 9]]]
end
end

View file

@ -0,0 +1,87 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#slice_before" do
before :each do
@enum = EnumerableSpecs::Numerous.new(7,6,5,4,3,2,1)
end
describe "when given an argument and no block" do
it "calls === on the argument to determine when to yield" do
arg = mock "filter"
arg.should_receive(:===).and_return(false, true, false, false, false, true, false)
e = @enum.slice_before(arg)
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
end
it "doesn't yield an empty array if the filter matches the first entry or the last entry" do
arg = mock "filter"
arg.should_receive(:===).and_return(true).exactly(7)
e = @enum.slice_before(arg)
e.to_a.should == [[7], [6], [5], [4], [3], [2], [1]]
end
it "uses standard boolean as a test" do
arg = mock "filter"
arg.should_receive(:===).and_return(false, :foo, nil, false, false, 42, false)
e = @enum.slice_before(arg)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
end
end
describe "when given a block" do
describe "and no argument" do
it "calls the block to determine when to yield" do
e = @enum.slice_before{|i| i == 6 || i == 2}
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
end
end
ruby_version_is ""..."2.3" do
describe "and an argument" do
it "calls the block with a copy of that argument" do
arg = [:foo]
first = nil
e = @enum.slice_before(arg) do |i, init|
init.should == arg
init.should_not equal(arg)
first = init
i == 6 || i == 2
end
e.should be_an_instance_of(Enumerator)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
e = @enum.slice_before(arg) do |i, init|
init.should_not equal(first)
end
e.to_a
end
end
end
ruby_version_is "2.3" do
it "does not accept arguments" do
lambda {
@enum.slice_before(1) {}
}.should raise_error(ArgumentError)
end
end
end
it "raises an ArgumentError when given an incorrect number of arguments" do
lambda { @enum.slice_before("one", "two") }.should raise_error(ArgumentError)
lambda { @enum.slice_before }.should raise_error(ArgumentError)
end
describe "when an iterator method yields more than one value" do
it "processes all yielded values" do
enum = EnumerableSpecs::YieldsMulti.new
result = enum.slice_before { |i| i == [3, 4, 5] }.to_a
result.should == [[[1, 2]], [[3, 4, 5], [6, 7, 8, 9]]]
end
end
it_behaves_like :enumerable_enumeratorized_with_unknown_size, [:slice_before, 3]
end

View file

@ -0,0 +1,54 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#slice_when" do
before :each do
ary = [10, 9, 7, 6, 4, 3, 2, 1]
@enum = EnumerableSpecs::Numerous.new(*ary)
@result = @enum.slice_when { |i, j| i - 1 != j }
@enum_length = ary.length
end
context "when given a block" do
it "returns an enumerator" do
@result.should be_an_instance_of(Enumerator)
end
it "splits chunks between adjacent elements i and j where the block returns true" do
@result.to_a.should == [[10, 9], [7, 6], [4, 3, 2, 1]]
end
it "calls the block for length of the receiver enumerable minus one times" do
times_called = 0
@enum.slice_when do |i, j|
times_called += 1
i - 1 != j
end.to_a
times_called.should == (@enum_length - 1)
end
it "doesn't yield an empty array if the block matches the first or the last time" do
@enum.slice_when { true }.to_a.should == [[10], [9], [7], [6], [4], [3], [2], [1]]
end
it "doesn't yield an empty array on a small enumerable" do
EnumerableSpecs::Empty.new.slice_when { raise }.to_a.should == []
EnumerableSpecs::Numerous.new(42).slice_when { raise }.to_a.should == [[42]]
end
end
context "when not given a block" do
it "raises an ArgumentError" do
lambda { @enum.slice_when }.should raise_error(ArgumentError)
end
end
describe "when an iterator method yields more than one value" do
it "processes all yielded values" do
def foo
yield 1, 2
end
to_enum(:foo).slice_when { true }.to_a.should == [[[1, 2]]]
end
end
end

View file

@ -0,0 +1,36 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#sort_by" do
it "returns an array of elements ordered by the result of block" do
a = EnumerableSpecs::Numerous.new("once", "upon", "a", "time")
a.sort_by { |i| i[0] }.should == ["a", "once", "time", "upon"]
end
it "sorts the object by the given attribute" do
a = EnumerableSpecs::SortByDummy.new("fooo")
b = EnumerableSpecs::SortByDummy.new("bar")
ar = [a, b].sort_by { |d| d.s }
ar.should == [b, a]
end
it "returns an Enumerator when a block is not supplied" do
a = EnumerableSpecs::Numerous.new("a","b")
a.sort_by.should be_an_instance_of(Enumerator)
a.to_a.should == ["a", "b"]
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.sort_by {|e| e.size}.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
it "returns an array of elements when a block is supplied and #map returns an enumerable" do
b = EnumerableSpecs::MapReturnsEnumerable.new
b.sort_by{ |x| -x }.should == [3, 2, 1]
end
it_behaves_like :enumerable_enumeratorized_with_origin_size, :sort_by
end

View file

@ -0,0 +1,54 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#sort" do
it "sorts by the natural order as defined by <=>" do
EnumerableSpecs::Numerous.new.sort.should == [1, 2, 3, 4, 5, 6]
sorted = EnumerableSpecs::ComparesByVowelCount.wrap("a" * 1, "a" * 2, "a"*3, "a"*4, "a"*5)
EnumerableSpecs::Numerous.new(sorted[2],sorted[0],sorted[1],sorted[3],sorted[4]).sort.should == sorted
end
it "yields elements to the provided block" do
EnumerableSpecs::Numerous.new.sort { |a, b| b <=> a }.should == [6, 5, 4, 3, 2, 1]
EnumerableSpecs::Numerous.new(2,0,1,3,4).sort { |n, m| -(n <=> m) }.should == [4,3,2,1,0]
end
it "raises a NoMethodError if elements do not define <=>" do
lambda do
EnumerableSpecs::Numerous.new(BasicObject.new, BasicObject.new, BasicObject.new).sort
end.should raise_error(NoMethodError)
end
it "sorts enumerables that contain nils" do
arr = EnumerableSpecs::Numerous.new(nil, true, nil, false, nil, true, nil, false, nil)
arr.sort { |a, b|
x = a ? -1 : a.nil? ? 0 : 1
y = b ? -1 : b.nil? ? 0 : 1
x <=> y
}.should == [true, true, nil, nil, nil, nil, nil, false, false]
end
it "compare values returned by block with 0" do
EnumerableSpecs::Numerous.new.sort { |n, m| -(n+m) * (n <=> m) }.should == [6, 5, 4, 3, 2, 1]
EnumerableSpecs::Numerous.new.sort { |n, m|
EnumerableSpecs::ComparableWithFixnum.new(-(n+m) * (n <=> m))
}.should == [6, 5, 4, 3, 2, 1]
lambda {
EnumerableSpecs::Numerous.new.sort { |n, m| (n <=> m).to_s }
}.should raise_error(ArgumentError)
end
it "raises an error if objects can't be compared" do
a=EnumerableSpecs::Numerous.new(EnumerableSpecs::Uncomparable.new, EnumerableSpecs::Uncomparable.new)
lambda {a.sort}.should raise_error(ArgumentError)
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.sort {|a, b| a.first <=> b.first}.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
it "doesn't raise an error if #to_a returns a frozen Array" do
EnumerableSpecs::Freezy.new.sort.should == [1,2]
end
end

View file

@ -0,0 +1,30 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
ruby_version_is '2.4' do
describe 'Enumerable#sum' do
before :each do
@enum = Object.new.to_enum
class << @enum
def each
yield 0
yield(-1)
yield 2
yield 2/3r
end
end
end
it 'returns amount of the elements with taking an argument as the initial value' do
@enum.sum(10).should == 35/3r
end
it 'gives 0 as a default argument' do
@enum.sum.should == 5/3r
end
it 'takes a block to transform the elements' do
@enum.sum { |element| element * 2 }.should == 10/3r
end
end
end

View file

@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/take', __FILE__)
describe "Enumerable#take" do
it "requires an argument" do
lambda{ EnumerableSpecs::Numerous.new.take}.should raise_error(ArgumentError)
end
describe "when passed an argument" do
it_behaves_like :enumerable_take, :take
end
end

View file

@ -0,0 +1,51 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/enumerable_enumeratorized', __FILE__)
describe "Enumerable#take_while" do
before :each do
@enum = EnumerableSpecs::Numerous.new(3, 2, 1, :go)
end
it "returns an Enumerator if no block given" do
@enum.take_while.should be_an_instance_of(Enumerator)
end
it "returns no/all elements for {true/false} block" do
@enum.take_while{true}.should == @enum.to_a
@enum.take_while{false}.should == []
end
it "accepts returns other than true/false" do
@enum.take_while{1}.should == @enum.to_a
@enum.take_while{nil}.should == []
end
it "passes elements to the block until the first false" do
a = []
@enum.take_while{|obj| (a << obj).size < 3}.should == [3, 2]
a.should == [3, 2, 1]
end
it "will only go through what's needed" do
enum = EnumerableSpecs::EachCounter.new(4, 3, 2, 1, :stop)
enum.take_while { |x|
break 42 if x == 3
true
}.should == 42
enum.times_yielded.should == 2
end
it "doesn't return self when it could" do
a = [1,2,3]
a.take_while{true}.should_not equal(a)
end
it "calls the block with initial args when yielded with multiple arguments" do
yields = []
EnumerableSpecs::YieldsMixed.new.take_while{ |v| yields << v }
yields.should == [1, [2], 3, 5, [8, 9], nil, []]
end
it_behaves_like :enumerable_enumeratorized_with_unknown_size, :take_while
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/entries', __FILE__)
describe "Enumerable#to_a" do
it_behaves_like(:enumerable_entries , :to_a)
end

View file

@ -0,0 +1,46 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#to_h" do
it "converts empty enumerable to empty hash" do
enum = EnumerableSpecs::EachDefiner.new
enum.to_h.should == {}
end
it "converts yielded [key, value] pairs to a hash" do
enum = EnumerableSpecs::EachDefiner.new([:a, 1], [:b, 2])
enum.to_h.should == { a: 1, b: 2 }
end
it "uses the last value of a duplicated key" do
enum = EnumerableSpecs::EachDefiner.new([:a, 1], [:b, 2], [:a, 3])
enum.to_h.should == { a: 3, b: 2 }
end
it "calls #to_ary on contents" do
pair = mock('to_ary')
pair.should_receive(:to_ary).and_return([:b, 2])
enum = EnumerableSpecs::EachDefiner.new([:a, 1], pair)
enum.to_h.should == { a: 1, b: 2 }
end
it "forwards arguments to #each" do
enum = Object.new
def enum.each(*args)
yield(*args)
yield([:b, 2])
end
enum.extend Enumerable
enum.to_h(:a, 1).should == { a: 1, b: 2 }
end
it "raises TypeError if an element is not an array" do
enum = EnumerableSpecs::EachDefiner.new(:x)
lambda { enum.to_h }.should raise_error(TypeError)
end
it "raises ArgumentError if an element is not a [key, value] pair" do
enum = EnumerableSpecs::EachDefiner.new([:x])
lambda { enum.to_h }.should raise_error(ArgumentError)
end
end

View file

@ -0,0 +1,29 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
ruby_version_is '2.4' do
describe 'Enumerable#uniq' do
it 'returns an array that contains only unique elements' do
[0, 1, 2, 3].to_enum.uniq { |n| n.even? }.should == [0, 1]
end
context 'when yielded with multiple arguments' do
before :each do
@enum = Object.new.to_enum
class << @enum
def each
yield 0, 'foo'
yield 1, 'FOO'
yield 2, 'bar'
end
end
end
ruby_bug '#13669', ''...'2.5' do
it 'returns all yield arguments as an array' do
@enum.uniq { |_, label| label.downcase }.should == [[0, 'foo'], [2, 'bar']]
end
end
end
end
end

View file

@ -0,0 +1,42 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
describe "Enumerable#zip" do
it "combines each element of the receiver with the element of the same index in arrays given as arguments" do
EnumerableSpecs::Numerous.new(1,2,3).zip([4,5,6],[7,8,9]).should == [[1,4,7],[2,5,8],[3,6,9]]
EnumerableSpecs::Numerous.new(1,2,3).zip.should == [[1],[2],[3]]
end
it "passes each element of the result array to a block and return nil if a block is given" do
expected = [[1,4,7],[2,5,8],[3,6,9]]
EnumerableSpecs::Numerous.new(1,2,3).zip([4,5,6],[7,8,9]) do |result_component|
result_component.should == expected.shift
end.should == nil
expected.size.should == 0
end
it "fills resulting array with nils if an argument array is too short" do
EnumerableSpecs::Numerous.new(1,2,3).zip([4,5,6], [7,8]).should == [[1,4,7],[2,5,8],[3,6,nil]]
end
it "converts arguments to arrays using #to_ary" do
convertable = EnumerableSpecs::ArrayConvertable.new(4,5,6)
EnumerableSpecs::Numerous.new(1,2,3).zip(convertable).should == [[1,4],[2,5],[3,6]]
convertable.called.should == :to_ary
end
it "converts arguments to enums using #to_enum" do
convertable = EnumerableSpecs::EnumConvertable.new(4..6)
EnumerableSpecs::Numerous.new(1,2,3).zip(convertable).should == [[1,4],[2,5],[3,6]]
convertable.called.should == :to_enum
convertable.sym.should == :each
end
it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.zip(multi).should == [[[1, 2], [1, 2]], [[3, 4, 5], [3, 4, 5]], [[6, 7, 8, 9], [6, 7, 8, 9]]]
end
end