diff --git a/core/enumerator/lazy/compact_spec.rb b/core/enumerator/lazy/compact_spec.rb index baa80acd3..4f54ca322 100644 --- a/core/enumerator/lazy/compact_spec.rb +++ b/core/enumerator/lazy/compact_spec.rb @@ -29,3 +29,21 @@ Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil end end + +describe "Enumerator::Lazy#compact" do + # Cannot use shared/packed_propagation.rb wholesale: #compact removes the + # packed nil, so neither YieldsMixed nor a zero-argument yield survives it. + describe "propagating the source yield arity to a later stage" do + it "passes every value of a multiple-argument source yield to a later stage's splat block" do + args = nil + Enumerator.new { |y| y.yield 1, 2 }.lazy.compact.map { |*a| args = a }.force + args.should == [1, 2] + end + + it "stops propagating once a stage replaces the value" do + yields = [] + Enumerator.new { |y| y.yield 1, 2 }.lazy.compact.map { |x| x }.map { |*a| yields << a }.force + yields.should == [[1]] + end + end +end diff --git a/core/enumerator/lazy/drop_spec.rb b/core/enumerator/lazy/drop_spec.rb index 099dc3265..4a598a884 100644 --- a/core/enumerator/lazy/drop_spec.rb +++ b/core/enumerator/lazy/drop_spec.rb @@ -3,6 +3,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#drop" do describe "value packing of source yields (matches Enumerable#drop)" do @@ -72,3 +73,12 @@ s.first(200).drop(100) end end + +describe "Enumerator::Lazy#drop" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.drop(0) } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/drop_while_spec.rb b/core/enumerator/lazy/drop_while_spec.rb index e9862ba02..3bbb7d18e 100644 --- a/core/enumerator/lazy/drop_while_spec.rb +++ b/core/enumerator/lazy/drop_while_spec.rb @@ -3,6 +3,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#drop_while" do describe "value packing of source yields (matches Enumerable#drop_while)" do @@ -80,3 +81,12 @@ s.first(200).drop_while { |n| n < 100 } end end + +describe "Enumerator::Lazy#drop_while" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.drop_while { false } } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/grep_spec.rb b/core/enumerator/lazy/grep_spec.rb index 383f80a91..ef4d88125 100644 --- a/core/enumerator/lazy/grep_spec.rb +++ b/core/enumerator/lazy/grep_spec.rb @@ -2,8 +2,17 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' +require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#grep" do + describe "value packing of source yields (matches Enumerable#grep)" do + before :each do + @take = -> e { e.lazy.grep(Object) } + end + it_behaves_like :enumerable_value_packing, nil + end + before :each do @yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy @eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy @@ -119,3 +128,12 @@ s.first(100).grep(Numeric) end end + +describe "Enumerator::Lazy#grep" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.grep(Object) } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/grep_v_spec.rb b/core/enumerator/lazy/grep_v_spec.rb index 19c917f25..e85a1c8d3 100644 --- a/core/enumerator/lazy/grep_v_spec.rb +++ b/core/enumerator/lazy/grep_v_spec.rb @@ -1,5 +1,6 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#grep_v" do before(:each) do @@ -121,3 +122,12 @@ s.first(100).grep_v(String) end end + +describe "Enumerator::Lazy#grep_v" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.grep_v(Float) } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/reject_spec.rb b/core/enumerator/lazy/reject_spec.rb index 23c882b1d..7b95b5811 100644 --- a/core/enumerator/lazy/reject_spec.rb +++ b/core/enumerator/lazy/reject_spec.rb @@ -3,6 +3,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#reject" do describe "value packing of source yields (matches Enumerable#reject)" do @@ -84,3 +85,12 @@ s.first(100).reject { |n| false } end end + +describe "Enumerator::Lazy#reject" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.reject { false } } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/select_spec.rb b/core/enumerator/lazy/select_spec.rb index 5d6b68cff..6ca8edeb2 100644 --- a/core/enumerator/lazy/select_spec.rb +++ b/core/enumerator/lazy/select_spec.rb @@ -1,6 +1,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#select" do describe "value packing of source yields (matches Enumerable#select)" do @@ -109,3 +110,12 @@ eval_count.should == 1 end end + +describe "Enumerator::Lazy#select" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.select { true } } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/shared/packed_propagation.rb b/core/enumerator/lazy/shared/packed_propagation.rb new file mode 100644 index 000000000..3643531aa --- /dev/null +++ b/core/enumerator/lazy/shared/packed_propagation.rb @@ -0,0 +1,32 @@ +# The propagation checked here is the LAZY_MEMO_PACKED bit traveling along the chain in CRuby. +describe :enumerator_lazy_packed_propagation, shared: true do + # @stage: a Proc wrapping a lazy enumerator in the stage under test, e.g. -> e { e.take(12) }. + + before :each do + @yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy + end + + it "passes a multiple-argument source yield to a later stage's single-argument block as the first value" do + yields = [] + @stage.call(@yieldsmixed).map { |v| yields << v }.force + yields.should == EnumeratorLazySpecs::YieldsMixed.initial_yields + end + + it "passes every value of a multiple-argument source yield to a later stage's splat block" do + args = nil + @stage.call(Enumerator.new { |y| y.yield 1, 2 }.lazy).map { |*a| args = a }.force + args.should == [1, 2] + end + + it "passes a zero-argument source yield on as a single nil" do + args = nil + @stage.call(Enumerator.new { |y| y.yield }.lazy).map { |*a| args = a }.force + args.should == [nil] + end + + it "stops propagating once a stage replaces the value" do + yields = [] + @stage.call(Enumerator.new { |y| y.yield 1, 2 }.lazy).map { |x| x }.map { |*a| yields << a }.force + yields.should == [[1]] + end +end diff --git a/core/enumerator/lazy/take_spec.rb b/core/enumerator/lazy/take_spec.rb index 9976c587a..7404bc114 100644 --- a/core/enumerator/lazy/take_spec.rb +++ b/core/enumerator/lazy/take_spec.rb @@ -3,6 +3,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#take" do describe "value packing of source yields (matches Enumerable#take)" do @@ -78,3 +79,12 @@ end end end + +describe "Enumerator::Lazy#take" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.take(12) } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/take_while_spec.rb b/core/enumerator/lazy/take_while_spec.rb index 1dc62b242..6d8ade2bc 100644 --- a/core/enumerator/lazy/take_while_spec.rb +++ b/core/enumerator/lazy/take_while_spec.rb @@ -3,6 +3,7 @@ require_relative '../../../spec_helper' require_relative 'fixtures/classes' require_relative '../../enumerable/shared/value_packing' +require_relative 'shared/packed_propagation' describe "Enumerator::Lazy#take_while" do describe "value packing of source yields (matches Enumerable#take_while)" do @@ -66,3 +67,12 @@ end end end + +describe "Enumerator::Lazy#take_while" do + describe "propagating the source yield arity to a later stage" do + before :each do + @stage = -> e { e.take_while { true } } + end + it_behaves_like :enumerator_lazy_packed_propagation, nil + end +end diff --git a/core/enumerator/lazy/uniq_spec.rb b/core/enumerator/lazy/uniq_spec.rb index d928cb06e..8d2aaec11 100644 --- a/core/enumerator/lazy/uniq_spec.rb +++ b/core/enumerator/lazy/uniq_spec.rb @@ -80,3 +80,27 @@ def each s.first(100).uniq end end + +describe "Enumerator::Lazy#uniq" do + # Cannot use shared/packed_propagation.rb wholesale: the repeated yields of + # YieldsMixed are dropped by #uniq. + describe "propagating the source yield arity to a later stage" do + it "passes every value of a multiple-argument source yield to a later stage's splat block" do + args = nil + Enumerator.new { |y| y.yield 1, 2 }.lazy.uniq.map { |*a| args = a }.force + args.should == [1, 2] + end + + it "passes a zero-argument source yield on as a single nil" do + args = nil + Enumerator.new { |y| y.yield }.lazy.uniq.map { |*a| args = a }.force + args.should == [nil] + end + + it "stops propagating once a stage replaces the value" do + yields = [] + Enumerator.new { |y| y.yield 1, 2 }.lazy.uniq.map { |x| x }.map { |*a| yields << a }.force + yields.should == [[1]] + end + end +end