summaryrefslogtreecommitdiff
path: root/yarvtest/test_flow.rb
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-12-31 15:02:22 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-12-31 15:02:22 +0000
commita3e1b1ce7ed7e7ffac23015fc2fde56511b30681 (patch)
tree7b725552a9a4ded93849ca2faab1b257f7761790 /yarvtest/test_flow.rb
parent3e7566d8fb5138bb9cd647e5fdefc54fc9803509 (diff)
* Merge YARV
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'yarvtest/test_flow.rb')
-rw-r--r--yarvtest/test_flow.rb591
1 files changed, 591 insertions, 0 deletions
diff --git a/yarvtest/test_flow.rb b/yarvtest/test_flow.rb
new file mode 100644
index 0000000000..fa7224b987
--- /dev/null
+++ b/yarvtest/test_flow.rb
@@ -0,0 +1,591 @@
+#
+# This test program is contributed by George Marrows
+# Re: [Yarv-devel] Some tests for test_jump.rb
+#
+
+require 'yarvtest/yarvtest'
+
+class TestFlow < YarvTestBase
+ def ae_flow(src, for_value=true)
+ # Tracks flow through the code
+ # A test like
+ # begin
+ # ensure
+ # end
+ # gets transformed into
+ # a = []
+ # begin
+ # begin; a << 1
+ # ensure; a << 2
+ # end; a << 3
+ # rescue Exception
+ # a << 99
+ # end
+ # a
+ # before being run. This tracks control flow through the code.
+
+ cnt = 0
+ src = src.gsub(/(\n|$)/) { "; $a << #{cnt+=1}\n" }
+ src = "$a = []; begin; #{src}; rescue Exception; $a << 99; end; $a"
+
+ if false#||true
+ STDERR.puts
+ STDERR.puts '#----'
+ STDERR.puts src
+ STDERR.puts '#----'
+ end
+
+ ae(src)
+ end
+
+ def test_while_with_ensure
+ ae %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ next
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ }
+ ae %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ i+=1
+ begin
+ begin
+ break
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ }
+ ae %q{
+ a = []
+ i = 0
+ begin
+ while i < 1
+ if i>0
+ break
+ end
+ i+=1
+ begin
+ begin
+ redo
+ ensure
+ a << :ok
+ end
+ ensure
+ a << :ok2
+ end
+ end
+ ensure
+ a << :last
+ end
+ }
+ end
+
+ def test_ensure_normal_flow
+ ae_flow %{
+ begin
+ ensure
+ end }
+ end
+
+ def test_ensure_exception
+ ae_flow %{
+ begin
+ raise StandardError
+ ensure
+ end
+ }
+ end
+
+ def test_break_in_block_runs_ensure
+ ae_flow %{
+ [1,2].each do
+ begin
+ break
+ ensure
+ end
+ end
+ }
+ end
+
+ def test_next_in_block_runs_ensure
+ ae_flow %{
+ [1,2].each do
+ begin
+ next
+ ensure
+ end
+ end
+ }
+ end
+ def test_return_from_method_runs_ensure
+ ae_flow %{
+ o = "test"
+ def o.test(a)
+ return a
+ ensure
+ end
+ o.test(123)
+ }
+ end
+
+ def test_break_from_ifunc
+ ae %q{
+ ["a"].inject("ng"){|x,y|
+ break :ok
+ }
+ }
+ ae %q{
+ unless ''.respond_to? :lines
+ class String
+ def lines
+ self
+ end
+ end
+ end
+
+ ('a').lines.map{|e|
+ break :ok
+ }
+ }
+ ae_flow %q{
+ ["a"].inject("ng"){|x,y|
+ break :ok
+ }
+ }
+ ae_flow %q{
+ ('a'..'b').map{|e|
+ break :ok
+ }
+ }
+ end
+
+ def test_break_ensure_interaction1
+ # make sure that any 'break state' set up in the VM is c
+ # the time of the ensure
+ ae_flow %{
+ [1,2].each{
+ break
+ }
+ begin
+ ensure
+ end
+ }
+ end
+
+ def test_break_ensure_interaction2
+ # ditto, different arrangement
+ ae_flow %{
+ begin
+ [1,2].each do
+ break
+ end
+ ensure
+ end
+ }
+ end
+
+ def test_break_through_2_ensures
+ ae_flow %{
+ [1,2].each do
+ begin
+ begin
+ break
+ ensure
+ end
+ ensure
+ end
+ end
+ }
+ end
+
+ def test_ensure_break_ensure
+ # break through an ensure; run 2nd normally
+ ae_flow %{
+ begin
+ [1,2].each do
+ begin
+ break
+ ensure
+ end
+ end
+ ensure
+ end
+ }
+ end
+
+ def test_exception_overrides_break
+ ae_flow %{
+ [1,2].each do
+ begin
+ break
+ ensure
+ raise StandardError
+ end
+ end
+ }
+ end
+
+ def test_break_overrides_exception
+ ae_flow %{
+ [1,2].each do
+ begin
+ raise StandardError
+ ensure
+ break
+ end
+ end
+ }
+ ae_flow %{
+ [1,2].each do
+ begin
+ raise StandardError
+ rescue
+ break
+ end
+ end
+ }
+ end
+
+ def test_break_in_exception
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ ensure
+ break
+ end
+ end
+ }
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ raise
+ ensure
+ break
+ end
+ end
+ }
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ raise
+ rescue
+ break
+ end
+ end
+ }
+ end
+
+ def test_next_in_exception
+ return
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ ensure
+ next
+ end
+ end
+ }
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ raise
+ ensure
+ next
+ end
+ end
+ }
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ begin
+ raise
+ rescue
+ next
+ end
+ end
+ }
+ end
+
+ def test_complex_break
+ ae_flow %q{
+ i = 0
+ while i<3
+ i+=1
+ j = 0
+ while j<3
+ j+=1
+ begin
+ raise
+ rescue
+ break
+ end
+ end
+ end
+ }
+ ae_flow %q{
+ i = 0
+ while i<3
+ i+=1
+ j = 0
+ while j<3
+ j+=1
+ 1.times{
+ begin
+ raise
+ rescue
+ break
+ end
+ }
+ end
+ end
+ }
+ ae_flow %q{
+ i = 0
+ while i<3
+ i+=1
+ j = 0
+ while j<3
+ j+=1
+ begin
+ raise
+ ensure
+ break
+ end
+ end
+ end
+ }
+ ae_flow %q{
+ i = 0
+ while i<3
+ i+=1
+ j = 0
+ while j<3
+ j+=1
+ 1.times{
+ begin
+ raise
+ ensure
+ break
+ end
+ }
+ end
+ end
+ }
+ ae_flow %q{
+ while true
+ begin
+ break
+ ensure
+ break
+ end
+ end
+ }
+ ae_flow %q{
+ while true
+ begin
+ break
+ ensure
+ raise
+ end
+ end
+ }
+ end
+
+ def test_jump_from_class
+ ae_flow %q{
+ 3.times{
+ class C
+ break
+ end
+ }
+ }
+ ae_flow %q{
+ 3.times{
+ class A
+ class B
+ break
+ end
+ end
+ }
+ }
+ ae_flow %q{
+ 3.times{
+ class C
+ next
+ end
+ }
+ }
+ ae_flow %q{
+ 3.times{
+ class C
+ class D
+ next
+ end
+ end
+ }
+ }
+ ae_flow %q{
+ while true
+ class C
+ break
+ end
+ end
+ }
+ ae_flow %q{
+ while true
+ class C
+ class D
+ break
+ end
+ end
+ end
+ }
+ ae_flow %q{
+ i=0
+ while i<3
+ i+=1
+ class C
+ next 10
+ end
+ end
+ }
+ ae %q{
+ 1.times{
+ while true
+ class C
+ begin
+ break
+ ensure
+ break
+ end
+ end
+ end
+ }
+ }
+ end
+
+ def test_flow_with_cont_sp
+ ae %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ while true
+ break 2
+ end
+ )
+ }
+ ae %q{
+ def m a, b
+ a + b
+ end
+ m(1,
+ (i=0; while i<2
+ i+=1
+ class C
+ next 2
+ end
+ end; 3)
+ )
+ }
+ ae %q{
+ def m a, b
+ a+b
+ end
+ m(1, 1.times{break 3}) +
+ m(10, (1.times{next 3}; 20))
+ }
+ end
+
+ def test_return_in_deep_stack
+ ae_flow %q{
+ def m1 *args
+
+ end
+ def m2
+ m1(:a, :b, (return 1; :c))
+ end
+ m2
+ }
+ end
+
+ def test_return_in_ensure
+ ae_flow %q{
+ def m()
+ begin
+ 2
+ ensure
+ return 3
+ end
+ end
+ m
+ }
+ ae_flow %q{
+ def m2
+ end
+ def m()
+ m2(begin
+ 2
+ ensure
+ return 3
+ end)
+ 4
+ end
+ m()
+ }
+ ae_flow %q{
+ def m
+ 1
+ 1.times{
+ 2
+ begin
+ 3
+ return
+ 4
+ ensure
+ 5
+ end
+ 6
+ }
+ 7
+ end
+ m()
+ }
+ end
+end
+