summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-24 08:38:35 +0000
committerknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-24 08:38:35 +0000
commit045b0e54d884f2e67449caaaec670a76ed16f3d4 (patch)
treeb13fdfce8348eb8cbef757cf8c8c7eec215f749f /test
parentc0e20037f3fb16d75b55394e7bf0a1d3ef8b7b87 (diff)
downloadruby-045b0e54d884f2e67449caaaec670a76ed16f3d4.tar.gz
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
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_enumerator.rb116
1 files changed, 115 insertions, 1 deletions
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(
+ '#<Enumerator::Chain: [' +
+ '#<Enumerator::Chain: [' +
+ '#<Enumerator: 1..5:each>' +
+ ']>, ' +
+ '#<Enumerator::Chain: [' +
+ '#<Enumerator: 1..5:each>, ' +
+ '[6, 7, 8]' +
+ ']>' +
+ ']>',
+ e5.inspect
+ )
+ end
+end