2015-12-16 00:07:31 -05:00
# frozen_string_literal: false
2003-09-04 12:18:59 -04:00
require 'test/unit'
2011-12-13 09:50:12 -05:00
require 'tempfile'
2003-09-04 12:18:59 -04:00
class TestException < Test :: Unit :: TestCase
2012-08-06 09:06:37 -04:00
def test_exception_rescued
2003-09-04 12:18:59 -04:00
begin
raise " this must be handled "
assert ( false )
rescue
assert ( true )
end
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2012-08-06 09:06:37 -04:00
def test_exception_retry
2012-08-06 09:06:16 -04:00
bad = true
2003-09-04 12:18:59 -04:00
begin
raise " this must be handled no.2 "
rescue
2012-08-06 09:06:16 -04:00
if bad
bad = false
2003-09-04 12:18:59 -04:00
retry
end
2016-02-19 02:48:02 -05:00
assert ( ! bad )
2003-09-04 12:18:59 -04:00
end
assert ( true )
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2012-08-06 09:06:37 -04:00
def test_exception_in_rescue
2012-08-06 09:06:16 -04:00
string = " this must be handled no.3 "
2013-10-09 04:43:12 -04:00
assert_raise_with_message ( RuntimeError , string ) do
2003-09-04 12:18:59 -04:00
begin
raise " exception in rescue clause "
2003-09-05 11:15:43 -04:00
rescue
2012-08-06 09:06:16 -04:00
raise string
2003-09-04 12:18:59 -04:00
end
assert ( false )
end
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2012-08-06 09:06:37 -04:00
def test_exception_in_ensure
2012-08-06 09:06:16 -04:00
string = " exception in ensure clause "
2013-10-09 04:43:12 -04:00
assert_raise_with_message ( RuntimeError , string ) do
2003-09-04 12:18:59 -04:00
begin
raise " this must be handled no.4 "
2003-09-05 11:15:43 -04:00
ensure
assert_instance_of ( RuntimeError , $! )
assert_equal ( " this must be handled no.4 " , $! . message )
2003-09-04 12:18:59 -04:00
raise " exception in ensure clause "
end
assert ( false )
end
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2012-08-06 09:06:37 -04:00
def test_exception_ensure
2012-08-06 09:06:16 -04:00
bad = true
2003-09-04 12:18:59 -04:00
begin
begin
raise " this must be handled no.5 "
ensure
2012-08-06 09:06:16 -04:00
bad = false
2003-09-04 12:18:59 -04:00
end
rescue
end
2012-08-06 09:06:16 -04:00
assert ( ! bad )
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2012-08-06 09:06:37 -04:00
def test_exception_ensure_2 # just duplication?
2012-08-06 09:06:16 -04:00
bad = true
2003-09-04 12:18:59 -04:00
begin
begin
raise " this must be handled no.6 "
ensure
2012-08-06 09:06:16 -04:00
bad = false
2003-09-04 12:18:59 -04:00
end
rescue
end
2012-08-06 09:06:16 -04:00
assert ( ! bad )
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2014-02-25 23:26:23 -05:00
def test_errinfo_in_debug
bug9568 = EnvUtil . labeled_class ( " [ruby-core:61091] [Bug # 9568] " , RuntimeError ) do
def to_s
require '\0'
rescue LoadError
self . class . to_s
end
end
err = EnvUtil . verbose_warning do
assert_raise ( bug9568 ) do
$DEBUG , debug = true , $DEBUG
begin
raise bug9568
ensure
$DEBUG = debug
end
end
end
assert_include ( err , bug9568 . to_s )
end
2014-02-26 00:10:46 -05:00
def test_errinfo_encoding_in_debug
exc = Module . new { break class_eval ( " class C \ u{30a8 30e9 30fc} < RuntimeError; self; end " . encode ( Encoding :: EUC_JP ) ) }
exc . inspect
err = EnvUtil . verbose_warning do
assert_raise ( exc ) do
$DEBUG , debug = true , $DEBUG
begin
raise exc
ensure
$DEBUG = debug
end
end
end
assert_include ( err , exc . to_s )
end
2012-08-06 09:06:37 -04:00
def test_break_ensure
2012-08-06 09:06:16 -04:00
bad = true
2003-09-04 12:18:59 -04:00
while true
begin
break
ensure
2012-08-06 09:06:16 -04:00
bad = false
2003-09-04 12:18:59 -04:00
end
end
2012-08-06 09:06:16 -04:00
assert ( ! bad )
2012-08-06 09:06:37 -04:00
end
2003-09-05 11:15:43 -04:00
2014-11-07 07:08:24 -05:00
def test_catch_no_throw
assert_equal ( :foo , catch { :foo } )
end
2012-08-06 09:06:37 -04:00
def test_catch_throw
2014-11-07 07:08:24 -05:00
result = catch ( :foo ) {
loop do
loop do
throw :foo , true
break
end
2014-11-09 08:12:14 -05:00
assert ( false , " should not reach here " )
2014-11-07 07:08:24 -05:00
end
false
}
assert ( result )
end
def test_catch_throw_noarg
2014-11-15 02:28:08 -05:00
assert_nothing_raised ( UncaughtThrowError ) {
2014-11-07 07:08:24 -05:00
result = catch { | obj |
throw obj , :ok
2014-11-09 08:12:14 -05:00
assert ( false , " should not reach here " )
2014-11-07 07:08:24 -05:00
}
assert_equal ( :ok , result )
}
end
def test_uncaught_throw
2014-11-15 02:28:08 -05:00
tag = nil
e = assert_raise_with_message ( UncaughtThrowError , / uncaught throw / ) {
2014-11-07 07:08:24 -05:00
catch ( " foo " ) { | obj |
2014-11-15 02:28:08 -05:00
tag = obj . dup
throw tag , :ok
2014-11-09 08:12:14 -05:00
assert ( false , " should not reach here " )
2014-11-07 07:08:24 -05:00
}
2014-11-09 08:12:14 -05:00
assert ( false , " should not reach here " )
2014-11-07 07:08:24 -05:00
}
2014-11-15 02:28:08 -05:00
assert_not_nil ( tag )
assert_same ( tag , e . tag )
assert_equal ( :ok , e . value )
2012-10-19 09:22:03 -04:00
end
2003-09-05 11:15:43 -04:00
2012-10-19 09:22:03 -04:00
def test_catch_throw_in_require
bug7185 = '[ruby-dev:46234]'
* test/csv/test_features.rb, test/logger/test_logger.rb
test/mkmf/test_have_macro.rb, test/net/http/test_http.rb,
test/openssl/test_config.rb, test/psych/test_encoding.rb,
test/psych/test_exception.rb, test/psych/test_psych.rb,
test/psych/test_tainted.rb, test/readline/test_readline.rb,
test/rexml/test_contrib.rb, test/ruby/test_autoload.rb,
test/ruby/test_beginendblock.rb, test/ruby/test_exception.rb,
test/ruby/test_file.rb, test/ruby/test_io.rb,
test/ruby/test_marshal.rb, test/ruby/test_process.rb,
test/ruby/test_require.rb, test/ruby/test_rubyoptions.rb,
test/syslog/test_syslog_logger.rb, test/webrick/test_httpauth.rb,
test/zlib/test_zlib.rb: Use Tempfile.create.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40400 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-20 19:03:52 -04:00
Tempfile . create ( [ " dep " , " .rb " ] ) { | t |
t . puts ( " throw :extdep, 42 " )
t . close
2014-11-07 07:08:24 -05:00
assert_equal ( 42 , assert_throw ( :extdep , bug7185 ) { require t . path } , bug7185 )
* test/csv/test_features.rb, test/logger/test_logger.rb
test/mkmf/test_have_macro.rb, test/net/http/test_http.rb,
test/openssl/test_config.rb, test/psych/test_encoding.rb,
test/psych/test_exception.rb, test/psych/test_psych.rb,
test/psych/test_tainted.rb, test/readline/test_readline.rb,
test/rexml/test_contrib.rb, test/ruby/test_autoload.rb,
test/ruby/test_beginendblock.rb, test/ruby/test_exception.rb,
test/ruby/test_file.rb, test/ruby/test_io.rb,
test/ruby/test_marshal.rb, test/ruby/test_process.rb,
test/ruby/test_require.rb, test/ruby/test_rubyoptions.rb,
test/syslog/test_syslog_logger.rb, test/webrick/test_httpauth.rb,
test/zlib/test_zlib.rb: Use Tempfile.create.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40400 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-20 19:03:52 -04:00
}
2003-09-04 12:18:59 -04:00
end
2003-10-04 14:06:19 -04:00
2016-09-26 02:43:51 -04:00
def test_throw_false
bug12743 = '[ruby-core:77229] [Bug #12743]'
2017-12-12 13:44:49 -05:00
Thread . start {
e = assert_raise_with_message ( UncaughtThrowError , / false / , bug12743 ) {
2016-09-26 02:43:51 -04:00
throw false
2017-12-12 13:44:49 -05:00
}
assert_same ( false , e . tag , bug12743 )
} . join
2016-09-26 02:43:51 -04:00
end
2012-08-06 09:06:37 -04:00
def test_else_no_exception
2003-10-04 14:06:19 -04:00
begin
assert ( true )
rescue
assert ( false )
else
assert ( true )
end
2012-08-06 09:06:37 -04:00
end
2003-10-04 14:06:19 -04:00
2012-08-06 09:06:37 -04:00
def test_else_raised
2003-10-04 14:06:19 -04:00
begin
assert ( true )
raise
assert ( false )
rescue
assert ( true )
else
assert ( false )
end
2012-08-06 09:06:37 -04:00
end
2003-10-04 14:06:19 -04:00
2012-08-06 09:06:37 -04:00
def test_else_nested_no_exception
2003-10-04 14:06:19 -04:00
begin
assert ( true )
begin
assert ( true )
rescue
assert ( false )
else
assert ( true )
end
assert ( true )
rescue
assert ( false )
else
assert ( true )
end
2012-08-06 09:06:37 -04:00
end
2003-10-04 14:06:19 -04:00
2012-08-06 09:06:37 -04:00
def test_else_nested_rescued
2003-10-04 14:06:19 -04:00
begin
assert ( true )
begin
assert ( true )
raise
assert ( false )
rescue
assert ( true )
else
assert ( false )
end
assert ( true )
rescue
assert ( false )
else
assert ( true )
end
2012-08-06 09:06:37 -04:00
end
2003-10-04 14:06:19 -04:00
2012-08-06 09:06:37 -04:00
def test_else_nested_unrescued
2003-10-04 14:06:19 -04:00
begin
assert ( true )
begin
assert ( true )
rescue
assert ( false )
else
assert ( true )
end
assert ( true )
raise
assert ( false )
rescue
assert ( true )
else
assert ( false )
end
2012-08-06 09:06:37 -04:00
end
2003-10-04 14:06:19 -04:00
2012-08-06 09:06:37 -04:00
def test_else_nested_rescued_reraise
2003-10-04 14:06:19 -04:00
begin
assert ( true )
begin
assert ( true )
raise
assert ( false )
rescue
assert ( true )
else
assert ( false )
end
assert ( true )
raise
assert ( false )
rescue
assert ( true )
else
assert ( false )
end
end
2008-05-14 08:52:17 -04:00
def test_raise_with_wrong_number_of_arguments
assert_raise ( TypeError ) { raise nil }
assert_raise ( TypeError ) { raise 1 , 1 }
assert_raise ( ArgumentError ) { raise 1 , 1 , 1 , 1 }
end
2014-01-30 01:16:15 -05:00
def test_type_error_message_encoding
c = eval ( " Module.new do break class C \ u{4032}; self; end; end " )
o = c . new
assert_raise_with_message ( TypeError , / C \ u{4032} / ) do
" " [ o ]
end
c . class_eval { def to_int ; self ; end }
assert_raise_with_message ( TypeError , / C \ u{4032} / ) do
" " [ o ]
end
c . class_eval { def to_a ; self ; end }
assert_raise_with_message ( TypeError , / C \ u{4032} / ) do
[ * o ]
end
2015-09-27 22:40:46 -04:00
obj = eval ( " class C \ u{1f5ff}; self; end " ) . new
assert_raise_with_message ( TypeError , / C \ u{1f5ff} / ) do
Class . new { include obj }
end
2014-01-30 01:16:15 -05:00
end
2008-05-14 08:52:17 -04:00
def test_errat
2008-07-15 11:26:04 -04:00
assert_in_out_err ( [ ] , " p $@ " , %w( nil ) , [ ] )
2008-05-14 08:52:17 -04:00
2008-07-15 11:26:04 -04:00
assert_in_out_err ( [ ] , " $@ = 1 " , [ ] , / \ $! not set \ (ArgumentError \ )$ / )
2008-05-14 08:52:17 -04:00
2008-07-15 11:26:04 -04:00
assert_in_out_err ( [ ] , <<-INPUT, [], /backtrace must be Array of String \(TypeError\)$/)
begin
raise
rescue
$@ = 1
end
INPUT
2008-05-14 08:52:17 -04:00
2008-07-15 11:26:04 -04:00
assert_in_out_err ( [ ] , <<-INPUT, [], /^foo: unhandled exception$/)
begin
raise
rescue
$@ = 'foo'
raise
end
INPUT
2008-05-14 08:52:17 -04:00
2008-07-15 11:26:04 -04:00
assert_in_out_err ( [ ] , <<-INPUT, [], /^foo: unhandled exception\s+from bar\s+from baz$/)
begin
raise
rescue
$@ = %w( foo bar baz )
raise
end
INPUT
2008-05-14 08:52:17 -04:00
end
2009-07-16 05:28:12 -04:00
2010-01-27 09:25:19 -05:00
def test_thread_signal_location
2018-02-13 20:50:59 -05:00
skip
2016-02-23 11:51:43 -05:00
_ , stderr , _ = EnvUtil . invoke_ruby ( %w"--disable-gems -d" , <<-RUBY, false, true)
2010-01-05 05:34:00 -05:00
Thread . start do
2017-12-12 13:43:42 -05:00
Thread . current . report_on_exception = false
2010-01-05 05:34:00 -05:00
begin
Process . kill ( :INT , $$ )
ensure
raise " in ensure "
end
end . join
RUBY
assert_not_match ( / :0 / , stderr , " [ruby-dev:39116] " )
end
2010-01-22 10:03:32 -05:00
def test_errinfo
begin
raise " foo "
assert ( false )
rescue = > e
assert_equal ( e , $! )
1 . times { assert_equal ( e , $! ) }
end
assert_equal ( nil , $! )
end
def test_inspect
assert_equal ( " # <Exception: Exception> " , Exception . new . inspect )
e = Class . new ( Exception )
e . class_eval do
def to_s ; " " ; end
end
assert_equal ( e . inspect , e . new . inspect )
end
2013-10-28 00:11:20 -04:00
def test_to_s
e = StandardError . new ( " foo " )
assert_equal ( " foo " , e . to_s )
def ( s = Object . new ) . to_s
" bar "
end
e = StandardError . new ( s )
assert_equal ( " bar " , e . to_s )
end
2010-01-22 10:03:32 -05:00
def test_set_backtrace
e = Exception . new
e . set_backtrace ( " foo " )
assert_equal ( [ " foo " ] , e . backtrace )
e . set_backtrace ( %w( foo bar baz ) )
assert_equal ( %w( foo bar baz ) , e . backtrace )
assert_raise ( TypeError ) { e . set_backtrace ( 1 ) }
assert_raise ( TypeError ) { e . set_backtrace ( [ 1 ] ) }
end
def test_exit_success_p
begin
exit
rescue SystemExit = > e
end
2011-09-11 23:42:39 -04:00
assert_send ( [ e , :success? ] , " success by default " )
begin
exit ( true )
rescue SystemExit = > e
end
assert_send ( [ e , :success? ] , " true means success " )
begin
exit ( false )
rescue SystemExit = > e
end
assert_not_send ( [ e , :success? ] , " false means failure " )
2010-01-22 10:03:32 -05:00
begin
abort
rescue SystemExit = > e
end
2011-09-11 23:42:39 -04:00
assert_not_send ( [ e , :success? ] , " abort means failure " )
2010-01-22 10:03:32 -05:00
end
2010-05-04 05:51:27 -04:00
2010-10-11 01:15:03 -04:00
def test_errno
assert_equal ( Encoding . find ( " locale " ) , Errno :: EINVAL . new . message . encoding )
end
2011-12-07 04:56:01 -05:00
def test_too_many_args_in_eval
bug5720 = '[ruby-core:41520]'
arg_string = ( 0 ... 140000 ) . to_a . join ( " , " )
assert_raise ( SystemStackError , bug5720 ) { eval " raise( #{ arg_string } ) " }
end
2011-12-08 08:50:10 -05:00
def test_systemexit_new
e0 = SystemExit . new
assert_equal ( 0 , e0 . status )
assert_equal ( " SystemExit " , e0 . message )
ei = SystemExit . new ( 3 )
assert_equal ( 3 , ei . status )
assert_equal ( " SystemExit " , ei . message )
es = SystemExit . new ( " msg " )
assert_equal ( 0 , es . status )
assert_equal ( " msg " , es . message )
eis = SystemExit . new ( 7 , " msg " )
assert_equal ( 7 , eis . status )
assert_equal ( " msg " , eis . message )
2011-12-10 20:48:21 -05:00
bug5728 = '[ruby-dev:44951]'
et = SystemExit . new ( true )
assert_equal ( true , et . success? , bug5728 )
assert_equal ( " SystemExit " , et . message , bug5728 )
ef = SystemExit . new ( false )
assert_equal ( false , ef . success? , bug5728 )
assert_equal ( " SystemExit " , ef . message , bug5728 )
ets = SystemExit . new ( true , " msg " )
assert_equal ( true , ets . success? , bug5728 )
assert_equal ( " msg " , ets . message , bug5728 )
efs = SystemExit . new ( false , " msg " )
assert_equal ( false , efs . success? , bug5728 )
assert_equal ( " msg " , efs . message , bug5728 )
2011-12-08 08:50:10 -05:00
end
2011-12-13 09:50:12 -05:00
def test_exception_in_name_error_to_str
2019-09-02 03:46:28 -04:00
assert_separately ( [ ] , " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " )
2011-12-13 09:50:12 -05:00
bug5575 = '[ruby-core:41612]'
2019-09-02 03:46:28 -04:00
begin ;
2011-12-13 09:50:12 -05:00
begin
BasicObject . new . inspect
rescue
2019-09-02 03:46:28 -04:00
assert_nothing_raised ( NameError , bug5575 ) { $! . inspect }
2011-12-13 09:50:12 -05:00
end
2019-09-02 03:46:28 -04:00
end ;
2011-12-13 09:50:12 -05:00
end
2012-01-13 22:00:24 -05:00
def test_equal
bug5865 = '[ruby-core:41979]'
assert_equal ( RuntimeError . new ( " a " ) , RuntimeError . new ( " a " ) , bug5865 )
assert_not_equal ( RuntimeError . new ( " a " ) , StandardError . new ( " a " ) , bug5865 )
end
2012-01-14 04:36:18 -05:00
def test_exception_in_exception_equal
2019-09-02 03:46:28 -04:00
assert_separately ( [ ] , " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " )
2012-01-14 04:36:18 -05:00
bug5865 = '[ruby-core:41979]'
2019-09-02 03:46:28 -04:00
begin ;
2012-01-14 04:36:18 -05:00
o = Object . new
def o . exception ( arg )
end
* test/csv/test_features.rb, test/logger/test_logger.rb
test/mkmf/test_have_macro.rb, test/net/http/test_http.rb,
test/openssl/test_config.rb, test/psych/test_encoding.rb,
test/psych/test_exception.rb, test/psych/test_psych.rb,
test/psych/test_tainted.rb, test/readline/test_readline.rb,
test/rexml/test_contrib.rb, test/ruby/test_autoload.rb,
test/ruby/test_beginendblock.rb, test/ruby/test_exception.rb,
test/ruby/test_file.rb, test/ruby/test_io.rb,
test/ruby/test_marshal.rb, test/ruby/test_process.rb,
test/ruby/test_require.rb, test/ruby/test_rubyoptions.rb,
test/syslog/test_syslog_logger.rb, test/webrick/test_httpauth.rb,
test/zlib/test_zlib.rb: Use Tempfile.create.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40400 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-20 19:03:52 -04:00
assert_nothing_raised ( ArgumentError , bug5865 ) do
2019-09-02 03:46:28 -04:00
RuntimeError . new ( " a " ) == o
* test/csv/test_features.rb, test/logger/test_logger.rb
test/mkmf/test_have_macro.rb, test/net/http/test_http.rb,
test/openssl/test_config.rb, test/psych/test_encoding.rb,
test/psych/test_exception.rb, test/psych/test_psych.rb,
test/psych/test_tainted.rb, test/readline/test_readline.rb,
test/rexml/test_contrib.rb, test/ruby/test_autoload.rb,
test/ruby/test_beginendblock.rb, test/ruby/test_exception.rb,
test/ruby/test_file.rb, test/ruby/test_io.rb,
test/ruby/test_marshal.rb, test/ruby/test_process.rb,
test/ruby/test_require.rb, test/ruby/test_rubyoptions.rb,
test/syslog/test_syslog_logger.rb, test/webrick/test_httpauth.rb,
test/zlib/test_zlib.rb: Use Tempfile.create.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40400 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-20 19:03:52 -04:00
end
2019-09-02 03:46:28 -04:00
end ;
2012-01-14 04:36:18 -05:00
end
2012-08-08 03:52:19 -04:00
2019-09-02 03:47:12 -04:00
def test_backtrace_by_exception
begin
line = __LINE__ ; raise " foo "
rescue = > e
end
e2 = e . exception ( " bar " )
assert_not_equal ( e . message , e2 . message )
assert_equal ( e . backtrace , e2 . backtrace )
loc = e2 . backtrace_locations [ 0 ]
assert_equal ( [ __FILE__ , line ] , [ loc . path , loc . lineno ] )
end
2012-08-08 03:52:19 -04:00
Bug4438 = '[ruby-core:35364]'
def test_rescue_single_argument
assert_raise ( TypeError , Bug4438 ) do
begin
raise
rescue 1
end
end
end
def test_rescue_splat_argument
assert_raise ( TypeError , Bug4438 ) do
begin
raise
rescue * Array ( 1 )
end
end
end
2012-10-02 13:25:10 -04:00
2014-03-04 08:55:24 -05:00
def m
m ( & - > { return 0 } )
42
2013-08-06 04:33:05 -04:00
end
def test_stackoverflow
2014-06-28 00:58:25 -04:00
feature6216 = '[ruby-core:43794] [Feature #6216]'
e = assert_raise ( SystemStackError , feature6216 ) { m }
level = e . backtrace . size
assert_operator ( level , :> , 10 , feature6216 )
2014-06-28 00:58:53 -04:00
feature6216 = '[ruby-core:63377] [Feature #6216]'
e = assert_raise ( SystemStackError , feature6216 ) { raise e }
assert_equal ( level , e . backtrace . size , feature6216 )
2013-08-06 04:33:05 -04:00
end
2013-11-10 08:16:33 -05:00
2013-11-18 08:47:56 -05:00
def test_machine_stackoverflow
bug9109 = '[ruby-dev:47804] [Bug #9109]'
2014-05-30 11:06:07 -04:00
assert_separately ( %w[ --disable-gem ] , <<-SRC)
2013-11-20 04:01:42 -05:00
assert_raise ( SystemStackError , #{bug9109.dump}) {
h = { a : - > { h [ :a ] . call } }
h [ :a ] . call
}
2013-11-18 08:47:56 -05:00
SRC
2013-12-10 09:02:16 -05:00
rescue SystemStackError
2013-11-18 08:47:56 -05:00
end
2014-01-27 07:53:48 -05:00
def test_machine_stackoverflow_by_define_method
bug9454 = '[ruby-core:60113] [Bug #9454]'
2014-05-30 11:06:07 -04:00
assert_separately ( %w[ --disable-gem ] , <<-SRC)
2014-01-27 07:53:48 -05:00
assert_raise ( SystemStackError , #{bug9454.dump}) {
define_method ( :foo ) { self . foo }
self . foo
}
SRC
2014-01-29 21:45:40 -05:00
rescue SystemStackError
2014-01-27 07:53:48 -05:00
end
2017-05-10 02:38:30 -04:00
def test_machine_stackoverflow_by_trace
assert_normal_exit ( " #{ << - " begin; " } \n #{ << ~ " end; " } " , timeout : 60 )
begin ;
require 'timeout'
require 'tracer'
class HogeError < StandardError
def to_s
message . upcase # disable tailcall optimization
end
end
Tracer . stdout = open ( IO :: NULL , " w " )
begin
Timeout . timeout ( 5 ) do
Tracer . on
HogeError . new . to_s
end
rescue Timeout :: Error
# ok. there are no SEGV or critical error
rescue SystemStackError = > e
# ok.
end
end ;
end
2013-11-10 08:16:33 -05:00
def test_cause
msg = " [Feature # 8257] "
2013-11-15 09:08:49 -05:00
cause = nil
2013-11-10 08:16:33 -05:00
e = assert_raise ( StandardError ) {
begin
raise msg
rescue = > e
2013-11-15 09:08:49 -05:00
cause = e . cause
2013-11-10 08:16:33 -05:00
raise StandardError
end
}
2013-11-15 09:08:49 -05:00
assert_nil ( cause , msg )
2013-11-10 08:16:33 -05:00
cause = e . cause
assert_instance_of ( RuntimeError , cause , msg )
assert_equal ( msg , cause . message , msg )
end
2013-11-15 09:08:49 -05:00
def test_cause_reraised
msg = " [Feature # 8257] "
e = assert_raise ( RuntimeError ) {
begin
raise msg
rescue = > e
raise e
end
}
assert_not_same ( e , e . cause , " #{ msg } : should not be recursive " )
end
2013-12-31 09:49:16 -05:00
2016-02-14 02:19:23 -05:00
def test_cause_raised_in_rescue
2016-02-19 02:48:02 -05:00
a = nil
2016-02-14 02:19:23 -05:00
e = assert_raise_with_message ( RuntimeError , 'b' ) {
begin
raise 'a'
rescue = > a
begin
raise 'b'
rescue = > b
2016-02-19 02:48:02 -05:00
assert_same ( a , b . cause )
2016-02-14 02:19:23 -05:00
begin
raise 'c'
rescue
raise b
end
end
end
}
2016-02-19 02:48:02 -05:00
assert_same ( a , e . cause , 'cause should not be overwritten by reraise' )
2016-02-14 02:19:23 -05:00
end
def test_cause_at_raised
2016-02-19 02:48:02 -05:00
a = nil
2016-02-14 02:19:23 -05:00
e = assert_raise_with_message ( RuntimeError , 'b' ) {
begin
raise 'a'
rescue = > a
b = RuntimeError . new ( 'b' )
2016-02-19 02:48:02 -05:00
assert_nil ( b . cause )
2016-02-14 02:19:23 -05:00
begin
raise 'c'
rescue
raise b
end
end
}
assert_equal ( 'c' , e . cause . message , 'cause should be the exception at raised' )
2016-02-19 02:48:02 -05:00
assert_same ( a , e . cause . cause )
2016-02-14 02:19:23 -05:00
end
2018-11-05 18:06:50 -05:00
def test_cause_at_end
2018-12-22 02:14:12 -05:00
errs = [
/ -: unexpected return \ n / ,
/ .*undefined local variable or method `n'.* \ n / ,
]
assert_in_out_err ( [ ] , << - 'end;' , [ ] , errs )
2018-11-05 18:06:50 -05:00
END { n } ; END { return }
end ;
end
2013-12-31 09:49:16 -05:00
def test_raise_with_cause
msg = " [Feature # 8257] "
cause = ArgumentError . new ( " foobar " )
e = assert_raise ( RuntimeError ) { raise msg , cause : cause }
assert_same ( cause , e . cause )
end
def test_cause_with_no_arguments
cause = ArgumentError . new ( " foobar " )
assert_raise_with_message ( ArgumentError , / with no arguments / ) do
raise cause : cause
end
end
2014-06-16 23:37:47 -04:00
2016-02-14 02:19:23 -05:00
def test_raise_with_cause_in_rescue
e = assert_raise_with_message ( RuntimeError , 'b' ) {
begin
raise 'a'
rescue = > a
begin
raise 'b'
rescue = > b
2016-02-19 02:48:02 -05:00
assert_same ( a , b . cause )
2016-02-14 02:19:23 -05:00
begin
raise 'c'
rescue
raise b , cause : ArgumentError . new ( 'd' )
end
end
end
}
assert_equal ( 'd' , e . cause . message , 'cause option should be honored always' )
2016-02-19 02:48:02 -05:00
assert_nil ( e . cause . cause )
2016-02-14 02:19:23 -05:00
end
2016-09-09 04:59:48 -04:00
def test_cause_thread_no_cause
bug12741 = '[ruby-core:77222] [Bug #12741]'
x = Thread . current
a = false
y = Thread . start do
Thread . pass until a
x . raise " stop "
end
begin
raise bug12741
rescue
e = assert_raise_with_message ( RuntimeError , " stop " ) do
a = true
sleep 1
end
end
assert_nil ( e . cause )
2017-04-13 12:19:46 -04:00
ensure
y . join
2016-09-09 04:59:48 -04:00
end
def test_cause_thread_with_cause
bug12741 = '[ruby-core:77222] [Bug #12741]'
x = Thread . current
2016-09-13 05:39:08 -04:00
q = Queue . new
2016-09-09 04:59:48 -04:00
y = Thread . start do
2016-09-13 05:39:08 -04:00
q . pop
2016-09-09 04:59:48 -04:00
begin
raise " caller's cause "
rescue
x . raise " stop "
end
end
begin
raise bug12741
rescue
e = assert_raise_with_message ( RuntimeError , " stop " ) do
2016-09-13 05:39:08 -04:00
q . push ( true )
2016-09-09 04:59:48 -04:00
sleep 1
end
2016-09-13 05:39:08 -04:00
ensure
y . join
2016-09-09 04:59:48 -04:00
end
assert_equal ( " caller's cause " , e . cause . message )
end
2014-06-16 23:37:47 -04:00
def test_unknown_option
bug = '[ruby-core:63203] [Feature #8257] should pass unknown options'
exc = Class . new ( RuntimeError ) do
attr_reader :arg
def initialize ( msg = nil )
@arg = msg
super ( msg )
end
end
e = assert_raise ( exc , bug ) { raise exc , " foo " = > " bar " , foo : " bar " }
assert_equal ( { " foo " = > " bar " , foo : " bar " } , e . arg , bug )
2018-12-23 00:49:43 -05:00
e = assert_raise ( exc , bug ) { raise exc , " foo " = > " bar " , foo : " bar " , cause : RuntimeError . new ( " zzz " ) }
2014-06-16 23:37:47 -04:00
assert_equal ( { " foo " = > " bar " , foo : " bar " } , e . arg , bug )
e = assert_raise ( exc , bug ) { raise exc , { } }
assert_equal ( { } , e . arg , bug )
end
2014-06-25 13:45:10 -04:00
2016-12-21 06:12:39 -05:00
def test_circular_cause
bug13043 = '[ruby-core:78688] [Bug #13043]'
begin
begin
raise " error 1 "
ensure
orig_error = $!
begin
raise " error 2 "
rescue = > err
raise orig_error
end
end
rescue = > x
end
assert_equal ( orig_error , x )
assert_equal ( orig_error , err . cause )
assert_nil ( orig_error . cause , bug13043 )
end
2017-04-16 22:41:00 -04:00
def test_cause_with_frozen_exception
exc = ArgumentError . new ( " foo " ) . freeze
assert_raise_with_message ( ArgumentError , exc . message ) {
raise exc , cause : RuntimeError . new ( " bar " )
}
end
2014-06-25 13:45:10 -04:00
def test_anonymous_message
assert_in_out_err ( [ ] , " raise Class.new(RuntimeError), 'foo' " , [ ] , / foo \ n / )
end
2014-11-18 10:11:03 -05:00
2014-11-28 17:32:36 -05:00
def test_output_string_encoding
# "\x82\xa0" in cp932 is "\u3042" (Japanese hiragana 'a')
# change $stderr to force calling rb_io_write() instead of fwrite()
2014-11-29 01:00:19 -05:00
assert_in_out_err ( [ " -Eutf-8:cp932 " ] , ' # coding: cp932
2014-11-28 18:52:34 -05:00
$stderr = $stdout ; raise " \x82 \xa0 " ' ) do | outs , errs , status |
2014-11-28 17:32:36 -05:00
assert_equal 1 , outs . size
assert_equal 0 , errs . size
err = outs . first . force_encoding ( 'utf-8' )
assert err . valid_encoding? , 'must be valid encoding'
2016-02-19 02:48:02 -05:00
assert_match %r/\u3042/ , err
2014-11-28 17:32:36 -05:00
end
end
2015-01-09 23:02:08 -05:00
def test_multibyte_and_newline
bug10727 = '[ruby-core:67473] [Bug #10727]'
assert_in_out_err ( [ ] , << - 'end;' , [ ] , / \ u{306b 307b 3093 3054} \ (E \ ) \ n \ u{6539 884c} / , bug10727 , encoding : " UTF-8 " )
class E < StandardError
def initialize
super ( " \ u{306b 307b 3093 3054} \n \ u{6539 884c} " )
end
end
raise E
end ;
end
2015-07-29 02:25:21 -04:00
2019-01-08 04:08:31 -05:00
def assert_null_char ( src , * args , ** opts )
begin
eval ( src )
rescue = > e
end
assert_not_nil ( e )
assert_include ( e . message , " \0 " )
assert_in_out_err ( [ ] , src , [ ] , [ ] , * args , ** opts ) do | _ , err , |
err . each do | e |
assert_not_include ( e , " \0 " )
end
end
e
end
def test_control_in_message
bug7574 = '[ruby-dev:46749]'
assert_null_char ( " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " , bug7574 )
begin ;
Object . const_defined? ( " String \0 " )
end ;
assert_null_char ( " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " , bug7574 )
begin ;
Object . const_get ( " String \0 " )
end ;
end
def test_encoding_in_message
name = " \ u{e9}t \ u{e9} "
e = EnvUtil . with_default_external ( " US-ASCII " ) do
assert_raise ( NameError ) do
Object . const_get ( name )
end
end
assert_include ( e . message , name )
end
2015-07-29 02:25:21 -04:00
def test_method_missing_reason_clear
bug10969 = '[ruby-core:68515] [Bug #10969]'
a = Class . new { def method_missing ( * ) super end } . new
assert_raise ( NameError ) { a . instance_eval ( " foo " ) }
assert_raise ( NoMethodError , bug10969 ) { a . public_send ( " bar " , true ) }
end
2015-10-30 21:22:51 -04:00
def test_message_of_name_error
2015-10-30 23:18:25 -04:00
assert_raise_with_message ( NameError , / \ Aundefined method `foo' for module ` # <Module:.*>'$ / ) do
2015-10-30 21:22:51 -04:00
Module . new do
module_function :foo
end
end
end
2016-09-27 05:19:14 -04:00
2017-04-25 04:17:24 -04:00
def capture_warning_warn
2016-09-27 05:19:14 -04:00
verbose = $VERBOSE
2019-12-17 03:16:12 -05:00
deprecated = Warning [ :deprecated ]
2017-04-25 04:17:24 -04:00
warning = [ ]
2016-09-27 05:19:14 -04:00
:: Warning . class_eval do
alias_method :warn2 , :warn
remove_method :warn
define_method ( :warn ) do | str |
2017-04-25 04:17:24 -04:00
warning << str
2016-09-27 05:19:14 -04:00
end
end
$VERBOSE = true
2019-12-17 03:16:12 -05:00
Warning [ :deprecated ] = true
2017-04-25 04:17:24 -04:00
yield
2016-09-27 05:19:14 -04:00
2017-04-25 04:17:24 -04:00
return warning
2016-09-27 05:19:14 -04:00
ensure
$VERBOSE = verbose
2019-12-17 03:16:12 -05:00
Warning [ :deprecated ] = deprecated
2016-09-27 05:19:14 -04:00
:: Warning . class_eval do
remove_method :warn
alias_method :warn , :warn2
remove_method :warn2
end
end
2016-09-27 11:21:01 -04:00
2017-04-25 04:17:24 -04:00
def test_warning_warn
warning = capture_warning_warn { @a }
assert_match ( / instance variable @a not initialized / , warning [ 0 ] )
2017-04-26 16:13:07 -04:00
assert_equal ( [ " a \n z \n " ] , capture_warning_warn { warn " a \n " , " z " } )
assert_equal ( [ ] , capture_warning_warn { warn } )
assert_equal ( [ " \n " ] , capture_warning_warn { warn " " } )
2017-04-25 04:17:24 -04:00
end
2017-12-12 06:56:25 -05:00
def test_kernel_warn_uplevel
warning = capture_warning_warn { warn ( " test warning " , uplevel : 0 ) }
assert_equal ( " #{ __FILE__ } : #{ __LINE__ - 1 } : warning: test warning \n " , warning [ 0 ] )
2017-12-31 08:12:47 -05:00
def ( obj = Object . new ) . w ( n ) warn ( " test warning " , uplevel : n ) end
warning = capture_warning_warn { obj . w ( 0 ) }
assert_equal ( " #{ __FILE__ } : #{ __LINE__ - 2 } : warning: test warning \n " , warning [ 0 ] )
warning = capture_warning_warn { obj . w ( 1 ) }
assert_equal ( " #{ __FILE__ } : #{ __LINE__ - 1 } : warning: test warning \n " , warning [ 0 ] )
2017-12-31 08:01:55 -05:00
assert_raise ( ArgumentError ) { warn ( " test warning " , uplevel : - 1 ) }
2018-04-02 07:39:10 -04:00
assert_in_out_err ( [ " -e " , " warn 'ok', uplevel: 1 " ] , '' , [ ] , / warning: / )
Make rb_scan_args handle keywords more similar to Ruby methods (#2460)
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
2019-09-25 14:18:49 -04:00
warning = capture_warning_warn { warn ( " test warning " , { uplevel : 0 } ) }
2019-12-23 02:34:16 -05:00
assert_equal ( " #{ __FILE__ } : #{ __LINE__ - 1 } : warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call \n " , warning [ 0 ] )
2019-12-20 05:41:15 -05:00
assert_match ( / warning: The called method (?:`.*' )?is defined here|warning: test warning / , warning [ 1 ] )
Make rb_scan_args handle keywords more similar to Ruby methods (#2460)
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
2019-09-25 14:18:49 -04:00
warning = capture_warning_warn { warn ( " test warning " , ** { uplevel : 0 } ) }
assert_equal ( " #{ __FILE__ } : #{ __LINE__ - 1 } : warning: test warning \n " , warning [ 0 ] )
warning = capture_warning_warn { warn ( " test warning " , { uplevel : 0 } , ** { } ) }
assert_equal ( " test warning \n {:uplevel=>0} \n " , warning [ 0 ] )
assert_raise ( ArgumentError ) { warn ( " test warning " , foo : 1 ) }
2017-12-12 06:56:25 -05:00
end
2016-09-27 11:21:01 -04:00
def test_warning_warn_invalid_argument
assert_raise ( TypeError ) do
:: Warning . warn nil
end
assert_raise ( TypeError ) do
:: Warning . warn 1
end
assert_raise ( Encoding :: CompatibilityError ) do
:: Warning . warn " \x00 a \x00 b \x00 c " . force_encoding ( " utf-16be " )
end
end
2016-11-13 00:25:53 -05:00
2017-04-25 04:17:24 -04:00
def test_warning_warn_circular_require_backtrace
warning = nil
path = nil
Tempfile . create ( %w[ circular .rb ] ) do | t |
2017-09-21 03:29:20 -04:00
path = File . realpath ( t . path )
2017-04-25 04:17:24 -04:00
basename = File . basename ( path )
t . puts " require ' #{ basename } ' "
t . close
$LOAD_PATH . push ( File . dirname ( t ) )
warning = capture_warning_warn { require basename }
ensure
$LOAD_PATH . pop
$LOADED_FEATURES . delete ( t )
end
2017-04-27 08:07:43 -04:00
assert_equal ( 1 , warning . size )
2017-04-25 04:17:24 -04:00
assert_match ( / circular require / , warning . first )
2017-04-27 08:07:43 -04:00
assert_match ( / ^ \ tfrom #{ Regexp . escape ( path ) } :1: / , warning . first )
2017-04-25 04:17:24 -04:00
end
2017-10-12 21:34:52 -04:00
def test_warning_warn_super
assert_in_out_err ( %[ -W0 ] , " #{ << ~ " { # " } \n #{ << ~ '};' } " , [ ] , / instance variable @a not initialized / )
{ #
module Warning
def warn ( message )
super
end
end
$VERBOSE = true
@a
} ;
end
2019-11-12 04:34:49 -05:00
def test_warning_category
assert_raise ( TypeError ) { Warning [ nil ] }
assert_raise ( ArgumentError ) { Warning [ :XXXX ] }
assert_include ( [ true , false ] , Warning [ :deprecated ] )
2019-12-20 09:48:15 -05:00
assert_include ( [ true , false ] , Warning [ :experimental ] )
2019-11-12 04:34:49 -05:00
end
2016-11-13 00:25:53 -05:00
def test_undefined_backtrace
assert_separately ( [ ] , " #{ << - " begin; " } \n #{ << - " end; " } " )
begin ;
class Exception
undef backtrace
end
assert_raise ( RuntimeError ) {
raise RuntimeError , " hello "
}
end ;
end
2016-11-13 00:25:54 -05:00
def test_redefined_backtrace
assert_separately ( [ ] , " #{ << - " begin; " } \n #{ << - " end; " } " )
begin ;
$exc = nil
class Exception
undef backtrace
def backtrace
$exc = self
end
end
e = assert_raise ( RuntimeError ) {
raise RuntimeError , " hello "
}
assert_same ( e , $exc )
end ;
end
2018-03-06 00:15:57 -05:00
def test_blocking_backtrace
assert_separately ( [ ] , " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " )
begin ;
class Bug < RuntimeError
def backtrace
IO . readlines ( IO :: NULL )
end
end
bug = Bug . new '[ruby-core:85939] [Bug #14577]'
n = 10000
i = 0
n . times do
begin
raise bug
rescue Bug
i += 1
end
end
assert_equal ( n , i )
end ;
end
2016-11-13 00:25:54 -05:00
def test_wrong_backtrace
assert_separately ( [ ] , " #{ << - " begin; " } \n #{ << - " end; " } " )
begin ;
class Exception
undef backtrace
def backtrace ( a )
end
end
assert_raise ( RuntimeError ) {
raise RuntimeError , " hello "
}
end ;
2018-05-14 04:33:14 -04:00
error_class = Class . new ( StandardError ) do
def backtrace ; :backtrace ; end
end
begin
raise error_class
rescue error_class = > e
assert_raise ( TypeError ) { $@ }
assert_raise ( TypeError ) { e . full_message }
end
2016-11-13 00:25:54 -05:00
end
2017-12-12 06:47:16 -05:00
2017-12-26 04:05:28 -05:00
def test_backtrace_in_eval
bug = '[ruby-core:84434] [Bug #14229]'
assert_in_out_err ( [ '-e' , 'eval("raise")' ] , " " , [ ] , / ^ \ (eval \ ):1: / , bug )
end
2017-12-12 06:47:16 -05:00
def test_full_message
2018-01-07 00:38:37 -05:00
message = RuntimeError . new ( " testerror " ) . full_message
assert_operator ( message , :end_with? , " \n " )
2017-12-12 06:47:16 -05:00
test_method = " def foo; raise 'testerror'; end "
out1 , err1 , status1 = EnvUtil . invoke_ruby ( [ '-e' , " #{ test_method } ; begin; foo; rescue => e; puts e.full_message; end " ] , '' , true , true )
2018-01-06 23:23:55 -05:00
assert_predicate ( status1 , :success? )
assert_empty ( err1 , " expected nothing wrote to $stdout by # full_message " )
2017-12-12 06:47:16 -05:00
_ , err2 , status1 = EnvUtil . invoke_ruby ( [ '-e' , " #{ test_method } ; begin; foo; end " ] , '' , true , true )
assert_equal ( err2 , out1 )
2018-03-12 09:04:28 -04:00
2018-03-12 23:40:10 -04:00
e = RuntimeError . new ( " a \n " )
message = assert_nothing_raised ( ArgumentError , proc { e . pretty_inspect } ) do
e . full_message
2018-03-12 09:04:28 -04:00
end
2018-03-12 23:40:10 -04:00
assert_operator ( message , :end_with? , " \n " )
message = message . gsub ( / \ e \ [[ \ d;]*m / , '' )
assert_not_operator ( message , :end_with? , " \n \n " )
2018-03-12 23:48:56 -04:00
e = RuntimeError . new ( " a \n \n b \n \n c " )
message = assert_nothing_raised ( ArgumentError , proc { e . pretty_inspect } ) do
e . full_message
end
assert_all? ( message . lines ) do | m |
/ \ e \ [ \ d[; \ d]*m[^ \ e]* \ n / !~ m
end
2018-03-22 04:26:23 -04:00
e = RuntimeError . new ( " testerror " )
message = e . full_message ( highlight : false )
assert_not_match ( / \ e / , message )
bt = [ " test:100 " , " test:99 " , " test:98 " , " test:1 " ]
e = assert_raise ( RuntimeError ) { raise RuntimeError , " testerror " , bt }
2018-03-22 12:05:04 -04:00
bottom = " test:100: testerror (RuntimeError) \n "
top = " test:1 \n "
remark = " Traceback (most recent call last): "
2018-03-22 04:26:23 -04:00
message = e . full_message ( highlight : false , order : :top )
assert_not_match ( / \ e / , message )
assert_operator ( message . count ( " \n " ) , :> , 2 )
2018-03-22 12:05:04 -04:00
assert_operator ( message , :start_with? , bottom )
assert_operator ( message , :end_with? , top )
2018-03-22 04:26:23 -04:00
message = e . full_message ( highlight : false , order : :bottom )
assert_not_match ( / \ e / , message )
assert_operator ( message . count ( " \n " ) , :> , 2 )
2018-03-22 12:05:04 -04:00
assert_operator ( message , :start_with? , remark )
assert_operator ( message , :end_with? , bottom )
2018-03-22 04:26:23 -04:00
2018-07-16 21:26:22 -04:00
assert_raise_with_message ( ArgumentError , / :top or :bottom / ) {
e . full_message ( highlight : false , order : :middle )
}
2018-03-22 04:26:23 -04:00
message = e . full_message ( highlight : true )
assert_match ( / \ e / , message )
2019-07-15 06:31:48 -04:00
assert_not_match ( / ( \ e \ [1)m \ 1 / , message )
e2 = assert_raise ( RuntimeError ) { raise RuntimeError , " " , bt }
assert_not_match ( / ( \ e \ [1)m \ 1 / , e2 . full_message ( highlight : true ) )
2018-03-22 12:05:04 -04:00
message = e . full_message
if Exception . to_tty?
assert_match ( / \ e / , message )
message = message . gsub ( / \ e \ [[ \ d;]*m / , '' )
assert_operator ( message , :start_with? , remark )
assert_operator ( message , :end_with? , bottom )
else
assert_not_match ( / \ e / , message )
assert_operator ( message , :start_with? , bottom )
assert_operator ( message , :end_with? , top )
end
2017-12-12 06:47:16 -05:00
end
2018-04-11 04:03:43 -04:00
def test_exception_in_message
code = " #{ << ~ " begin; " } \n #{ << ~ 'end;' } "
begin ;
class Bug14566 < StandardError
def message ; raise self . class ; end
end
raise Bug14566
end ;
2018-06-27 14:27:58 -04:00
assert_in_out_err ( [ ] , code , [ ] , / Bug14566 / , success : false , timeout : 2 )
2018-04-11 04:03:43 -04:00
end
2018-04-11 23:48:48 -04:00
2018-12-21 06:44:21 -05:00
def test_non_exception_cause
2018-12-23 00:49:43 -05:00
assert_raise_with_message ( TypeError , / exception / ) do
2018-12-21 06:44:21 -05:00
raise " foo " , cause : 1
end ;
end
2018-12-22 02:14:14 -05:00
def test_circular_cause_handle
2018-12-23 06:11:36 -05:00
assert_raise_with_message ( ArgumentError , / circular cause / ) do
2018-12-22 02:14:14 -05:00
begin
raise " error 1 "
rescue = > e1
2018-12-23 06:11:36 -05:00
raise " error 2 " rescue raise e1 , cause : $!
2018-12-22 02:14:14 -05:00
end
end ;
end
2018-04-11 23:48:48 -04:00
def test_super_in_method_missing
assert_separately ( [ ] , " #{ << ~ " begin; " } \n #{ << ~ 'end;' } " )
begin ;
2018-12-06 18:06:13 -05:00
$VERBOSE = nil
2018-04-11 23:48:48 -04:00
class Object
def method_missing ( name , * args , & block )
super
end
end
bug14670 = '[ruby-dev:50522] [Bug #14670]'
assert_raise_with_message ( NoMethodError , / `foo' / , bug14670 ) do
Object . new . foo
end
end ;
end
2003-09-04 12:18:59 -04:00
end