diff options
author | Benoit Daloze <eregontp@gmail.com> | 2023-09-04 16:07:46 +0200 |
---|---|---|
committer | Benoit Daloze <eregontp@gmail.com> | 2023-09-04 16:07:46 +0200 |
commit | 0b5c61494eb30c8c1867b9e6a52ad678e3f47901 (patch) | |
tree | 30ca3af5dadae196c39dae8c7e35c28b0537dd4a /spec/ruby/core/enumerator | |
parent | 3504f928dfb60b763e7b66149ca45cdbb45df78a (diff) |
Update to ruby/spec@96d1072
Diffstat (limited to 'spec/ruby/core/enumerator')
-rw-r--r-- | spec/ruby/core/enumerator/chain/initialize_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/each_spec.rb | 18 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/generator/initialize_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/initialize_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/lazy/initialize_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/each_spec.rb | 73 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/initialize_copy_spec.rb | 54 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/initialize_spec.rb | 33 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/inspect_spec.rb | 22 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/rewind_spec.rb | 64 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product/size_spec.rb | 64 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/product_spec.rb | 5 | ||||
-rw-r--r-- | spec/ruby/core/enumerator/rewind_spec.rb | 4 |
13 files changed, 334 insertions, 19 deletions
diff --git a/spec/ruby/core/enumerator/chain/initialize_spec.rb b/spec/ruby/core/enumerator/chain/initialize_spec.rb index 69484dfcb4..daa30351d7 100644 --- a/spec/ruby/core/enumerator/chain/initialize_spec.rb +++ b/spec/ruby/core/enumerator/chain/initialize_spec.rb @@ -22,10 +22,10 @@ describe "Enumerator::Chain#initialize" do end describe "on frozen instance" do - it "raises a RuntimeError" do + it "raises a FrozenError" do -> { @uninitialized.freeze.send(:initialize) - }.should raise_error(RuntimeError) + }.should raise_error(FrozenError) end end end diff --git a/spec/ruby/core/enumerator/each_spec.rb b/spec/ruby/core/enumerator/each_spec.rb index 99ac3120af..3af16e5587 100644 --- a/spec/ruby/core/enumerator/each_spec.rb +++ b/spec/ruby/core/enumerator/each_spec.rb @@ -10,41 +10,41 @@ describe "Enumerator#each" do @enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2) - @enum_with_yielder = Enumerator.new {|y| y.yield :ok} + @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] + [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 } + 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] + 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 } + 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] + 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 diff --git a/spec/ruby/core/enumerator/generator/initialize_spec.rb b/spec/ruby/core/enumerator/generator/initialize_spec.rb index f75c7d6f26..acc1174253 100644 --- a/spec/ruby/core/enumerator/generator/initialize_spec.rb +++ b/spec/ruby/core/enumerator/generator/initialize_spec.rb @@ -17,10 +17,10 @@ describe "Enumerator::Generator#initialize" do end describe "on frozen instance" do - it "raises a RuntimeError" do + it "raises a FrozenError" do -> { @uninitialized.freeze.send(:initialize) {} - }.should raise_error(RuntimeError) + }.should raise_error(FrozenError) end end end diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb index 5e937aff2b..5e0256ca46 100644 --- a/spec/ruby/core/enumerator/initialize_spec.rb +++ b/spec/ruby/core/enumerator/initialize_spec.rb @@ -48,10 +48,10 @@ describe "Enumerator#initialize" do end describe "on frozen instance" do - it "raises a RuntimeError" do + it "raises a FrozenError" do -> { @uninitialized.freeze.send(:initialize) {} - }.should raise_error(RuntimeError) + }.should raise_error(FrozenError) end end end diff --git a/spec/ruby/core/enumerator/lazy/initialize_spec.rb b/spec/ruby/core/enumerator/lazy/initialize_spec.rb index f23018d010..e1e0b1d608 100644 --- a/spec/ruby/core/enumerator/lazy/initialize_spec.rb +++ b/spec/ruby/core/enumerator/lazy/initialize_spec.rb @@ -56,8 +56,8 @@ describe "Enumerator::Lazy#initialize" do end describe "on frozen instance" do - it "raises a RuntimeError" do - -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(RuntimeError) + it "raises a FrozenError" do + -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(FrozenError) end end end diff --git a/spec/ruby/core/enumerator/product/each_spec.rb b/spec/ruby/core/enumerator/product/each_spec.rb new file mode 100644 index 0000000000..868a1ea6bf --- /dev/null +++ b/spec/ruby/core/enumerator/product/each_spec.rb @@ -0,0 +1,73 @@ +require_relative '../../../spec_helper' +require_relative '../../enumerable/shared/enumeratorized' + +ruby_version_is "3.2" do + describe "Enumerator::Product#each" do + it_behaves_like :enumeratorized_with_origin_size, :each, Enumerator::Product.new([1, 2], [:a, :b]) + + it "yields each element of Cartesian product of enumerators" do + enum = Enumerator::Product.new([1, 2], [:a, :b]) + acc = [] + enum.each { |e| acc << e } + acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "calls #each_entry method on enumerators" do + object1 = Object.new + def object1.each_entry + yield 1 + yield 2 + end + + object2 = Object.new + def object2.each_entry + yield :a + yield :b + end + + enum = Enumerator::Product.new(object1, object2) + acc = [] + enum.each { |e| acc << e } + acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "raises a NoMethodError if the object doesn't respond to #each_entry" do + -> { + Enumerator::Product.new(Object.new).each {} + }.should raise_error(NoMethodError, /undefined method `each_entry' for/) + end + + it "returns enumerator if not given a block" do + enum = Enumerator::Product.new([1, 2], [:a, :b]) + enum.each.should.kind_of?(Enumerator) + + enum = Enumerator::Product.new([1, 2], [:a, :b]) + enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "returns self if given a block" do + enum = Enumerator::Product.new([1, 2], [:a, :b]) + enum.each {}.should.equal?(enum) + end + + it "doesn't accept arguments" do + Enumerator::Product.instance_method(:each).arity.should == 0 + end + + it "yields each element to a block that takes multiple arguments" do + enum = Enumerator::Product.new([1, 2], [:a, :b]) + + acc = [] + enum.each { |x, y| acc << x } + acc.should == [1, 1, 2, 2] + + acc = [] + enum.each { |x, y| acc << y } + acc.should == [:a, :b, :a, :b] + + acc = [] + enum.each { |x, y, z| acc << z } + acc.should == [nil, nil, nil, nil] + end + end +end diff --git a/spec/ruby/core/enumerator/product/initialize_copy_spec.rb b/spec/ruby/core/enumerator/product/initialize_copy_spec.rb new file mode 100644 index 0000000000..46e8421322 --- /dev/null +++ b/spec/ruby/core/enumerator/product/initialize_copy_spec.rb @@ -0,0 +1,54 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.2" do + describe "Enumerator::Product#initialize_copy" do + it "replaces content of the receiver with content of the other object" do + enum = Enumerator::Product.new([true, false]) + enum2 = Enumerator::Product.new([1, 2], [:a, :b]) + + enum.send(:initialize_copy, enum2) + enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "returns self" do + enum = Enumerator::Product.new([true, false]) + enum2 = Enumerator::Product.new([1, 2], [:a, :b]) + + enum.send(:initialize_copy, enum2).should.equal?(enum) + end + + it "is a private method" do + Enumerator::Product.should have_private_instance_method(:initialize_copy, false) + end + + it "does nothing if the argument is the same as the receiver" do + enum = Enumerator::Product.new(1..2) + enum.send(:initialize_copy, enum).should.equal?(enum) + + enum.freeze + enum.send(:initialize_copy, enum).should.equal?(enum) + end + + it "raises FrozenError if the receiver is frozen" do + enum = Enumerator::Product.new(1..2) + enum2 = Enumerator::Product.new(3..4) + + -> { enum.freeze.send(:initialize_copy, enum2) }.should raise_error(FrozenError) + end + + it "raises TypeError if the objects are of different class" do + enum = Enumerator::Product.new(1..2) + enum2 = Class.new(Enumerator::Product).new(3..4) + + -> { enum.send(:initialize_copy, enum2) }.should raise_error(TypeError, 'initialize_copy should take same class object') + -> { enum2.send(:initialize_copy, enum) }.should raise_error(TypeError, 'initialize_copy should take same class object') + end + + it "raises ArgumentError if the argument is not initialized yet" do + enum = Enumerator::Product.new(1..2) + enum2 = Enumerator::Product.allocate + + -> { enum.send(:initialize_copy, enum2) }.should raise_error(ArgumentError, 'uninitialized product') + end + end +end diff --git a/spec/ruby/core/enumerator/product/initialize_spec.rb b/spec/ruby/core/enumerator/product/initialize_spec.rb new file mode 100644 index 0000000000..4b60564240 --- /dev/null +++ b/spec/ruby/core/enumerator/product/initialize_spec.rb @@ -0,0 +1,33 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.2" do + describe "Enumerator::Product#initialize" do + before :each do + @uninitialized = Enumerator::Product.allocate + end + + it "is a private method" do + Enumerator::Product.should have_private_instance_method(:initialize, false) + end + + it "returns self" do + @uninitialized.send(:initialize).should equal(@uninitialized) + end + + it "accepts many arguments" do + @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized) + end + + it "accepts arguments that are not Enumerable nor responding to :each_entry" do + @uninitialized.send(:initialize, Object.new).should equal(@uninitialized) + end + + describe "on frozen instance" do + it "raises a FrozenError" do + -> { + @uninitialized.freeze.send(:initialize, 0..1) + }.should raise_error(FrozenError) + end + end + end +end diff --git a/spec/ruby/core/enumerator/product/inspect_spec.rb b/spec/ruby/core/enumerator/product/inspect_spec.rb new file mode 100644 index 0000000000..1ea8e9c49b --- /dev/null +++ b/spec/ruby/core/enumerator/product/inspect_spec.rb @@ -0,0 +1,22 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.2" do + describe "Enumerator::Product#inspect" do + it "returns a String including enumerators" do + enum = Enumerator::Product.new([1, 2], [:a, :b]) + enum.inspect.should == "#<Enumerator::Product: [[1, 2], [:a, :b]]>" + end + + it "represents a recursive element with '[...]'" do + enum = [1, 2] + enum_recursive = Enumerator::Product.new(enum) + + enum << enum_recursive + enum_recursive.inspect.should == "#<Enumerator::Product: [[1, 2, #<Enumerator::Product: ...>]]>" + end + + it "returns a not initialized representation if #initialized is not called yet" do + Enumerator::Product.allocate.inspect.should == "#<Enumerator::Product: uninitialized>" + end + end +end diff --git a/spec/ruby/core/enumerator/product/rewind_spec.rb b/spec/ruby/core/enumerator/product/rewind_spec.rb new file mode 100644 index 0000000000..e8ee730239 --- /dev/null +++ b/spec/ruby/core/enumerator/product/rewind_spec.rb @@ -0,0 +1,64 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.2" do + describe "Enumerator::Product#rewind" do + before :each do + @enum = Enumerator::Product.new([1, 2].each.to_enum, [:a, :b].each.to_enum) + end + + it "resets the enumerator to its initial state" do + @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + @enum.rewind + @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "returns self" do + @enum.rewind.should.equal? @enum + end + + it "has no effect on a new enumerator" do + @enum.rewind + @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "has no effect if called multiple, consecutive times" do + @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + @enum.rewind + @enum.rewind + @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]] + end + + it "calls the enclosed object's rewind method if one exists" do + obj = mock('rewinder') + enum = Enumerator::Product.new(obj.to_enum) + + obj.should_receive(:rewind) + enum.rewind + end + + it "does nothing if the object doesn't have a #rewind method" do + obj = mock('rewinder') + enum = Enumerator::Product.new(obj.to_enum) + + enum.rewind.should == enum + end + + it "calls a rewind method on each enumerable in direct order" do + ScratchPad.record [] + + object1 = Object.new + def object1.rewind; ScratchPad << :object1; end + + object2 = Object.new + def object2.rewind; ScratchPad << :object2; end + + object3 = Object.new + def object3.rewind; ScratchPad << :object3; end + + enum = Enumerator::Product.new(object1, object2, object3) + enum.rewind + + ScratchPad.recorded.should == [:object1, :object2, :object3] + end + end +end diff --git a/spec/ruby/core/enumerator/product/size_spec.rb b/spec/ruby/core/enumerator/product/size_spec.rb new file mode 100644 index 0000000000..fb0efdf748 --- /dev/null +++ b/spec/ruby/core/enumerator/product/size_spec.rb @@ -0,0 +1,64 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.2" do + describe "Enumerator::Product#size" do + it "returns the total size of the enumerator product calculated by multiplying the sizes of enumerables in the product" do + product = Enumerator::Product.new(1..2, 1..3, 1..4) + product.size.should == 24 # 2 * 3 * 4 + end + + it "returns nil if any enumerable reports its size as nil" do + enum = Object.new + def enum.size; nil; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == nil + end + + it "returns Float::INFINITY if any enumerable reports its size as Float::INFINITY" do + enum = Object.new + def enum.size; Float::INFINITY; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == Float::INFINITY + end + + it "returns -Float::INFINITY if any enumerable reports its size as -Float::INFINITY" do + enum = Object.new + def enum.size; -Float::INFINITY; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == -Float::INFINITY + end + + it "returns nil if any enumerable reports its size as Float::NAN" do + enum = Object.new + def enum.size; Float::NAN; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == nil + end + + it "returns nil if any enumerable doesn't respond to #size" do + enum = Object.new + product = Enumerator::Product.new(1..2, enum) + product.size.should == nil + end + + it "returns nil if any enumerable reports a not-convertible to Integer" do + enum = Object.new + def enum.size; :symbol; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == nil + end + + it "returns nil if any enumerable reports a non-Integer but convertible to Integer size" do + enum = Object.new + def enum.size; 1.0; end + + product = Enumerator::Product.new(1..2, enum) + product.size.should == nil + end + end +end diff --git a/spec/ruby/core/enumerator/product_spec.rb b/spec/ruby/core/enumerator/product_spec.rb index 44fc6441e1..0fb00fc7ee 100644 --- a/spec/ruby/core/enumerator/product_spec.rb +++ b/spec/ruby/core/enumerator/product_spec.rb @@ -44,6 +44,11 @@ ruby_version_is "3.2" do elems.should == [[1, "X"], [1, "Y"], [2, "X"], [2, "Y"]] end + it "returns nil when a block passed" do + Enumerator.product(1..2) {}.should == nil + end + + # https://bugs.ruby-lang.org/issues/19829 it "reject keyword arguments" do -> { Enumerator.product(1..3, foo: 1, bar: 2) diff --git a/spec/ruby/core/enumerator/rewind_spec.rb b/spec/ruby/core/enumerator/rewind_spec.rb index a105f2c619..6ba0edf174 100644 --- a/spec/ruby/core/enumerator/rewind_spec.rb +++ b/spec/ruby/core/enumerator/rewind_spec.rb @@ -14,7 +14,7 @@ describe "Enumerator#rewind" do end it "returns self" do - @enum.rewind.should == @enum + @enum.rewind.should.equal? @enum end it "has no effect on a new enumerator" do @@ -49,7 +49,7 @@ describe "Enumerator#rewind" do obj = mock('rewinder') enum = obj.to_enum obj.should_receive(:each).at_most(1) - -> { enum.rewind.should == enum }.should_not raise_error + enum.rewind.should == enum end end |