Skip to content

Commit e6e770f

Browse files
Specs for Enumerator::Lazy propagating source yield arity through stages
A lazy stage that passes its source values through unchanged keeps the arity they were yielded with, so a block belonging to a later stage still receives them the way a block on the first stage would. In CRuby this is the LAZY_MEMO_PACKED bit traveling along the chain; stages that replace the value with a block result clear it. Covers take, drop, select, reject, take_while, drop_while and grep, plus the zero-argument yield (which becomes a single nil). Also adds the existing :enumerable_value_packing examples to grep, the one Lazy method they did not already cover.
1 parent f84b436 commit e6e770f

8 files changed

Lines changed: 110 additions & 0 deletions

File tree

core/enumerator/lazy/drop_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
55
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
67

78
describe "Enumerator::Lazy#drop" do
89
describe "value packing of source yields (matches Enumerable#drop)" do
@@ -72,3 +73,12 @@
7273
s.first(200).drop(100)
7374
end
7475
end
76+
77+
describe "Enumerator::Lazy#drop" do
78+
describe "propagating the source yield arity to a later stage" do
79+
before :each do
80+
@stage = -> e { e.drop(0) }
81+
end
82+
it_behaves_like :enumerator_lazy_packed_propagation, nil
83+
end
84+
end

core/enumerator/lazy/drop_while_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
55
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
67

78
describe "Enumerator::Lazy#drop_while" do
89
describe "value packing of source yields (matches Enumerable#drop_while)" do
@@ -80,3 +81,12 @@
8081
s.first(200).drop_while { |n| n < 100 }
8182
end
8283
end
84+
85+
describe "Enumerator::Lazy#drop_while" do
86+
describe "propagating the source yield arity to a later stage" do
87+
before :each do
88+
@stage = -> e { e.drop_while { false } }
89+
end
90+
it_behaves_like :enumerator_lazy_packed_propagation, nil
91+
end
92+
end

core/enumerator/lazy/grep_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22

33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
5+
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
57

68
describe "Enumerator::Lazy#grep" do
9+
describe "value packing of source yields (matches Enumerable#grep)" do
10+
before :each do
11+
@take = -> e { e.lazy.grep(Object) }
12+
end
13+
it_behaves_like :enumerable_value_packing, nil
14+
end
15+
716
before :each do
817
@yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
918
@eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy
@@ -119,3 +128,12 @@
119128
s.first(100).grep(Numeric)
120129
end
121130
end
131+
132+
describe "Enumerator::Lazy#grep" do
133+
describe "propagating the source yield arity to a later stage" do
134+
before :each do
135+
@stage = -> e { e.grep(Object) }
136+
end
137+
it_behaves_like :enumerator_lazy_packed_propagation, nil
138+
end
139+
end

core/enumerator/lazy/reject_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
55
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
67

78
describe "Enumerator::Lazy#reject" do
89
describe "value packing of source yields (matches Enumerable#reject)" do
@@ -84,3 +85,12 @@
8485
s.first(100).reject { |n| false }
8586
end
8687
end
88+
89+
describe "Enumerator::Lazy#reject" do
90+
describe "propagating the source yield arity to a later stage" do
91+
before :each do
92+
@stage = -> e { e.reject { false } }
93+
end
94+
it_behaves_like :enumerator_lazy_packed_propagation, nil
95+
end
96+
end

core/enumerator/lazy/select_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require_relative '../../../spec_helper'
22
require_relative 'fixtures/classes'
33
require_relative '../../enumerable/shared/value_packing'
4+
require_relative 'shared/packed_propagation'
45

56
describe "Enumerator::Lazy#select" do
67
describe "value packing of source yields (matches Enumerable#select)" do
@@ -109,3 +110,12 @@
109110
eval_count.should == 1
110111
end
111112
end
113+
114+
describe "Enumerator::Lazy#select" do
115+
describe "propagating the source yield arity to a later stage" do
116+
before :each do
117+
@stage = -> e { e.select { true } }
118+
end
119+
it_behaves_like :enumerator_lazy_packed_propagation, nil
120+
end
121+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# The propagation checked here is the LAZY_MEMO_PACKED bit traveling along the chain in CRuby.
2+
describe :enumerator_lazy_packed_propagation, shared: true do
3+
# @stage: a Proc wrapping a lazy enumerator in the stage under test, e.g. -> e { e.take(12) }.
4+
5+
before :each do
6+
@yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
7+
end
8+
9+
it "passes a multiple-argument source yield to a later stage's single-argument block as the first value" do
10+
yields = []
11+
@stage.call(@yieldsmixed).map { |v| yields << v }.force
12+
yields.should == EnumeratorLazySpecs::YieldsMixed.initial_yields
13+
end
14+
15+
it "passes every value of a multiple-argument source yield to a later stage's splat block" do
16+
args = nil
17+
@stage.call(Enumerator.new { |y| y.yield 1, 2 }.lazy).map { |*a| args = a }.force
18+
args.should == [1, 2]
19+
end
20+
21+
it "passes a zero-argument source yield on as a single nil" do
22+
args = nil
23+
@stage.call(Enumerator.new { |y| y.yield }.lazy).map { |*a| args = a }.force
24+
args.should == [nil]
25+
end
26+
27+
it "stops propagating once a stage replaces the value" do
28+
yields = []
29+
@stage.call(Enumerator.new { |y| y.yield 1, 2 }.lazy).map { |x| x }.map { |*a| yields << a }.force
30+
yields.should == [[1]]
31+
end
32+
end

core/enumerator/lazy/take_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
55
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
67

78
describe "Enumerator::Lazy#take" do
89
describe "value packing of source yields (matches Enumerable#take)" do
@@ -78,3 +79,12 @@
7879
end
7980
end
8081
end
82+
83+
describe "Enumerator::Lazy#take" do
84+
describe "propagating the source yield arity to a later stage" do
85+
before :each do
86+
@stage = -> e { e.take(12) }
87+
end
88+
it_behaves_like :enumerator_lazy_packed_propagation, nil
89+
end
90+
end

core/enumerator/lazy/take_while_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative '../../../spec_helper'
44
require_relative 'fixtures/classes'
55
require_relative '../../enumerable/shared/value_packing'
6+
require_relative 'shared/packed_propagation'
67

78
describe "Enumerator::Lazy#take_while" do
89
describe "value packing of source yields (matches Enumerable#take_while)" do
@@ -66,3 +67,12 @@
6667
end
6768
end
6869
end
70+
71+
describe "Enumerator::Lazy#take_while" do
72+
describe "propagating the source yield arity to a later stage" do
73+
before :each do
74+
@stage = -> e { e.take_while { true } }
75+
end
76+
it_behaves_like :enumerator_lazy_packed_propagation, nil
77+
end
78+
end

0 commit comments

Comments
 (0)