Upgrade to 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-enumerator / test / enumerator.rb
1 @obj = Object.new
2 class << @obj
3   include Enumerable
4   def foo *a
5     a.each { |x| yield x }
6   end
7 end
8
9 def assert_take(exp, enumerator)
10   result = []
11   n = exp.size
12   enumerator.each do |v|
13     result << v
14     n -= 1
15     break if n == 0
16   end if n > 0
17   assert_equal exp, result
18 end
19
20 assert 'Enumerator.class' do
21   assert_equal Class, Enumerator.class
22 end
23
24 assert 'Enumerator.superclass' do
25   assert_equal Object, Enumerator.superclass
26 end
27
28 assert 'Enumerator.new' do
29   assert_equal [0,1,2], 3.times.map{|i| i}.sort
30   assert_equal [:x,:y,:z], [:x,:y,:z].each.map{|i| i}.sort
31   assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort
32   assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a
33   assert_take [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }
34   assert_raise(ArgumentError) { Enumerator.new }
35
36   # examples
37   fib = Enumerator.new do |y|
38     a = b = 1
39     loop do
40       y << a
41       a, b = b, a + b
42     end
43   end
44   assert_take [1,1,2,3,5,8,13,21,34,55], fib
45 end
46
47 assert 'Enumerator#initialize_copy' do
48   assert_equal [1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a
49   e = @obj.to_enum :foo, 1, 2, 3
50   assert_nothing_raised { assert_equal(1, e.next) }
51   assert_raise(TypeError) { e.dup }
52
53   e = Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.dup
54   assert_nothing_raised { assert_equal(1, e.next) }
55   assert_raise(TypeError) { e.dup }
56 end
57
58 assert 'Enumerator#with_index' do
59   assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)
60   assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a)
61   a = []
62   @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i }
63   assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a
64 end
65
66 assert 'Enumerator#with_index string offset' do
67   assert_raise(TypeError){ @obj.to_enum(:foo, 1, 2, 3).with_index('1').to_a }
68 end
69
70 assert 'Enumerator#each_with_index' do
71   assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).each_with_index.to_a)
72   a = []
73   @obj.to_enum(:foo, 1, 2, 3).each_with_index {|*i| a << i}
74   assert_equal([[1, 0], [2, 1], [3, 2]], a)
75 end
76
77 assert 'Enumerator#with_object' do
78   obj = [0, 1]
79   ret = (1..10).each.with_object(obj) {|i, memo|
80     memo[0] += i
81     memo[1] *= i
82   }
83   assert_true(obj.equal?(ret))
84   assert_equal([55, 3628800], ret)
85 end
86
87 assert 'Enumerator#with_object arguments' do
88   to_three = Enumerator.new do |y|
89     3.times do |x|
90       y << x
91     end
92   end
93
94   a = []
95   to_three_with_string = to_three.with_object("foo")
96   to_three_with_string.each do |x,string|
97     a << "#{string}:#{x}"
98   end
99   assert_equal ["foo:0","foo:1","foo:2"], a
100 end
101
102 assert 'Enumerator#inspect' do
103   e = (0..10).each
104   assert_equal('#<Enumerator: 0..10:each>', e.inspect)
105   e = 'FooObject'.enum_for(:foo, 1)
106   assert_equal('#<Enumerator: "FooObject":foo(1)>', e.inspect)
107   e = 'FooObject'.enum_for(:foo, 1, 2, 3)
108   assert_equal('#<Enumerator: "FooObject":foo(1, 2, 3)>', e.inspect)
109   e = nil.enum_for(:to_s)
110   assert_equal('#<Enumerator: nil:to_s>', e.inspect)
111 end
112
113 assert 'Enumerator#each' do
114   o = Object.new
115   def o.each(ary)
116     ary << 1
117     yield
118   end
119   ary = []
120   e = o.to_enum.each(ary)
121   e.next
122   assert_equal([1], ary)
123 end
124
125 assert 'Enumerator#each arguments' do
126   obj = Object.new
127
128   def obj.each_arg(a, b=:b, *rest)
129     yield a
130     yield b
131     yield rest
132     :method_returned
133   end
134
135   enum = obj.to_enum :each_arg, :a, :x
136
137   assert_equal [:a, :x, []], enum.each.to_a
138   assert_true enum.each.equal?(enum)
139   assert_equal :method_returned, enum.each { |elm| elm }
140
141   assert_equal [:a, :x, [:y, :z]], enum.each(:y, :z).to_a
142   assert_false enum.each(:y, :z).equal?(enum)
143   assert_equal :method_returned, enum.each(:y, :z) { |elm| elm }
144 end
145
146 assert 'Enumerator#next' do
147   e = 3.times
148   3.times { |i|
149     assert_equal i, e.next
150   }
151   assert_raise(StopIteration) { e.next }
152 end
153
154 assert 'Enumerator#next_values' do
155   o = Object.new
156   def o.each
157     yield
158     yield 1
159     yield 1, 2
160   end
161   e = o.to_enum
162   assert_equal nil, e.next
163   assert_equal 1, e.next
164   assert_equal [1,2], e.next
165   e = o.to_enum
166   assert_equal [], e.next_values
167   assert_equal [1], e.next_values
168   assert_equal [1,2], e.next_values
169 end
170
171 assert 'Enumerator#peek' do
172   a = [1]
173   e = a.each
174   assert_equal 1, e.peek
175   assert_equal 1, e.peek
176   assert_equal 1, e.next
177   assert_raise(StopIteration) { e.peek }
178   assert_raise(StopIteration) { e.peek }
179 end
180
181 assert 'Enumerator#peek modify' do
182   o = Object.new
183   def o.each
184     yield 1,2
185   end
186   e = o.to_enum
187   a = e.peek
188   a << 3
189   assert_equal([1,2], e.peek)
190 end
191
192 assert 'Enumerator#peek_values' do
193   o = Object.new
194   def o.each
195     yield
196     yield 1
197     yield 1, 2
198   end
199   e = o.to_enum
200   assert_equal nil, e.peek
201   assert_equal nil, e.next
202   assert_equal 1, e.peek
203   assert_equal 1, e.next
204   assert_equal [1,2], e.peek
205   assert_equal [1,2], e.next
206   e = o.to_enum
207   assert_equal [], e.peek_values
208   assert_equal [], e.next_values
209   assert_equal [1], e.peek_values
210   assert_equal [1], e.next_values
211   assert_equal [1,2], e.peek_values
212   assert_equal [1,2], e.next_values
213   e = o.to_enum
214   assert_equal [], e.peek_values
215   assert_equal nil, e.next
216   assert_equal [1], e.peek_values
217   assert_equal 1, e.next
218   assert_equal [1,2], e.peek_values
219   assert_equal [1,2], e.next
220   e = o.to_enum
221   assert_equal nil, e.peek
222   assert_equal [], e.next_values
223   assert_equal 1, e.peek
224   assert_equal [1], e.next_values
225   assert_equal [1,2], e.peek
226   assert_equal [1,2], e.next_values
227 end
228
229 assert 'Enumerator#peek_values modify' do
230   o = Object.new
231   def o.each
232     yield 1,2
233   end
234   e = o.to_enum
235   a = e.peek_values
236   a << 3
237   assert_equal [1,2], e.peek
238 end
239
240 assert 'Enumerator#feed' do
241   o = Object.new
242   def o.each(ary)
243     ary << yield
244     ary << yield
245     ary << yield
246   end
247   ary = []
248   e = o.to_enum :each, ary
249   e.next
250   e.feed 1
251   e.next
252   e.feed 2
253   e.next
254   e.feed 3
255   assert_raise(StopIteration) { e.next }
256   assert_equal [1,2,3], ary
257 end
258
259 assert 'Enumerator#feed mixed' do
260   o = Object.new
261   def o.each(ary)
262     ary << yield
263     ary << yield
264     ary << yield
265   end
266   ary = []
267   e = o.to_enum :each, ary
268   e.next
269   e.feed 1
270   e.next
271   e.next
272   e.feed 3
273   assert_raise(StopIteration) { e.next }
274   assert_equal [1,nil,3], ary
275 end
276
277 assert 'Enumerator#feed twice' do
278   o = Object.new
279   def o.each(ary)
280     ary << yield
281     ary << yield
282     ary << yield
283   end
284   ary = []
285   e = o.to_enum :each, ary
286   e.feed 1
287   assert_raise(TypeError) { e.feed 2 }
288 end
289
290 assert 'Enumerator#feed before first next' do
291   o = Object.new
292   def o.each(ary)
293     ary << yield
294     ary << yield
295     ary << yield
296   end
297   ary = []
298   e = o.to_enum :each, ary
299   e.feed 1
300   e.next
301   e.next
302   assert_equal [1], ary
303 end
304
305 assert 'Enumerator#feed yielder' do
306   x = nil
307   e = Enumerator.new {|y| x = y.yield; 10 }
308   e.next
309   e.feed 100
310   assert_raise(StopIteration) { e.next }
311   assert_equal 100, x
312 end
313
314 assert 'Enumerator#rewind' do
315   e = @obj.to_enum(:foo, 1, 2, 3)
316   assert_equal 1, e.next
317   assert_equal 2, e.next
318   e.rewind
319   assert_equal 1, e.next
320   assert_equal 2, e.next
321   assert_equal 3, e.next
322   assert_raise(StopIteration) { e.next }
323 end
324
325 assert 'Enumerator#rewind clear feed' do
326   o = Object.new
327   def o.each(ary)
328     ary << yield
329     ary << yield
330     ary << yield
331   end
332   ary = []
333   e = o.to_enum(:each, ary)
334   e.next
335   e.feed 1
336   e.next
337   e.feed 2
338   e.rewind
339   e.next
340   e.next
341   assert_equal([1,nil], ary)
342 end
343
344 assert 'Enumerator#rewind clear' do
345   o = Object.new
346   def o.each(ary)
347     ary << yield
348     ary << yield
349     ary << yield
350   end
351   ary = []
352   e = o.to_enum :each, ary
353   e.next
354   e.feed 1
355   e.next
356   e.feed 2
357   e.rewind
358   e.next
359   e.next
360   assert_equal [1,nil], ary
361 end
362
363 assert 'Enumerator::Generator' do
364   # note: Enumerator::Generator is a class just for internal
365   g = Enumerator::Generator.new {|y| y << 1 << 2 << 3; :foo }
366   g2 = g.dup
367   a = []
368   assert_equal(:foo, g.each {|x| a << x })
369   assert_equal([1, 2, 3], a)
370   a = []
371   assert_equal(:foo, g2.each {|x| a << x })
372   assert_equal([1, 2, 3], a)
373 end
374
375 assert 'Enumerator::Generator args' do
376   g = Enumerator::Generator.new {|y, x| y << 1 << 2 << 3; x }
377   a = []
378   assert_equal(:bar, g.each(:bar) {|x| a << x })
379   assert_equal([1, 2, 3], a)
380 end
381
382 assert 'Enumerator::Yielder' do
383   # note: Enumerator::Yielder is a class just for internal
384   a = []
385   y = Enumerator::Yielder.new {|x| a << x }
386   assert_equal(y, y << 1 << 2 << 3)
387   assert_equal([1, 2, 3], a)
388
389   a = []
390   y = Enumerator::Yielder.new {|x| a << x }
391   assert_equal([1], y.yield(1))
392   assert_equal([1, 2], y.yield(2))
393   assert_equal([1, 2, 3], y.yield(3))
394
395   assert_raise(LocalJumpError) { Enumerator::Yielder.new }
396 end
397
398 assert 'next after StopIteration' do
399   a = [1]
400   e = a.each
401   assert_equal(1, e.next)
402   assert_raise(StopIteration) { e.next }
403   assert_raise(StopIteration) { e.next }
404   e.rewind
405   assert_equal(1, e.next)
406   assert_raise(StopIteration) { e.next }
407   assert_raise(StopIteration) { e.next }
408 end
409
410 assert 'gc' do
411   assert_nothing_raised do
412     1.times do
413       foo = [1,2,3].to_enum
414       GC.start
415     end
416     GC.start
417   end
418 end
419
420 assert 'nested iteration' do
421   def (o = Object.new).each
422     yield :ok1
423     yield [:ok2, :x].each.next
424   end
425   e = o.to_enum
426   assert_equal :ok1, e.next
427   assert_equal :ok2, e.next
428   assert_raise(StopIteration) { e.next }
429 end
430
431 assert 'Kernel#to_enum' do
432   e = nil
433   assert_equal Enumerator, [].to_enum.class
434   assert_nothing_raised { e = [].to_enum(:_not_implemented_) }
435   assert_raise(NoMethodError) { e.first }
436 end
437
438 assert 'modifying existing methods' do
439   assert_equal Enumerator, loop.class
440   e = 3.times
441   i = 0
442   loop_ret = loop {
443     assert_equal i, e.next
444     i += 1
445   }
446 end
447
448 assert 'Integral#times' do
449   a = 3
450   b = a.times
451   c = []
452   b.with_object(c) do |i, obj|
453     obj << i
454   end
455   assert_equal 3, a
456   assert_equal Enumerator, b.class
457   assert_equal [0,1,2], c
458 end
459
460 assert 'Enumerable#each_with_index' do
461   assert_equal [['a',0],['b',1],['c',2]], ['a','b','c'].each_with_index.to_a
462 end
463
464 assert 'Enumerable#map' do
465   a = [1,2,3]
466   b = a.map
467   c = b.with_index do |i, index|
468     [i*i, index*index]
469   end
470   assert_equal [1,2,3], a
471   assert_equal [[1,0],[4,1],[9,4]], c
472 end
473
474 assert 'Enumerable#find_all' do
475   assert_equal [[3,4]], [[1,2],[3,4],[5,6]].find_all.each{ |i| i[1] == 4 }
476 end
477
478 assert 'Array#each_index' do
479   a = [1,2,3]
480   b = a.each_index
481   c = []
482   b.with_index do |index1,index2|
483     c << [index1+2,index2+5]
484   end
485   assert_equal [1,2,3], a
486   assert_equal [[2,5],[3,6],[4,7]], c
487 end
488
489 assert 'Array#map!' do
490   a = [1,2,3]
491   b = a.map!
492   b.with_index do |i, index|
493     [i*i, index*index]
494   end
495   assert_equal [[1,0],[4,1],[9,4]], a
496 end
497
498 assert 'Hash#each' do
499   a = {a:1,b:2}
500   b = a.each
501   c = []
502   b.each do |k,v|
503     c << [k,v]
504   end
505   assert_equal [[:a,1], [:b,2]], c.sort
506 end
507
508 assert 'Hash#each_key' do
509   assert_equal [:a,:b], {a:1,b:2}.each_key.to_a.sort
510 end
511
512 assert 'Hash#each_value' do
513   assert_equal [1,2], {a:1,b:2}.each_value.to_a.sort
514 end
515
516 assert 'Hash#select' do
517   h = {1=>2,3=>4,5=>6}
518   hret = h.select.with_index {|a,_b| a[1] == 4}
519   assert_equal({3=>4}, hret)
520   assert_equal({1=>2,3=>4,5=>6}, h)
521 end
522
523 assert 'Hash#select!' do
524   h = {1=>2,3=>4,5=>6}
525   hret = h.select!.with_index {|a,_b| a[1] == 4}
526   assert_equal h, hret
527   assert_equal({3=>4}, h)
528 end
529
530 assert 'Hash#reject' do
531   h = {1=>2,3=>4,5=>6}
532   hret = h.reject.with_index {|a,_b| a[1] == 4}
533   assert_equal({1=>2,5=>6}, hret)
534   assert_equal({1=>2,3=>4,5=>6}, h)
535 end
536
537 assert 'Hash#reject!' do
538   h = {1=>2,3=>4,5=>6}
539   hret = h.reject!.with_index {|a,_b| a[1] == 4}
540   assert_equal h, hret
541   assert_equal({1=>2,5=>6}, h)
542 end
543
544 assert 'Range#each' do
545   a = (1..5)
546   b = a.each
547   c = []
548   b.each do |i|
549     c << i
550   end
551   assert_equal [1,2,3,4,5], c
552 end
553
554 assert 'Enumerable#zip' do
555   assert_equal [[1, 10], [2, 11], [3, 12]], [1,2,3].zip(10..Float::INFINITY)
556
557   ret = []
558   assert_equal nil, [1,2,3].zip(10..Float::INFINITY) { |i| ret << i }
559   assert_equal [[1, 10], [2, 11], [3, 12]], ret
560
561   assert_raise(TypeError) { [1].zip(1) }
562 end
563
564 assert 'Enumerator.produce' do
565   assert_raise(ArgumentError) { Enumerator.produce }
566
567   # Without initial object
568   passed_args = []
569   enum = Enumerator.produce {|obj| passed_args << obj; (obj || 0).succ }
570   assert_equal Enumerator, enum.class 
571   assert_take [1, 2, 3], enum
572   assert_equal [nil, 1, 2], passed_args
573
574   # With initial object
575   passed_args = []
576   enum = Enumerator.produce(1) {|obj| passed_args << obj; obj.succ }
577   assert_take [1, 2, 3], enum
578   assert_equal [1, 2], passed_args
579
580   # Raising StopIteration
581   words = %w[The quick brown fox jumps over the lazy dog]
582   enum = Enumerator.produce { words.shift or raise StopIteration }
583   assert_equal %w[The quick brown fox jumps over the lazy dog], enum.to_a
584
585   # Raising StopIteration
586   object = [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"]
587   enum = Enumerator.produce(object) {|obj|
588     obj.respond_to?(:first) or raise StopIteration
589     obj.first
590   }
591   assert_nothing_raised {
592     assert_equal [
593       [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"],
594       [[["abc", "def"], "ghi", "jkl"], "mno", "pqr"],
595       [["abc", "def"], "ghi", "jkl"],
596       ["abc", "def"],
597       "abc",
598     ], enum.to_a
599   }
600 end