From 045b0e54d884f2e67449caaaec670a76ed16f3d4 Mon Sep 17 00:00:00 2001 From: knu Date: Sat, 24 Nov 2018 08:38:35 +0000 Subject: Implement Enumerator#+ and Enumerable#chain [Feature #15144] They return an Enumerator::Chain object which is a subclass of Enumerator, which represents a chain of enumerables that works as a single enumerator. ```ruby e = (1..3).chain([4, 5]) e.to_a #=> [1, 2, 3, 4, 5] e = (1..3).each + [4, 5] e.to_a #=> [1, 2, 3, 4, 5] ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_enumerator.rb | 116 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb index 0839c2c3dd..afd356105d 100644 --- a/test/ruby/test_enumerator.rb +++ b/test/ruby/test_enumerator.rb @@ -670,5 +670,119 @@ class TestEnumerator < Test::Unit::TestCase assert_equal([0, 1], u.force) assert_equal([0, 1], u.force) end -end + def test_enum_chain_and_plus + r = 1..5 + + e1 = r.chain() + assert_kind_of(Enumerator::Chain, e1) + assert_equal(5, e1.size) + ary = [] + e1.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5], ary) + + e2 = r.chain([6, 7, 8]) + assert_kind_of(Enumerator::Chain, e2) + assert_equal(8, e2.size) + ary = [] + e2.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8], ary) + + e3 = r.chain([6, 7], 8.step) + assert_kind_of(Enumerator::Chain, e3) + assert_equal(Float::INFINITY, e3.size) + ary = [] + e3.take(10).each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ary) + + # `a + b + c` should not return `Enumerator::Chain.new(a, b, c)` + # because it is expected that `(a + b).each` be called. + e4 = e2.dup + class << e4 + attr_reader :each_is_called + def each + super + @each_is_called = true + end + end + e5 = e4 + 9.step + assert_kind_of(Enumerator::Chain, e5) + assert_equal(Float::INFINITY, e5.size) + ary = [] + e5.take(10).each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ary) + assert_equal(true, e4.each_is_called) + end + + def test_chained_enums + a = (1..5).each + + e0 = Enumerator::Chain.new() + assert_kind_of(Enumerator::Chain, e0) + assert_equal(0, e0.size) + ary = [] + e0.each { |x| ary << x } + assert_equal([], ary) + + e1 = Enumerator::Chain.new(a) + assert_kind_of(Enumerator::Chain, e1) + assert_equal(5, e1.size) + ary = [] + e1.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5], ary) + + e2 = Enumerator::Chain.new(a, [6, 7, 8]) + assert_kind_of(Enumerator::Chain, e2) + assert_equal(8, e2.size) + ary = [] + e2.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8], ary) + + e3 = Enumerator::Chain.new(a, [6, 7], 8.step) + assert_kind_of(Enumerator::Chain, e3) + assert_equal(Float::INFINITY, e3.size) + ary = [] + e3.take(10).each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ary) + + e4 = Enumerator::Chain.new(a, Enumerator.new { |y| y << 6 << 7 << 8 }) + assert_kind_of(Enumerator::Chain, e4) + assert_equal(nil, e4.size) + ary = [] + e4.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8], ary) + + e5 = Enumerator::Chain.new(e1, e2) + assert_kind_of(Enumerator::Chain, e5) + assert_equal(13, e5.size) + ary = [] + e5.each { |x| ary << x } + assert_equal([1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 7, 8], ary) + + rewound = [] + e1.define_singleton_method(:rewind) { rewound << object_id } + e2.define_singleton_method(:rewind) { rewound << object_id } + e5.rewind + assert_equal(rewound, [e2.object_id, e1.object_id]) + + rewound = [] + a = [1] + e6 = Enumerator::Chain.new(a) + a.define_singleton_method(:rewind) { rewound << object_id } + e6.rewind + assert_equal(rewound, []) + + assert_equal( + '#' + + ']>, ' + + '#, ' + + '[6, 7, 8]' + + ']>' + + ']>', + e5.inspect + ) + end +end -- cgit v1.2.3