Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/enumerable/collect_concat_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/collect_concat'

describe "Enumerable#collect_concat" do
it_behaves_like :enumerable_collect_concat, :collect_concat
it "is an alias of Enumerable#flat_map" do
Enumerable.instance_method(:collect_concat).should == Enumerable.instance_method(:flat_map)
end
end
6 changes: 3 additions & 3 deletions core/enumerable/collect_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/collect'

describe "Enumerable#collect" do
it_behaves_like :enumerable_collect, :collect
it "is an alias of Enumerable#map" do
Enumerable.instance_method(:collect).should == Enumerable.instance_method(:map)
end
end
6 changes: 3 additions & 3 deletions core/enumerable/detect_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/find'

describe "Enumerable#detect" do
it_behaves_like :enumerable_find, :detect
it "is an alias of Enumerable#find" do
Enumerable.instance_method(:detect).should == Enumerable.instance_method(:find)
end
end
6 changes: 3 additions & 3 deletions core/enumerable/entries_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/entries'

describe "Enumerable#entries" do
it_behaves_like :enumerable_entries, :entries
it "is an alias of Enumerable#to_a" do
Enumerable.instance_method(:entries).should == Enumerable.instance_method(:to_a)
end
end
6 changes: 3 additions & 3 deletions core/enumerable/filter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/find_all'

describe "Enumerable#filter" do
it_behaves_like :enumerable_find_all, :filter
it "is an alias of Enumerable#select" do
Enumerable.instance_method(:filter).should == Enumerable.instance_method(:select)
end
end
6 changes: 3 additions & 3 deletions core/enumerable/find_all_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/find_all'

describe "Enumerable#find_all" do
it_behaves_like :enumerable_find_all, :find_all
it "is an alias of Enumerable#select" do
Enumerable.instance_method(:find_all).should == Enumerable.instance_method(:select)
end
end
75 changes: 73 additions & 2 deletions core/enumerable/find_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,78 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/find'
require_relative 'shared/enumerable_enumeratorized'

describe "Enumerable#find" do
it_behaves_like :enumerable_find, :find
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.find 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.find {|e| false }.should == nil
end

it "returns the first element for which the block is not false" do
@elements.each do |element|
@numerous.find {|e| e > element - 1 }.should == element
end
end

it "returns the value of the ifnone proc if the block is false" do
fail_proc = -> { "cheeseburgers" }
@numerous.find(fail_proc) {|e| false }.should == "cheeseburgers"
end

it "doesn't call the ifnone proc if an element is found" do
fail_proc = -> { raise "This shouldn't have been called" }
@numerous.find(fail_proc) {|e| e == @elements.first }.should == 2
end

it "calls the ifnone proc only once when the block is false" do
times = 0
fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" }
@numerous.find(fail_proc) {|e| false }.should == "cheeseburgers"
end

it "calls the ifnone proc when there are no elements" do
fail_proc = -> { "yay" }
@empty.find(fail_proc) {|e| true}.should == "yay"
end

it "ignores the ifnone argument when nil" do
@numerous.find(nil) {|e| false }.should == nil
end

it "passes through the values yielded by #each_with_index" do
[:a, :b].each_with_index.find { |x, i| ScratchPad << [x, i]; nil }
ScratchPad.recorded.should == [[:a, 0], [:b, 1]]
end

it "returns an enumerator when no block given" do
@numerous.find.should.instance_of?(Enumerator)
end

it "passes the ifnone proc to the enumerator" do
times = 0
fail_proc = -> { times += 1; raise if times > 1; "cheeseburgers" }
@numerous.find(fail_proc).each {|e| false }.should == "cheeseburgers"
end
Comment thread
Earlopain marked this conversation as resolved.

it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.find {|e| e == [1, 2] }.should == [1, 2]
end

