diff options
Diffstat (limited to 'spec/ruby/core/enumerator/each_spec.rb')
| -rw-r--r-- | spec/ruby/core/enumerator/each_spec.rb | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/spec/ruby/core/enumerator/each_spec.rb b/spec/ruby/core/enumerator/each_spec.rb new file mode 100644 index 0000000000..03be53fe05 --- /dev/null +++ b/spec/ruby/core/enumerator/each_spec.rb @@ -0,0 +1,104 @@ +require_relative '../../spec_helper' + +describe "Enumerator#each" do + before :each do + object_each_with_arguments = Object.new + def object_each_with_arguments.each_with_arguments(arg, *args) + yield arg, *args + :method_returned + end + + @enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2) + + @enum_with_yielder = Enumerator.new { |y| y.yield :ok } + end + + it "yields each element of self to the given block" do + acc = [] + [1, 2, 3].to_enum.each { |e| acc << e } + acc.should == [1, 2, 3] + end + + it "calls #each on the object given in the constructor by default" do + each = mock('each') + each.should_receive(:each) + each.to_enum.each { |e| e } + end + + it "calls #each on the underlying object until it's exhausted" do + each = mock('each') + each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3) + acc = [] + each.to_enum.each { |e| acc << e } + acc.should == [1, 2, 3] + end + + it "calls the method given in the constructor instead of #each" do + each = mock('peach') + each.should_receive(:peach) + each.to_enum(:peach).each { |e| e } + end + + it "calls the method given in the constructor until it's exhausted" do + each = mock('peach') + each.should_receive(:peach).and_yield(1).and_yield(2).and_yield(3) + acc = [] + each.to_enum(:peach).each { |e| acc << e } + acc.should == [1, 2, 3] + end + + it "raises a NoMethodError if the object doesn't respond to #each" do + enum = Object.new.to_enum + -> do + enum.each { |e| e } + end.should.raise(NoMethodError) + end + + it "returns self if not given arguments and not given a block" do + @enum_with_arguments.each.should.equal?(@enum_with_arguments) + + @enum_with_yielder.each.should.equal?(@enum_with_yielder) + end + + it "returns the same value from receiver.each if block is given" do + @enum_with_arguments.each {}.should.equal?(:method_returned) + end + + it "passes given arguments at initialized to receiver.each" do + @enum_with_arguments.each.to_a.should == [[:arg0, :arg1, :arg2]] + end + + it "requires multiple arguments" do + Enumerator.instance_method(:each).arity.should < 0 + end + + it "appends given arguments to receiver.each" do + @enum_with_arguments.each(:each0, :each1).to_a.should == [[:arg0, :arg1, :arg2, :each0, :each1]] + @enum_with_arguments.each(:each2, :each3).to_a.should == [[:arg0, :arg1, :arg2, :each2, :each3]] + end + + it "returns the same value from receiver.each if block and arguments are given" do + @enum_with_arguments.each(:each1, :each2) {}.should.equal?(:method_returned) + end + + it "returns new Enumerator if given arguments but not given a block" do + ret = @enum_with_arguments.each 1 + ret.should.instance_of?(Enumerator) + ret.should_not.equal?(@enum_with_arguments) + end + + it "does not destructure yielded array values when chaining each.map" do + result = [[[1]]].each.map { |a, b| [a, b] } + result.should == [[[1], nil]] + end + + it "preserves array values yielded from the enumerator" do + result = [[1, 2]].each.map { |a| a } + result.should == [[1, 2]] + end + + it "allows destructuring to occur in the block, not the enumerator" do + result = [[1, 2]].each.map { |a, b| a } + result.should == [1] + end +end |
