Skip to content

Commit 43babf4

Browse files
committed
* Enumerator#size{=}: Basic generic specs
* Kernel#to_enum: Basic spec for block form
1 parent bb9ccf0 commit 43babf4

File tree

3 files changed

+330
-0
lines changed

3 files changed

+330
-0
lines changed

core/enumerator/fixtures/classes.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module EnumeratorSpecs
2+
3+
class Numerous
4+
include Enumerable
5+
def initialize(*list)
6+
@list = list.empty? ? [2, 5, 3, 6, 1, 4] : list
7+
end
8+
9+
def each
10+
return to_enum unless block_given?
11+
@list.each { |i| yield i }
12+
end
13+
14+
def more(*list)
15+
@list += list
16+
end
17+
end
18+
19+
class SizedNumerous < Numerous
20+
def size
21+
@list.size
22+
end
23+
end
24+
end

core/enumerator/size_spec.rb

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
# encoding: utf-8
2+
3+
require File.expand_path('../../../spec_helper', __FILE__)
4+
require File.expand_path('../fixtures/classes', __FILE__)
5+
6+
# Note: this describes the generic #size and #size=
7+
# Specialized #size methods are found in subfolders, e.g. loop/size_spec.rb
8+
9+
ruby_version_is "1.9.3" do
10+
describe "Enumerator#size" do
11+
before :each do
12+
@e = Enumerator.new{|y| y << :foo << :bar}
13+
end
14+
15+
describe "when called without a block" do
16+
it "returns nil when size was not specified" do
17+
@e.size.should == nil
18+
end
19+
20+
it "returns the specified size" do
21+
@e.size = 42
22+
@e.size.should == 42
23+
end
24+
25+
it "returns the result of the given size block or method" do
26+
values = [42, 1, 2, 3]
27+
@e.size = Proc.new{ values.pop }
28+
@e.size.should == 3
29+
@e.size.should == 2
30+
def values.shift(x)
31+
super()
32+
end
33+
@e.size = values.method(:shift)
34+
@e.size.should == 42
35+
@e.size.should == 1
36+
end
37+
38+
it "yields the receiver and the arguments to the given size block or method" do
39+
values = [42, 1, 2, 3]
40+
def values.foo(*args)
41+
each{|x| yield x}
42+
end
43+
s = "hello"
44+
@e = values.to_enum(:foo, s)
45+
receiver = nil
46+
arg = nil
47+
@e.size = lambda{|r, a| receiver = r; arg = a; r.size }
48+
@e.size.should == 4
49+
receiver.should equal(values)
50+
arg.should equal(s)
51+
end
52+
53+
it "is lazy and doesn't iterate" do
54+
lambda{
55+
Enumerator.new{ raise "be lazy!" }.size
56+
}.should_not raise_error
57+
end
58+
end
59+
60+
describe "when called with a block" do
61+
it "returns the actual size when size was not specified" do
62+
@e.size{}.should == 2
63+
end
64+
65+
it "ignores the specified size" do
66+
@e.size = 42
67+
@e.size{}.should == 2
68+
end
69+
70+
it "ignores the given size block or method" do
71+
@e.size = Proc.new{ raise "ignore me" }
72+
lambda{
73+
@e.size{}
74+
}.should_not raise_error
75+
end
76+
end
77+
end
78+
79+
describe "Array#permutation.size" do
80+
it "returns the number of permutations" do
81+
[].permutation.size.should == 1
82+
[1].permutation.size.should == 1
83+
[1, 2].permutation(3).size.should == 0
84+
(1..5).to_a.permutation(2).size.should == 20
85+
(1..100).to_a.permutation.size.should == 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
86+
end
87+
end
88+
89+
describe "Array#combination.size" do
90+
it "returns the number of combinations" do
91+
[].combination(0).size.should == 1
92+
[1].combination(0).size.should == 1
93+
[1].combination(1).size.should == 1
94+
[1, 2].combination(3).size.should == 0
95+
(1..5).to_a.combination(2).size.should == 10
96+
(1..5).to_a.combination(3).size.should == 10
97+
(1..100).to_a.combination(40).size.should == 13746234145802811501267369720
98+
end
99+
end
100+
101+
describe "Array#repeated_permutation.size" do
102+
it "returns the number of repeated permutations" do
103+
[ ].repeated_permutation(0).size.should == 1
104+
[ ].repeated_permutation(2).size.should == 0
105+
[1].repeated_permutation(0).size.should == 1
106+
[1].repeated_permutation(5).size.should == 1
107+
[1].repeated_permutation(-1).size.should == 0
108+
(1..100).to_a.repeated_permutation(40).size.should == 100**40
109+
end
110+
end
111+
112+
describe "Array#repeated_combination.size" do
113+
it "returns the number of repeated combinations" do
114+
[ ].repeated_combination(0).size.should == 1
115+
[ ].repeated_combination(2).size.should == 0
116+
[1].repeated_combination(0).size.should == 1
117+
[1].repeated_combination(5).size.should == 1
118+
[1].repeated_combination(-1).size.should == 0
119+
(1..5).to_a.repeated_combination(3).size.should == 35
120+
(1..100).to_a.repeated_combination(40).size.should == 126279609474586092455213621207360700
121+
end
122+
end
123+
124+
describe "Array#cycle.size" do
125+
it "returns the size" do
126+
[ ].cycle.size.should == 0
127+
[1].cycle.size.should == Float::INFINITY
128+
[1,2].cycle(3).size.should == 6
129+
end
130+
end
131+
132+
describe "Kernel#loop.size" do
133+
it "returns Infinity" do
134+
loop.size.should == Float::INFINITY
135+
end
136+
end
137+
138+
describe "Enumerator#size when created from an enumerable" do
139+
before :each do
140+
@methods = [:each_with_index, :each_entry, :reverse_each,
141+
:find_all, :reject, :map, :flat_map, :partition, :group_by, :sort_by,
142+
:min_by, :max_by, :minmax_by ]
143+
end
144+
145+
it "returns nil if the Enumerable has no size method" do
146+
e = EnumeratorSpecs::Numerous.new
147+
@methods.each do |method|
148+
e.send(method).size.should == nil
149+
end
150+
e.each_with_object(:foo).size.should == nil
151+
end
152+
153+
it "uses the size method if there is one" do
154+
e = EnumeratorSpecs::SizedNumerous.new
155+
@methods.each do |method|
156+
e.send(method).size.should == 6
157+
end
158+
e.each_with_object(:foo).size.should == 6
159+
end
160+
end
161+
162+
describe "Enumerable#each_slize.size" do
163+
it "returns the right size" do
164+
e = EnumeratorSpecs::SizedNumerous.new(*1..42)
165+
e.each_slice(3).size.should == 14
166+
e.each_slice(4).size.should == 11
167+
end
168+
end
169+
170+
describe "Enumerable#each_cons.size" do
171+
it "returns the right size" do
172+
e = EnumeratorSpecs::SizedNumerous.new(*1..42)
173+
e.each_cons(3).size.should == 40
174+
e.each_cons(50).size.should == 0
175+
end
176+
end
177+
178+
describe "Enumerable#cycle.size" do
179+
it "returns the right size" do
180+
e = EnumeratorSpecs::SizedNumerous.new
181+
e.cycle(3).size.should == 18
182+
e.cycle(0).size.should == 0
183+
e.cycle(-1).size.should == 0
184+
e.cycle.size.should == Float::INFINITY
185+
end
186+
end
187+
188+
describe "Enumerator#size when created from a Hash" do
189+
it "returns the hash's size" do
190+
h = {"hello" => "world", :foo => :bar, 1 => 2}
191+
[ :each, :each_value, :each_key, :each_pair,
192+
:keep_if, :delete_if, :reject!, :select, :select!
193+
].each do |method|
194+
h.send(method).size.should == 3
195+
end
196+
end
197+
end
198+
199+
describe "Enumerator#size when created from ENV" do
200+
it "returns the number of environment variables" do
201+
s = ENV.to_a.size
202+
[ :each, :each_value, :each_key, :each_pair,
203+
:keep_if, :delete_if, :reject!, :select, :select!
204+
].each do |method|
205+
ENV.send(method).size.should == s
206+
end
207+
end
208+
end
209+
210+
describe "Enumerator#size when created from a Struct" do
211+
it "returns the number of fields" do
212+
klass = Struct.new(:foo, :bar, :baz)
213+
s = klass.new
214+
[ :each, :each_pair, :select
215+
].each do |method|
216+
s.send(method).size.should == 3
217+
end
218+
end
219+
end
220+
221+
describe "Numeric#step.size" do
222+
it "returns the right size for fixnums" do
223+
42.step(99, 3).size.should == 20
224+
42.step(100, 3).size.should == 20
225+
42.step(20, 3).size.should == 0
226+
42.step(20, -3).size.should == 8
227+
10.step(20).size.should == 11
228+
end
229+
230+
it "returns the right size for floats" do
231+
0.5.step(4.2, 0.3).size.should == 13
232+
0.5.step(4.2, -0.3).size.should == 0
233+
-0.5.step(-4.2, -0.3).size.should == 13
234+
end
235+
236+
it "returns the right size for bignums" do
237+
(2 ** 100).step(2 ** 100 + 42, 2).size.should == 22
238+
(2 ** 100).step(2 ** 100 - 41, 2).size.should == 0
239+
(2 ** 100).step(2 ** 100 - 41, -2).size.should == 21
240+
end
241+
end
242+
243+
describe "Numeric#upto.size" do
244+
it "returns the right size for fixnums" do
245+
42.upto(99).size.should == 58
246+
42.upto(20).size.should == 0
247+
end
248+
249+
it "returns the right size for bignum arguments" do
250+
(2 ** 100).upto(2 ** 100 + 42).size.should == 43
251+
(2 ** 100).upto(2 ** 100 - 42).size.should == 0
252+
end
253+
end
254+
255+
describe "Numeric#downto.size" do
256+
it "returns the right size for fixnums" do
257+
42.downto(99).size.should == 0
258+
42.downto(20).size.should == 23
259+
end
260+
261+
it "returns the right size for bignum arguments" do
262+
(2 ** 100).downto(2 ** 100 + 42).size.should == 0
263+
(2 ** 100).downto(2 ** 100 - 42).size.should == 43
264+
end
265+
end
266+
267+
describe "Numeric#times.size" do
268+
it "returns the right size" do
269+
5.times.size.should == 5
270+
(2 ** 99).times.size.should == 2 ** 99
271+
end
272+
273+
it "returns 0 for negative integers" do
274+
(-5).times.size.should == 0
275+
(-2 ** 99).times.size.should == 0
276+
end
277+
end
278+
279+
describe "String#each_byte.size" do
280+
it "returns the size" do
281+
"Môntréål".each_byte.size.should == 11
282+
end
283+
end
284+
285+
describe "String#each_char.size" do
286+
it "returns the number of characters" do
287+
"Môntréål".each_char.size.should == 8
288+
end
289+
end
290+
291+
describe "String#each_codepoint.size" do
292+
it "returns the number of characters" do
293+
"Môntréål".each_codepoint.size.should == 8
294+
end
295+
end
296+
end

core/kernel/to_enum_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,15 @@
33
ruby_version_is "1.9" do
44
describe "Kernel#to_enum" do
55
it "needs to be reviewed for spec completeness"
6+
7+
ruby_version_is "1.9.3" do
8+
it "accepts a size block" do
9+
x = "foo"
10+
args = nil
11+
enum = x.to_enum(:foo, :bar){|*a| args = a; 42}
12+
enum.size.should == 42
13+
args.should == [x, :bar]
14+
end
15+
end
616
end
717
end

0 commit comments

Comments
 (0)