summaryrefslogtreecommitdiff
path: root/test/ruby/test_iterator.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_iterator.rb')
-rw-r--r--test/ruby/test_iterator.rb218
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