mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 6e33c16ffd
			
		
	
	
		6e33c16ffd
		
	
	
	
	
		
			
			* cont.c (cont_restore_thread): cause error if trace-status is changed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66007 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			145 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: false
 | |
| require 'test/unit'
 | |
| EnvUtil.suppress_warning {require 'continuation'}
 | |
| require 'fiber'
 | |
| 
 | |
| class TestContinuation < Test::Unit::TestCase
 | |
|   def test_create
 | |
|     assert_equal(:ok, callcc{:ok})
 | |
|     assert_equal(:ok, callcc{|c| c.call :ok})
 | |
|   end
 | |
| 
 | |
|   def test_call
 | |
|     assert_equal(:ok, callcc{|c| c.call :ok})
 | |
| 
 | |
|     ary = []
 | |
|     ary << callcc{|c|
 | |
|       @cont = c
 | |
|       :a
 | |
|     }
 | |
|     @cont.call :b if ary.length < 3
 | |
|     assert_equal([:a, :b, :b], ary)
 | |
|   end
 | |
| 
 | |
|   def test_check_localvars
 | |
|     vv = 0
 | |
|     @v = 0
 | |
|     @ary = []
 | |
|     [1, 2, 3].each{|i|
 | |
|       callcc {|k| @k = k}
 | |
|       @v += 1
 | |
|       vv += 1
 | |
|     }
 | |
|     @ary << [vv, @v]
 | |
|     @k.call if @v < 10
 | |
|     assert_equal((3..10).map{|e| [e, e]}, @ary)
 | |
|   end
 | |
| 
 | |
|   def test_error
 | |
|     cont = callcc{|c| c}
 | |
|     Thread.new{
 | |
|       assert_raise(RuntimeError){
 | |
|         cont.call
 | |
|       }
 | |
|     }.join
 | |
|     assert_raise(LocalJumpError){
 | |
|       callcc
 | |
|     }
 | |
|     assert_raise(RuntimeError){
 | |
|       c = nil
 | |
|       Fiber.new do
 | |
|         callcc {|c2| c = c2 }
 | |
|       end.resume
 | |
|       c.call
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def test_ary_flatten
 | |
|     assert_normal_exit %q{
 | |
|       require 'continuation'
 | |
|       n = 0
 | |
|       o = Object.new
 | |
|       def o.to_ary() callcc {|k| $k = k; [1,2,3]} end
 | |
|       [10,20,o,30,o,40].flatten.inspect
 | |
|       n += 1
 | |
|       $k.call if n < 100
 | |
|     }, '[ruby-dev:34798]'
 | |
|   end
 | |
| 
 | |
|   def test_marshal_dump
 | |
|     assert_normal_exit %q{
 | |
|       require 'continuation'
 | |
|       n = 0
 | |
|       o = Object.new
 | |
|       def o.marshal_dump() callcc {|k| $k = k };  "fofof" end
 | |
|       a = [1,2,3,o,4,5,6]
 | |
|       Marshal.dump(a).inspect
 | |
|       n += 1
 | |
|       $k.call if n < 100
 | |
|     }, '[ruby-dev:34802]'
 | |
|   end
 | |
| 
 | |
|   def tracing_with_set_trace_func
 | |
|     orig_thread = Thread.current
 | |
|     cont = nil
 | |
|     func = lambda do |*args|
 | |
|       if orig_thread == Thread.current
 | |
|         if cont
 | |
|           @memo += 1
 | |
|           c = cont
 | |
|           cont = nil
 | |
|           begin
 | |
|             c.call(nil)
 | |
|           rescue RuntimeError
 | |
|             set_trace_func(nil)
 | |
|           end
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|     cont = callcc { |cc| cc }
 | |
| 
 | |
|     if cont
 | |
|       set_trace_func(func)
 | |
|     else
 | |
|       set_trace_func(nil)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def _test_tracing_with_set_trace_func
 | |
|     @memo = 0
 | |
|     tracing_with_set_trace_func
 | |
|     tracing_with_set_trace_func
 | |
|     tracing_with_set_trace_func
 | |
|     assert_equal 0, @memo
 | |
|   end
 | |
| 
 | |
|   def tracing_with_thread_set_trace_func
 | |
|     cont = nil
 | |
|     func = lambda do |*args|
 | |
|       if cont
 | |
|         @memo += 1
 | |
|         c = cont
 | |
|         cont = nil
 | |
|         begin
 | |
|           c.call(nil)
 | |
|         rescue RuntimeError
 | |
|           Thread.current.set_trace_func(nil)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|     cont = callcc { |cc| cc }
 | |
|     if cont
 | |
|       Thread.current.set_trace_func(func)
 | |
|     else
 | |
|       Thread.current.set_trace_func(nil)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_tracing_with_thread_set_trace_func
 | |
|     @memo = 0
 | |
|     tracing_with_thread_set_trace_func
 | |
|     tracing_with_thread_set_trace_func
 | |
|     tracing_with_thread_set_trace_func
 | |
|     assert_equal 3, @memo
 | |
|   end
 | |
| end
 |