diff options
author | Jeremy Evans <code@jeremyevans.net> | 2019-09-02 13:22:26 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2019-09-03 11:30:49 -0700 |
commit | a7d7a0df91805e59fe6b383ea7ecdad509222966 (patch) | |
tree | 2732b61d102fa75d78a3271c83b4eedd91a0f1c0 /test/ruby | |
parent | 4a3972c2612c3e3695d7f67b096b2ef8cbb6649a (diff) | |
download | ruby-a7d7a0df91805e59fe6b383ea7ecdad509222966.tar.gz |
Fix Enumerator::Lazy#{to_enum,enum_for} where method is defined in Lazy
Previously, passing to_enum/enum_for a method that was defined in
Lazy itself returned wrong results:
[1,2,3].to_enum(:map).to_a
# => [1, 2, 3]
[1,2,3].lazy.to_enum(:map).to_a
# => []
I'm not sure why methods that are designed to be lazy do not work
with to_enum/enum_for. However, one possible way to work around
this bug is to have to_enum/enum_for use the implementation found
in Enumerable/Enumerator, which is what this commit does.
While this commit works around the problem, it is a band-aid, not a
real fix. It doesn't handle aliases of Enumerable::Lazy methods,
for instance. A better fix would be appreciated.
Diffstat (limited to 'test/ruby')
-rw-r--r-- | test/ruby/test_lazy_enumerator.rb | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb index 80977a0bbd..72fe1a4a24 100644 --- a/test/ruby/test_lazy_enumerator.rb +++ b/test/ruby/test_lazy_enumerator.rb @@ -466,6 +466,54 @@ EOS assert_equal [1, 2, 3], lazy.to_enum.to_a end + def test_lazy_to_enum_lazy_methods + a = [1, 2, 3].to_enum + pr = proc{|x| [x, x * 2]} + selector = proc{|x| x*2 if x % 2 == 0} + + [ + [:with_index, nil], + [:with_index, 10, nil], + [:with_index, 10, pr], + [:map, nil], + [:map, pr], + [:collect, nil], + [:flat_map, nil], + [:flat_map, pr], + [:collect_concat, nil], + [:select, nil], + [:select, selector], + [:find_all, nil], + [:filter, nil], + [:filter_map, selector], + [:filter_map, nil], + [:reject, selector], + [:grep, selector, nil], + [:grep, selector, pr], + [:grep_v, selector, nil], + [:grep_v, selector, pr], + [:zip, a, nil], + [:take, 3, nil], + [:take_while, nil], + [:take_while, selector], + [:drop, 1, nil], + [:drop_while, nil], + [:drop_while, selector], + [:uniq, nil], + [:uniq, proc{|x| x.odd?}], + ].each do |args| + block = args.pop + assert_equal [1, 2, 3].to_enum.to_enum(*args).first(2).to_a, [1, 2, 3].to_enum.lazy.to_enum(*args).first(2).to_a + assert_equal (0..50).to_enum.to_enum(*args).first(2).to_a, (0..50000).to_enum.lazy.to_enum(*args).first(2).to_a + if block + assert_equal [1, 2, 3, 4].to_enum.to_enum(*args).map(&block).first(2).to_a, [1, 2, 3, 4].to_enum.lazy.to_enum(*args).map(&block).first(2).to_a + unless args.first == :take_while || args.first == :drop_while + assert_equal (0..50).to_enum.to_enum(*args).map(&block).first(2).to_a, (0..50000).to_enum.lazy.to_enum(*args).map(&block).first(2).to_a + end + end + end + end + def test_size lazy = [1, 2, 3].lazy assert_equal 3, lazy.size |