it_behaves_like :enumerable_enumeratorized_with_unknown_size, :find
end
53 changes: 51 additions & 2 deletions core/enumerable/flat_map_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,56 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/collect_concat'
require_relative 'shared/enumerable_enumeratorized'

describe "Enumerable#flat_map" do
it_behaves_like :enumerable_collect_concat, :flat_map
it "yields elements to the block and flattens one level" do
numerous = EnumerableSpecs::Numerous.new(1, [2, 3], [4, [5, 6]], {foo: :bar})
numerous.flat_map { |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.flat_map { |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.flat_map { |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.flat_map { |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.flat_map { |i| i }.should == [1, obj, 2]
end

it "raises a TypeError if an element defining #to_ary does not return an Array or nil" do
obj = mock("to_ary defined")
obj.should_receive(:to_ary).and_return("array")

-> { [1, obj, 3].flat_map { |i| i } }.should.raise(TypeError)
end

it "returns an enumerator when no block given" do
enum = EnumerableSpecs::Numerous.new(1, 2).flat_map
enum.should.instance_of?(Enumerator)
enum.each{ |i| [i] * i }.should == [1, 2, 2]
end

it_behaves_like :enumerable_enumeratorized_with_origin_size, :flat_map
end
33 changes: 31 additions & 2 deletions core/enumerable/include_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/include'

describe "Enumerable#include?" do
it_behaves_like :enumerable_include, :include?
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).include?(5).should == true
EnumerableSpecs::Numerous.new(*elements).include?(10).should == false
EnumerableSpecs::Numerous.new(*elements).include?(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).include?('5').should == true
EnumerableSpecs::Numerous.new(*elements).include?('10').should == false
EnumerableSpecs::Numerous.new(*elements).include?(EnumerableSpecIncludeP11.new).should == true
EnumerableSpecs::Numerous.new(*elements).include?('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).include?(2.0).should == true
EnumerableSpecs::Numerous.new(2,4,[6,8],10).include?([6, 8]).should == true
EnumerableSpecs::Numerous.new(2,4,[6,8],10).include?([6.0, 8.0]).should == true
end

it "gathers whole arrays as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
multi.include?([1,2]).should == true
end
end
141 changes: 139 additions & 2 deletions core/enumerable/inject_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,144 @@
require_relative '../../spec_helper'
require_relative '../array/shared/iterable_and_tolerating_size_increasing'
require_relative 'fixtures/classes'
require_relative 'shared/inject'

describe "Enumerable#inject" do
it_behaves_like :enumerable_inject, :inject
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.inject(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).inject(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].inject(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).inject(10, :-).should == 4
EnumerableSpecs::Numerous.new(1, 2, 3).inject(10, "-").should == 4

[1, 2, 3].inject(10, :-).should == 4
[1, 2, 3].inject(10, "-").should == 4
end

it "converts non-Symbol method name argument to String with #to_str if two arguments" do
name = Object.new
def name.to_str; "-"; end

EnumerableSpecs::Numerous.new(1, 2, 3).inject(10, name).should == 4
[1, 2, 3].inject(10, name).should == 4
end

it "raises TypeError when the second argument is not Symbol or String and it cannot be converted to String if two arguments" do
-> { EnumerableSpecs::Numerous.new(1, 2, 3).inject(10, Object.new) }.should.raise(TypeError, /is not a symbol nor a string/)
-> { [1, 2, 3].inject(10, Object.new) }.should.raise(TypeError, /is not a symbol nor a string/)
end

it "ignores the block if two arguments" do
-> {
EnumerableSpecs::Numerous.new(1, 2, 3).inject(10, :-) { raise "we never get here"}.should == 4
}.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)

-> {
[1, 2, 3].inject(10, :-) { raise "we never get here"}.should == 4
}.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true)
end

it "does not warn when given a Symbol with $VERBOSE true" do
-> {
[1, 2].inject(0, :+)
[1, 2].inject(:+)
EnumerableSpecs::Numerous.new(1, 2).inject(0, :+)
EnumerableSpecs::Numerous.new(1, 2).inject(:+)
}.should_not complain(verbose: true)
end

it "can take a symbol argument" do
EnumerableSpecs::Numerous.new(10, 1, 2, 3).inject(:-).should == 4
[10, 1, 2, 3].inject(:-).should == 4
end

it "can take a String argument" do
EnumerableSpecs::Numerous.new(10, 1, 2, 3).inject("-").should == 4
[10, 1, 2, 3].inject("-").should == 4
end

it "converts non-Symbol method name argument to String with #to_str" do
name = Object.new
def name.to_str; "-"; end

EnumerableSpecs::Numerous.new(10, 1, 2, 3).inject(name).should == 4
[10, 1, 2, 3].inject(name).should == 4
end

it "raises TypeError when passed not Symbol or String method name argument and it cannot be converted to String" do
-> { EnumerableSpecs::Numerous.new(10, 1, 2, 3).inject(Object.new) }.should.raise(TypeError, /is not a symbol nor a string/)
-> { [10, 1, 2, 3].inject(Object.new) }.should.raise(TypeError, /is not a symbol nor a string/)
end

it "without argument takes a block with an accumulator (with first element as initial value) and the current element. Value of block becomes new accumulator" do
a = []
EnumerableSpecs::Numerous.new.inject { |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.inject([]) {|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().inject(1) {|acc,x| 999 }.should == 1
EnumerableSpecs::EachDefiner.new(2).inject(1) {|acc,x| 999 }.should == 999
EnumerableSpecs::EachDefiner.new(2).inject(1) {|acc,x| acc }.should == 1
EnumerableSpecs::EachDefiner.new(2).inject(1) {|acc,x| x }.should == 2

EnumerableSpecs::EachDefiner.new(1,2,3,4).inject(100) {|acc,x| acc + x }.should == 110
EnumerableSpecs::EachDefiner.new(1,2,3,4).inject(100) {|acc,x| acc * x }.should == 2400

EnumerableSpecs::EachDefiner.new('a','b','c').inject("z") {|result, i| i+result}.should == "cbaz"
end

it "without inject arguments(legacy rubycon)" do
# no inject argument
EnumerableSpecs::EachDefiner.new(2).inject {|acc,x| 999 }.should == 2
EnumerableSpecs::EachDefiner.new(2).inject {|acc,x| acc }.should == 2
EnumerableSpecs::EachDefiner.new(2).inject {|acc,x| x }.should == 2

EnumerableSpecs::EachDefiner.new(1,2,3,4).inject {|acc,x| acc + x }.should == 10
EnumerableSpecs::EachDefiner.new(1,2,3,4).inject {|acc,x| acc * x }.should == 24

EnumerableSpecs::EachDefiner.new('a','b','c').inject {|result, i| i+result}.should == "cba"
EnumerableSpecs::EachDefiner.new(3, 4, 5).inject {|result, i| result*i}.should == 60
EnumerableSpecs::EachDefiner.new([1], 2, 'a','b').inject {|r,i| r<<i}.should == [1, 2, 'a', 'b']
end

it "returns nil when fails(legacy rubycon)" do
EnumerableSpecs::EachDefiner.new().inject {|acc,x| 999 }.should == nil
end

it "tolerates increasing a collection size during iterating Array" do
array = [:a, :b, :c]
ScratchPad.record []
i = 0

array.inject(nil) do |_, e|
ScratchPad << e
array << i if i < 100
i += 1
end

actual = ScratchPad.recorded
expected = [:a, :b, :c] + (0..99).to_a
actual.sort_by(&:to_s).should == expected.sort_by(&:to_s)
end

it "raises an ArgumentError when no parameters or block is given" do
-> { [1,2].inject }.should.raise(ArgumentError)
-> { {one: 1, two: 2}.inject }.should.raise(ArgumentError)
end
end
Loading
Loading