diff options
Diffstat (limited to 'test/ruby/test_iterator.rb')
| -rw-r--r-- | test/ruby/test_iterator.rb | 218 |
1 files changed, 140 insertions, 78 deletions
diff --git a/test/ruby/test_iterator.rb b/test/ruby/test_iterator.rb index 1c293069c4..1bb655d52e 100644 --- a/test/ruby/test_iterator.rb +++ b/test/ruby/test_iterator.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: false require 'test/unit' class Array @@ -5,34 +6,29 @@ class Array collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]} end def iter_test2 - a = collect{|e| [e, yield(e)]} - a.sort{|a,b|a[1]<=>b[1]} + ary = collect{|e| [e, yield(e)]} + ary.sort{|a,b|a[1]<=>b[1]} end end class TestIterator < Test::Unit::TestCase - def ttt - assert(iterator?) - end - - def test_iterator - assert(!iterator?) - - ttt{} - - # yield at top level !! here's not toplevel - assert(!defined?(yield)) + def test_yield_at_toplevel + assert_separately([],"#{<<~"begin;"}\n#{<<~'end;'}") + begin; + assert(!block_given?) + assert(!defined?(yield)) + end; end def test_array - $x = [1, 2, 3, 4] - $y = [] + x = [1, 2, 3, 4] + y = [] # iterator over array - for i in $x - $y.push i + for i in x + y.push i end - assert_equal($x, $y) + assert_equal(x, y) end def tt @@ -51,10 +47,10 @@ class TestIterator < Test::Unit::TestCase def test_nested_iterator i = 0 - tt{|i| break if i == 5} - assert_equal(5, i) + tt{|j| break if j == 5} + assert_equal(0, i) - assert_raises(ArgumentError) do + assert_raise(ArgumentError) do tt3{} end end @@ -64,63 +60,61 @@ class TestIterator < Test::Unit::TestCase end def test_block_argument_without_paren - assert_raises(ArgumentError) do + assert_raise(ArgumentError) do tt4{} end end - # iterator break/redo/next/retry + # iterator break/redo/next def test_break done = true loop{ - break + break if true done = false # should not reach here } assert(done) done = false - $bad = false + bad = false loop { break if done done = true - next - $bad = true # should not reach here + next if true + bad = true # should not reach here } - assert(!$bad) + assert(!bad) done = false - $bad = false + bad = false loop { break if done done = true - redo - $bad = true # should not reach here + redo if true + bad = true # should not reach here } - assert(!$bad) + assert(!bad) - $x = [] + x = [] for i in 1 .. 7 - $x.push i - end - assert_equal(7, $x.size) - assert_equal([1, 2, 3, 4, 5, 6, 7], $x) - - $done = false - $x = [] - for i in 1 .. 7 # see how retry works in iterator loop - if i == 4 and not $done - $done = true - retry - end - $x.push(i) + x.push i end - assert_equal(10, $x.size) - assert_equal([1, 2, 3, 1, 2, 3, 4, 5, 6, 7], $x) + assert_equal(7, x.size) + assert_equal([1, 2, 3, 4, 5, 6, 7], x) + end + + def test_array_for_masgn + a = [Struct.new(:to_ary).new([1,2])] + x = [] + a.each {|i,j|x << [i,j]} + assert_equal([[1,2]], x) + x = [] + for i,j in a; x << [i,j]; end + assert_equal([[1,2]], x) end def test_append_method_to_built_in_class - $x = [[1,2],[3,4],[5,6]] - assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x}) + x = [[1,2],[3,4],[5,6]] + assert_equal(x.iter_test1{|e|e}, x.iter_test2{|e|e}) end class IterTest @@ -149,11 +143,9 @@ class TestIterator < Test::Unit::TestCase IterTest.new([0]).each0 {|x| assert_equal(0, x)} IterTest.new([1]).each1 {|x| assert_equal(1, x)} IterTest.new([2]).each2 {|x| assert_equal([2], x)} - IterTest.new([3]).each3 {|x| assert_equal(3, x)} IterTest.new([4]).each4 {|x| assert_equal(4, x)} IterTest.new([5]).each5 {|x| assert_equal(5, x)} IterTest.new([6]).each6 {|x| assert_equal([6], x)} - IterTest.new([7]).each7 {|x| assert_equal(7, x)} IterTest.new([8]).each8 {|x| assert_equal(8, x)} IterTest.new([[0]]).each0 {|x| assert_equal([0], x)} @@ -166,8 +158,8 @@ class TestIterator < Test::Unit::TestCase IterTest.new([[7]]).each7 {|x| assert_equal(7, x)} IterTest.new([[8]]).each8 {|x| assert_equal([8], x)} - IterTest.new([[0,0]]).each0 {|x| assert_equal([0,0], x)} - IterTest.new([[8,8]]).each8 {|x| assert_equal([8,8], x)} + IterTest.new([[0,0]]).each0 {|*x| assert_equal([[0,0]], x)} + IterTest.new([[8,8]]).each8 {|*x| assert_equal([[8,8]], x)} end def m(var) @@ -183,10 +175,27 @@ class TestIterator < Test::Unit::TestCase end def test_block_given + verbose_bak, $VERBOSE = $VERBOSE, nil assert(m1{p 'test'}) assert(m2{p 'test'}) assert(!m1()) assert(!m2()) + ensure + $VERBOSE = verbose_bak + end + + def m3(var, &block) + m(yield(var), &block) + end + + def m4(&block) + m(m1(), &block) + end + + def test_block_passing + assert(!m4()) + assert(!m4 {}) + assert_equal(100, m3(10) {|x|x*x}) end class C @@ -216,10 +225,10 @@ class TestIterator < Test::Unit::TestCase def test_argument assert_nothing_raised {lambda{||}.call} - assert_raises(ArgumentError) {lambda{||}.call(1)} + assert_raise(ArgumentError) {lambda{||}.call(1)} assert_nothing_raised {lambda{|a,|}.call(1)} - assert_raises(ArgumentError) {lambda{|a,|}.call()} - assert_raises(ArgumentError) {lambda{|a,|}.call(1,2)} + assert_raise(ArgumentError) {lambda{|a,|}.call()} + assert_raise(ArgumentError) {lambda{|a,|}.call(1,2)} end def get_block(&block) @@ -235,9 +244,9 @@ class TestIterator < Test::Unit::TestCase assert_nothing_raised {get_block{|a,|}.call(1,2)} assert_nothing_raised {get_block(&lambda{||}).call()} - assert_raises(ArgumentError) {get_block(&lambda{||}).call(1)} + assert_raise(ArgumentError) {get_block(&lambda{||}).call(1)} assert_nothing_raised {get_block(&lambda{|a,|}).call(1)} - assert_raises(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)} + assert_raise(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)} block = get_block{11} assert_instance_of(Proc, block) @@ -245,11 +254,11 @@ class TestIterator < Test::Unit::TestCase assert_equal(block.clone.call, 11) assert_instance_of(Proc, get_block(&block)) - lambda = lambda{44} - assert_instance_of(Proc, lambda) - assert_instance_of(Proc, lambda.to_proc) - assert_equal(lambda.clone.call, 44) - assert_instance_of(Proc, get_block(&lambda)) + lmd = lambda{44} + assert_instance_of(Proc, lmd) + assert_instance_of(Proc, lmd.to_proc) + assert_equal(lmd.clone.call, 44) + assert_instance_of(Proc, get_block(&lmd)) assert_equal(1, Proc.new{|a,| a}.call(1,2,3)) assert_nothing_raised {Proc.new{|a,|}.call(1,2)} @@ -278,6 +287,9 @@ class TestIterator < Test::Unit::TestCase def proc_call(&b) b.call end + def proc_call2(b) + b.call + end def proc_yield() yield end @@ -298,7 +310,19 @@ class TestIterator < Test::Unit::TestCase end def test_ljump - assert_raises(LocalJumpError) {get_block{break}.call} + assert_raise(LocalJumpError) {get_block{break}.call} + begin + verbose_bak, $VERBOSE = $VERBOSE, nil + # See the commit https://github.com/ruby/ruby/commit/7d8a415bc2d08a1b5e9d1ea802493b6eeb99c219 + # This block is not used but this is intentional. + # | + # +-----------------------------------------------------+ + # | + # vv + assert_raise(LocalJumpError) {proc_call2(get_block{break}){}} + ensure + $VERBOSE = verbose_bak + end # cannot use assert_nothing_raised due to passing block. begin @@ -306,13 +330,13 @@ class TestIterator < Test::Unit::TestCase rescue LocalJumpError assert(false, "LocalJumpError occurred from break in lambda") else - assert(11, val) + assert_equal(11, val) end block = get_block{11} - lambda = lambda{44} + lmd = lambda{44} assert_equal(0, block.arity) - assert_equal(0, lambda.arity) + assert_equal(0, lmd.arity) assert_equal(0, lambda{||}.arity) assert_equal(1, lambda{|a|}.arity) assert_equal(1, lambda{|a,|}.arity) @@ -320,8 +344,8 @@ class TestIterator < Test::Unit::TestCase end def marity_test(m) - method = method(m) - assert_equal(method.arity, method.to_proc.arity) + mobj = method(m) + assert_equal(mobj.arity, mobj.to_proc.arity) end def test_marity @@ -329,15 +353,14 @@ class TestIterator < Test::Unit::TestCase marity_test(:marity_test) marity_test(:p) - lambda(&method(:assert)).call(true) - lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity") + get_block{|a,n| assert(a,n)}.call(true, "marity") end def foo - yield([:key, :value]) + yield(:key, :value) end def bar(&blk) - blk.call([:key, :value]) + blk.call(:key, :value) end def test_yield_vs_call @@ -349,13 +372,19 @@ class TestIterator < Test::Unit::TestCase def each yield [:key, :value] end + alias each_pair each end def test_assoc_yield - [{:key=>:value}, H.new].each {|h| - h.each{|a| assert_equal([:key, :value], a)} - h.each{|*a| assert_equal([[:key, :value]], a)} - h.each{|k,v| assert_equal([:key, :value], [k,v])} + [{:key=>:value}, H.new].each {|h| + h.each{|a| assert_equal([:key, :value], a)} + h.each{|a,| assert_equal(:key, a)} + h.each{|*a| assert_equal([[:key, :value]], a)} + h.each{|k,v| assert_equal([:key, :value], [k,v])} + h.each_pair{|a| assert_equal([:key, :value], a)} + h.each_pair{|a,| assert_equal(:key, a)} + h.each_pair{|*a| assert_equal([[:key, :value]], a)} + h.each_pair{|k,v| assert_equal([:key, :value], [k,v])} } end @@ -455,4 +484,37 @@ class TestIterator < Test::Unit::TestCase assert_equal(ok, result) return end + + class IterString < ::String + def ===(other) + super if !block_given? + end + end + + # Check that the block passed to an iterator + # does not get propagated inappropriately + def test_block_given_within_iterator + assert_equal(["b"], ["a", "b", "c"].grep(IterString.new("b")) {|s| s}) + end + + def test_enumerator + [1,2,3].each.with_index {|x,i| + assert_equal(x, i+1) + } + + e = [1,2,3].each + assert_equal(1, e.next) + assert_equal(2, e.next) + assert_equal(3, e.next) + assert_raise(StopIteration){e.next} + e.rewind + assert_equal(1, e.next) + e.rewind + a = [] + loop{a.push e.next} + assert_equal([1,2,3], a) + + assert_equal([[8, 1, 10], [6, 2, 11], [4, 3, 12]], + [8,6,4].zip((1..10),(10..100)).to_a) + end end |
