diff options
Diffstat (limited to 'spec/rubyspec/shared/enumerator')
-rw-r--r-- | spec/rubyspec/shared/enumerator/each.rb | 89 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/enum_cons.rb | 12 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/enum_for.rb | 50 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/new.rb | 42 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/next.rb | 28 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/rewind.rb | 39 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/with_index.rb | 32 | ||||
-rw-r--r-- | spec/rubyspec/shared/enumerator/with_object.rb | 42 |
8 files changed, 334 insertions, 0 deletions
diff --git a/spec/rubyspec/shared/enumerator/each.rb b/spec/rubyspec/shared/enumerator/each.rb new file mode 100644 index 0000000000..bbab86fed7 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/each.rb @@ -0,0 +1,89 @@ +# -*- encoding: us-ascii -*- + +describe :enum_each, shared: true 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('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 "raises a NoMethodError if the object doesn't respond to #each" do + enum = Object.new.to_enum + lambda do + enum.each { |e| e } + end.should raise_error(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 be_an_instance_of(Enumerator) + ret.should_not equal(@enum_with_arguments) + end +end diff --git a/spec/rubyspec/shared/enumerator/enum_cons.rb b/spec/rubyspec/shared/enumerator/enum_cons.rb new file mode 100644 index 0000000000..59eed949d8 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/enum_cons.rb @@ -0,0 +1,12 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require File.expand_path('../../../fixtures/enumerator/classes', __FILE__) + +describe :enum_cons, shared: true do + it "returns an enumerator of the receiver with iteration of each_cons for each array of n concecutive elements" do + a = [] + enum = EnumSpecs::Numerous.new.enum_cons(3) + enum.each {|x| a << x} + enum.should be_an_instance_of(Enumerator) + a.should == [[2, 5, 3], [5, 3, 6], [3, 6, 1], [6, 1, 4]] + end +end diff --git a/spec/rubyspec/shared/enumerator/enum_for.rb b/spec/rubyspec/shared/enumerator/enum_for.rb new file mode 100644 index 0000000000..9030ffbd7d --- /dev/null +++ b/spec/rubyspec/shared/enumerator/enum_for.rb @@ -0,0 +1,50 @@ +describe :enum_for, shared: true do + it "is defined in Kernel" do + Kernel.method_defined?(@method).should be_true + end + + it "returns a new enumerator" do + "abc".send(@method).should be_an_instance_of(Enumerator) + end + + it "defaults the first argument to :each" do + enum = [1,2].send(@method) + enum.map { |v| v }.should == [1,2].each { |v| v } + end + + it "exposes multi-arg yields as an array" do + o = Object.new + def o.each + yield :a + yield :b1, :b2 + yield [:c] + yield :d1, :d2 + yield :e1, :e2, :e3 + end + + enum = o.send(@method) + enum.next.should == :a + enum.next.should == [:b1, :b2] + enum.next.should == [:c] + enum.next.should == [:d1, :d2] + enum.next.should == [:e1, :e2, :e3] + end + + it "uses the passed block's value to calculate the size of the enumerator" do + Object.new.enum_for { 100 }.size.should == 100 + end + + it "defers the evaluation of the passed block until #size is called" do + ScratchPad.record [] + + enum = Object.new.enum_for do + ScratchPad << :called + 100 + end + + ScratchPad.recorded.should be_empty + + enum.size + ScratchPad.recorded.should == [:called] + end +end diff --git a/spec/rubyspec/shared/enumerator/new.rb b/spec/rubyspec/shared/enumerator/new.rb new file mode 100644 index 0000000000..23ace99816 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/new.rb @@ -0,0 +1,42 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe :enum_new, shared: true do + it "creates a new custom enumerator with the given object, iterator and arguments" do + enum = Enumerator.new(1, :upto, 3) + enum.should be_an_instance_of(Enumerator) + end + + it "creates a new custom enumerator that responds to #each" do + enum = Enumerator.new(1, :upto, 3) + enum.respond_to?(:each).should == true + end + + it "creates a new custom enumerator that runs correctly" do + Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3] + end + + it "aliases the second argument to :each" do + Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a + end + + it "doesn't check for the presence of the iterator method" do + Enumerator.new(nil).should be_an_instance_of(Enumerator) + end + + it "uses the latest define iterator method" do + class StrangeEach + def each + yield :foo + end + end + enum = Enumerator.new(StrangeEach.new) + enum.to_a.should == [:foo] + class StrangeEach + def each + yield :bar + end + end + enum.to_a.should == [:bar] + end + +end diff --git a/spec/rubyspec/shared/enumerator/next.rb b/spec/rubyspec/shared/enumerator/next.rb new file mode 100644 index 0000000000..d8ae6d9673 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/next.rb @@ -0,0 +1,28 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe :enum_next, shared: true do + + before :each do + @enum = 1.upto(3) + end + + it "returns the next element of the enumeration" do + @enum.next.should == 1 + @enum.next.should == 2 + @enum.next.should == 3 + end + + it "raises a StopIteration exception at the end of the stream" do + 3.times { @enum.next } + lambda { @enum.next }.should raise_error(StopIteration) + end + + it "cannot be called again until the enumerator is rewound" do + 3.times { @enum.next } + lambda { @enum.next }.should raise_error(StopIteration) + lambda { @enum.next }.should raise_error(StopIteration) + lambda { @enum.next }.should raise_error(StopIteration) + @enum.rewind + @enum.next.should == 1 + end +end diff --git a/spec/rubyspec/shared/enumerator/rewind.rb b/spec/rubyspec/shared/enumerator/rewind.rb new file mode 100644 index 0000000000..4d4139204c --- /dev/null +++ b/spec/rubyspec/shared/enumerator/rewind.rb @@ -0,0 +1,39 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe :enum_rewind, shared: true do + + before :each do + @enum = 1.upto(3) + end + + it "resets the enumerator to its initial state" do + @enum.next.should == 1 + @enum.next.should == 2 + @enum.rewind + @enum.next.should == 1 + end + + it "returns self" do + @enum.rewind.should == @enum + end + + it "has no effect on a new enumerator" do + @enum.rewind + @enum.next.should == 1 + end + + it "has no effect if called multiple, consecutive times" do + @enum.next.should == 1 + @enum.rewind + @enum.rewind + @enum.next.should == 1 + end + + it "works with peek to reset the position" do + @enum.next + @enum.next + @enum.rewind + @enum.next + @enum.peek.should == 2 + end +end diff --git a/spec/rubyspec/shared/enumerator/with_index.rb b/spec/rubyspec/shared/enumerator/with_index.rb new file mode 100644 index 0000000000..37048a7b52 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/with_index.rb @@ -0,0 +1,32 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe :enum_with_index, shared: true do + + require File.expand_path('../../../fixtures/enumerator/classes', __FILE__) + + before :each do + @enum = [1, 2, 3, 4].to_enum + end + + it "passes each element and its index to block" do + @a = [] + @enum.send(@method) { |o, i| @a << [o, i] } + @a.should == [[1, 0], [2, 1], [3, 2], [4, 3]] + end + + it "returns the object being enumerated when given a block" do + [1, 2, 3, 4].should == @enum.send(@method) { |o, i| :glark } + end + + it "binds splat arguments properly" do + acc = [] + @enum.send(@method) { |*b| c,d = b; acc << c; acc << d } + [1, 0, 2, 1, 3, 2, 4, 3].should == acc + end + + it "returns an enumerator if no block is supplied" do + ewi = @enum.send(@method) + ewi.should be_an_instance_of(Enumerator) + ewi.to_a.should == [[1, 0], [2, 1], [3, 2], [4, 3]] + end +end diff --git a/spec/rubyspec/shared/enumerator/with_object.rb b/spec/rubyspec/shared/enumerator/with_object.rb new file mode 100644 index 0000000000..1830736713 --- /dev/null +++ b/spec/rubyspec/shared/enumerator/with_object.rb @@ -0,0 +1,42 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe :enum_with_object, shared: true do + before :each do + @enum = [:a, :b].to_enum + @memo = '' + @block_params = @enum.send(@method, @memo).to_a + end + + it "receives an argument" do + @enum.method(@method).arity.should == 1 + end + + context "with block" do + it "returns the given object" do + ret = @enum.send(@method, @memo) do |elm, memo| + # nothing + end + ret.should equal(@memo) + end + + context "the block parameter" do + it "passes each element to first parameter" do + @block_params[0][0].should equal(:a) + @block_params[1][0].should equal(:b) + end + + it "passes the given object to last parameter" do + @block_params[0][1].should equal(@memo) + @block_params[1][1].should equal(@memo) + end + end + end + + context "without block" do + it "returns new Enumerator" do + ret = @enum.send(@method, @memo) + ret.should be_an_instance_of(Enumerator) + ret.should_not equal(@enum) + end + end +end |