summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb9
-rw-r--r--test/-ext-/float/test_nextafter.rb2
-rw-r--r--test/-ext-/gvl/test_ubf_async_safe.rb2
-rw-r--r--test/-ext-/iseq_load/test_iseq_load.rb6
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb7
-rw-r--r--test/-ext-/string/test_capacity.rb2
-rw-r--r--test/-ext-/string/test_fstring.rb14
-rw-r--r--test/-ext-/string/test_set_len.rb2
-rw-r--r--test/bigdecimal/helper.rb11
-rw-r--r--test/bigdecimal/test_bigdecimal.rb183
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb15
-rw-r--r--test/cgi/test_cgi_cookie.rb5
-rw-r--r--test/cgi/test_cgi_util.rb17
-rw-r--r--test/csv/parse/test_convert.rb2
-rw-r--r--test/csv/parse/test_general.rb4
-rw-r--r--test/csv/parse/test_strip.rb29
-rw-r--r--test/csv/test_table.rb2
-rw-r--r--test/date/test_date_parse.rb71
-rw-r--r--test/date/test_date_strftime.rb2
-rw-r--r--test/did_you_mean/core_ext/test_name_error_extension.rb7
-rw-r--r--test/did_you_mean/helper.rb4
-rw-r--r--test/drb/drbtest.rb2
-rw-r--r--test/dtrace/helper.rb2
-rw-r--r--test/error_highlight/test_error_highlight.rb30
-rw-r--r--test/fiber/scheduler.rb90
-rw-r--r--test/fiber/test_enumerator.rb4
-rw-r--r--test/fiber/test_io.rb42
-rw-r--r--test/fiber/test_io_buffer.rb125
-rw-r--r--test/fiber/test_process.rb15
-rw-r--r--test/fiber/test_ractor.rb2
-rw-r--r--test/fiber/test_scheduler.rb1
-rw-r--r--test/io/console/test_io_console.rb18
-rw-r--r--test/io/nonblock/test_flush.rb2
-rw-r--r--test/io/wait/test_io_wait_uncommon.rb4
-rw-r--r--test/io/wait/test_ractor.rb6
-rw-r--r--test/irb/test_cmd.rb7
-rw-r--r--test/irb/test_context.rb6
-rw-r--r--test/irb/test_init.rb1
-rw-r--r--test/irb/test_ruby_lex.rb25
-rw-r--r--test/lib/jit_support.rb19
-rw-r--r--test/logger/test_formatter.rb35
-rw-r--r--test/logger/test_logdevice.rb3
-rw-r--r--test/logger/test_logger.rb6
-rw-r--r--test/net/http/test_http.rb24
-rw-r--r--test/net/http/test_http_request.rb5
-rw-r--r--test/net/http/test_httpresponse.rb2
-rw-r--r--test/net/http/test_https.rb6
-rw-r--r--test/net/http/test_https_proxy.rb2
-rw-r--r--test/openssl/test_asn1.rb2
-rw-r--r--test/openssl/test_bn.rb25
-rw-r--r--test/openssl/test_cipher.rb13
-rw-r--r--test/openssl/test_hmac.rb1
-rw-r--r--test/openssl/test_pkey_dh.rb56
-rw-r--r--test/openssl/test_pkey_dsa.rb8
-rw-r--r--test/openssl/test_pkey_ec.rb79
-rw-r--r--test/openssl/test_pkey_rsa.rb91
-rw-r--r--test/openssl/test_ssl.rb151
-rw-r--r--test/optparse/test_did_you_mean.rb12
-rw-r--r--test/ostruct/test_ostruct.rb1
-rw-r--r--test/pathname/test_pathname.rb12
-rw-r--r--test/psych/test_numeric.rb11
-rw-r--r--test/psych/test_scalar_scanner.rb25
-rw-r--r--test/rdoc/test_rdoc_class_module.rb8
-rw-r--r--test/rdoc/test_rdoc_context.rb2
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb9
-rw-r--r--test/rdoc/test_rdoc_extend.rb8
-rw-r--r--test/rdoc/test_rdoc_include.rb11
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb4
-rw-r--r--test/rdoc/test_rdoc_store.rb6
-rw-r--r--test/rdoc/test_rdoc_top_level.rb4
-rw-r--r--test/rdoc/xref_data.rb17
-rw-r--r--test/rdoc/xref_test_case.rb8
-rw-r--r--test/readline/test_readline.rb42
-rw-r--r--test/reline/helper.rb13
-rw-r--r--test/reline/test_config.rb18
-rw-r--r--test/reline/test_key_actor_emacs.rb60
-rw-r--r--test/reline/test_key_actor_vi.rb28
-rw-r--r--test/reline/test_reline.rb92
-rw-r--r--test/reline/test_terminfo.rb37
-rw-r--r--test/reline/test_within_pipe.rb2
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl34
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb2
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb165
-rw-r--r--test/resolv/test_addr.rb4
-rw-r--r--test/resolv/test_dns.rb8
-rw-r--r--test/rinda/test_rinda.rb24
-rw-r--r--test/ripper/test_scanner_events.rb35
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb2
-rw-r--r--test/ruby/enc/test_emoji_breaks.rb2
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb2
-rw-r--r--test/ruby/enc/test_regex_casefold.rb2
-rw-r--r--test/ruby/test_alias.rb29
-rw-r--r--test/ruby/test_argf.rb4
-rw-r--r--test/ruby/test_array.rb2
-rw-r--r--test/ruby/test_assignment.rb108
-rw-r--r--test/ruby/test_ast.rb101
-rw-r--r--test/ruby/test_bignum.rb4
-rw-r--r--test/ruby/test_class.rb45
-rw-r--r--test/ruby/test_complex2.rb2
-rw-r--r--test/ruby/test_complexrational.rb4
-rw-r--r--test/ruby/test_default_gems.rb2
-rw-r--r--test/ruby/test_dir.rb14
-rw-r--r--test/ruby/test_enum.rb19
-rw-r--r--test/ruby/test_env.rb888
-rw-r--r--test/ruby/test_eval.rb70
-rw-r--r--test/ruby/test_exception.rb30
-rw-r--r--test/ruby/test_fiber.rb17
-rw-r--r--test/ruby/test_file.rb10
-rw-r--r--test/ruby/test_file_exhaustive.rb36
-rw-r--r--test/ruby/test_gc.rb78
-rw-r--r--test/ruby/test_gc_compact.rb12
-rw-r--r--test/ruby/test_hash.rb10
-rw-r--r--test/ruby/test_integer.rb25
-rw-r--r--test/ruby/test_io.rb91
-rw-r--r--test/ruby/test_io_buffer.rb330
-rw-r--r--test/ruby/test_iseq.rb147
-rw-r--r--test/ruby/test_jit.rb32
-rw-r--r--test/ruby/test_jit_debug.rb4
-rw-r--r--test/ruby/test_literal.rb2
-rw-r--r--test/ruby/test_m17n.rb3
-rw-r--r--test/ruby/test_method.rb65
-rw-r--r--test/ruby/test_module.rb80
-rw-r--r--test/ruby/test_objectspace.rb2
-rw-r--r--test/ruby/test_optimization.rb32
-rw-r--r--test/ruby/test_pack.rb8
-rw-r--r--test/ruby/test_parse.rb2
-rw-r--r--test/ruby/test_proc.rb19
-rw-r--r--test/ruby/test_process.rb58
-rw-r--r--test/ruby/test_rand.rb6
-rw-r--r--test/ruby/test_random_formatter.rb123
-rw-r--r--test/ruby/test_refinement.rb207
-rw-r--r--test/ruby/test_require.rb44
-rw-r--r--test/ruby/test_require_lib.rb2
-rw-r--r--test/ruby/test_rubyoptions.rb58
-rw-r--r--test/ruby/test_rubyvm_jit.rb26
-rw-r--r--test/ruby/test_settracefunc.rb162
-rw-r--r--test/ruby/test_signal.rb5
-rw-r--r--test/ruby/test_sprintf.rb15
-rw-r--r--test/ruby/test_string.rb568
-rw-r--r--test/ruby/test_struct.rb42
-rw-r--r--test/ruby/test_super.rb37
-rw-r--r--test/ruby/test_syntax.rb78
-rw-r--r--test/ruby/test_thread.rb16
-rw-r--r--test/ruby/test_thread_queue.rb4
-rw-r--r--test/ruby/test_time.rb43
-rw-r--r--test/ruby/test_time_tz.rb2
-rw-r--r--test/ruby/test_undef.rb16
-rw-r--r--test/ruby/test_vm_dump.rb2
-rw-r--r--test/ruby/test_weakmap.rb11
-rw-r--r--test/ruby/test_yjit.rb103
-rw-r--r--test/rubygems/encrypted_private_key.pem52
-rw-r--r--test/rubygems/helper.rb96
-rw-r--r--test/rubygems/test_gem.rb81
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb65
-rw-r--r--test/rubygems/test_gem_command.rb2
-rw-r--r--test/rubygems/test_gem_command_manager.rb14
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb16
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb133
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb49
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb50
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb86
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb59
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb2
-rw-r--r--test/rubygems/test_gem_dependency.rb12
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb10
-rw-r--r--test/rubygems/test_gem_install_update_options.rb4
-rw-r--r--test/rubygems/test_gem_installer.rb243
-rw-r--r--test/rubygems/test_gem_package.rb4
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb15
-rw-r--r--test/rubygems/test_gem_request.rb14
-rw-r--r--test/rubygems/test_gem_resolver.rb14
-rw-r--r--test/rubygems/test_gem_security.rb2
-rw-r--r--test/rubygems/test_gem_server.rb608
-rw-r--r--test/rubygems/test_gem_specification.rb52
-rw-r--r--test/rubygems/test_gem_stream_ui.rb2
-rw-r--r--test/rubygems/test_gem_stub_specification.rb16
-rw-r--r--test/rubygems/test_gem_version.rb4
-rw-r--r--test/rubygems/test_kernel.rb14
-rw-r--r--test/rubygems/test_project_sanity.rb2
-rw-r--r--test/rubygems/test_require.rb68
-rw-r--r--test/rubygems/test_rubygems.rb27
-rw-r--r--test/rubygems/utilities.rb8
-rw-r--r--test/runner.rb2
-rw-r--r--test/socket/test_addrinfo.rb2
-rw-r--r--test/socket/test_basicsocket.rb2
-rw-r--r--test/socket/test_nonblock.rb8
-rw-r--r--test/socket/test_socket.rb12
-rw-r--r--test/socket/test_sockopt.rb2
-rw-r--r--test/socket/test_udp.rb2
-rw-r--r--test/test_find.rb16
-rw-r--r--test/test_getoptlong.rb163
-rw-r--r--test/test_open3.rb13
-rw-r--r--test/test_pp.rb12
-rw-r--r--test/test_pty.rb30
-rw-r--r--test/test_securerandom.rb121
-rw-r--r--test/test_tmpdir.rb2
-rw-r--r--test/win32ole/test_err_in_callback.rb2
-rw-r--r--test/win32ole/test_win32ole.rb2
-rw-r--r--test/win32ole/test_win32ole_event.rb5
-rw-r--r--test/win32ole/test_win32ole_method_event.rb2
-rw-r--r--test/win32ole/test_win32ole_param_event.rb2
-rw-r--r--test/win32ole/test_win32ole_record.rb2
-rw-r--r--test/win32ole/test_win32ole_type_event.rb2
-rw-r--r--test/win32ole/test_win32ole_variable.rb4
-rw-r--r--test/win32ole/test_win32ole_variant.rb2
-rw-r--r--test/win32ole/test_win32ole_variant_outarg.rb2
-rw-r--r--test/win32ole/test_word.rb2
-rw-r--r--test/zlib/test_zlib.rb24
211 files changed, 5878 insertions, 2361 deletions
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index 759e295fb62..990b6a2cc5b 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -4,11 +4,11 @@ require 'tmpdir'
class TestBugReporter < Test::Unit::TestCase
def test_bug_reporter_add
- skip if ENV['RUBY_ON_BUG']
+ omit if ENV['RUBY_ON_BUG']
description = RUBY_DESCRIPTION
- description = description.sub(/\+JIT /, '') if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
- description = description.sub(/\+YJIT /, '') if defined?(YJIT.enabled?) && YJIT.enabled?
+ description = description.sub(/\+MJIT /, '') if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ description = description.sub(/\+YJIT /, '') if defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
expected_stderr = [
:*,
/\[BUG\]\sSegmentation\sfault.*\n/,
@@ -19,9 +19,10 @@ class TestBugReporter < Test::Unit::TestCase
]
tmpdir = Dir.mktmpdir
+ no_core = "Process.setrlimit(Process::RLIMIT_CORE, 0); " if defined?(Process.setrlimit) && defined?(Process::RLIMIT_CORE)
args = ["--disable-gems", "-r-test-/bug_reporter",
"-C", tmpdir]
- stdin = "register_sample_bug_reporter(12345); Process.kill :SEGV, $$"
+ stdin = "#{no_core}register_sample_bug_reporter(12345); Process.kill :SEGV, $$"
assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT")
ensure
FileUtils.rm_rf(tmpdir) if tmpdir
diff --git a/test/-ext-/float/test_nextafter.rb b/test/-ext-/float/test_nextafter.rb
index e0a76935b16..ea8d7c7fc70 100644
--- a/test/-ext-/float/test_nextafter.rb
+++ b/test/-ext-/float/test_nextafter.rb
@@ -52,7 +52,7 @@ class TestFloatExt < Test::Unit::TestCase
"#{'%a' % v2} = Bug::Float.system_nextafter(#{'%a' % n1}, #{'%a' % n2})")
rescue Test::Unit::AssertionFailedError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in nextafter(3) on AIX"
+ omit "Known bug in nextafter(3) on AIX"
end
raise $!
end
diff --git a/test/-ext-/gvl/test_ubf_async_safe.rb b/test/-ext-/gvl/test_ubf_async_safe.rb
index fdaa4d418b8..3261b424759 100644
--- a/test/-ext-/gvl/test_ubf_async_safe.rb
+++ b/test/-ext-/gvl/test_ubf_async_safe.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class TestUbfAsyncSafe < Test::Unit::TestCase
def test_ubf_async_safe
- skip 'need fork for single-threaded test' unless Process.respond_to?(:fork)
+ omit 'need fork for single-threaded test' unless Process.respond_to?(:fork)
IO.pipe do |r, w|
pid = fork do
require '-test-/gvl/call_without_gvl'
diff --git a/test/-ext-/iseq_load/test_iseq_load.rb b/test/-ext-/iseq_load/test_iseq_load.rb
index ffa6541c727..6e5bc8e811b 100644
--- a/test/-ext-/iseq_load/test_iseq_load.rb
+++ b/test/-ext-/iseq_load/test_iseq_load.rb
@@ -98,7 +98,7 @@ class TestIseqLoad < Test::Unit::TestCase
iseq = ISeq.iseq_load(a)
iseq.eval
assert_equal false, @next_broke
- skip "failing due to stack_max mismatch"
+ omit "failing due to stack_max mismatch"
assert_iseq_roundtrip(src)
end
@@ -121,7 +121,7 @@ class TestIseqLoad < Test::Unit::TestCase
iseq = ISeq.iseq_load(a)
iseq.eval
assert_equal false, test_break_ensure_def_method
- skip "failing due to exception entry sp mismatch"
+ omit "failing due to exception entry sp mismatch"
assert_iseq_roundtrip(src)
end
@@ -137,7 +137,7 @@ class TestIseqLoad < Test::Unit::TestCase
# FIXME: still failing
def test_require_integration
- skip "iseq loader require integration tests still failing"
+ omit "iseq loader require integration tests still failing"
f = File.expand_path(__FILE__)
# $(top_srcdir)/test/ruby/test_....rb
3.times { f = File.dirname(f) }
diff --git a/test/-ext-/postponed_job/test_postponed_job.rb b/test/-ext-/postponed_job/test_postponed_job.rb
index 7dc28776d0c..fee0172d114 100644
--- a/test/-ext-/postponed_job/test_postponed_job.rb
+++ b/test/-ext-/postponed_job/test_postponed_job.rb
@@ -25,4 +25,11 @@ class TestPostponed_job < Test::Unit::TestCase
Bug.postponed_job_register_one(ary = [])
assert_equal [1], ary
end
+
+ if Bug.respond_to?(:postponed_job_register_in_c_thread)
+ def test_register_in_c_thread
+ assert Bug.postponed_job_register_in_c_thread(ary = [])
+ assert_equal [1], ary
+ end
+ end
end
diff --git a/test/-ext-/string/test_capacity.rb b/test/-ext-/string/test_capacity.rb
index 583c98fca46..6b3172a46d3 100644
--- a/test/-ext-/string/test_capacity.rb
+++ b/test/-ext-/string/test_capacity.rb
@@ -66,7 +66,7 @@ class Test_StringCapacity < Test::Unit::TestCase
def embed_header_size
if GC.using_rvargc?
- 2 * RbConfig::SIZEOF['void*'] + RbConfig::SIZEOF['short']
+ 2 * RbConfig::SIZEOF['void*'] + RbConfig::SIZEOF['long']
else
2 * RbConfig::SIZEOF['void*']
end
diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb
index 9b4956ecef4..5a3456c5664 100644
--- a/test/-ext-/string/test_fstring.rb
+++ b/test/-ext-/string/test_fstring.rb
@@ -57,18 +57,4 @@ class Test_String_Fstring < Test::Unit::TestCase
str.freeze
assert_fstring(str) {|s| assert_instance_of(S, s)}
end
-
- def test_shared_string_safety
- _unused = -('a' * 30).force_encoding(Encoding::ASCII)
- begin
- verbose_back, $VERBOSE = $VERBOSE, nil
- str = ('a' * 30).force_encoding(Encoding::ASCII).taint
- ensure
- $VERBOSE = verbose_back
- end
- frozen_str = Bug::String.rb_str_new_frozen(str)
- assert_fstring(frozen_str) {|s| assert_equal(str, s)}
- GC.start
- assert_equal('a' * 30, str, "[Bug #16151]")
- end
end
diff --git a/test/-ext-/string/test_set_len.rb b/test/-ext-/string/test_set_len.rb
index 58f51012fb7..5216e6195f5 100644
--- a/test/-ext-/string/test_set_len.rb
+++ b/test/-ext-/string/test_set_len.rb
@@ -20,7 +20,7 @@ class Test_StrSetLen < Test::Unit::TestCase
def test_shared
assert_raise(RuntimeError) {
- assert_equal("abc", @s1.set_len(3))
+ @s1.set_len(3)
}
end
diff --git a/test/bigdecimal/helper.rb b/test/bigdecimal/helper.rb
index 22b05f09ae4..46721fb9a81 100644
--- a/test/bigdecimal/helper.rb
+++ b/test/bigdecimal/helper.rb
@@ -1,8 +1,19 @@
# frozen_string_literal: false
require "test/unit"
require "bigdecimal"
+require 'rbconfig/sizeof'
module TestBigDecimalBase
+ if RbConfig::SIZEOF.key?("int64_t")
+ SIZEOF_DECDIG = RbConfig::SIZEOF["int32_t"]
+ BASE = 1_000_000_000
+ BASE_FIG = 9
+ else
+ SIZEOF_DECDIG = RbConfig::SIZEOF["int16_t"]
+ BASE = 1000
+ BASE_FIG = 4
+ end
+
def setup
@mode = BigDecimal.mode(BigDecimal::EXCEPTION_ALL)
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true)
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index 49e6b2a70e1..0cd85249adc 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: false
require_relative "helper"
require 'bigdecimal/math'
-require 'rbconfig/sizeof'
class TestBigDecimal < Test::Unit::TestCase
include TestBigDecimalBase
@@ -12,7 +11,12 @@ class TestBigDecimal < Test::Unit::TestCase
require 'fiddle'
LONG_MAX = (1 << (Fiddle::SIZEOF_LONG*8 - 1)) - 1
LONG_MIN = [LONG_MAX + 1].pack("L!").unpack("l!")[0]
+ LLONG_MAX = (1 << (Fiddle::SIZEOF_LONG_LONG*8 - 1)) - 1
+ LLONG_MIN = [LLONG_MAX + 1].pack("Q!").unpack("q!")[0]
+ ULLONG_MAX = (1 << Fiddle::SIZEOF_LONG_LONG*8) - 1
LIMITS = {
+ "LLONG_MIN" => LLONG_MIN,
+ "ULLONG_MAX" => ULLONG_MAX,
"FIXNUM_MIN" => LONG_MIN / 2,
"FIXNUM_MAX" => LONG_MAX / 2,
"INT64_MIN" => -9223372036854775808,
@@ -96,6 +100,19 @@ class TestBigDecimal < Test::Unit::TestCase
assert_not_same(bd, BigDecimal(bd, 1, exception: false))
end
+ def test_BigDecimal_issue_192
+ # https://github.com/ruby/bigdecimal/issues/192
+ # https://github.com/rails/rails/pull/42125
+ if BASE_FIG == 9
+ int = 1_000_000_000_12345_0000
+ big = BigDecimal("0.100000000012345e19")
+ else # BASE_FIG == 4
+ int = 1_0000_12_00
+ big = BigDecimal("0.1000012e9")
+ end
+ assert_equal(BigDecimal(int), big, "[ruby/bigdecimal#192]")
+ end
+
def test_BigDecimal_with_invalid_string
[
'', '.', 'e1', 'd1', '.e', '.d', '1.e', '1.d', '.1e', '.1d',
@@ -936,9 +953,13 @@ class TestBigDecimal < Test::Unit::TestCase
assert_equal(2, BigDecimal("2") / 1)
assert_equal(-2, BigDecimal("2") / -1)
- assert_equal(BigDecimal('1486.868686869'), BigDecimal('1472.0') / BigDecimal('0.99'), '[ruby-core:59365] [#9316]')
+ assert_equal(BigDecimal('1486.868686869'),
+ (BigDecimal('1472.0') / BigDecimal('0.99')).round(9),
+ '[ruby-core:59365] [#9316]')
- assert_equal(4.124045235, BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0')), '[#9305]')
+ assert_in_delta(4.124045235,
+ (BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0'))).round(9, half: :up),
+ 10**Float::MIN_10_EXP, '[#9305]')
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
assert_positive_zero(BigDecimal("1.0") / BigDecimal("Infinity"))
@@ -948,8 +969,24 @@ class TestBigDecimal < Test::Unit::TestCase
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
- assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { BigDecimal("1") / 0 }
- assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { BigDecimal("-1") / 0 }
+ assert_raise_with_message(FloatDomainError, "Computation results in 'Infinity'") { BigDecimal("1") / 0 }
+ assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 }
+ end
+
+ def test_div_gh220
+ x = BigDecimal("1.0")
+ y = BigDecimal("3672577333.6608990499165058135986328125")
+ c = BigDecimal("0.272288343892592687909520102748926752911779209181321744700032723729015151607289998e-9")
+ assert_equal(c, x / y, "[GH-220]")
+ end
+
+ def test_div_precision
+ bug13754 = '[ruby-core:82107] [Bug #13754]'
+ a = BigDecimal('101')
+ b = BigDecimal('0.9163472602589686')
+ c = a/b
+ assert(c.precision > b.precision,
+ "(101/0.9163472602589686).precision >= (0.9163472602589686).precision #{bug13754}")
end
def test_div_with_float
@@ -1013,6 +1050,19 @@ class TestBigDecimal < Test::Unit::TestCase
assert_raise(ZeroDivisionError){BigDecimal("0").divmod(0)}
end
+ def test_divmod_precision
+ a = BigDecimal('2e55')
+ b = BigDecimal('1.23456789e10')
+ q, r = a.divmod(b)
+ assert_equal((a/b).round(0, :down), q)
+ assert_equal((a - q*b), r)
+
+ b = BigDecimal('-1.23456789e10')
+ q, r = a.divmod(b)
+ assert_equal((a/b).round(0, :down) - 1, q)
+ assert_equal((a - q*b), r)
+ end
+
def test_divmod_error
assert_raise(TypeError) { BigDecimal(20).divmod('2') }
end
@@ -1050,6 +1100,40 @@ class TestBigDecimal < Test::Unit::TestCase
end
end
+ def test_div_bigdecimal_with_float_and_precision
+ x = BigDecimal(5)
+ y = 5.1
+ assert_equal(x.div(BigDecimal(y, 0), 8),
+ x.div(y, 8))
+
+ assert_equal(x.div(BigDecimal(y, 0), 100),
+ x.div(y, 100))
+ end
+
+ def test_quo_without_prec
+ x = BigDecimal(5)
+ y = BigDecimal(229)
+ assert_equal(BigDecimal("0.021834061135371179039301310043668122"), x.quo(y))
+ end
+
+ def test_quo_with_prec
+ begin
+ saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
+ BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up)
+
+ x = BigDecimal(5)
+ y = BigDecimal(229)
+ assert_equal(BigDecimal("0.021834061135371179039301310043668122"), x.quo(y, 0))
+ assert_equal(BigDecimal("0.022"), x.quo(y, 2))
+ assert_equal(BigDecimal("0.0218"), x.quo(y, 3))
+ assert_equal(BigDecimal("0.0218341"), x.quo(y, 6))
+ assert_equal(BigDecimal("0.02183406114"), x.quo(y, 10))
+ assert_equal(BigDecimal("0.021834061135371179039301310043668122270742358078603"), x.quo(y, 50))
+ ensure
+ BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
+ end
+ end
+
def test_abs_bigdecimal
x = BigDecimal((2**100).to_s)
assert_equal(1267650600228229401496703205376, x.abs)
@@ -1995,10 +2079,14 @@ class TestBigDecimal < Test::Unit::TestCase
def test_precision_only_fraction
assert_equal(1, BigDecimal("0.1").precision)
assert_equal(1, BigDecimal("-0.1").precision)
- assert_equal(1, BigDecimal("0.01").precision)
- assert_equal(1, BigDecimal("-0.01").precision)
+ assert_equal(2, BigDecimal("0.01").precision)
+ assert_equal(2, BigDecimal("-0.01").precision)
assert_equal(2, BigDecimal("0.11").precision)
assert_equal(2, BigDecimal("-0.11").precision)
+ assert_equal(9, BigDecimal("0.000_000_001").precision)
+ assert_equal(9, BigDecimal("-0.000_000_001").precision)
+ assert_equal(10, BigDecimal("0.000_000_000_1").precision)
+ assert_equal(10, BigDecimal("-0.000_000_000_1").precision)
assert_equal(21, BigDecimal("0.000_000_000_000_000_000_001").precision)
assert_equal(21, BigDecimal("-0.000_000_000_000_000_000_001").precision)
assert_equal(100, BigDecimal("111e-100").precision)
@@ -2006,12 +2094,8 @@ class TestBigDecimal < Test::Unit::TestCase
end
def test_precision_full
- assert_equal(1, BigDecimal("0.1").precision)
- assert_equal(1, BigDecimal("-0.1").precision)
- assert_equal(1, BigDecimal("0.01").precision)
- assert_equal(1, BigDecimal("-0.01").precision)
- assert_equal(2, BigDecimal("0.11").precision)
- assert_equal(2, BigDecimal("-0.11").precision)
+ assert_equal(5, BigDecimal("11111e-2").precision)
+ assert_equal(5, BigDecimal("-11111e-2").precision)
assert_equal(5, BigDecimal("11111e-2").precision)
assert_equal(5, BigDecimal("-11111e-2").precision)
assert_equal(21, BigDecimal("100.000_000_000_000_000_001").precision)
@@ -2029,6 +2113,70 @@ class TestBigDecimal < Test::Unit::TestCase
end
end
+ def test_scale_only_integer
+ assert_equal(0, BigDecimal(0).scale)
+ assert_equal(0, BigDecimal(1).scale)
+ assert_equal(0, BigDecimal(-1).scale)
+ assert_equal(0, BigDecimal(10).scale)
+ assert_equal(0, BigDecimal(-10).scale)
+ assert_equal(0, BigDecimal(100_000_000).scale)
+ assert_equal(0, BigDecimal(-100_000_000).scale)
+ assert_equal(0, BigDecimal(100_000_000_000).scale)
+ assert_equal(0, BigDecimal(-100_000_000_000).scale)
+ assert_equal(0, BigDecimal(100_000_000_000_000_000_000).scale)
+ assert_equal(0, BigDecimal(-100_000_000_000_000_000_000).scale)
+ assert_equal(0, BigDecimal("111e100").scale)
+ assert_equal(0, BigDecimal("-111e100").scale)
+ end
+
+ def test_scale_only_fraction
+ assert_equal(1, BigDecimal("0.1").scale)
+ assert_equal(1, BigDecimal("-0.1").scale)
+ assert_equal(2, BigDecimal("0.01").scale)
+ assert_equal(2, BigDecimal("-0.01").scale)
+ assert_equal(2, BigDecimal("0.11").scale)
+ assert_equal(2, BigDecimal("-0.11").scale)
+ assert_equal(21, BigDecimal("0.000_000_000_000_000_000_001").scale)
+ assert_equal(21, BigDecimal("-0.000_000_000_000_000_000_001").scale)
+ assert_equal(100, BigDecimal("111e-100").scale)
+ assert_equal(100, BigDecimal("-111e-100").scale)
+ end
+
+ def test_scale_full
+ assert_equal(1, BigDecimal("0.1").scale)
+ assert_equal(1, BigDecimal("-0.1").scale)
+ assert_equal(2, BigDecimal("0.01").scale)
+ assert_equal(2, BigDecimal("-0.01").scale)
+ assert_equal(2, BigDecimal("0.11").scale)
+ assert_equal(2, BigDecimal("-0.11").scale)
+ assert_equal(2, BigDecimal("11111e-2").scale)
+ assert_equal(2, BigDecimal("-11111e-2").scale)
+ assert_equal(18, BigDecimal("100.000_000_000_000_000_001").scale)
+ assert_equal(18, BigDecimal("-100.000_000_000_000_000_001").scale)
+ end
+
+ def test_scale_special
+ BigDecimal.save_exception_mode do
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+
+ assert_equal(0, BigDecimal("Infinity").scale)
+ assert_equal(0, BigDecimal("-Infinity").scale)
+ assert_equal(0, BigDecimal("NaN").scale)
+ end
+ end
+
+ def test_precision_scale
+ assert_equal([2, 0], BigDecimal("11.0").precision_scale)
+ assert_equal([2, 1], BigDecimal("1.1").precision_scale)
+ assert_equal([2, 2], BigDecimal("0.11").precision_scale)
+
+ BigDecimal.save_exception_mode do
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ assert_equal([0, 0], BigDecimal("Infinity").precision_scale)
+ end
+ end
+
def test_n_significant_digits_only_integer
assert_equal(0, BigDecimal(0).n_significant_digits)
assert_equal(1, BigDecimal(1).n_significant_digits)
@@ -2089,6 +2237,15 @@ class TestBigDecimal < Test::Unit::TestCase
assert_raise(err) { bd.send(:initialize_dup, bd2) }
end
+ def test_llong_min_gh_200
+ # https://github.com/ruby/bigdecimal/issues/199
+ # Between LLONG_MIN and -ULLONG_MAX
+ assert_equal(BigDecimal(LIMITS["LLONG_MIN"].to_s), BigDecimal(LIMITS["LLONG_MIN"]), "[GH-200]")
+
+ minus_ullong_max = -LIMITS["ULLONG_MAX"]
+ assert_equal(BigDecimal(minus_ullong_max.to_s), BigDecimal(minus_ullong_max), "[GH-200]")
+ end
+
def assert_no_memory_leak(code, *rest, **opt)
code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}"
super(["-rbigdecimal"],
diff --git a/test/bigdecimal/test_bigdecimal_util.rb b/test/bigdecimal/test_bigdecimal_util.rb
index ffd4c5f679d..2f27163ebfa 100644
--- a/test/bigdecimal/test_bigdecimal_util.rb
+++ b/test/bigdecimal/test_bigdecimal_util.rb
@@ -25,6 +25,8 @@ class TestBigDecimalUtil < Test::Unit::TestCase
assert_equal(9.05, 9.05.to_d.to_f)
assert_equal("9.05", 9.05.to_d.to_s('F'))
+ assert_equal("65.6", 65.6.to_d.to_s("F"))
+
assert_equal(Math::PI, Math::PI.to_d.to_f)
bug9214 = '[ruby-core:58858]'
@@ -60,6 +62,19 @@ class TestBigDecimalUtil < Test::Unit::TestCase
"[ruby-core:80234] [Bug #13331]")
end
+ def test_Float_to_d_issue_192
+ # https://github.com/ruby/bigdecimal/issues/192
+ # https://github.com/rails/rails/pull/42125
+ if BASE_FIG == 9
+ flo = 1_000_000_000.12345
+ big = BigDecimal("0.100000000012345e10")
+ else # BASE_FIG == 4
+ flo = 1_0000.12
+ big = BigDecimal("0.1000012e5")
+ end
+ assert_equal(flo.to_d, big, "[ruby/bigdecimal#192]")
+ end
+
def test_Rational_to_d
digits = 100
delta = 1.0/10**(digits)
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
index 115a57e4a10..985cc0d7a1a 100644
--- a/test/cgi/test_cgi_cookie.rb
+++ b/test/cgi/test_cgi_cookie.rb
@@ -101,6 +101,11 @@ class CGICookieTest < Test::Unit::TestCase
end
end
+ def test_cgi_cookie_parse_not_decode_name
+ cookie_str = "%66oo=baz;foo=bar"
+ cookies = CGI::Cookie.parse(cookie_str)
+ assert_equal({"%66oo" => ["baz"], "foo" => ["bar"]}, cookies)
+ end
def test_cgi_cookie_arrayinterface
cookie = CGI::Cookie.new('name1', 'a', 'b', 'c')
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index 6ce8b42c20f..5a2d07b328f 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -104,6 +104,23 @@ class CGIUtilTest < Test::Unit::TestCase
assert_not_predicate CGI.escapeHTML("Ruby".freeze), :frozen?
end
+ def test_cgi_escape_html_large
+ ulong_max, size_max = RbConfig::LIMITS.values_at("ULONG_MAX", "SIZE_MAX")
+ return unless ulong_max < size_max # Platforms not concerned
+
+ size = (ulong_max / 6 + 1)
+ begin
+ str = '"' * size
+ escaped = CGI.escapeHTML(str)
+ rescue NoMemoryError
+ omit "Not enough memory"
+ rescue => e
+ end
+ assert_raise_with_message(ArgumentError, /overflow/, ->{"length = #{escaped.length}"}) do
+ raise e if e
+ end
+ end
+
def test_cgi_unescapeHTML
assert_equal("'&\"><", CGI.unescapeHTML("&#39;&amp;&quot;&gt;&lt;"))
end
diff --git a/test/csv/parse/test_convert.rb b/test/csv/parse/test_convert.rb
index bfe6ddd527c..21d9f20b28e 100644
--- a/test/csv/parse/test_convert.rb
+++ b/test/csv/parse/test_convert.rb
@@ -43,7 +43,7 @@ class TestCSVParseConvert < Test::Unit::TestCase
@parser.shift)
end
- def test_numberic
+ def test_numeric
@parser.convert(:numeric)
assert_equal(["Numbers", ":integer", 1, ":float", 3.015],
@parser.shift)
diff --git a/test/csv/parse/test_general.rb b/test/csv/parse/test_general.rb
index 14903d462cb..d2b74008ebb 100644
--- a/test/csv/parse/test_general.rb
+++ b/test/csv/parse/test_general.rb
@@ -14,7 +14,7 @@ require_relative "../helper"
class TestCSVParseGeneral < Test::Unit::TestCase
extend DifferentOFS
- BIG_DATA = "123456789\n" * 1024
+ BIG_DATA = "123456789\n" * 512
def test_mastering_regex_example
ex = %Q{Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K}
@@ -247,7 +247,7 @@ line,5,jkl
def assert_parse_errors_out(data, **options)
assert_raise(CSV::MalformedCSVError) do
timeout = 0.2
- if defined?(RubyVM::JIT.enabled?) and RubyVM::JIT.enabled?
+ if defined?(RubyVM::MJIT.enabled?) and RubyVM::MJIT.enabled?
timeout = 5 # for --jit-wait
end
Timeout.timeout(timeout) do
diff --git a/test/csv/parse/test_strip.rb b/test/csv/parse/test_strip.rb
index 3564fcb3ba5..c5e35209cc1 100644
--- a/test/csv/parse/test_strip.rb
+++ b/test/csv/parse/test_strip.rb
@@ -80,4 +80,33 @@ class TestCSVParseStrip < Test::Unit::TestCase
%Q{"a" ,"b " \r\n},
strip: true))
end
+
+ def test_col_sep_incompatible_true
+ message = "The provided strip (true) and " \
+ "col_sep (\\t) options are incompatible."
+ assert_raise_with_message(ArgumentError, message) do
+ CSV.parse_line(%Q{"a"\t"b"\n},
+ col_sep: "\t",
+ strip: true)
+ end
+ end
+
+ def test_col_sep_incompatible_string
+ message = "The provided strip (\\t) and " \
+ "col_sep (\\t) options are incompatible."
+ assert_raise_with_message(ArgumentError, message) do
+ CSV.parse_line(%Q{"a"\t"b"\n},
+ col_sep: "\t",
+ strip: "\t")
+ end
+ end
+
+ def test_col_sep_compatible_string
+ assert_equal(
+ ["a", "b"],
+ CSV.parse_line(%Q{\va\tb\v\n},
+ col_sep: "\t",
+ strip: "\v")
+ )
+ end
end
diff --git a/test/csv/test_table.rb b/test/csv/test_table.rb
index 3202963a676..968e64eae70 100644
--- a/test/csv/test_table.rb
+++ b/test/csv/test_table.rb
@@ -20,7 +20,7 @@ class TestCSVTable < Test::Unit::TestCase
@header_only_table = CSV::Table.new([], headers: %w{A B C})
end
- def test_initialze
+ def test_initialize
assert_not_nil(@table)
assert_instance_of(CSV::Table, @table)
end
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
index 9f92635387b..34a672b069c 100644
--- a/test/date/test_date_parse.rb
+++ b/test/date/test_date_parse.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'test/unit'
require 'date'
+require 'timeout'
class TestDateParse < Test::Unit::TestCase
@@ -847,6 +848,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._iso8601('')
assert_equal({}, h)
+
+ h = Date._iso8601(nil)
+ assert_equal({}, h)
+
+ h = Date._iso8601('01-02-03T04:05:06Z'.to_sym)
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test__rfc3339
@@ -862,6 +870,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc3339('')
assert_equal({}, h)
+
+ h = Date._rfc3339(nil)
+ assert_equal({}, h)
+
+ h = Date._rfc3339('2001-02-03T04:05:06Z'.to_sym)
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test__xmlschema
@@ -944,6 +959,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._xmlschema('')
assert_equal({}, h)
+
+ h = Date._xmlschema(nil)
+ assert_equal({}, h)
+
+ h = Date._xmlschema('2001-02-03'.to_sym)
+ assert_equal([2001, 2, 3, nil, nil, nil, nil],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test__rfc2822
@@ -976,6 +998,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc2822('')
assert_equal({}, h)
+
+ h = Date._rfc2822(nil)
+ assert_equal({}, h)
+
+ h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT'.to_sym)
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test__httpdate
@@ -996,6 +1025,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._httpdate('')
assert_equal({}, h)
+
+ h = Date._httpdate(nil)
+ assert_equal({}, h)
+
+ h = Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT'.to_sym)
+ assert_equal([2001, 2, 3, 4, 5, 6, 0],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test__jisx0301
@@ -1072,6 +1108,13 @@ class TestDateParse < Test::Unit::TestCase
h = Date._jisx0301('')
assert_equal({}, h)
+
+ h = Date._jisx0301(nil)
+ assert_equal({}, h)
+
+ h = Date._jisx0301('H13.02.03T04:05:06.07+0100'.to_sym)
+ assert_equal([2001, 2, 3, 4, 5, 6, 3600],
+ h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
def test_iso8601
@@ -1228,4 +1271,32 @@ class TestDateParse < Test::Unit::TestCase
assert_equal(s0, s)
end
+ def test_length_limit
+ assert_raise(ArgumentError) { Date._parse("1" * 1000) }
+ assert_raise(ArgumentError) { Date._iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { Date._xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { Date._jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { Date.parse("1" * 1000) }
+ assert_raise(ArgumentError) { Date.iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { Date.xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { Date.jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { DateTime.parse("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { Date._parse("Jan " + "9" * 1000000) }
+ assert_raise(Timeout::Error) { Timeout.timeout(1) { Date._parse("Jan " + "9" * 1000000, limit: nil) } }
+ end
end
diff --git a/test/date/test_date_strftime.rb b/test/date/test_date_strftime.rb
index be9354504a5..dd04c0d9a4e 100644
--- a/test/date/test_date_strftime.rb
+++ b/test/date/test_date_strftime.rb
@@ -125,7 +125,7 @@ class TestDateStrftime < Test::Unit::TestCase
def test_strftime__3_2
s = Time.now.strftime('%G')
- skip if s.empty? || s == '%G'
+ omit if s.empty? || s == '%G'
(Date.new(1970,1,1)..Date.new(2037,12,31)).each do |d|
t = Time.utc(d.year,d.mon,d.mday)
assert_equal(t.strftime('%G'), d.strftime('%G'))
diff --git a/test/did_you_mean/core_ext/test_name_error_extension.rb b/test/did_you_mean/core_ext/test_name_error_extension.rb
index 9dc08dbde3d..91871cda9a7 100644
--- a/test/did_you_mean/core_ext/test_name_error_extension.rb
+++ b/test/did_you_mean/core_ext/test_name_error_extension.rb
@@ -1,7 +1,7 @@
require_relative '../helper'
class NameErrorExtensionTest < Test::Unit::TestCase
- SPELL_CHECKERS = DidYouMean::SPELL_CHECKERS
+ SPELL_CHECKERS = DidYouMean.spell_checkers
class TestSpellChecker
def initialize(*); end
@@ -9,13 +9,14 @@ class NameErrorExtensionTest < Test::Unit::TestCase
end
def setup
- @org, SPELL_CHECKERS['NameError'] = SPELL_CHECKERS['NameError'], TestSpellChecker
+ @original_spell_checker = DidYouMean.spell_checkers['NameError']
+ DidYouMean.correct_error(NameError, TestSpellChecker)
@error = assert_raise(NameError){ doesnt_exist }
end
def teardown
- SPELL_CHECKERS['NameError'] = @org
+ DidYouMean.correct_error(NameError, @original_spell_checker)
end
def test_message
diff --git a/test/did_you_mean/helper.rb b/test/did_you_mean/helper.rb
index d8aa41c3d1c..7cb7b102823 100644
--- a/test/did_you_mean/helper.rb
+++ b/test/did_you_mean/helper.rb
@@ -4,6 +4,10 @@ module DidYouMean
module TestHelper
class << self
attr_reader :root
+
+ def ractor_compatible?
+ defined?(Ractor) && RUBY_VERSION >= "3.1.0"
+ end
end
if File.file?(File.expand_path('../lib/did_you_mean.rb', __dir__))
diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb
index f3d20201bc9..3c33aedb6f1 100644
--- a/test/drb/drbtest.rb
+++ b/test/drb/drbtest.rb
@@ -216,7 +216,7 @@ module DRbCore
def test_06_timeout
omit if RUBY_PLATFORM.include?("armv7l-linux")
omit if RUBY_PLATFORM.include?("sparc-solaris2.10")
- omit if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # expecting a certain delay is difficult for --jit-wait CI
+ omit if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # expecting a certain delay is difficult for --jit-wait CI
Timeout.timeout(60) do
ten = Onecky.new(10)
assert_raise(Timeout::Error) do
diff --git a/test/dtrace/helper.rb b/test/dtrace/helper.rb
index ce730800b47..7fa16965f12 100644
--- a/test/dtrace/helper.rb
+++ b/test/dtrace/helper.rb
@@ -122,7 +122,7 @@ module DTrace
def trap_probe d_program, ruby_program
if Hash === d_program
d_program = d_program[IMPL] or
- skip "#{d_program} not implemented for #{IMPL}"
+ omit "#{d_program} not implemented for #{IMPL}"
elsif String === d_program && IMPL == :stap
d_program = dtrace2systemtap(d_program)
end
diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb
index 08036bca542..a3cc7aa1496 100644
--- a/test/error_highlight/test_error_highlight.rb
+++ b/test/error_highlight/test_error_highlight.rb
@@ -1194,4 +1194,34 @@ undefined method `time' for 1:Integer
end
end
end
+
+ def test_simulate_funcallv_from_embedded_ruby
+ assert_error_message(NoMethodError, <<~END) do
+undefined method `foo' for nil:NilClass
+ END
+
+ nil.foo + 1
+ rescue NoMethodError => exc
+ def exc.backtrace_locations = []
+ raise
+ end
+ end
+
+ def test_spoofed_filename
+ Tempfile.create(["error_highlight_test", ".rb"], binmode: true) do |tmp|
+ tmp << "module Dummy\nend\n"
+ tmp.close
+
+ assert_error_message(NameError, <<~END) do
+ undefined local variable or method `foo' for "dummy":String
+ END
+
+ "dummy".instance_eval do
+ eval <<-END, nil, tmp.path
+ foo
+ END
+ end
+ end
+ end
+ end
end
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index 8c2fdcb0e06..4138015e4b6 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -14,6 +14,14 @@ rescue LoadError
end
class Scheduler
+ experimental = Warning[:experimental]
+ begin
+ Warning[:experimental] = false
+ IO::Buffer.new(0)
+ ensure
+ Warning[:experimental] = experimental
+ end
+
def initialize
@readable = {}
@writable = {}
@@ -184,6 +192,9 @@ class Scheduler
end
Fiber.yield
+ ensure
+ @readable.delete(io)
+ @writable.delete(io)
end
# Used for Kernel#sleep and Thread::Mutex#sleep
@@ -249,6 +260,85 @@ class Scheduler
end
end
+class IOBufferScheduler < Scheduler
+ EAGAIN = Errno::EAGAIN::Errno
+
+ def io_read(io, buffer, length)
+ offset = 0
+
+ while true
+ maximum_size = buffer.size - offset
+ result = blocking{io.read_nonblock(maximum_size, exception: false)}
+
+ # blocking{pp read: maximum_size, result: result, length: length}
+
+ case result
+ when :wait_readable
+ if length > 0
+ self.io_wait(io, IO::READABLE, nil)
+ else
+ return -EAGAIN
+ end
+ when :wait_writable
+ if length > 0
+ self.io_wait(io, IO::WRITABLE, nil)
+ else
+ return -EAGAIN
+ end
+ else
+ break unless result
+
+ buffer.set_string(result, offset)
+
+ size = result.bytesize
+ offset += size
+ break if size >= length
+ length -= size
+ end
+ end
+
+ return offset
+ end
+
+ def io_write(io, buffer, length)
+ offset = 0
+
+ while true
+ maximum_size = buffer.size - offset
+
+ chunk = buffer.get_string(offset, maximum_size)
+ result = blocking{io.write_nonblock(chunk, exception: false)}
+
+ # blocking{pp write: maximum_size, result: result, length: length}
+
+ case result
+ when :wait_readable
+ if length > 0
+ self.io_wait(io, IO::READABLE, nil)
+ else
+ return -EAGAIN
+ end
+ when :wait_writable
+ if length > 0
+ self.io_wait(io, IO::WRITABLE, nil)
+ else
+ return -EAGAIN
+ end
+ else
+ offset += result
+ break if result >= length
+ length -= result
+ end
+ end
+
+ return offset
+ end
+
+ def blocking(&block)
+ Fiber.new(blocking: true, &block).resume
+ end
+end
+
class BrokenUnblockScheduler < Scheduler
def unblock(blocker, fiber)
super
diff --git a/test/fiber/test_enumerator.rb b/test/fiber/test_enumerator.rb
index cd4ccd1de54..c635f474dbd 100644
--- a/test/fiber/test_enumerator.rb
+++ b/test/fiber/test_enumerator.rb
@@ -6,14 +6,14 @@ class TestFiberEnumerator < Test::Unit::TestCase
MESSAGE = "Hello World"
def test_read_characters
- skip "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
unless i.nonblock? && o.nonblock?
i.close
o.close
- skip "I/O is not non-blocking!"
+ omit "I/O is not non-blocking!"
end
message = String.new
diff --git a/test/fiber/test_io.rb b/test/fiber/test_io.rb
index ce65a55f780..4252641cde1 100644
--- a/test/fiber/test_io.rb
+++ b/test/fiber/test_io.rb
@@ -6,14 +6,14 @@ class TestFiberIO < Test::Unit::TestCase
MESSAGE = "Hello World"
def test_read
- skip "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
unless i.nonblock? && o.nonblock?
i.close
o.close
- skip "I/O is not non-blocking!"
+ omit "I/O is not non-blocking!"
end
message = nil
@@ -41,7 +41,7 @@ class TestFiberIO < Test::Unit::TestCase
end
def test_heavy_read
- skip unless defined?(UNIXSocket)
+ omit unless defined?(UNIXSocket)
16.times.map do
Thread.new do
@@ -64,14 +64,14 @@ class TestFiberIO < Test::Unit::TestCase
end
def test_epipe_on_read
- skip "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
unless i.nonblock? && o.nonblock?
i.close
o.close
- skip "I/O is not non-blocking!"
+ omit "I/O is not non-blocking!"
end
error = nil
@@ -140,4 +140,36 @@ class TestFiberIO < Test::Unit::TestCase
server.close
th.join
end
+
+ def test_read_write_blocking
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+ i.nonblock = false
+ o.nonblock = false
+
+ message = nil
+
+ thread = Thread.new do
+ # This scheduler provides non-blocking `io_read`/`io_write`:
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ message = i.read(20)
+ i.close
+ end
+
+ Fiber.schedule do
+ o.write("Hello World")
+ o.close
+ end
+ end
+
+ thread.join
+
+ assert_equal MESSAGE, message
+ assert_predicate(i, :closed?)
+ assert_predicate(o, :closed?)
+ end
end
diff --git a/test/fiber/test_io_buffer.rb b/test/fiber/test_io_buffer.rb
new file mode 100644
index 00000000000..48a34c31b61
--- /dev/null
+++ b/test/fiber/test_io_buffer.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: true
+require 'test/unit'
+require_relative 'scheduler'
+
+require 'timeout'
+
+class TestFiberIOBuffer < Test::Unit::TestCase
+ MESSAGE = "Hello World"
+
+ def test_read_write_blocking
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+ i.nonblock = false
+ o.nonblock = false
+
+ message = nil
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ message = i.read(20)
+ i.close
+ end
+
+ Fiber.schedule do
+ o.write(MESSAGE)
+ o.close
+ end
+ end
+
+ thread.join
+
+ assert_equal MESSAGE, message
+ assert_predicate(i, :closed?)
+ assert_predicate(o, :closed?)
+ ensure
+ i&.close
+ o&.close
+ end
+
+ def test_timeout_after
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+ i.nonblock = false
+ o.nonblock = false
+
+ message = nil
+ error = nil
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ Timeout.timeout(0.1) do
+ message = i.read(20)
+ end
+ rescue Timeout::Error => error
+ # Assertions below.
+ ensure
+ i.close
+ end
+ end
+
+ thread.join
+
+ assert_nil message
+ assert_kind_of Timeout::Error, error
+ ensure
+ i&.close
+ o&.close
+ end
+
+ def test_read_nonblock
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+
+ message = nil
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ message = i.read_nonblock(20, exception: false)
+ i.close
+ end
+ end
+
+ thread.join
+
+ assert_equal :wait_readable, message
+ ensure
+ i&.close
+ o&.close
+ end
+
+ def test_write_nonblock
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ o.write_nonblock(MESSAGE, exception: false)
+ o.close
+ end
+ end
+
+ thread.join
+
+ assert_equal MESSAGE, i.read
+ ensure
+ i&.close
+ o&.close
+ end
+end
diff --git a/test/fiber/test_process.rb b/test/fiber/test_process.rb
index c6583cac9bc..a5990be2044 100644
--- a/test/fiber/test_process.rb
+++ b/test/fiber/test_process.rb
@@ -33,4 +33,19 @@ class TestFiberProcess < Test::Unit::TestCase
end
end.join
end
+
+ def test_fork
+ omit 'fork not supported' unless Process.respond_to?(:fork)
+ Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ pid = Process.fork {}
+ Process.wait(pid)
+
+ assert_predicate $?, :success?
+ end
+ end.join
+ end
end
diff --git a/test/fiber/test_ractor.rb b/test/fiber/test_ractor.rb
index d03455a9f76..3c4ccbd8e5f 100644
--- a/test/fiber/test_ractor.rb
+++ b/test/fiber/test_ractor.rb
@@ -4,7 +4,7 @@ require "fiber"
class TestFiberCurrentRactor < Test::Unit::TestCase
def setup
- skip unless defined? Ractor
+ omit unless defined? Ractor
end
def test_ractor_shareable
diff --git a/test/fiber/test_scheduler.rb b/test/fiber/test_scheduler.rb
index f0f5b79f36f..1870ab1c33e 100644
--- a/test/fiber/test_scheduler.rb
+++ b/test/fiber/test_scheduler.rb
@@ -55,6 +55,7 @@ class TestFiberScheduler < Test::Unit::TestCase
def test_close_at_exit
assert_in_out_err %W[-I#{__dir__} -], <<-RUBY, ['Running Fiber'], [], success: true
require 'scheduler'
+ Warning[:experimental] = false
scheduler = Scheduler.new
Fiber.set_scheduler scheduler
diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb
index d119ec23e03..3c29f9f2b34 100644
--- a/test/io/console/test_io_console.rb
+++ b/test/io/console/test_io_console.rb
@@ -7,7 +7,13 @@ rescue LoadError
end
class TestIO_Console < Test::Unit::TestCase
- PATHS = $LOADED_FEATURES.grep(%r"/io/console(?:\.#{RbConfig::CONFIG['DLEXT']}|\.rb|/\w+\.rb)\z") {$`}
+ begin
+ PATHS = $LOADED_FEATURES.grep(%r"/io/console(?:\.#{RbConfig::CONFIG['DLEXT']}|\.rb|/\w+\.rb)\z") {$`}
+ rescue Encoding::CompatibilityError
+ $stderr.puts "test_io_console.rb debug"
+ $LOADED_FEATURES.each{|path| $stderr.puts [path, path.encoding].inspect}
+ raise
+ end
PATHS.uniq!
# FreeBSD seems to hang on TTOU when running parallel tests
@@ -401,6 +407,10 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
assert_equal(["true"], run_pty("IO.console(:close); p IO.console(:tty?)"))
end
+ def test_console_kw
+ assert_equal(["File"], run_pty("IO.console.close; p IO.console(:clone, freeze: true).class"))
+ end
+
def test_sync
assert_equal(["true"], run_pty("p IO.console.sync"))
end
@@ -477,6 +487,12 @@ defined?(IO.console) and TestIO_Console.class_eval do
IO.console(:close)
end
+ def test_console_kw
+ io = IO.console(:clone, freeze: true)
+ io.close
+ assert_kind_of(IO, io)
+ end
+
def test_sync
assert(IO.console.sync, "console should be unbuffered")
ensure
diff --git a/test/io/nonblock/test_flush.rb b/test/io/nonblock/test_flush.rb
index 08d129de3f4..447d761f18a 100644
--- a/test/io/nonblock/test_flush.rb
+++ b/test/io/nonblock/test_flush.rb
@@ -15,7 +15,7 @@ class TestIONonblock < Test::Unit::TestCase
Socket.pair(:INET, :STREAM) {|s1, s2|
return if flush_test(s1, s2)
}
- skip "nonblocking IO did not work"
+ omit "nonblocking IO did not work"
end
def flush_test(r, w)
diff --git a/test/io/wait/test_io_wait_uncommon.rb b/test/io/wait/test_io_wait_uncommon.rb
index b6f1c29bcd9..7b92e4c7582 100644
--- a/test/io/wait/test_io_wait_uncommon.rb
+++ b/test/io/wait/test_io_wait_uncommon.rb
@@ -13,7 +13,7 @@ class TestIOWaitUncommon < Test::Unit::TestCase
end
def test_fifo_wait
- skip 'no mkfifo' unless File.respond_to?(:mkfifo) && IO.const_defined?(:NONBLOCK)
+ omit 'no mkfifo' unless File.respond_to?(:mkfifo) && IO.const_defined?(:NONBLOCK)
require 'tmpdir'
Dir.mktmpdir('rubytest-fifo') do |dir|
fifo = "#{dir}/fifo"
@@ -45,7 +45,7 @@ class TestIOWaitUncommon < Test::Unit::TestCase
rescue Errno::ENOENT
return # Ignore silently
rescue SystemCallError => e
- skip "#{dev} could not be opened #{e.message} (#{e.class})"
+ omit "#{dev} could not be opened #{e.message} (#{e.class})"
end
if block
yield fp
diff --git a/test/io/wait/test_ractor.rb b/test/io/wait/test_ractor.rb
index 3d286af77f9..3742680cf75 100644
--- a/test/io/wait/test_ractor.rb
+++ b/test/io/wait/test_ractor.rb
@@ -4,10 +4,6 @@ require 'rbconfig'
require 'io/wait'
class TestIOWaitInRactor < Test::Unit::TestCase
- def setup
- omit unless defined? Ractor
- end
-
def test_ractor
ext = "/io/wait.#{RbConfig::CONFIG['DLEXT']}"
path = $".find {|path| path.end_with?(ext)}
@@ -19,4 +15,4 @@ class TestIOWaitInRactor < Test::Unit::TestCase
puts r.take
end;
end
-end
+end if defined? Ractor
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb
index 8eee36badc6..7b7ab55a64c 100644
--- a/test/irb/test_cmd.rb
+++ b/test/irb/test_cmd.rb
@@ -81,6 +81,7 @@ module TestIRB
InputMethod:\sAbstract\sInputMethod\n
\.irbrc\spath:\s.+\n
RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
}x
assert_match expected, irb.context.main.irb_info.to_s
@@ -107,6 +108,7 @@ module TestIRB
InputMethod:\sAbstract\sInputMethod\n
\.irbrc\spath:\s.+\n
RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
}x
assert_match expected, irb.context.main.irb_info.to_s
@@ -135,6 +137,7 @@ module TestIRB
IRB\sversion:\sirb\s.+\n
InputMethod:\sAbstract\sInputMethod\n
RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
\z
}x
@@ -167,6 +170,7 @@ module TestIRB
IRB\sversion:\sirb\s.+\n
InputMethod:\sAbstract\sInputMethod\n
RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
#{@is_win ? 'Code\spage:\s\d+\n' : ''}
\z
}x
@@ -200,7 +204,8 @@ module TestIRB
\.irbrc\spath: .+\n
RUBY_PLATFORM: .+\n
LANG\senv:\sja_JP\.UTF-8\n
- LC_ALL\s env:\sen_US\.UTF-8\n
+ LC_ALL\senv:\sen_US\.UTF-8\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
}x
assert_match expected, irb.context.main.irb_info.to_s
ensure
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
index d908195e6a5..42f82fc37ed 100644
--- a/test/irb/test_context.rb
+++ b/test/irb/test_context.rb
@@ -259,6 +259,7 @@ module TestIRB
end
def test_omit_on_assignment
+ IRB.conf[:USE_COLORIZE] = false
input = TestInputMethod.new([
"a = [1] * 100\n",
"a\n",
@@ -322,6 +323,7 @@ module TestIRB
end
def test_omit_multiline_on_assignment
+ IRB.conf[:USE_COLORIZE] = false
input = TestInputMethod.new([
"class A; def inspect; ([?* * 1000] * 3).join(%{\\n}); end; end; a = A.new\n",
"a\n"
@@ -347,7 +349,7 @@ module TestIRB
irb.eval_input
end
assert_empty err
- assert_equal("=> #{value_first_line[0..(input.winsize.last - 9)]}...\e[0m\n=> \n#{value}\n", out)
+ assert_equal("=> #{value_first_line[0..(input.winsize.last - 9)]}...\n=> \n#{value}\n", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)
input.reset
@@ -395,6 +397,7 @@ module TestIRB
# Default
IRB.conf[:ECHO] = nil
IRB.conf[:ECHO_ON_ASSIGNMENT] = nil
+ IRB.conf[:USE_COLORIZE] = false
input = TestInputMethod.new()
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
@@ -422,6 +425,7 @@ module TestIRB
def main.inspect
"abc\ndef"
end
+ IRB.conf[:USE_COLORIZE] = false
input = TestInputMethod.new([
"self"
])
diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb
index e5417b18c3f..d8c7c79263b 100644
--- a/test/irb/test_init.rb
+++ b/test/irb/test_init.rb
@@ -62,6 +62,7 @@ module TestIRB
end
def test_recovery_sigint
+ pend "This test gets stuck on Solaris for unknown reason; contribution is welcome" if RUBY_PLATFORM =~ /solaris/
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e binding.irb;loop{Process.kill("SIGINT",$$)} -- -f --], "exit\n", //, //)
Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index e02370d3f74..47435d675ea 100644
--- a/test/irb/test_ruby_lex.rb
+++ b/test/irb/test_ruby_lex.rb
@@ -399,6 +399,23 @@ module TestIRB
end
end
+ def test_corresponding_syntax_to_keyword_in
+ input_with_correct_indents = [
+ Row.new(%q(module E), nil, 2, 1),
+ Row.new(%q(end), 0, 0, 0),
+ Row.new(%q(class A), nil, 2, 1),
+ Row.new(%q( in), nil, 4, 1)
+ ]
+
+ lines = []
+ input_with_correct_indents.each do |row|
+ lines << row.content
+ assert_indenting(lines, row.current_line_spaces, false)
+ assert_indenting(lines, row.new_line_spaces, true)
+ assert_nesting_level(lines, row.nesting_level)
+ end
+ end
+
def test_bracket_corresponding_to_times
input_with_correct_indents = [
Row.new(%q(3.times { |i|), nil, 2, 1),
@@ -581,8 +598,8 @@ module TestIRB
tokens = RubyLex.ripper_lex_without_warning('%wwww')
pos_to_index = {}
tokens.each_with_index { |t, i|
- assert_nil(pos_to_index[t[0]], "There is already another token in the position of #{t.inspect}.")
- pos_to_index[t[0]] = i
+ assert_nil(pos_to_index[t.pos], "There is already another token in the position of #{t.inspect}.")
+ pos_to_index[t.pos] = i
}
end
@@ -598,8 +615,8 @@ module TestIRB
EOC
pos_to_index = {}
tokens.each_with_index { |t, i|
- assert_nil(pos_to_index[t[0]], "There is already another token in the position of #{t.inspect}.")
- pos_to_index[t[0]] = i
+ assert_nil(pos_to_index[t.pos], "There is already another token in the position of #{t.inspect}.")
+ pos_to_index[t.pos] = i
}
end
end
diff --git a/test/lib/jit_support.rb b/test/lib/jit_support.rb
index 779aa8567e2..c7618e03a08 100644
--- a/test/lib/jit_support.rb
+++ b/test/lib/jit_support.rb
@@ -21,7 +21,7 @@ module JITSupport
]
module_function
- # Run Ruby script with --jit-wait (Synchronous JIT compilation).
+ # Run Ruby script with --mjit-wait (Synchronous JIT compilation).
# Returns [stdout, stderr]
def eval_with_jit(env = nil, script, **opts)
stdout, stderr = nil, nil
@@ -36,13 +36,13 @@ module JITSupport
def eval_with_jit_without_retry(env = nil, script, verbose: 0, min_calls: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
args = [
- '--disable-gems', "--jit-verbose=#{verbose}",
- "--jit-min-calls=#{min_calls}", "--jit-max-cache=#{max_cache}",
+ '--disable-gems', "--mjit-verbose=#{verbose}",
+ "--mjit-min-calls=#{min_calls}", "--mjit-max-cache=#{max_cache}",
]
args << '--disable-yjit'
- args << '--jit-wait' if wait
- args << '--jit-save-temps' if save_temps
- args << '--jit-debug' if defined?(@jit_debug) && @jit_debug
+ args << '--mjit-wait' if wait
+ args << '--mjit-save-temps' if save_temps
+ args << '--mjit-debug' if defined?(@mjit_debug) && @mjit_debug
args << '-e' << script
base_env = { 'MJIT_SEARCH_BUILD_DIR' => 'true' } # workaround to skip requiring `make install` for `make test-all`
if preloadenv = RbConfig::CONFIG['PRELOADENV'] and !preloadenv.empty?
@@ -62,6 +62,11 @@ module JITSupport
end && !appveyor_pdb_corrupted? && !PENDING_RUBYCI_NICKNAMES.include?(ENV['RUBYCI_NICKNAME'])
end
+ def yjit_supported?
+ # e.g. x86_64-linux, x64-mswin64_140, x64-mingw32, x64-mingw-ucrt
+ RUBY_PLATFORM.match?(/^(x86_64|x64)-/)
+ end
+
# AppVeyor's Visual Studio 2013 / 2015 are known to spuriously generate broken pch / pdb, like:
# error C2859: c:\projects\ruby\x64-mswin_120\include\ruby-2.8.0\x64-mswin64_120\rb_mjit_header-2.8.0.pdb
# is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.
@@ -75,7 +80,7 @@ module JITSupport
end
def remove_mjit_logs(stderr)
- if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # utility for -DFORCE_MJIT_ENABLE
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # utility for -DFORCE_MJIT_ENABLE
stderr.gsub(/^MJIT warning: Skipped to compile unsupported instruction: \w+\n/m, '')
else
stderr
diff --git a/test/logger/test_formatter.rb b/test/logger/test_formatter.rb
new file mode 100644
index 00000000000..94657229914
--- /dev/null
+++ b/test/logger/test_formatter.rb
@@ -0,0 +1,35 @@
+# coding: US-ASCII
+# frozen_string_literal: false
+require 'logger'
+
+class TestFormatter < Test::Unit::TestCase
+ def test_call
+ severity = 'INFO'
+ time = Time.now
+ progname = 'ruby'
+ msg = 'This is a test'
+ formatter = Logger::Formatter.new
+
+ result = formatter.call(severity, time, progname, msg)
+ time_matcher = /\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}/
+ matcher = /#{severity[0..0]}, \[#{time_matcher} #\d+\] #{severity} -- #{progname}: #{msg}\n/
+
+ assert_match(matcher, result)
+ end
+
+ class CustomFormatter < Logger::Formatter
+ def call(time)
+ format_datetime(time)
+ end
+ end
+
+ def test_format_datetime
+ time = Time.now
+ formatter = CustomFormatter.new
+
+ result = formatter.call(time)
+ matcher = /^\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}$/
+
+ assert_match(matcher, result)
+ end
+end
diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb
index d360fa2107d..8f1c15542ab 100644
--- a/test/logger/test_logdevice.rb
+++ b/test/logger/test_logdevice.rb
@@ -435,6 +435,7 @@ class TestLogDevice < Test::Unit::TestCase
logdev1.write(message)
assert_file.identical?(log, logdev1.dev)
+ # NOTE: below assertion fails in JRuby 9.3 and TruffleRuby
assert_file.identical?(log + ".0", logdev2.dev)
logdev2.write(message)
@@ -451,7 +452,7 @@ class TestLogDevice < Test::Unit::TestCase
end
ensure
logdev0.close
- end unless /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
+ end unless /mswin|mingw|cygwin/ =~ RbConfig::CONFIG['host_os']
def test_shifting_midnight
Dir.mktmpdir do |tmpdir|
diff --git a/test/logger/test_logger.rb b/test/logger/test_logger.rb
index 3281d17c7bb..37d0f5862ab 100644
--- a/test/logger/test_logger.rb
+++ b/test/logger/test_logger.rb
@@ -13,7 +13,7 @@ class TestLogger < Test::Unit::TestCase
class Log
attr_reader :label, :datetime, :pid, :severity, :progname, :msg
def initialize(line)
- /\A(\w+), \[([^#]*)#(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ line
+ /\A(\w+), \[([^#]*) #(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ line
@label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6
end
end
@@ -124,7 +124,7 @@ class TestLogger < Test::Unit::TestCase
dummy = STDERR
logger = Logger.new(dummy)
log = log_add(logger, INFO, "foo")
- assert_match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\s*\d+ $/, log.datetime)
+ assert_match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\s*\d+$/, log.datetime)
logger.datetime_format = "%d%b%Y@%H:%M:%S"
log = log_add(logger, INFO, "foo")
assert_match(/^\d\d\w\w\w\d\d\d\d@\d\d:\d\d:\d\d$/, log.datetime)
@@ -203,7 +203,7 @@ class TestLogger < Test::Unit::TestCase
# default
logger = Logger.new(STDERR)
log = log_add(logger, INFO, "foo")
- assert_match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\s*\d+ $/, log.datetime)
+ assert_match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\s*\d+$/, log.datetime)
# config
logger = Logger.new(STDERR, datetime_format: "%d%b%Y@%H:%M:%S")
log = log_add(logger, INFO, "foo")
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb
index c8590219560..b5156078a44 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -1168,6 +1168,30 @@ class TestNetHTTPKeepAlive < Test::Unit::TestCase
}
end
+ def test_keep_alive_reset_on_new_connection
+ # Using WEBrick's debug log output on accepting connection:
+ #
+ # "[2021-04-29 20:36:46] DEBUG accept: 127.0.0.1:50674\n"
+ @log_tester = nil
+ @server.logger.level = WEBrick::BasicLog::DEBUG
+
+ start {|http|
+ res = http.get('/')
+ http.keep_alive_timeout = 1
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ http.finish
+ assert_equal 1, @log.grep(/accept/i).size
+
+ sleep 1.5
+ http.start
+ res = http.get('/')
+ assert_kind_of Net::HTTPResponse, res
+ assert_kind_of String, res.body
+ assert_equal 2, @log.grep(/accept/i).size
+ }
+ end
+
class MockSocket
attr_reader :count
def initialize(success_after: nil)
diff --git a/test/net/http/test_http_request.rb b/test/net/http/test_http_request.rb
index 239b2d10095..7fd82b03539 100644
--- a/test/net/http/test_http_request.rb
+++ b/test/net/http/test_http_request.rb
@@ -46,8 +46,9 @@ class HTTPRequestTest < Test::Unit::TestCase
assert_not_predicate req, :response_body_permitted?
expected = {
- 'accept' => %w[*/*],
- 'user-agent' => %w[Ruby],
+ 'accept' => %w[*/*],
+ "accept-encoding" => %w[gzip;q=1.0,deflate;q=0.6,identity;q=0.3],
+ 'user-agent' => %w[Ruby],
}
assert_equal expected, req.to_hash
diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb
index 00b0072e706..86a467ac194 100644
--- a/test/net/http/test_httpresponse.rb
+++ b/test/net/http/test_httpresponse.rb
@@ -78,7 +78,7 @@ EOS
def test_read_body_block_mod
# http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3019353
- if defined?(RubyVM::JIT) ? RubyVM::JIT.enabled? : defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
omit 'too unstable with --jit-wait, and extending read_timeout did not help it'
end
IO.pipe do |r, w|
diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
index 4dc9f1b026c..603d6ecc1ab 100644
--- a/test/net/http/test_https.rb
+++ b/test/net/http/test_https.rb
@@ -137,7 +137,7 @@ class TestNetHTTPS < Test::Unit::TestCase
def test_session_reuse
# FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h.
# See https://github.com/openssl/openssl/pull/5967 for details.
- skip if OpenSSL::OPENSSL_LIBRARY_VERSION =~ /OpenSSL 1.1.0h/
+ omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h')
http = Net::HTTP.new(HOST, config("port"))
http.use_ssl = true
@@ -164,7 +164,7 @@ class TestNetHTTPS < Test::Unit::TestCase
def test_session_reuse_but_expire
# FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h.
- skip if OpenSSL::OPENSSL_LIBRARY_VERSION =~ /OpenSSL 1.1.0h/
+ omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h')
http = Net::HTTP.new(HOST, config("port"))
http.use_ssl = true
@@ -255,7 +255,7 @@ class TestNetHTTPS < Test::Unit::TestCase
ex = assert_raise(OpenSSL::SSL::SSLError){
http.request_get("/") {|res| }
}
- re_msg = /certificate verify failed|hostname \"#{HOST_IP}\" does not match/
+ re_msg = /certificate verify failed|hostname \"#{HOST_IP}\" does not match|ssl3 ext invalid servername/
assert_match(re_msg, ex.message)
end
diff --git a/test/net/http/test_https_proxy.rb b/test/net/http/test_https_proxy.rb
index f833f1a1e3f..4c2a92ccd62 100644
--- a/test/net/http/test_https_proxy.rb
+++ b/test/net/http/test_https_proxy.rb
@@ -10,7 +10,7 @@ class HTTPSProxyTest < Test::Unit::TestCase
begin
OpenSSL
rescue LoadError
- skip 'autoload problem. see [ruby-dev:45021][Bug #5786]'
+ omit 'autoload problem. see [ruby-dev:45021][Bug #5786]'
end
TCPServer.open("127.0.0.1", 0) {|serv|
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb
index 6bd847806bd..0fd79715857 100644
--- a/test/openssl/test_asn1.rb
+++ b/test/openssl/test_asn1.rb
@@ -170,7 +170,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
str = +"\000"; str[0] = 0b00000110.chr
assert_equal(str, extv.value)
- ext = extensions.value[0].value[2] # subjetKeyIdentifier
+ ext = extensions.value[0].value[2] # subjectKeyIdentifier
assert_equal(OpenSSL::ASN1::Sequence, ext.class)
assert_equal(2, ext.value.size)
assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 3f0622f94fd..346602dada2 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -334,6 +334,31 @@ class OpenSSL::TestBN < OpenSSL::TestCase
e.set_flags(0)
assert_equal(4, e.get_flags(OpenSSL::BN::CONSTTIME))
end
+
+ if respond_to?(:ractor)
+ ractor
+ def test_ractor
+ assert_equal(@e1, Ractor.new { OpenSSL::BN.new("999") }.take)
+ assert_equal(@e3, Ractor.new { OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2) }.take)
+ assert_equal("999", Ractor.new(@e1) { |e1| e1.to_s }.take)
+ assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", Ractor.new(@e3) { |e3| e3.to_s(16) }.take)
+ assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.take)
+ assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.take)
+ assert_equal(false, Ractor.new { 1.to_bn.zero? }.take)
+ assert_equal(true, Ractor.new { 1.to_bn.one? }.take)
+ assert_equal(true, Ractor.new(@e2) { _1.negative? }.take)
+ assert_equal("-03E7", Ractor.new(@e2) { _1.to_s(16) }.take)
+ assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.take)
+ assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.take)
+ assert_equal(true, Ractor.new { 0.to_bn.zero? }.take)
+ assert_equal(true, Ractor.new { 1.to_bn.one? }.take )
+ assert_equal(false,Ractor.new { 2.to_bn.odd? }.take)
+ assert_equal(true, Ractor.new(@e2) { _1.negative? }.take)
+ assert_include(128..255, Ractor.new { OpenSSL::BN.rand(8)}.take)
+ assert_include(0...2**32, Ractor.new { OpenSSL::BN.generate_prime(32) }.take)
+ assert_equal(0, Ractor.new { OpenSSL::BN.new(999).get_flags(OpenSSL::BN::CONSTTIME) }.take)
+ end
+ end
end
end
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index 6d18c0c85c8..b5fdf0b3d11 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -135,14 +135,11 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
def test_ciphers
- OpenSSL::Cipher.ciphers.each{|name|
- next if /netbsd/ =~ RUBY_PLATFORM && /idea|rc5/i =~ name
- begin
- assert_kind_of(OpenSSL::Cipher, OpenSSL::Cipher.new(name))
- rescue OpenSSL::Cipher::CipherError => e
- raise unless /wrap/ =~ name and /wrap mode not allowed/ =~ e.message
- end
- }
+ ciphers = OpenSSL::Cipher.ciphers
+ assert_kind_of Array, ciphers
+ assert_include ciphers, "aes-128-cbc"
+ assert_include ciphers, "aes128" # alias of aes-128-cbc
+ assert_include ciphers, "aes-128-gcm"
end
def test_AES
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
index 2f53a813e19..47cb3718dff 100644
--- a/test/openssl/test_hmac.rb
+++ b/test/openssl/test_hmac.rb
@@ -21,6 +21,7 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
end
def test_dup
+ pend "HMAC#initialize_copy is currently broken on OpenSSL 3.0.0" if openssl?(3, 0, 0)
h1 = OpenSSL::HMAC.new("KEY", "MD5")
h1.update("DATA")
h = h1.dup
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 757704caf67..161af1897bd 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -26,14 +26,19 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_derive_key
- dh1 = Fixtures.pkey("dh1024").generate_key!
- dh2 = Fixtures.pkey("dh1024").generate_key!
+ params = Fixtures.pkey("dh1024")
+ dh1 = OpenSSL::PKey.generate_key(params)
+ dh2 = OpenSSL::PKey.generate_key(params)
dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
dh2_pub = OpenSSL::PKey.read(dh2.public_to_der)
+
z = dh1.g.mod_exp(dh1.priv_key, dh1.p).mod_exp(dh2.priv_key, dh1.p).to_s(2)
assert_equal z, dh1.derive(dh2_pub)
assert_equal z, dh2.derive(dh1_pub)
+ assert_raise(OpenSSL::PKey::PKeyError) { params.derive(dh1_pub) }
+ assert_raise(OpenSSL::PKey::PKeyError) { dh1_pub.derive(params) }
+
assert_equal z, dh1.compute_key(dh2.pub_key)
assert_equal z, dh2.compute_key(dh1.pub_key)
end
@@ -74,19 +79,16 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_generate_key
- dh = Fixtures.pkey("dh1024").public_key # creates a copy
+ # Deprecated in v3.0.0; incompatible with OpenSSL 3.0
+ dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only
assert_no_key(dh)
dh.generate_key!
assert_key(dh)
- end
- def test_key_exchange
- dh = Fixtures.pkey("dh1024")
dh2 = dh.public_key
- dh.generate_key!
dh2.generate_key!
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
- end
+ end if !openssl?(3, 0, 0)
def test_params_ok?
dh0 = Fixtures.pkey("dh1024")
@@ -105,13 +107,32 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_dup
- dh = Fixtures.pkey("dh1024")
- dh2 = dh.dup
- assert_equal dh.to_der, dh2.to_der # params
- assert_equal_params dh, dh2 # keys
- dh2.set_pqg(dh2.p + 1, nil, dh2.g)
- assert_not_equal dh2.p, dh.p
- assert_equal dh2.g, dh.g
+ # Parameters only
+ dh1 = Fixtures.pkey("dh1024")
+ dh2 = dh1.dup
+ assert_equal dh1.to_der, dh2.to_der
+ assert_not_equal nil, dh1.p
+ assert_not_equal nil, dh1.g
+ assert_equal [dh1.p, dh1.g], [dh2.p, dh2.g]
+ assert_equal nil, dh1.pub_key
+ assert_equal nil, dh1.priv_key
+ assert_equal [dh1.pub_key, dh1.priv_key], [dh2.pub_key, dh2.priv_key]
+
+ # PKey is immutable in OpenSSL >= 3.0
+ if !openssl?(3, 0, 0)
+ dh2.set_pqg(dh2.p + 1, nil, dh2.g)
+ assert_not_equal dh2.p, dh1.p
+ end
+
+ # With a key pair
+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024"))
+ dh4 = dh3.dup
+ assert_equal dh3.to_der, dh4.to_der
+ assert_equal dh1.to_der, dh4.to_der # encodes parameters only
+ assert_equal [dh1.p, dh1.g], [dh4.p, dh4.g]
+ assert_not_equal nil, dh3.pub_key
+ assert_not_equal nil, dh3.priv_key
+ assert_equal [dh3.pub_key, dh3.priv_key], [dh4.pub_key, dh4.priv_key]
end
def test_marshal
@@ -123,11 +144,6 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
private
- def assert_equal_params(dh1, dh2)
- assert_equal(dh1.g, dh2.g)
- assert_equal(dh1.p, dh2.p)
- end
-
def assert_no_key(dh)
assert_equal(false, dh.public?)
assert_equal(false, dh.private?)
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 0994607f21a..726b7dbf7e6 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -208,8 +208,12 @@ fWLOqqkzFeRrYMDzUpl36XktY6Yq8EJYlW9pCMmBVNy/dQ==
key = Fixtures.pkey("dsa1024")
key2 = key.dup
assert_equal key.params, key2.params
- key2.set_pqg(key2.p + 1, key2.q, key2.g)
- assert_not_equal key.params, key2.params
+
+ # PKey is immutable in OpenSSL >= 3.0
+ if !openssl?(3, 0, 0)
+ key2.set_pqg(key2.p + 1, key2.q, key2.g)
+ assert_not_equal key.params, key2.params
+ end
end
def test_marshal
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index 3f5958af50b..ffe5a94e5b1 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -13,21 +13,23 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
# FIPS-selftest failure on some environment, so skip for now.
next if ["Oakley", "X25519"].any? { |n| curve_name.start_with?(n) }
- key = OpenSSL::PKey::EC.new(curve_name)
- key.generate_key!
-
+ key = OpenSSL::PKey::EC.generate(curve_name)
assert_predicate key, :private?
assert_predicate key, :public?
assert_nothing_raised { key.check_key }
end
- key1 = OpenSSL::PKey::EC.new("prime256v1").generate_key!
+ key1 = OpenSSL::PKey::EC.generate("prime256v1")
- key2 = OpenSSL::PKey::EC.new
- key2.group = key1.group
- key2.private_key = key1.private_key
- key2.public_key = key1.public_key
- assert_equal key1.to_der, key2.to_der
+ # PKey is immutable in OpenSSL >= 3.0; constructing an empty EC object is
+ # deprecated
+ if !openssl?(3, 0, 0)
+ key2 = OpenSSL::PKey::EC.new
+ key2.group = key1.group
+ key2.private_key = key1.private_key
+ key2.public_key = key1.public_key
+ assert_equal key1.to_der, key2.to_der
+ end
key3 = OpenSSL::PKey::EC.new(key1)
assert_equal key1.to_der, key3.to_der
@@ -37,10 +39,14 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
key5 = key1.dup
assert_equal key1.to_der, key5.to_der
- key_tmp = OpenSSL::PKey::EC.new("prime256v1").generate_key!
- key5.private_key = key_tmp.private_key
- key5.public_key = key_tmp.public_key
- assert_not_equal key1.to_der, key5.to_der
+
+ # PKey is immutable in OpenSSL >= 3.0; EC object should not be modified
+ if !openssl?(3, 0, 0)
+ key_tmp = OpenSSL::PKey::EC.generate("prime256v1")
+ key5.private_key = key_tmp.private_key
+ key5.public_key = key_tmp.public_key
+ assert_not_equal key1.to_der, key5.to_der
+ end
end
def test_generate
@@ -52,6 +58,13 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal(true, ec.private?)
end
+ def test_generate_key
+ ec = OpenSSL::PKey::EC.new("prime256v1")
+ assert_equal false, ec.private?
+ ec.generate_key!
+ assert_equal true, ec.private?
+ end if !openssl?(3, 0, 0)
+
def test_marshal
key = Fixtures.pkey("p256")
deserialized = Marshal.load(Marshal.dump(key))
@@ -60,22 +73,26 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
def test_check_key
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key!
- assert_equal(true, key.check_key)
- assert_equal(true, key.private?)
- assert_equal(true, key.public?)
- key2 = OpenSSL::PKey::EC.new(key.group)
- assert_equal(false, key2.private?)
- assert_equal(false, key2.public?)
- key2.public_key = key.public_key
- assert_equal(false, key2.private?)
- assert_equal(true, key2.public?)
- key2.private_key = key.private_key
+ key0 = Fixtures.pkey("p256")
+ assert_equal(true, key0.check_key)
+ assert_equal(true, key0.private?)
+ assert_equal(true, key0.public?)
+
+ key1 = OpenSSL::PKey.read(key0.public_to_der)
+ assert_equal(true, key1.check_key)
+ assert_equal(false, key1.private?)
+ assert_equal(true, key1.public?)
+
+ key2 = OpenSSL::PKey.read(key0.private_to_der)
assert_equal(true, key2.private?)
assert_equal(true, key2.public?)
assert_equal(true, key2.check_key)
- key2.private_key += 1
- assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
+
+ # EC#private_key= is deprecated in 3.0 and won't work on OpenSSL 3.0
+ if !openssl?(3, 0, 0)
+ key2.private_key += 1
+ assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
+ end
end
def test_sign_verify
@@ -107,7 +124,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal [zIUT].pack("H*"), a.derive(b)
assert_equal a.derive(b), a.dh_compute_key(b.public_key)
- end
+ end if !openssl?(3, 0, 0) # TODO: Test it without using #private_key=
def test_sign_verify_raw
key = Fixtures.pkey("p256")
@@ -136,7 +153,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
def test_dsa_sign_asn1_FIPS186_3
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key!
+ key = OpenSSL::PKey::EC.generate("prime256v1")
size = key.group.order.num_bits / 8 + 1
dgst = (1..size).to_a.pack('C*')
sig = key.dsa_sign_asn1(dgst)
@@ -145,8 +162,8 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
def test_dh_compute_key
- key_a = OpenSSL::PKey::EC.new("prime256v1").generate_key!
- key_b = OpenSSL::PKey::EC.new(key_a.group).generate_key!
+ key_a = OpenSSL::PKey::EC.generate("prime256v1")
+ key_b = OpenSSL::PKey::EC.generate(key_a.group)
pub_a = key_a.public_key
pub_b = key_b.public_key
@@ -276,7 +293,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
def test_ec_point
group = OpenSSL::PKey::EC::Group.new("prime256v1")
- key = OpenSSL::PKey::EC.new(group).generate_key!
+ key = OpenSSL::PKey::EC.generate(group)
point = key.public_key
point2 = OpenSSL::PKey::EC::Point.new(group, point.to_bn)
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index dbe87ba4c1b..4bb39ed4a64 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -31,15 +31,18 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
assert(!key4.private?)
rsa1024 = Fixtures.pkey("rsa1024")
- # Generated by RSA#set_key
- key5 = OpenSSL::PKey::RSA.new
- key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
- assert(key5.private?)
-
- # Generated by RSA#set_key, without d
- key6 = OpenSSL::PKey::RSA.new
- key6.set_key(rsa1024.n, rsa1024.e, nil)
- assert(!key6.private?)
+ if !openssl?(3, 0, 0)
+ key = OpenSSL::PKey::RSA.new
+ # Generated by RSA#set_key
+ key5 = OpenSSL::PKey::RSA.new
+ key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
+ assert(key5.private?)
+
+ # Generated by RSA#set_key, without d
+ key6 = OpenSSL::PKey::RSA.new
+ key6.set_key(rsa1024.n, rsa1024.e, nil)
+ assert(!key6.private?)
+ end
end
def test_new
@@ -235,36 +238,52 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
def test_export
rsa1024 = Fixtures.pkey("rsa1024")
- key = OpenSSL::PKey::RSA.new
- # key has only n, e and d
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
- assert_equal rsa1024.public_key.export, key.export
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der)
+ assert_not_equal rsa1024.export, pub.export
+ assert_equal rsa1024.public_to_pem, pub.export
+
+ # PKey is immutable in OpenSSL >= 3.0
+ if !openssl?(3, 0, 0)
+ key = OpenSSL::PKey::RSA.new
+
+ # key has only n, e and d
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
+ assert_equal rsa1024.public_key.export, key.export
- # key has only n, e, d, p and q
- key.set_factors(rsa1024.p, rsa1024.q)
- assert_equal rsa1024.public_key.export, key.export
+ # key has only n, e, d, p and q
+ key.set_factors(rsa1024.p, rsa1024.q)
+ assert_equal rsa1024.public_key.export, key.export
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
- assert_equal rsa1024.export, key.export
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
+ assert_equal rsa1024.export, key.export
+ end
end
def test_to_der
rsa1024 = Fixtures.pkey("rsa1024")
- key = OpenSSL::PKey::RSA.new
- # key has only n, e and d
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
- assert_equal rsa1024.public_key.to_der, key.to_der
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der)
+ assert_not_equal rsa1024.to_der, pub.to_der
+ assert_equal rsa1024.public_to_der, pub.to_der
+
+ # PKey is immutable in OpenSSL >= 3.0
+ if !openssl?(3, 0, 0)
+ key = OpenSSL::PKey::RSA.new
- # key has only n, e, d, p and q
- key.set_factors(rsa1024.p, rsa1024.q)
- assert_equal rsa1024.public_key.to_der, key.to_der
+ # key has only n, e and d
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
+ assert_equal rsa1024.public_key.to_der, key.to_der
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
- assert_equal rsa1024.to_der, key.to_der
+ # key has only n, e, d, p and q
+ key.set_factors(rsa1024.p, rsa1024.q)
+ assert_equal rsa1024.public_key.to_der, key.to_der
+
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
+ assert_equal rsa1024.to_der, key.to_der
+ end
end
def test_RSAPrivateKey
@@ -306,6 +325,12 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
assert_equal asn1.to_der, rsa1024.to_der
assert_equal pem, rsa1024.export
+
+ # Unknown PEM prepended
+ cert = issue_cert(OpenSSL::X509::Name.new([["CN", "nobody"]]), rsa1024, 1, [], nil, nil)
+ str = cert.to_text + cert.to_pem + rsa1024.to_pem
+ key = OpenSSL::PKey::RSA.new(str)
+ assert_same_rsa rsa1024, key
end
def test_RSAPrivateKey_encrypted
@@ -495,8 +520,12 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
key = Fixtures.pkey("rsa1024")
key2 = key.dup
assert_equal key.params, key2.params
- key2.set_key(key2.n, 3, key2.d)
- assert_not_equal key.params, key2.params
+
+ # PKey is immutable in OpenSSL >= 3.0
+ if !openssl?(3, 0, 0)
+ key2.set_key(key2.n, 3, key2.d)
+ assert_not_equal key.params, key2.params
+ end
end
def test_marshal
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 65dbe7ac241..a7607da0736 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -373,59 +373,20 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
- def test_read_nonblock_without_session
- EnvUtil.suppress_warning do
- start_server(start_immediately: false) { |port|
- sock = TCPSocket.new("127.0.0.1", port)
- ssl = OpenSSL::SSL::SSLSocket.new(sock)
- ssl.sync_close = true
-
- assert_equal :wait_readable, ssl.read_nonblock(100, exception: false)
- ssl.write("abc\n")
- IO.select [ssl]
- assert_equal('a', ssl.read_nonblock(1))
- assert_equal("bc\n", ssl.read_nonblock(100))
- assert_equal :wait_readable, ssl.read_nonblock(100, exception: false)
- ssl.close
- }
- end
- end
-
- def test_starttls
- server_proc = -> (ctx, ssl) {
- while line = ssl.gets
- if line =~ /^STARTTLS$/
- ssl.write("x")
- ssl.flush
- ssl.accept
- break
- end
- ssl.write(line)
- end
- readwrite_loop(ctx, ssl)
- }
-
- EnvUtil.suppress_warning do # read/write on not started session
- start_server(start_immediately: false,
- server_proc: server_proc) { |port|
- begin
- sock = TCPSocket.new("127.0.0.1", port)
- ssl = OpenSSL::SSL::SSLSocket.new(sock)
-
- ssl.puts "plaintext"
- assert_equal "plaintext\n", ssl.gets
+ def test_unstarted_session
+ start_server do |port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
- ssl.puts("STARTTLS")
- ssl.read(1)
- ssl.connect
+ assert_raise(OpenSSL::SSL::SSLError) { ssl.syswrite("data") }
+ assert_raise(OpenSSL::SSL::SSLError) { ssl.sysread(1) }
- ssl.puts "over-tls"
- assert_equal "over-tls\n", ssl.gets
- ensure
- ssl&.close
- sock&.close
- end
- }
+ ssl.connect
+ ssl.puts "abc"
+ assert_equal "abc\n", ssl.gets
+ ensure
+ ssl&.close
+ sock&.close
end
end
@@ -932,14 +893,12 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
end
- begin
- sock = TCPSocket.new("127.0.0.1", port)
- sock.puts "abc"
- ensure
- sock&.close
- end
+ sock = TCPSocket.new("127.0.0.1", port)
+ sock << "\x00" * 1024
assert t.join
+ ensure
+ sock&.close
server.close
end
@@ -1041,8 +1000,9 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
ctx_proc = proc { |ctx|
+ now = Time.now
ctx.cert = issue_cert(@svr, @svr_key, 30, [], @ca_cert, @ca_key,
- not_before: Time.now-100, not_after: Time.now-10)
+ not_before: now - 7200, not_after: now - 3600)
}
start_server(ignore_listener_error: true, ctx_proc: ctx_proc) { |port|
store = OpenSSL::X509::Store.new
@@ -1249,46 +1209,51 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_options_disable_versions
- # Note: Use of these OP_* flags has been deprecated since OpenSSL 1.1.0.
+ # It's recommended to use SSLContext#{min,max}_version= instead in real
+ # applications. The purpose of this test case is to check that SSL options
+ # are properly propagated to OpenSSL library.
supported = check_supported_protocol_versions
+ if !defined?(OpenSSL::SSL::TLS1_3_VERSION) ||
+ !supported.include?(OpenSSL::SSL::TLS1_2_VERSION) ||
+ !supported.include?(OpenSSL::SSL::TLS1_3_VERSION) ||
+ !defined?(OpenSSL::SSL::OP_NO_TLSv1_3) # LibreSSL < 3.4
+ pend "this test case requires both TLS 1.2 and TLS 1.3 to be supported " \
+ "and enabled by default"
+ end
- if supported.include?(OpenSSL::SSL::TLS1_1_VERSION) &&
- supported.include?(OpenSSL::SSL::TLS1_2_VERSION)
- # Server disables ~ TLS 1.1
- ctx_proc = proc { |ctx|
- ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
- OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1
- }
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
- # Client only supports TLS 1.1
- ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_1_VERSION
- assert_handshake_error { server_connect(port, ctx1) { } }
+ # Server disables TLS 1.2 and earlier
+ ctx_proc = proc { |ctx|
+ ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
+ OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 |
+ OpenSSL::SSL::OP_NO_TLSv1_2
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ # Client only supports TLS 1.2
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ assert_handshake_error { server_connect(port, ctx1) { } }
- # Client only supports TLS 1.2
- ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_2_VERSION
- assert_nothing_raised { server_connect(port, ctx2) { } }
- }
+ # Client only supports TLS 1.3
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_3_VERSION
+ assert_nothing_raised { server_connect(port, ctx2) { } }
+ }
- # Server only supports TLS 1.1
- ctx_proc = proc { |ctx|
- ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
- }
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
- # Client disables TLS 1.1
- ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_1
- assert_handshake_error { server_connect(port, ctx1) { } }
+ # Server only supports TLS 1.2
+ ctx_proc = proc { |ctx|
+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ # Client doesn't support TLS 1.2
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_2
+ assert_handshake_error { server_connect(port, ctx1) { } }
- # Client disables TLS 1.2
- ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_2
- assert_nothing_raised { server_connect(port, ctx2) { } }
- }
- else
- pend "TLS 1.1 and TLS 1.2 must be supported; skipping"
- end
+ # Client supports TLS 1.2 by default
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_3
+ assert_nothing_raised { server_connect(port, ctx2) { } }
+ }
end
def test_ssl_methods_constant
diff --git a/test/optparse/test_did_you_mean.rb b/test/optparse/test_did_you_mean.rb
index 39129ffb19b..4c6da4f74ec 100644
--- a/test/optparse/test_did_you_mean.rb
+++ b/test/optparse/test_did_you_mean.rb
@@ -13,10 +13,14 @@ class TestOptionParser::DidYouMean < TestOptionParser
@opt.def_option("--bar", Integer) { |v| @bar = v }
@opt.def_option("--baz", Integer) { |v| @baz = v }
@formatter = ::DidYouMean.formatter
- case @formatter
- when ::DidYouMean::PlainFormatter
+ if ::DidYouMean.const_defined?(:Formatter)
+ ::DidYouMean.formatter = ::DidYouMean::Formatter
else
- ::DidYouMean.formatter = ::DidYouMean::PlainFormatter.new
+ case @formatter
+ when ::DidYouMean::PlainFormatter
+ else
+ ::DidYouMean.formatter = ::DidYouMean::PlainFormatter.new
+ end
end
end
@@ -36,7 +40,7 @@ class TestOptionParser::DidYouMean < TestOptionParser
end
end
- def test_ambiguos
+ def test_ambiguous
assert_raise_with_message(OptionParser::AmbiguousOption, /ambiguous option: --ba\nDid you mean\?\s+bar\s+baz\Z/) do
@opt.permute!(%w"--ba")
end
diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb
index 4ec4d43084e..6487cc831c4 100644
--- a/test/ostruct/test_ostruct.rb
+++ b/test/ostruct/test_ostruct.rb
@@ -280,6 +280,7 @@ class TC_OpenStruct < Test::Unit::TestCase
os = OpenStruct.new(method: :foo, hash: 42)
assert_equal(os.object_id, os.method!(:object_id).call)
assert_not_equal(42, os.hash!)
+ refute os.methods.include?(:"!~!")
end
def test_override_subclass
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 9e14668c99f..c971597602b 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -1355,6 +1355,18 @@ class TestPathname < Test::Unit::TestCase
}
end
+ def test_each_entry_enumerator
+ with_tmpchdir('rubytest-pathname') {|dir|
+ open("a", "w") {}
+ open("b", "w") {}
+ a = []
+ e = Pathname(".").each_entry
+ assert_kind_of(Enumerator, e)
+ e.each {|v| a << v }
+ assert_equal([Pathname("."), Pathname(".."), Pathname("a"), Pathname("b")], a.sort)
+ }
+ end
+
def test_mkdir
with_tmpchdir('rubytest-pathname') {|dir|
Pathname("d").mkdir
diff --git a/test/psych/test_numeric.rb b/test/psych/test_numeric.rb
index 8c3dcd173c1..9c75c016cd4 100644
--- a/test/psych/test_numeric.rb
+++ b/test/psych/test_numeric.rb
@@ -43,5 +43,16 @@ module Psych
str = Psych.load('--- 1.1.1')
assert_equal '1.1.1', str
end
+
+ # This behavior is not to YML spec, but is kept for backwards compatibility
+ def test_string_with_commas
+ number = Psych.load('--- 12,34,56')
+ assert_equal 123456, number
+ end
+
+ def test_string_with_commas_with_strict_integer
+ str = Psych.load('--- 12,34,56', strict_integer: true)
+ assert_equal '12,34,56', str
+ end
end
end
diff --git a/test/psych/test_scalar_scanner.rb b/test/psych/test_scalar_scanner.rb
index ebc9fbdcd2e..145db58fd95 100644
--- a/test/psych/test_scalar_scanner.rb
+++ b/test/psych/test_scalar_scanner.rb
@@ -149,6 +149,31 @@ module Psych
assert_equal 0x123456789abcdef, ss.tokenize('0x12_,34,_56,_789abcdef__')
end
+ def test_scan_strict_int_commas_and_underscores
+ # this test is to ensure adherance to YML spec using the 'strict_integer' option
+ scanner = Psych::ScalarScanner.new ClassLoader.new, strict_integer: true
+ assert_equal 123_456_789, scanner.tokenize('123_456_789')
+ assert_equal '123,456,789', scanner.tokenize('123,456,789')
+ assert_equal '1_2,3,4_5,6_789', scanner.tokenize('1_2,3,4_5,6_789')
+
+ assert_equal 1, scanner.tokenize('1')
+ assert_equal 1, scanner.tokenize('+1')
+ assert_equal(-1, scanner.tokenize('-1'))
+
+ assert_equal 0b010101010, scanner.tokenize('0b010101010')
+ assert_equal 0b010101010, scanner.tokenize('0b01_01_01_010')
+ assert_equal '0b0,1_0,1_,0,1_01,0', scanner.tokenize('0b0,1_0,1_,0,1_01,0')
+
+ assert_equal 01234567, scanner.tokenize('01234567')
+ assert_equal '0_,,,1_2,_34567', scanner.tokenize('0_,,,1_2,_34567')
+
+ assert_equal 0x123456789abcdef, scanner.tokenize('0x123456789abcdef')
+ assert_equal 0x123456789abcdef, scanner.tokenize('0x12_34_56_789abcdef')
+ assert_equal '0x12_,34,_56,_789abcdef', scanner.tokenize('0x12_,34,_56,_789abcdef')
+ assert_equal '0x_12_,34,_56,_789abcdef', scanner.tokenize('0x_12_,34,_56,_789abcdef')
+ assert_equal '0x12_,34,_56,_789abcdef__', scanner.tokenize('0x12_,34,_56,_789abcdef__')
+ end
+
def test_scan_dot
assert_equal '.', ss.tokenize('.')
end
diff --git a/test/rdoc/test_rdoc_class_module.rb b/test/rdoc/test_rdoc_class_module.rb
index 4dcc5d15ab1..13021b9cc79 100644
--- a/test/rdoc/test_rdoc_class_module.rb
+++ b/test/rdoc/test_rdoc_class_module.rb
@@ -63,7 +63,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_ancestors
- assert_equal [@parent, "Object"], @child.ancestors
+ assert_equal [@parent, @object, "BasicObject"], @child.ancestors
end
def test_comment_equals
@@ -89,7 +89,7 @@ class TestRDocClassModule < XrefTestCase
assert_equal 'comment', cm.comment.text
end
- def test_docuent_self_or_methods
+ def test_document_self_or_methods
assert @c1.document_self_or_methods
@c1.document_self = false
@@ -129,7 +129,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_each_ancestor
- assert_equal [@parent], @child.each_ancestor.to_a
+ assert_equal [@parent, @object], @child.each_ancestor.to_a
end
def test_each_ancestor_cycle
@@ -238,7 +238,7 @@ class TestRDocClassModule < XrefTestCase
assert_equal tl, loaded.method_list.first.file
end
- def test_marshal_dump_visibilty
+ def test_marshal_dump_visibility
@store.path = Dir.tmpdir
tl = @store.add_file 'file.rb'
diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb
index ecdb3cbd673..f77fb313832 100644
--- a/test/rdoc/test_rdoc_context.rb
+++ b/test/rdoc/test_rdoc_context.rb
@@ -125,7 +125,7 @@ class TestRDocContext < XrefTestCase
basic = @c1.find_module_named 'BasicObject'
- assert_equal 'Object', basic.superclass
+ assert_equal @object, basic.superclass
end
def test_add_class_object
diff --git a/test/rdoc/test_rdoc_cross_reference.rb b/test/rdoc/test_rdoc_cross_reference.rb
index 94ddc1e1e47..f73681ebc85 100644
--- a/test/rdoc/test_rdoc_cross_reference.rb
+++ b/test/rdoc/test_rdoc_cross_reference.rb
@@ -88,6 +88,15 @@ class TestRDocCrossReference < XrefTestCase
assert_ref @c4_c4, 'C4'
end
+ def test_resolve_class_and_method_of_the_same_name
+ assert_ref @c10_class, 'C10'
+ assert_ref @c10_method, '#C10'
+ assert_ref @c11_class, 'C11'
+ assert_ref @c11_method, '#C11'
+ assert_ref @c10_c11_class, 'C10::C11'
+ assert_ref @c10_c11_method, 'C10#C11'
+ end
+
def test_resolve_class
assert_ref @c1, 'C1'
refute_ref 'H1'
diff --git a/test/rdoc/test_rdoc_extend.rb b/test/rdoc/test_rdoc_extend.rb
index f4c84258646..e78f287b838 100644
--- a/test/rdoc/test_rdoc_extend.rb
+++ b/test/rdoc/test_rdoc_extend.rb
@@ -43,7 +43,7 @@ class TestRDocExtend < XrefTestCase
m1_m2_k0.add_extend e0_m3
assert_equal [e0_m4, e0_m5, e0_m6, e0_m1, e0_m2, e0_m3], m1_m2_k0.extends
- assert_equal ['Object'], m1_m2_k0.ancestors
+ assert_equal [@object, 'BasicObject'], m1_m2_k0.ancestors
m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'
@@ -60,7 +60,7 @@ class TestRDocExtend < XrefTestCase
m1_k1.add_extend e1_k0_m4
assert_equal [e1_m1, e1_m2, e1_m3, e1_m4, e1_k0_m4], m1_k1.extends
- assert_equal ['Object'], m1_k1.ancestors
+ assert_equal [@object, 'BasicObject'], m1_k1.ancestors
m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'
@@ -75,7 +75,7 @@ class TestRDocExtend < XrefTestCase
m1_k2.add_extend e2_k0_m4
assert_equal [e2_m1, e2_m3, e2_m2, e2_k0_m4], m1_k2.extends
- assert_equal ['Object'], m1_k2.ancestors
+ assert_equal [@object, 'BasicObject'], m1_k2.ancestors
m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'
@@ -88,7 +88,7 @@ class TestRDocExtend < XrefTestCase
m1_k3.add_extend e3_m4
assert_equal [e3_m1, e3_m2, e3_m4], m1_k3.extends
- assert_equal ['Object'], m1_k3.ancestors
+ assert_equal [@object, 'BasicObject'], m1_k3.ancestors
end
end
diff --git a/test/rdoc/test_rdoc_include.rb b/test/rdoc/test_rdoc_include.rb
index 67d3dfd88ee..b8e8f260390 100644
--- a/test/rdoc/test_rdoc_include.rb
+++ b/test/rdoc/test_rdoc_include.rb
@@ -46,7 +46,7 @@ class TestRDocInclude < XrefTestCase
assert_equal [i0_m4, i0_m5, i0_m6, i0_m1, i0_m2, i0_m3], m1_m2_k0.includes
assert_equal [m1_m2_m3, m1_m2, m1, m1_m2_k0_m4_m6, m1_m2_k0_m5,
- m1_m2_k0_m4, 'Object'], m1_m2_k0.ancestors
+ m1_m2_k0_m4, @object, 'BasicObject'], m1_m2_k0.ancestors
m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'
@@ -63,8 +63,8 @@ class TestRDocInclude < XrefTestCase
m1_k1.add_include i1_k0_m4
assert_equal [i1_m1, i1_m2, i1_m3, i1_m4, i1_k0_m4], m1_k1.includes
- assert_equal [m1_m2_k0_m4, m1_m2_m3_m4, m1_m2_m3, m1_m2, m1, 'Object'],
- m1_k1.ancestors
+ assert_equal [m1_m2_k0_m4, m1_m2_m3_m4, m1_m2_m3, m1_m2, m1, @object,
+ 'BasicObject'], m1_k1.ancestors
m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'
@@ -79,7 +79,8 @@ class TestRDocInclude < XrefTestCase
m1_k2.add_include i2_k0_m4
assert_equal [i2_m1, i2_m3, i2_m2, i2_k0_m4], m1_k2.includes
- assert_equal [m1_m2_k0_m4, m1_m2, m1_m3, m1, 'Object'], m1_k2.ancestors
+ assert_equal [m1_m2_k0_m4, m1_m2, m1_m3, m1, @object, 'BasicObject'],
+ m1_k2.ancestors
m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'
@@ -92,7 +93,7 @@ class TestRDocInclude < XrefTestCase
m1_k3.add_include i3_m4
assert_equal [i3_m1, i3_m2, i3_m4], m1_k3.includes
- assert_equal [m1_m2_m4, m1_m2, m1, 'Object'], m1_k3.ancestors
+ assert_equal [m1_m2_m4, m1_m2, m1, @object, 'BasicObject'], m1_k3.ancestors
end
def test_store_equals
diff --git a/test/rdoc/test_rdoc_normal_class.rb b/test/rdoc/test_rdoc_normal_class.rb
index 874eaaa88c9..7cb5e4bfc78 100644
--- a/test/rdoc/test_rdoc_normal_class.rb
+++ b/test/rdoc/test_rdoc_normal_class.rb
@@ -11,7 +11,7 @@ class TestRDocNormalClass < XrefTestCase
sub_klass.superclass = klass
sub_klass.add_include incl
- assert_equal [incl.name, klass, 'Object'], sub_klass.ancestors
+ assert_equal [incl.name, klass, @object, 'BasicObject'], sub_klass.ancestors
end
def test_ancestors_multilevel
@@ -19,7 +19,7 @@ class TestRDocNormalClass < XrefTestCase
c2 = @top_level.add_class RDoc::NormalClass, 'Middle', c1.full_name
c3 = @top_level.add_class RDoc::NormalClass, 'Inner', c2.full_name
- assert_equal [c2, c1, 'Object'], c3.ancestors
+ assert_equal [c2, c1, @object, 'BasicObject'], c3.ancestors
end
def test_aref
diff --git a/test/rdoc/test_rdoc_store.rb b/test/rdoc/test_rdoc_store.rb
index 82340e6b7a1..0abad423289 100644
--- a/test/rdoc/test_rdoc_store.rb
+++ b/test/rdoc/test_rdoc_store.rb
@@ -161,9 +161,10 @@ class TestRDocStore < XrefTestCase
def test_all_classes_and_modules
expected = %w[
- C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
+ C1 C10 C10::C11 C11 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
Child
M1 M1::M2
+ Object
Parent
]
@@ -212,8 +213,9 @@ class TestRDocStore < XrefTestCase
def test_classes
expected = %w[
- C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
+ C1 C10 C10::C11 C11 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
Child
+ Object
Parent
]
diff --git a/test/rdoc/test_rdoc_top_level.rb b/test/rdoc/test_rdoc_top_level.rb
index a954fde9810..3f6d153b681 100644
--- a/test/rdoc/test_rdoc_top_level.rb
+++ b/test/rdoc/test_rdoc_top_level.rb
@@ -90,7 +90,7 @@ class TestRDocTopLevel < XrefTestCase
@top_level.add_method method
object = @store.find_class_named 'Object'
- assert_equal [method], object.method_list
+ assert_equal [@c10_method, @c11_method, method], object.method_list
assert_includes object.in_files, @top_level
end
@@ -101,7 +101,7 @@ class TestRDocTopLevel < XrefTestCase
@top_level.add_method method
object = @store.find_class_named('Object')
- assert_empty object.method_list
+ assert_equal [@c10_method, @c11_method], object.method_list
assert_includes object.in_files, @top_level
end
diff --git a/test/rdoc/xref_data.rb b/test/rdoc/xref_data.rb
index aa9faaecd95..de76a906021 100644
--- a/test/rdoc/xref_data.rb
+++ b/test/rdoc/xref_data.rb
@@ -115,6 +115,23 @@ class C9
end
end
+class C10
+ class C11
+ end
+
+ def C11
+ end
+end
+
+def C10
+end
+
+class C11
+end
+
+def C11
+end
+
module M1
def m
end
diff --git a/test/rdoc/xref_test_case.rb b/test/rdoc/xref_test_case.rb
index 729e4a70b74..22b00d04bc4 100644
--- a/test/rdoc/xref_test_case.rb
+++ b/test/rdoc/xref_test_case.rb
@@ -70,6 +70,14 @@ class XrefTestCase < RDoc::TestCase
@c9_b_c_foo = @c9_b.method_list.first
@c9_b_i_bar = @c9_b.method_list.last
+ @object = @xref_data.find_module_named 'Object'
+ @c10_class = @xref_data.find_module_named 'C10'
+ @c10_method = @object.find_method_named 'C10'
+ @c11_class = @xref_data.find_module_named 'C11'
+ @c10_c11_class = @c10_class.find_module_named 'C11'
+ @c10_c11_method = @c10_class.find_method_named 'C11'
+ @c11_method = @object.find_method_named 'C11'
+
@m1 = @xref_data.find_module_named 'M1'
@m1_m = @m1.method_list.first
diff --git a/test/readline/test_readline.rb b/test/readline/test_readline.rb
index a0438aa1fdf..be338c6c0d4 100644
--- a/test/readline/test_readline.rb
+++ b/test/readline/test_readline.rb
@@ -7,6 +7,7 @@ require "open3"
module BasetestReadline
INPUTRC = "INPUTRC"
+ TERM = "TERM"
SAVED_ENV = %w[COLUMNS LINES]
TIMEOUT = 8
@@ -14,10 +15,12 @@ module BasetestReadline
def setup
@saved_env = ENV.values_at(*SAVED_ENV)
@inputrc, ENV[INPUTRC] = ENV[INPUTRC], IO::NULL
+ @term, ENV[TERM] = ENV[TERM], "vt100"
end
def teardown
ENV[INPUTRC] = @inputrc
+ ENV[TERM] = @term
Readline.instance_variable_set("@completion_proc", nil)
begin
Readline.delete_text
@@ -485,18 +488,23 @@ module BasetestReadline
omit "Skip Readline 7.0" if Readline::VERSION == "7.0"
omit unless respond_to?(:assert_ruby_status)
omit if /mswin|mingw/ =~ RUBY_PLATFORM
+
+ # On 32-bit machine, readline library (or libtinfo) seems to cause SEGV internally even with Readline 8.0
+ # GDB Backtrace: https://gist.github.com/mame/d12b9de3bbc3f16d440c1927398d176a
+ # Maybe the same issue: https://github.com/facebookresearch/nle/issues/120
+ omit if /i[3-6]86-linux/ =~ RUBY_PLATFORM
+
+ if defined?(TestReadline) && self.class == TestReadline
+ use = "use_ext_readline"
+ elsif defined?(TestRelineAsReadline) && self.class == TestRelineAsReadline
+ use = "use_lib_reline"
+ end
code = <<-"end;"
$stdout.sync = true
require 'readline'
require 'helper'
+ #{use}
puts "Readline::VERSION is \#{Readline::VERSION}."
- #{
- if defined?(TestReadline) && self.class == TestReadline
- "use_ext_readline"
- elsif defined?(TestRelineAsReadline) && self.class == TestRelineAsReadline
- "use_lib_reline"
- end
- }
Readline.input = STDIN
# 0. Send SIGINT to this script.
begin
@@ -526,11 +534,12 @@ module BasetestReadline
loop do
c = _out.read(1)
log << c if c
- break if log.include?('input>')
+ break if log.include?('input> ')
end
log << "** SIGINT **"
+ sleep 0.5
Process.kill(:INT, pid)
- sleep 0.1
+ sleep 0.5
loop do
c = _out.read(1)
log << c if c
@@ -559,10 +568,21 @@ module BasetestReadline
assert interrupt_suppressed, "Should handle SIGINT correctly but raised interrupt.\nLog: #{log}\n----"
end
rescue Timeout::Error => e
+ Process.kill(:KILL, pid)
+ log << "\nKilled by timeout"
assert false, "Timed out to handle SIGINT!\nLog: #{log}\nBacktrace:\n#{e.full_message(highlight: false)}\n----"
ensure
- status = Process.wait2(pid).last
- assert status.success?, "Unknown failure with exit status #{status}\nLog: #{log}\n----"
+ status = nil
+ begin
+ Timeout.timeout(TIMEOUT) do
+ status = Process.wait2(pid).last
+ end
+ rescue Timeout::Error => e
+ log << "\nKilled by timeout to wait2"
+ Process.kill(:KILL, pid)
+ assert false, "Timed out to wait for terminating a process in a test of SIGINT!\nLog: #{log}\nBacktrace:\n#{e.full_message(highlight: false)}\n----"
+ end
+ assert status&.success?, "Unknown failure with exit status #{status.inspect}\nLog: #{log}\n----"
end
assert log.include?('INT'), "Interrupt was handled correctly."
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
index cd3783ddb86..e8b8e3a6e10 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -77,6 +77,13 @@ class Reline::TestCase < Test::Unit::TestCase
end
end
+ def input_raw_keys(input, convert = true)
+ input = convert_str(input) if convert
+ input.bytes.each do |b|
+ @line_editor.input_key(Reline::Key.new(b, b, false))
+ end
+ end
+
def assert_line(expected)
expected = convert_str(expected)
assert_equal(expected, @line_editor.line)
@@ -85,9 +92,13 @@ class Reline::TestCase < Test::Unit::TestCase
def assert_byte_pointer_size(expected)
expected = convert_str(expected)
byte_pointer = @line_editor.instance_variable_get(:@byte_pointer)
+ chunk = @line_editor.line.byteslice(0, byte_pointer)
assert_equal(
expected.bytesize, byte_pointer,
- "<#{expected.inspect}> expected but was\n<#{@line_editor.line.byteslice(0, byte_pointer).inspect}>")
+ <<~EOM)
+ <#{expected.inspect} (#{expected.encoding.inspect})> expected but was
+ <#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::GeneralIO.encoding.inspect}>
+ EOM
end
def assert_cursor(expected)
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index aa549a392d6..e00a47c7057 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -11,12 +11,14 @@ class Reline::Config::Test < Reline::TestCase
Dir.mkdir(@tmpdir)
end
Dir.chdir(@tmpdir)
+ Reline.test_mode
@config = Reline::Config.new
end
def teardown
Dir.chdir(@pwd)
FileUtils.rm_rf(@tmpdir)
+ Reline.test_reset
@config.reset
end
@@ -81,6 +83,22 @@ class Reline::Config::Test < Reline::TestCase
assert_equal '(Emacs)', @config.instance_variable_get(:@emacs_mode_string)
end
+ def test_encoding_is_ascii
+ @config.reset
+ Reline::IOGate.reset(encoding: Encoding::US_ASCII)
+ @config = Reline::Config.new
+
+ assert_equal true, @config.convert_meta
+ end
+
+ def test_encoding_is_not_ascii
+ @config.reset
+ Reline::IOGate.reset(encoding: Encoding::UTF_8)
+ @config = Reline::Config.new
+
+ assert_equal nil, @config.convert_meta
+ end
+
def test_comment_line
@config.read_lines([" #a: error\n"])
assert_not_include @config.key_bindings, nil
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 8053225d244..40b26e5058a 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -255,31 +255,31 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
end
def test_em_kill_line
- input_keys("\C-u", false)
+ @line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
assert_byte_pointer_size('')
assert_cursor(0)
assert_cursor_max(0)
assert_line('')
input_keys('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
- input_keys("\C-u", false)
+ @line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
assert_byte_pointer_size('')
assert_cursor(0)
assert_cursor_max(0)
assert_line('')
input_keys('abc')
- input_keys("\C-b\C-u", false)
+ input_keys("\C-b", false)
+ @line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
assert_byte_pointer_size('')
assert_cursor(0)
- assert_cursor_max(1)
- assert_line('c')
- input_keys("\C-u", false)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ input_keys("\C-a", false)
+ @line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
assert_byte_pointer_size('')
assert_cursor(0)
- assert_cursor_max(1)
- assert_line('c')
+ assert_cursor_max(0)
+ assert_line('')
end
def test_ed_move_to_beg
@@ -2306,6 +2306,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
assert_line('abcd')
end
+ def test_halfwidth_kana_width_dakuten
+ input_raw_keys('ガギゲゴ')
+ assert_byte_pointer_size('ガギゲゴ')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ input_keys("\C-b\C-b", false)
+ assert_byte_pointer_size('ガギ')
+ assert_cursor(4)
+ assert_cursor_max(8)
+ input_raw_keys('グ', false)
+ assert_byte_pointer_size('ガギグ')
+ assert_cursor(6)
+ assert_cursor_max(10)
+ assert_line('ガギグゲゴ')
+ end
+
def test_input_unknown_char
input_keys('͸') # U+0378 (unassigned)
assert_line('͸')
@@ -2313,4 +2329,26 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
assert_cursor(1)
assert_cursor_max(1)
end
+
+ def test_unix_line_discard
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-b\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
+ input_keys("\C-f\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
end
diff --git a/test/reline/test_key_actor_vi.rb b/test/reline/test_key_actor_vi.rb
index 722cdc0b75f..b3d49c9bbb2 100644
--- a/test/reline/test_key_actor_vi.rb
+++ b/test/reline/test_key_actor_vi.rb
@@ -1426,4 +1426,32 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
assert_cursor(4)
assert_cursor_max(4)
end
+
+ def test_vi_kill_line_prev
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ input_keys("\C-[\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
+ end
end
diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb
index dd049ac1270..0d45c5da54f 100644
--- a/test/reline/test_reline.rb
+++ b/test/reline/test_reline.rb
@@ -137,14 +137,14 @@ class Reline::Test < Reline::TestCase
end
def test_completion_proc
- skip unless Reline.completion_proc == nil
+ omit unless Reline.completion_proc == nil
# Another test can set Reline.completion_proc
# assert_equal(nil, Reline.completion_proc)
- p = proc {}
- Reline.completion_proc = p
- assert_equal(p, Reline.completion_proc)
+ dummy_proc = proc {}
+ Reline.completion_proc = dummy_proc
+ assert_equal(dummy_proc, Reline.completion_proc)
l = lambda {}
Reline.completion_proc = l
@@ -161,9 +161,9 @@ class Reline::Test < Reline::TestCase
def test_output_modifier_proc
assert_equal(nil, Reline.output_modifier_proc)
- p = proc {}
- Reline.output_modifier_proc = p
- assert_equal(p, Reline.output_modifier_proc)
+ dummy_proc = proc {}
+ Reline.output_modifier_proc = dummy_proc
+ assert_equal(dummy_proc, Reline.output_modifier_proc)
l = lambda {}
Reline.output_modifier_proc = l
@@ -180,9 +180,9 @@ class Reline::Test < Reline::TestCase
def test_prompt_proc
assert_equal(nil, Reline.prompt_proc)
- p = proc {}
- Reline.prompt_proc = p
- assert_equal(p, Reline.prompt_proc)
+ dummy_proc = proc {}
+ Reline.prompt_proc = dummy_proc
+ assert_equal(dummy_proc, Reline.prompt_proc)
l = lambda {}
Reline.prompt_proc = l
@@ -199,9 +199,9 @@ class Reline::Test < Reline::TestCase
def test_auto_indent_proc
assert_equal(nil, Reline.auto_indent_proc)
- p = proc {}
- Reline.auto_indent_proc = p
- assert_equal(p, Reline.auto_indent_proc)
+ dummy_proc = proc {}
+ Reline.auto_indent_proc = dummy_proc
+ assert_equal(dummy_proc, Reline.auto_indent_proc)
l = lambda {}
Reline.auto_indent_proc = l
@@ -218,9 +218,9 @@ class Reline::Test < Reline::TestCase
def test_pre_input_hook
assert_equal(nil, Reline.pre_input_hook)
- p = proc {}
- Reline.pre_input_hook = p
- assert_equal(p, Reline.pre_input_hook)
+ dummy_proc = proc {}
+ Reline.pre_input_hook = dummy_proc
+ assert_equal(dummy_proc, Reline.pre_input_hook)
l = lambda {}
Reline.pre_input_hook = l
@@ -230,9 +230,9 @@ class Reline::Test < Reline::TestCase
def test_dig_perfect_match_proc
assert_equal(nil, Reline.dig_perfect_match_proc)
- p = proc {}
- Reline.dig_perfect_match_proc = p
- assert_equal(p, Reline.dig_perfect_match_proc)
+ dummy_proc = proc {}
+ Reline.dig_perfect_match_proc = dummy_proc
+ assert_equal(dummy_proc, Reline.dig_perfect_match_proc)
l = lambda {}
Reline.dig_perfect_match_proc = l
@@ -310,6 +310,48 @@ class Reline::Test < Reline::TestCase
assert_equal(Reline::KeyActor::Emacs, Reline.send(:core).config.editing_mode.class)
end
+ def test_add_dialog_proc
+ dummy_proc = proc {}
+ Reline.add_dialog_proc(:test_proc, dummy_proc)
+ d = Reline.dialog_proc(:test_proc)
+ assert_equal(dummy_proc, d.dialog_proc)
+
+ dummy_proc_2 = proc {}
+ Reline.add_dialog_proc(:test_proc, dummy_proc_2)
+ d = Reline.dialog_proc(:test_proc)
+ assert_equal(dummy_proc_2, d.dialog_proc)
+
+ l = lambda {}
+ Reline.add_dialog_proc(:test_lambda, l)
+ d = Reline.dialog_proc(:test_lambda)
+ assert_equal(l, d.dialog_proc)
+
+ assert_equal(nil, Reline.dialog_proc(:test_nothing))
+
+ assert_raise(ArgumentError) { Reline.add_dialog_proc(:error, 42) }
+ assert_raise(ArgumentError) { Reline.add_dialog_proc(:error, 'hoge') }
+ assert_raise(ArgumentError) { Reline.add_dialog_proc('error', proc {} ) }
+
+ dummy = DummyCallbackObject.new
+ Reline.add_dialog_proc(:dummy, dummy)
+ d = Reline.dialog_proc(:dummy)
+ assert_equal(dummy, d.dialog_proc)
+ end
+
+ def test_add_dialog_proc_with_context
+ dummy_proc = proc {}
+ array = Array.new
+ Reline.add_dialog_proc(:test_proc, dummy_proc, array)
+ d = Reline.dialog_proc(:test_proc)
+ assert_equal(dummy_proc, d.dialog_proc)
+ assert_equal(array, d.context)
+
+ Reline.add_dialog_proc(:test_proc, dummy_proc, nil)
+ d = Reline.dialog_proc(:test_proc)
+ assert_equal(dummy_proc, d.dialog_proc)
+ assert_equal(nil, d.context)
+ end
+
def test_readmultiline
# readmultiline is module function
assert_include(Reline.methods, :readmultiline)
@@ -322,22 +364,10 @@ class Reline::Test < Reline::TestCase
assert_include(Reline.private_instance_methods, :readline)
end
- def test_inner_readline
- # TODO in Reline::Core
- end
-
def test_read_io
# TODO in Reline::Core
end
- def test_read_escaped_key
- # TODO in Reline::Core
- end
-
- def test_may_req_ambiguous_char_width
- # TODO in Reline::Core
- end
-
def get_reline_encoding
if encoding = Reline::IOGate.encoding
encoding
diff --git a/test/reline/test_terminfo.rb b/test/reline/test_terminfo.rb
index f1bf1979312..dda9b324954 100644
--- a/test/reline/test_terminfo.rb
+++ b/test/reline/test_terminfo.rb
@@ -9,24 +9,53 @@ class Reline::Terminfo::Test < Reline::TestCase
def test_tigetstr
assert Reline::Terminfo.tigetstr('khome')
rescue Reline::Terminfo::TerminfoError => e
- skip e.message
+ omit e.message
+ end
+
+ def test_tigetstr_with_error
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetstr('unknown') }
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetstr(nil) }
end
def test_tiparm
assert Reline::Terminfo.tigetstr('khome').tiparm
rescue Reline::Terminfo::TerminfoError => e
- skip e.message
+ omit e.message
end
def test_tigetstr_with_param
assert Reline::Terminfo.tigetstr('cuu').include?('%p1%d')
rescue Reline::Terminfo::TerminfoError => e
- skip e.message
+ omit e.message
end
def test_tiparm_with_param
assert Reline::Terminfo.tigetstr('cuu').tiparm(4649).include?('4649')
rescue Reline::Terminfo::TerminfoError => e
- skip e.message
+ omit e.message
+ end
+
+ def test_tigetflag
+ assert_instance_of Integer, Reline::Terminfo.tigetflag('xenl')
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ def test_tigetflag_with_error
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetflag('cuu') }
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetflag('unknown') }
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetflag(nil) }
+ end
+
+ def test_tigetnum
+ assert_instance_of Integer, Reline::Terminfo.tigetnum('colors')
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ def test_tigetnum_with_error
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum('cuu') }
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum('unknown') }
+ assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum(nil) }
end
end if Reline::Terminfo.enabled?
diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb
index ff2d68bb828..43a66f45f47 100644
--- a/test/reline/test_within_pipe.rb
+++ b/test/reline/test_within_pipe.rb
@@ -9,7 +9,7 @@ class Reline::WithinPipeTest < Reline::TestCase
@reader, @output_writer = IO.pipe(@encoding)
@output = Reline.output = @output_writer
@config = Reline.send(:core).config
- @config.keyseq_timeout *= 600 if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # for --jit-wait CI
+ @config.keyseq_timeout *= 600 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait CI
@line_editor = Reline.send(:core).line_editor
end
diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl
index da886b8f06f..d27d216652b 100755
--- a/test/reline/yamatanooroti/multiline_repl
+++ b/test/reline/yamatanooroti/multiline_repl
@@ -1,5 +1,9 @@
#!/usr/bin/env ruby
+
+require 'bundler'
+Bundler.require
+
require 'reline'
require 'optparse'
require_relative 'termination_checker'
@@ -27,6 +31,14 @@ opt.on('--broken-dynamic-prompt') {
opt.on('--dynamic-prompt-returns-empty') {
Reline.prompt_proc = proc { |l| [] }
}
+opt.on('--dynamic-prompt-with-newline') {
+ Reline.prompt_proc = proc { |lines|
+ range = lines.size > 1 ? (0..(lines.size - 2)) : (0..0)
+ lines[range].each_with_index.map { |l, i|
+ '[%04d\n]> ' % i
+ }
+ }
+}
opt.on('--auto-indent') {
AutoIndent.new
}
@@ -137,6 +149,28 @@ opt.on('--autocomplete-super-long') {
2000.times.map{ s = "Str_#{c}"; c.succ!; s }.select{ |c| c.start_with?(target) }
}
}
+
+opt.on('--autocomplete-width-long') {
+ Reline.autocompletion = true
+ Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil|
+ %w{
+ remove_instance_variable
+ respond_to?
+ ruby2_keywords
+ rand
+ readline
+ readlines
+ require
+ require_relative
+ raise
+ respond_to_missing?
+ redo
+ rescue
+ retry
+ return
+ }.select{ |c| c.start_with?(target) }
+ }
+}
opt.parse!(ARGV)
begin
diff --git a/test/reline/yamatanooroti/termination_checker.rb b/test/reline/yamatanooroti/termination_checker.rb
index 9c2c3ae740e..24fb24c4b15 100644
--- a/test/reline/yamatanooroti/termination_checker.rb
+++ b/test/reline/yamatanooroti/termination_checker.rb
@@ -4,7 +4,7 @@ require 'irb/ruby-lex'
class TerminationChecker < RubyLex
def terminated?(code)
code.gsub!(/\n*$/, '').concat("\n")
- @tokens = Ripper.lex(code)
+ @tokens = self.class.ripper_lex_without_warning(code)
continue = process_continue
code_block_open = check_code_block(code)
indent = process_nesting_level
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index e1dde835896..c3831121319 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -121,6 +121,7 @@ begin
end
def test_finish_autowrapped_line_in_the_middle_of_multilines
+ omit if RUBY_VERSION < '2.7'
start_terminal(30, 16, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("<<~EOM\n ABCDEFG\nEOM\n")
close
@@ -739,6 +740,16 @@ begin
EOC
end
+ def test_not_meta_key
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("おだんご") # "だ" in UTF-8 contains "\xA0"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> おだんご
+ EOC
+ end
+
def test_force_enter
start_terminal(30, 120, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\nend\C-p\C-e")
@@ -756,6 +767,7 @@ begin
omit if Reline::IOGate.win?
cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
start_terminal(40, 50, ['bash', '-c', cmd])
+ sleep 1
close
assert_screen(<<~'EOC')
> abc def
@@ -937,7 +949,7 @@ begin
def test_dialog_with_fullwidth_chars
ENV['RELINE_TEST_PROMPT'] = '> '
- start_terminal(30, 5, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
+ start_terminal(20, 5, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
6.times{ write('j') }
close
assert_screen(<<~'EOC')
@@ -954,7 +966,7 @@ begin
def test_dialog_with_fullwidth_chars_split
ENV['RELINE_TEST_PROMPT'] = '> '
- start_terminal(30, 6, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
+ start_terminal(20, 6, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
6.times{ write('j') }
close
assert_screen(<<~'EOC')
@@ -1172,6 +1184,155 @@ begin
EOC
end
+ def test_autocomplete_old_dialog_width_greater_than_dialog_width
+ start_terminal(40, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-width-long}, startup_message: 'Multiline REPL.')
+ write("0+ \n12345678901234")
+ write("\C-p")
+ write("r")
+ write("a")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> 0+ ra
+ prompt> 123rand 901234
+ raise
+ EOC
+ end
+
+ def test_scroll_at_bottom_for_dialog
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("\n\n\n\n\n\n")
+ write("def hoge\n\n\n\n\n\n\nend\C-p\C-p\C-p\C-e")
+ write(" S")
+ close
+ assert_screen(<<~'EOC')
+ prompt> def hoge
+ prompt>
+ prompt>
+ prompt>
+ prompt> S
+ prompt> String
+ prompt> Struct
+ prompt> enSymbol
+ ScriptError
+ Signal
+ EOC
+ end
+
+ def test_clear_dialog_in_pasting
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("S")
+ write("tring ")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> String
+ EOC
+ end
+
+ def test_prompt_with_newline
+ ENV['RELINE_TEST_PROMPT'] = "::\n> "
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def hoge\n 3\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ ::\n> def hoge
+ ::\n> 3
+ ::\n> end
+ EOC
+ end
+
+ def test_dynamic_prompt_with_newline
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-with-newline}, startup_message: 'Multiline REPL.')
+ write("def hoge\n 3\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ [0000\n]> def hoge
+ [0001\n]> 3
+ [0001\n]> end
+ EOC
+ end
+
+ def test_clear_dialog_when_just_move_cursor_at_last_line
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n 3\nend\n")
+ write("\C-p\C-p\C-p\C-e\C-hS")
+ write("\C-n")
+ write("1")
+ close
+ assert_screen(<<~'EOC')
+ prompt> 3
+ prompt> end
+ => 3
+ prompt> class S
+ prompt> 31
+ prompt> end
+ EOC
+ end
+
+ def test_clear_dialog_when_adding_new_line_to_end_of_buffer
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n def a\n 3\n end\nend")
+ write("\n")
+ write("class S")
+ write("\n")
+ write(" 3")
+ close
+ assert_screen(<<~'EOC')
+ prompt> end
+ prompt> end
+ => :a
+ prompt> class S
+ prompt> 3
+ EOC
+ end
+
+ def test_insert_newline_in_the_middle_of_buffer_just_after_dialog
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n def a\n 3\n end\nend")
+ write("\n")
+ write("\C-p\C-p\C-p\C-p\C-p\C-e\C-hS")
+ write("\M-\x0D")
+ write(" 3")
+ close
+ assert_screen(<<~'EOC')
+ prompt> end
+ prompt> end
+ => :a
+ prompt> class S
+ prompt> 3
+ prompt> def a
+ prompt> 3
+ prompt> end
+ prompt> end
+ EOC
+ end
+
+ def test_incremental_search_on_not_last_line
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("def abc\nend\n")
+ write("def def\nend\n")
+ write("\C-p\C-p\C-e")
+ write("\C-r")
+ write("a")
+ write("\n\n")
+ close
+ assert_screen(<<~'EOC')
+ prompt> def abc
+ prompt> end
+ => :abc
+ prompt> def def
+ prompt> end
+ => :def
+ prompt> def abc
+ prompt> end
+ => :abc
+ prompt>
+ EOC
+ end
+
def write_inputrc(content)
File.open(@inputrc_file, 'w') do |f|
f.write content
diff --git a/test/resolv/test_addr.rb b/test/resolv/test_addr.rb
index 62092676bae..f701c31d3e5 100644
--- a/test/resolv/test_addr.rb
+++ b/test/resolv/test_addr.rb
@@ -28,6 +28,10 @@ class TestResolvAddr < Test::Unit::TestCase
assert_match(Resolv::IPv6::Regex, "FE80:2:3:4:5:6:7:8%EM1", bug17112)
assert_match(Resolv::IPv6::Regex, "FE80::20D:3AFF:FE7D:9760%ETH0", bug17112)
assert_match(Resolv::IPv6::Regex, "FE80::1%EM1", bug17112)
+
+ bug17524 = "[ruby-core:101992]"
+ assert_match(Resolv::IPv6::Regex, "FE80::20D:3AFF:FE7D:9760%ruby_3.0.0-1", bug17524)
+ assert_match(Resolv::IPv6::Regex, "fe80::1%ruby_3.0.0-1", bug17524)
end
def test_valid_socket_ip_address_list
diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb
index 5171604a823..9d243bbf502 100644
--- a/test/resolv/test_dns.rb
+++ b/test/resolv/test_dns.rb
@@ -72,7 +72,7 @@ class TestResolvDNS < Test::Unit::TestCase
begin
OpenSSL
rescue LoadError
- skip 'autoload problem. see [ruby-dev:45021][Bug #5786]'
+ omit 'autoload problem. see [ruby-dev:45021][Bug #5786]'
end if defined?(OpenSSL)
with_udp('127.0.0.1', 0) {|u|
@@ -161,7 +161,7 @@ class TestResolvDNS < Test::Unit::TestCase
begin
OpenSSL
rescue LoadError
- skip 'autoload problem. see [ruby-dev:45021][Bug #5786]'
+ omit 'autoload problem. see [ruby-dev:45021][Bug #5786]'
end if defined?(OpenSSL)
with_udp('127.0.0.1', 0) {|u|
@@ -297,7 +297,7 @@ class TestResolvDNS < Test::Unit::TestCase
end
def test_no_server
- skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
+ omit if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
u = UDPSocket.new
u.bind("127.0.0.1", 0)
_, port, _, host = u.addr
@@ -314,7 +314,7 @@ class TestResolvDNS < Test::Unit::TestCase
rescue Timeout::Error
if RUBY_PLATFORM.match?(/mingw/)
# cannot repo locally
- skip 'Timeout Error on MinGW CI'
+ omit 'Timeout Error on MinGW CI'
else
raise Timeout::Error
end
diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb
index f155e88de1e..d937cd0f455 100644
--- a/test/rinda/test_rinda.rb
+++ b/test/rinda/test_rinda.rb
@@ -402,7 +402,7 @@ module TupleSpaceTestModule
end
def test_cancel_02
- skip 'this test is unstable with --jit-wait' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ omit 'this test is unstable with --jit-wait' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
entry = @ts.write([:removeme, 1])
assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
entry.cancel
@@ -528,7 +528,7 @@ class TupleSpaceProxyTest < Test::Unit::TestCase
end
def test_take_bug_8215
- skip "this test randomly fails on mswin" if /mswin/ =~ RUBY_PLATFORM
+ omit "this test randomly fails on mswin" if /mswin/ =~ RUBY_PLATFORM
service = DRb.start_service("druby://localhost:0", @ts_base)
uri = service.uri
@@ -591,7 +591,7 @@ module RingIPv6
return if
Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
end
- skip 'IPv6 not available'
+ omit 'IPv6 not available'
end
def ipv6_mc(rf, hops = nil)
@@ -662,7 +662,7 @@ class TestRingServer < Test::Unit::TestCase
end
def test_do_reply_local
- skip 'timeout-based test becomes unstable with --jit-wait' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ omit 'timeout-based test becomes unstable with --jit-wait' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
with_timeout(30) {_test_do_reply_local}
end
@@ -693,7 +693,7 @@ class TestRingServer < Test::Unit::TestCase
begin
v4mc = @rs.make_socket('239.0.0.1')
rescue Errno::ENOBUFS => e
- skip "Missing multicast support in OS: #{e.message}"
+ omit "Missing multicast support in OS: #{e.message}"
end
begin
@@ -704,7 +704,7 @@ class TestRingServer < Test::Unit::TestCase
end
rescue TypeError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in getsockopt(2) on AIX"
+ omit "Known bug in getsockopt(2) on AIX"
end
raise $!
end
@@ -714,7 +714,7 @@ class TestRingServer < Test::Unit::TestCase
end
def test_make_socket_ipv6_multicast
- skip 'IPv6 not available' unless
+ omit 'IPv6 not available' unless
Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
begin
@@ -722,7 +722,7 @@ class TestRingServer < Test::Unit::TestCase
rescue Errno::EADDRNOTAVAIL
return # IPv6 address for multicast not available
rescue Errno::ENOBUFS => e
- skip "Missing multicast support in OS: #{e.message}"
+ omit "Missing multicast support in OS: #{e.message}"
end
if Socket.const_defined?(:SO_REUSEPORT) then
@@ -740,7 +740,7 @@ class TestRingServer < Test::Unit::TestCase
begin
@rs = Rinda::RingServer.new(@ts, [['239.0.0.1', '0.0.0.0']], @port)
rescue Errno::ENOBUFS => e
- skip "Missing multicast support in OS: #{e.message}"
+ omit "Missing multicast support in OS: #{e.message}"
end
v4mc = @rs.instance_variable_get('@sockets').first
@@ -753,7 +753,7 @@ class TestRingServer < Test::Unit::TestCase
end
rescue TypeError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in getsockopt(2) on AIX"
+ omit "Known bug in getsockopt(2) on AIX"
end
raise $!
end
@@ -763,7 +763,7 @@ class TestRingServer < Test::Unit::TestCase
end
def test_ring_server_ipv6_multicast
- skip 'IPv6 not available' unless
+ omit 'IPv6 not available' unless
Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
@rs.shutdown
@@ -852,7 +852,7 @@ class TestRingFinger < Test::Unit::TestCase
assert(v4.getsockopt(:SOL_SOCKET, :SO_BROADCAST).bool)
rescue TypeError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in getsockopt(2) on AIX"
+ omit "Known bug in getsockopt(2) on AIX"
end
raise $!
ensure
diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb
index cef584c1577..13bd44e83d0 100644
--- a/test/ripper/test_scanner_events.rb
+++ b/test/ripper/test_scanner_events.rb
@@ -56,13 +56,13 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
end
def test_lex
- assert_equal [],
+ assert_lex [],
Ripper.lex('')
- assert_equal [[[1,0], :on_ident, "a", Ripper::EXPR_CMDARG]],
+ assert_lex [[[1,0], :on_ident, "a", Ripper::EXPR_CMDARG]],
Ripper.lex('a')
- assert_equal [[[1, 0], :on_kw, "nil", Ripper::EXPR_END]],
+ assert_lex [[[1, 0], :on_kw, "nil", Ripper::EXPR_END]],
Ripper.lex("nil")
- assert_equal [[[1, 0], :on_kw, "def", Ripper::EXPR_FNAME],
+ assert_lex [[[1, 0], :on_kw, "def", Ripper::EXPR_FNAME],
[[1, 3], :on_sp, " ", Ripper::EXPR_FNAME],
[[1, 4], :on_ident, "m", Ripper::EXPR_ENDFN],
[[1, 5], :on_lparen, "(", Ripper::EXPR_BEG | Ripper::EXPR_LABEL],
@@ -70,39 +70,39 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
[[1, 7], :on_rparen, ")", Ripper::EXPR_ENDFN],
[[1, 8], :on_kw, "end", Ripper::EXPR_END]],
Ripper.lex("def m(a)end")
- assert_equal [[[1, 0], :on_int, "1", Ripper::EXPR_END],
+ assert_lex [[[1, 0], :on_int, "1", Ripper::EXPR_END],
[[1, 1], :on_nl, "\n", Ripper::EXPR_BEG],
[[2, 0], :on_int, "2", Ripper::EXPR_END],
[[2, 1], :on_nl, "\n", Ripper::EXPR_BEG],
[[3, 0], :on_int, "3", Ripper::EXPR_END]],
Ripper.lex("1\n2\n3")
- assert_equal [[[1, 0], :on_heredoc_beg, "<<""EOS", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_heredoc_beg, "<<""EOS", Ripper::EXPR_BEG],
[[1, 5], :on_nl, "\n", Ripper::EXPR_BEG],
[[2, 0], :on_tstring_content, "heredoc\n", Ripper::EXPR_BEG],
[[3, 0], :on_heredoc_end, "EOS", Ripper::EXPR_BEG]],
Ripper.lex("<<""EOS\nheredoc\nEOS")
- assert_equal [[[1, 0], :on_heredoc_beg, "<<""EOS", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_heredoc_beg, "<<""EOS", Ripper::EXPR_BEG],
[[1, 5], :on_nl, "\n", Ripper::EXPR_BEG],
[[2, 0], :on_heredoc_end, "EOS", Ripper::EXPR_BEG]],
Ripper.lex("<<""EOS\nEOS"),
"bug#4543"
- assert_equal [[[1, 0], :on_regexp_beg, "/", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_regexp_beg, "/", Ripper::EXPR_BEG],
[[1, 1], :on_tstring_content, "foo\nbar", Ripper::EXPR_BEG],
[[2, 3], :on_regexp_end, "/", Ripper::EXPR_BEG]],
Ripper.lex("/foo\nbar/")
- assert_equal [[[1, 0], :on_regexp_beg, "/", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_regexp_beg, "/", Ripper::EXPR_BEG],
[[1, 1], :on_tstring_content, "foo\n\u3020", Ripper::EXPR_BEG],
[[2, 3], :on_regexp_end, "/", Ripper::EXPR_BEG]],
Ripper.lex("/foo\n\u3020/")
- assert_equal [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
[[1, 1], :on_tstring_content, "foo\n\xe3\x80\xa0", Ripper::EXPR_BEG],
[[2, 3], :on_tstring_end, "'", Ripper::EXPR_END]],
Ripper.lex("'foo\n\xe3\x80\xa0'")
- assert_equal [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
[[1, 1], :on_tstring_content, "\u3042\n\u3044", Ripper::EXPR_BEG],
[[2, 3], :on_tstring_end, "'", Ripper::EXPR_END]],
Ripper.lex("'\u3042\n\u3044'")
- assert_equal [[[1, 0], :on_rational, "1r", Ripper::EXPR_END],
+ assert_lex [[[1, 0], :on_rational, "1r", Ripper::EXPR_END],
[[1, 2], :on_nl, "\n", Ripper::EXPR_BEG],
[[2, 0], :on_imaginary, "2i", Ripper::EXPR_END],
[[2, 2], :on_nl, "\n", Ripper::EXPR_BEG],
@@ -113,18 +113,25 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
[[5, 0], :on_imaginary, "5.6ri", Ripper::EXPR_END],
],
Ripper.lex("1r\n2i\n3ri\n4.2r\n5.6ri")
- assert_equal [[[1, 0], :on_heredoc_beg, "<<~EOS", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_heredoc_beg, "<<~EOS", Ripper::EXPR_BEG],
[[1, 6], :on_nl, "\n", Ripper::EXPR_BEG],
[[2, 0], :on_ignored_sp, " ", Ripper::EXPR_BEG],
[[2, 2], :on_tstring_content, "heredoc\n", Ripper::EXPR_BEG],
[[3, 0], :on_heredoc_end, "EOS", Ripper::EXPR_BEG]
],
Ripper.lex("<<~EOS\n heredoc\nEOS")
- assert_equal [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
+ assert_lex [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
[[1, 1], :on_tstring_content, "foo", Ripper::EXPR_BEG]],
Ripper.lex("'foo")
end
+ def assert_lex(expected, *rest)
+ expected = expected.map do |pos, type, tok, state, *rest|
+ [pos, type, tok, Ripper::Lexer::State.new(state), *rest]
+ end
+ assert_equal(expected, *rest)
+ end
+
def test_location
assert_location ""
assert_location " "
diff --git a/test/ruby/enc/test_case_comprehensive.rb b/test/ruby/enc/test_case_comprehensive.rb
index bde47017a20..bc57d57ee4e 100644
--- a/test/ruby/enc/test_case_comprehensive.rb
+++ b/test/ruby/enc/test_case_comprehensive.rb
@@ -24,7 +24,7 @@ class TestComprehensiveCaseMapping < Test::Unit::TestCase
def test_data_files_available
unless TestComprehensiveCaseMapping.data_files_available?
- skip "Unicode data files not available in #{UNICODE_DATA_PATH}."
+ omit "Unicode data files not available in #{UNICODE_DATA_PATH}."
end
end
end
diff --git a/test/ruby/enc/test_emoji_breaks.rb b/test/ruby/enc/test_emoji_breaks.rb
index cdde4da9bf2..0aad14e75b3 100644
--- a/test/ruby/enc/test_emoji_breaks.rb
+++ b/test/ruby/enc/test_emoji_breaks.rb
@@ -68,7 +68,7 @@ class TestEmojiBreaks < Test::Unit::TestCase
def test_data_files_available
assert_equal 4, EMOJI_DATA_FILES.size # debugging test
unless TestEmojiBreaks.data_files_available?
- skip "Emoji data files not available in #{EMOJI_DATA_PATH}."
+ omit "Emoji data files not available in #{EMOJI_DATA_PATH}."
end
end
end
diff --git a/test/ruby/enc/test_grapheme_breaks.rb b/test/ruby/enc/test_grapheme_breaks.rb
index 2d210946a9e..2a31e078cfd 100644
--- a/test/ruby/enc/test_grapheme_breaks.rb
+++ b/test/ruby/enc/test_grapheme_breaks.rb
@@ -40,7 +40,7 @@ class TestGraphemeBreaksFromFile < Test::Unit::TestCase
def test_data_files_available
unless TestGraphemeBreaksFromFile.file_available?
- skip "Unicode data file GraphemeBreakTest not available in #{UNICODE_DATA_PATH}."
+ omit "Unicode data file GraphemeBreakTest not available in #{UNICODE_DATA_PATH}."
end
end
end
diff --git a/test/ruby/enc/test_regex_casefold.rb b/test/ruby/enc/test_regex_casefold.rb
index ec5dc7f220c..eaabbc58a2f 100644
--- a/test/ruby/enc/test_regex_casefold.rb
+++ b/test/ruby/enc/test_regex_casefold.rb
@@ -39,7 +39,7 @@ class TestCaseFold < Test::Unit::TestCase
@@tests ||= read_tests
rescue Errno::ENOENT => e
@@tests ||= []
- skip e.message
+ omit e.message
end
def self.generate_test_casefold(encoding)
diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb
index 271d552bf50..99f2223b49d 100644
--- a/test/ruby/test_alias.rb
+++ b/test/ruby/test_alias.rb
@@ -253,4 +253,33 @@ class TestAlias < Test::Unit::TestCase
assert_equal(:foo, k.instance_method(:bar).original_name)
assert_equal(:foo, name)
end
+
+ def test_alias_suppressing_redefinition
+ assert_in_out_err(%w[-w], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ def foo; end
+ alias foo foo
+ def foo; end
+ end
+ end;
+ end
+
+ def test_alias_memory_leak
+ assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true)
+ begin;
+ class A
+ 500.times do
+ 1000.times do |i|
+ define_method(:"foo_#{i}") {}
+
+ alias :"foo_#{i}" :"foo_#{i}"
+
+ remove_method :"foo_#{i}"
+ end
+ GC.start
+ end
+ end
+ end;
+ end
end
diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb
index e3bd1cd075c..dbffd24370f 100644
--- a/test/ruby/test_argf.rb
+++ b/test/ruby/test_argf.rb
@@ -257,13 +257,13 @@ class TestArgf < Test::Unit::TestCase
def test_inplace_nonascii
ext = Encoding.default_external or
- skip "no default external encoding"
+ omit "no default external encoding"
t = nil
["\u{3042}", "\u{e9}"].any? do |n|
t = make_tempfile(n.encode(ext))
rescue Encoding::UndefinedConversionError
end
- t or skip "no name to test"
+ t or omit "no name to test"
assert_in_out_err(["-i.bak", "-", t.path],
"#{<<~"{#"}\n#{<<~'};'}")
{#
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index a97a9c25580..b100cf334ce 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -3270,7 +3270,7 @@ class TestArray < Test::Unit::TestCase
end
EOS
rescue Timeout::Error => e
- skip e.message
+ omit e.message
end
end
diff --git a/test/ruby/test_assignment.rb b/test/ruby/test_assignment.rb
index 41e8bffe82f..3a8dafb7f0a 100644
--- a/test/ruby/test_assignment.rb
+++ b/test/ruby/test_assignment.rb
@@ -139,6 +139,104 @@ class TestAssignment < Test::Unit::TestCase
order.clear
end
+ def test_massign_const_order
+ order = []
+
+ test_mod_class = Class.new(Module) do
+ define_method(:x1){order << :x1; self}
+ define_method(:y1){order << :y1; self}
+ define_method(:x2){order << :x2; self}
+ define_method(:x3){order << :x3; self}
+ define_method(:x4){order << :x4; self}
+ define_method(:[]){|*args| order << [:[], *args]; self}
+ define_method(:r1){order << :r1; :r1}
+ define_method(:r2){order << :r2; :r2}
+
+ define_method(:constant_values) do
+ h = {}
+ constants.each do |sym|
+ h[sym] = const_get(sym)
+ end
+ h
+ end
+
+ define_singleton_method(:run) do |code|
+ m = new
+ m.instance_eval(code)
+ ret = [order.dup, m.constant_values]
+ order.clear
+ ret
+ end
+ end
+
+ ord, constants = test_mod_class.run(
+ "x1.y1::A, x2[1, 2, 3]::B, self[4]::C = r1, 6, r2"
+ )
+ assert_equal([:x1, :y1, :x2, [:[], 1, 2, 3], [:[], 4], :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>6, :C=>:r2}, constants)
+
+ ord, constants = test_mod_class.run(
+ "x1.y1::A, *x2[1, 2, 3]::B, self[4]::C = r1, 6, 7, r2"
+ )
+ assert_equal([:x1, :y1, :x2, [:[], 1, 2, 3], [:[], 4], :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>[6, 7], :C=>:r2}, constants)
+
+ ord, constants = test_mod_class.run(
+ "x1.y1::A, *x2[1, 2, 3]::B, x3[4]::C = r1, 6, 7, r2"
+ )
+ assert_equal([:x1, :y1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>[6, 7], :C=>:r2}, constants)
+
+
+ ord, constants = test_mod_class.run(
+ "x1.y1::A, *x2[1, 2, 3]::B, x3[4]::C, x4::D = r1, 6, 7, r2, 8"
+ )
+ assert_equal([:x1, :y1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>[6, 7], :C=>:r2, :D=>8}, constants)
+
+ ord, constants = test_mod_class.run(
+ "(x1.y1::A, x2::B), _a = [r1, r2], 7"
+ )
+ assert_equal([:x1, :y1, :x2, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>:r2}, constants)
+
+ ord, constants = test_mod_class.run(
+ "(x1.y1::A, x1::B), *x2[1, 2, 3]::C = [r1, 5], 6, 7, r2, 8"
+ )
+ assert_equal([:x1, :y1, :x1, :x2, [:[], 1, 2, 3], :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>5, :C=>[6, 7, :r2, 8]}, constants)
+
+ ord, constants = test_mod_class.run(
+ "*x2[1, 2, 3]::A, (x3[4]::B, x4::C) = 6, 7, [r2, 8]"
+ )
+ assert_equal([:x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r2], ord)
+ assert_equal({:A=>[6, 7], :B=>:r2, :C=>8}, constants)
+
+ ord, constants = test_mod_class.run(
+ "(x1.y1::A, x1::B), *x2[1, 2, 3]::C, x3[4]::D, x4::E = [r1, 5], 6, 7, r2, 8"
+ )
+ assert_equal([:x1, :y1, :x1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>5, :C=>[6, 7], :D=>:r2, :E=>8}, constants)
+
+ ord, constants = test_mod_class.run(
+ "(x1.y1::A, x1::B), *x2[1, 2, 3]::C, (x3[4]::D, x4::E) = [r1, 5], 6, 7, [r2, 8]"
+ )
+ assert_equal([:x1, :y1, :x1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>5, :C=>[6, 7], :D=>:r2, :E=>8}, constants)
+
+ ord, constants = test_mod_class.run(
+ "((x1.y1::A, x1::B), _a), *x2[1, 2, 3]::C, ((x3[4]::D, x4::E), _b) = [[r1, 5], 10], 6, 7, [[r2, 8], 11]"
+ )
+ assert_equal([:x1, :y1, :x1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>5, :C=>[6, 7], :D=>:r2, :E=>8}, constants)
+
+ ord, constants = test_mod_class.run(
+ "((x1.y1::A, x1::B), _a), *x2[1, 2, 3]::C, ((*x3[4]::D, x4::E), _b) = [[r1, 5], 10], 6, 7, [[r2, 8], 11]"
+ )
+ assert_equal([:x1, :y1, :x1, :x2, [:[], 1, 2, 3], :x3, [:[], 4], :x4, :r1, :r2], ord)
+ assert_equal({:A=>:r1, :B=>5, :C=>[6, 7], :D=>[:r2], :E=>8}, constants)
+ end
+
def test_massign_splat
a,b,*c = *[]; assert_equal([nil,nil,[]], [a,b,c])
a,b,*c = *[1]; assert_equal([1,nil,[]], [a,b,c])
@@ -619,6 +717,16 @@ class TestAssignment < Test::Unit::TestCase
result = eval("if (a, b = MyObj.new); [a, b]; end", nil, __FILE__, __LINE__)
assert_equal [[1,2],[3,4]], result
end
+
+ def test_const_assign_order
+ assert_raise(RuntimeError) do
+ eval('raise("recv")::C = raise(ArgumentError, "bar")')
+ end
+
+ assert_raise(RuntimeError) do
+ eval('m = 1; m::C = raise("bar")')
+ end
+ end
end
require_relative 'sentence'
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index 953c8435c33..a4edfd3cbeb 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -185,7 +185,7 @@ class TestAst < Test::Unit::TestCase
end
end
- def test_of
+ def test_of_proc_and_method
proc = Proc.new { 1 + 2 }
method = self.method(__method__)
@@ -194,7 +194,6 @@ class TestAst < Test::Unit::TestCase
assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node_proc)
assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node_method)
- assert_raise(TypeError) { RubyVM::AbstractSyntaxTree.of("1 + 2") }
Tempfile.create(%w"test_of .rb") do |tmp|
tmp.print "#{<<-"begin;"}\n#{<<-'end;'}"
@@ -211,7 +210,25 @@ class TestAst < Test::Unit::TestCase
end
end
- def test_of_eval
+ def sample_backtrace_location
+ [caller_locations(0).first, __LINE__]
+ end
+
+ def test_of_backtrace_location
+ backtrace_location, lineno = sample_backtrace_location
+ node = RubyVM::AbstractSyntaxTree.of(backtrace_location)
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node)
+ assert_equal(lineno, node.first_lineno)
+ end
+
+ def test_of_error
+ assert_raise(TypeError) { RubyVM::AbstractSyntaxTree.of("1 + 2") }
+ end
+
+ def test_of_proc_and_method_under_eval
+ keep_script_lines_back = RubyVM.keep_script_lines
+ RubyVM.keep_script_lines = false
+
method = self.method(eval("def example_method_#{$$}; end"))
assert_raise(ArgumentError) { RubyVM::AbstractSyntaxTree.of(method) }
@@ -229,6 +246,79 @@ class TestAst < Test::Unit::TestCase
method = eval("Class.new{def example_method; end}.instance_method(:example_method)")
assert_raise(ArgumentError) { RubyVM::AbstractSyntaxTree.of(method) }
+
+ method = eval("Class.new{def example_method; end}.instance_method(:example_method)")
+ assert_raise(ArgumentError) { RubyVM::AbstractSyntaxTree.of(method) }
+
+ ensure
+ RubyVM.keep_script_lines = keep_script_lines_back
+ end
+
+ def test_of_proc_and_method_under_eval_with_keep_script_lines
+ keep_script_lines_back = RubyVM.keep_script_lines
+ RubyVM.keep_script_lines = true
+
+ method = self.method(eval("def example_method_#{$$}_with_keep_script_lines; end"))
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = self.method(eval("def self.example_singleton_method_#{$$}_with_keep_script_lines; end"))
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = eval("proc{}")
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = self.method(eval("singleton_class.define_method(:example_define_method_#{$$}_with_keep_script_lines){}"))
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = self.method(eval("define_singleton_method(:example_dsm_#{$$}_with_keep_script_lines){}"))
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = eval("Class.new{def example_method_with_keep_script_lines; end}.instance_method(:example_method_with_keep_script_lines)")
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ method = eval("Class.new{def example_method_with_keep_script_lines; end}.instance_method(:example_method_with_keep_script_lines)")
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.of(method))
+
+ ensure
+ RubyVM.keep_script_lines = keep_script_lines_back
+ end
+
+ def test_of_backtrace_location_under_eval
+ keep_script_lines_back = RubyVM.keep_script_lines
+ RubyVM.keep_script_lines = false
+
+ m = Module.new do
+ eval(<<-END, nil, __FILE__, __LINE__)
+ def self.sample_backtrace_location
+ caller_locations(0).first
+ end
+ END
+ end
+ backtrace_location = m.sample_backtrace_location
+ assert_raise(ArgumentError) { RubyVM::AbstractSyntaxTree.of(backtrace_location) }
+
+ ensure
+ RubyVM.keep_script_lines = keep_script_lines_back
+ end
+
+ def test_of_backtrace_location_under_eval_with_keep_script_lines
+ keep_script_lines_back = RubyVM.keep_script_lines
+ RubyVM.keep_script_lines = true
+
+ m = Module.new do
+ eval(<<-END, nil, __FILE__, __LINE__)
+ def self.sample_backtrace_location
+ caller_locations(0).first
+ end
+ END
+ end
+ backtrace_location = m.sample_backtrace_location
+ node = RubyVM::AbstractSyntaxTree.of(backtrace_location)
+ assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node)
+ assert_equal(2, node.first_lineno)
+
+ ensure
+ RubyVM.keep_script_lines = keep_script_lines_back
end
def test_of_c_method
@@ -447,4 +537,9 @@ dummy
assert_equal("{ 1 + 2 }", node_proc.source)
assert_equal("def test_keep_script_lines_for_of\n", node_method.source.lines.first)
end
+
+ def test_e_option
+ assert_in_out_err(["-e", "def foo; end; pp RubyVM::AbstractSyntaxTree.of(method(:foo)).type"],
+ "", [":SCOPE"], [])
+ end
end
diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb
index 3ffe7114b5f..53a2b20cc84 100644
--- a/test/ruby/test_bignum.rb
+++ b/test/ruby/test_bignum.rb
@@ -644,7 +644,7 @@ class TestBignum < Test::Unit::TestCase
thread.raise
thread.join
time = Time.now - time
- skip "too fast cpu" if end_flag
+ omit "too fast cpu" if end_flag
assert_operator(time, :<, 10)
end
@@ -675,7 +675,7 @@ class TestBignum < Test::Unit::TestCase
return
end
end
- skip "cannot create suitable test case"
+ omit "cannot create suitable test case"
ensure
Signal.trap(:INT, oldtrap) if oldtrap
end
diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb
index 96bca08601c..07c34ce9d57 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -738,7 +738,7 @@ class TestClass < Test::Unit::TestCase
assert_same(c, Module.new.const_set(:Foo, c))
end
- def test_descendants
+ def test_subclasses
c = Class.new
sc = Class.new(c)
ssc = Class.new(sc)
@@ -746,13 +746,42 @@ class TestClass < Test::Unit::TestCase
k.include Module.new
k.new.define_singleton_method(:force_singleton_class){}
end
- assert_equal([sc, ssc], c.descendants)
- assert_equal([ssc], sc.descendants)
- assert_equal([], ssc.descendants)
+ assert_equal([sc], c.subclasses)
+ assert_equal([ssc], sc.subclasses)
+ assert_equal([], ssc.subclasses)
+
+ object_subclasses = Object.subclasses
+ assert_include(object_subclasses, c)
+ assert_not_include(object_subclasses, sc)
+ assert_not_include(object_subclasses, ssc)
+ object_subclasses.each do |subclass|
+ assert_equal Object, subclass.superclass, "Expected #{subclass}.superclass to be Object"
+ end
+ end
+
+ def test_subclass_gc
+ c = Class.new
+ 10_000.times do
+ cc = Class.new(c)
+ 100.times { Class.new(cc) }
+ end
+ assert(c.subclasses.size <= 10_000)
+ end
+
+ def test_subclass_gc_stress
+ 10000.times do
+ c = Class.new
+ 100.times { Class.new(c) }
+ assert(c.subclasses.size <= 100)
+ end
+ end
- object_descendants = Object.descendants
- assert_include(object_descendants, c)
- assert_include(object_descendants, sc)
- assert_include(object_descendants, ssc)
+ def test_classext_memory_leak
+ assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
+code = proc { Class.new }
+1_000.times(&code)
+PREP
+3_000_000.times(&code)
+CODE
end
end
diff --git a/test/ruby/test_complex2.rb b/test/ruby/test_complex2.rb
index 594fc3f45a6..b89e83efb2b 100644
--- a/test/ruby/test_complex2.rb
+++ b/test/ruby/test_complex2.rb
@@ -4,7 +4,7 @@ require 'test/unit'
class Complex_Test2 < Test::Unit::TestCase
def test_kumi
- skip unless defined?(Rational)
+ omit unless defined?(Rational)
assert_equal(Complex(1, 0), +Complex(1, 0))
assert_equal(Complex(-1, 0), -Complex(1, 0))
diff --git a/test/ruby/test_complexrational.rb b/test/ruby/test_complexrational.rb
index bf4e2b1809d..31d11fe3179 100644
--- a/test/ruby/test_complexrational.rb
+++ b/test/ruby/test_complexrational.rb
@@ -4,7 +4,7 @@ require 'test/unit'
class ComplexRational_Test < Test::Unit::TestCase
def test_rat_srat
- skip unless defined?(Rational)
+ omit unless defined?(Rational)
c = SimpleRat(1,3)
cc = Rational(3,2)
@@ -89,7 +89,7 @@ class ComplexRational_Test < Test::Unit::TestCase
end
def test_comp_srat
- skip unless defined?(Rational)
+ omit unless defined?(Rational)
c = Complex(SimpleRat(2,3),SimpleRat(1,2))
cc = Complex(Rational(3,2),Rational(2,1))
diff --git a/test/ruby/test_default_gems.rb b/test/ruby/test_default_gems.rb
index 3c4aea15617..467e5ecf835 100644
--- a/test/ruby/test_default_gems.rb
+++ b/test/ruby/test_default_gems.rb
@@ -4,7 +4,7 @@ require 'rubygems'
class TestDefaultGems < Test::Unit::TestCase
def test_validate_gemspec
- skip "git not found" unless system("git", "rev-parse", %i[out err]=>IO::NULL)
+ omit "git not found" unless system("git", "rev-parse", %i[out err]=>IO::NULL)
srcdir = File.expand_path('../../..', __FILE__)
Dir.glob("#{srcdir}/{lib,ext}/**/*.gemspec").map do |src|
assert_nothing_raised do
diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb
index 71bff5f5c37..514c6e5921e 100644
--- a/test/ruby/test_dir.rb
+++ b/test/ruby/test_dir.rb
@@ -152,7 +152,7 @@ class TestDir < Test::Unit::TestCase
end
def test_chroot_nodir
- skip if RUBY_PLATFORM =~ /android/
+ omit if RUBY_PLATFORM =~ /android/
assert_raise(NotImplementedError, Errno::ENOENT, Errno::EPERM
) { Dir.chroot(File.join(@nodir, "")) }
end
@@ -171,9 +171,17 @@ class TestDir < Test::Unit::TestCase
Dir.glob([@root, File.join(@root, "*")]))
assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) },
Dir.glob([@root, File.join(@root, "*")], sort: false).sort)
+ assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) },
+ Dir.glob([@root, File.join(@root, "*")], sort: true))
assert_raise_with_message(ArgumentError, /nul-separated/) do
Dir.glob(@root + "\0\0\0" + File.join(@root, "*"))
end
+ assert_raise_with_message(ArgumentError, /expected true or false/) do
+ Dir.glob(@root, sort: 1)
+ end
+ assert_raise_with_message(ArgumentError, /expected true or false/) do
+ Dir.glob(@root, sort: nil)
+ end
assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") },
Dir.glob(File.join(@root, "*/")))
@@ -482,9 +490,9 @@ class TestDir < Test::Unit::TestCase
def test_glob_legacy_short_name
bug10819 = '[ruby-core:67954] [Bug #10819]'
bug11206 = '[ruby-core:69435] [Bug #11206]'
- skip unless /\A\w:/ =~ ENV["ProgramFiles"]
+ omit unless /\A\w:/ =~ ENV["ProgramFiles"]
short = "#$&/PROGRA~1"
- skip unless File.directory?(short)
+ omit unless File.directory?(short)
entries = Dir.glob("#{short}/Common*")
assert_not_empty(entries, bug10819)
long = File.expand_path(short)
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 702c332cd22..b0c43b9a7fa 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -134,6 +134,12 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal([1, 2, 3, 1, 2], @obj.to_a)
end
+ def test_to_a_keywords
+ @obj.singleton_class.remove_method(:each)
+ def @obj.each(foo:) yield foo end
+ assert_equal([1], @obj.to_a(foo: 1))
+ end
+
def test_to_a_size_symbol
sym = Object.new
class << sym
@@ -455,6 +461,17 @@ class TestEnumerable < Test::Unit::TestCase
empty.first
empty.block.call
end;
+
+ bug18475 = '[ruby-dev:107059]'
+ assert_in_out_err([], <<-'end;', [], /unexpected break/, bug18475)
+ e = Enumerator.new do |g|
+ Thread.new do
+ g << 1
+ end.join
+ end
+
+ e.first
+ end;
end
def test_sort
@@ -733,6 +750,7 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], ary)
assert_equal(1..10, (1..10).each_slice(3) { })
+ assert_equal([], [].each_slice(3) { })
end
def test_each_cons
@@ -754,6 +772,7 @@ class TestEnumerable < Test::Unit::TestCase
assert_empty(ary)
assert_equal(1..5, (1..5).each_cons(3) { })
+ assert_equal([], [].each_cons(3) { })
end
def test_zip
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index ea0f367334f..87ccd5102b7 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -503,7 +503,7 @@ class TestEnv < Test::Unit::TestCase
end
def test_huge_value
- if /mswin/ =~ RUBY_PLATFORM || /ucrt/ =~ RbConfig::CONFIG['sitearch']
+ if /mswin|ucrt/ =~ RUBY_PLATFORM
# On Windows >= Vista each environment variable can be max 32768 characters
huge_value = "bar" * 10900
else
@@ -578,6 +578,892 @@ class TestEnv < Test::Unit::TestCase
assert_nil(e1, bug12475)
end
+ def ignore_case_str
+ IGNORE_CASE ? "true" : "false"
+ end
+
+ def str_for_yielding_exception_class(code_str, exception_var: "raised_exception")
+ <<-"end;"
+ #{exception_var} = nil
+ begin
+ #{code_str}
+ rescue Exception => e
+ #{exception_var} = e
+ end
+ Ractor.yield #{exception_var}.class
+ end;
+ end
+
+ def str_for_assert_raise_on_yielded_exception_class(expected_error_class, ractor_var)
+ <<-"end;"
+ error_class = #{ractor_var}.take
+ assert_raise(#{expected_error_class}) do
+ if error_class < Exception
+ raise error_class
+ end
+ end
+ end;
+ end
+
+ def str_to_yield_invalid_envvar_errors(var_name, code_str)
+ <<-"end;"
+ envvars_to_check = [
+ "foo\0bar",
+ "#{'\xa1\xa1'}".force_encoding(Encoding::UTF_16LE),
+ "foo".force_encoding(Encoding::ISO_2022_JP),
+ ]
+ envvars_to_check.each do |#{var_name}|
+ #{str_for_yielding_exception_class(code_str)}
+ end
+ end;
+ end
+
+ def str_to_receive_invalid_envvar_errors(ractor_var)
+ <<-"end;"
+ 3.times do
+ #{str_for_assert_raise_on_yielded_exception_class(ArgumentError, ractor_var)}
+ end
+ end;
+ end
+
+ STR_DEFINITION_FOR_CHECK = %Q{
+ def check(as, bs)
+ if #{IGNORE_CASE ? "true" : "false"}
+ as = as.map {|k, v| [k.upcase, v] }
+ bs = bs.map {|k, v| [k.upcase, v] }
+ end
+ assert_equal(as.sort, bs.sort)
+ end
+ }
+
+ def test_bracket_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ Ractor.yield ENV['test']
+ Ractor.yield ENV['TEST']
+ ENV['test'] = 'foo'
+ Ractor.yield ENV['test']
+ Ractor.yield ENV['TEST']
+ ENV['TEST'] = 'bar'
+ Ractor.yield ENV['TEST']
+ Ractor.yield ENV['test']
+ #{str_for_yielding_exception_class("ENV[1]")}
+ #{str_for_yielding_exception_class("ENV[1] = 'foo'")}
+ #{str_for_yielding_exception_class("ENV['test'] = 0")}
+ end
+ assert_nil(r.take)
+ assert_nil(r.take)
+ assert_equal('foo', r.take)
+ if #{ignore_case_str}
+ assert_equal('foo', r.take)
+ else
+ assert_nil(r.take)
+ end
+ assert_equal('bar', r.take)
+ if #{ignore_case_str}
+ assert_equal('bar', r.take)
+ else
+ assert_equal('foo', r.take)
+ end
+ 3.times do
+ #{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")}
+ end
+ end;
+ end
+
+ def test_dup_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ #{str_for_yielding_exception_class("ENV.dup")}
+ end
+ #{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")}
+ end;
+ end
+
+ def test_clone_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ original_warning_state = Warning[:deprecated]
+ Warning[:deprecated] = false
+
+ begin
+ Ractor.yield ENV.clone.object_id
+ Ractor.yield ENV.clone(freeze: false).object_id
+ Ractor.yield ENV.clone(freeze: nil).object_id
+
+ #{str_for_yielding_exception_class("ENV.clone(freeze: true)")}
+ #{str_for_yielding_exception_class("ENV.clone(freeze: 1)")}
+ #{str_for_yielding_exception_class("ENV.clone(foo: false)")}
+ #{str_for_yielding_exception_class("ENV.clone(1)")}
+ #{str_for_yielding_exception_class("ENV.clone(1, foo: false)")}
+
+ ensure
+ Warning[:deprecated] = original_warning_state
+ end
+ end
+ assert_equal(ENV.object_id, r.take)
+ assert_equal(ENV.object_id, r.take)
+ assert_equal(ENV.object_id, r.take)
+ #{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")}
+ 4.times do
+ #{str_for_assert_raise_on_yielded_exception_class(ArgumentError, "r")}
+ end
+ end;
+ end
+
+ def test_has_value_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ val = 'a'
+ val.succ! while ENV.has_value?(val) || ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+ Ractor.yield(ENV.has_value?(val))
+ Ractor.yield(ENV.has_value?(val.upcase))
+ ENV['test'] = val
+ Ractor.yield(ENV.has_value?(val))
+ Ractor.yield(ENV.has_value?(val.upcase))
+ ENV['test'] = val.upcase
+ Ractor.yield ENV.has_value?(val)
+ Ractor.yield ENV.has_value?(val.upcase)
+ end
+ assert_equal(false, r.take)
+ assert_equal(false, r.take)
+ assert_equal(true, r.take)
+ assert_equal(false, r.take)
+ assert_equal(false, r.take)
+ assert_equal(true, r.take)
+ end;
+ end
+
+ def test_key_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ val = 'a'
+ val.succ! while ENV.has_value?(val) || ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+ Ractor.yield ENV.key(val)
+ Ractor.yield ENV.key(val.upcase)
+ ENV['test'] = val
+ Ractor.yield ENV.key(val)
+ Ractor.yield ENV.key(val.upcase)
+ ENV['test'] = val.upcase
+ Ractor.yield ENV.key(val)
+ Ractor.yield ENV.key(val.upcase)
+ end
+ assert_nil(r.take)
+ assert_nil(r.take)
+ if #{ignore_case_str}
+ assert_equal('TEST', r.take.upcase)
+ else
+ assert_equal('test', r.take)
+ end
+ assert_nil(r.take)
+ assert_nil(r.take)
+ if #{ignore_case_str}
+ assert_equal('TEST', r.take.upcase)
+ else
+ assert_equal('test', r.take)
+ end
+ end;
+
+ end
+
+ def test_delete_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ #{str_to_yield_invalid_envvar_errors("v", "ENV.delete(v)")}
+ Ractor.yield ENV.delete("TEST")
+ #{str_for_yielding_exception_class("ENV.delete('#{PATH_ENV}')")}
+ Ractor.yield(ENV.delete("TEST"){|name| "NO "+name})
+ end
+ #{str_to_receive_invalid_envvar_errors("r")}
+ assert_nil(r.take)
+ exception_class = r.take
+ assert_equal(NilClass, exception_class)
+ assert_equal("NO TEST", r.take)
+ end;
+ end
+
+ def test_getenv_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ #{str_to_yield_invalid_envvar_errors("v", "ENV[v]")}
+ ENV["#{PATH_ENV}"] = ""
+ Ractor.yield ENV["#{PATH_ENV}"]
+ Ractor.yield ENV[""]
+ end
+ #{str_to_receive_invalid_envvar_errors("r")}
+ assert_equal("", r.take)
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_fetch_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV["test"] = "foo"
+ Ractor.yield ENV.fetch("test")
+ ENV.delete("test")
+ #{str_for_yielding_exception_class("ENV.fetch('test')", exception_var: "ex")}
+ Ractor.yield ex.receiver.object_id
+ Ractor.yield ex.key
+ Ractor.yield ENV.fetch("test", "foo")
+ Ractor.yield(ENV.fetch("test"){"bar"})
+ #{str_to_yield_invalid_envvar_errors("v", "ENV.fetch(v)")}
+ #{str_for_yielding_exception_class("ENV.fetch('#{PATH_ENV}', 'foo')")}
+ ENV['#{PATH_ENV}'] = ""
+ Ractor.yield ENV.fetch('#{PATH_ENV}')
+ end
+ assert_equal("foo", r.take)
+ #{str_for_assert_raise_on_yielded_exception_class(KeyError, "r")}
+ assert_equal(ENV.object_id, r.take)
+ assert_equal("test", r.take)
+ assert_equal("foo", r.take)
+ assert_equal("bar", r.take)
+ #{str_to_receive_invalid_envvar_errors("r")}
+ exception_class = r.take
+ assert_equal(NilClass, exception_class)
+ assert_equal("", r.take)
+ end;
+ end
+
+ def test_aset_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ #{str_for_yielding_exception_class("ENV['test'] = nil")}
+ ENV["test"] = nil
+ Ractor.yield ENV["test"]
+ #{str_to_yield_invalid_envvar_errors("v", "ENV[v] = 'test'")}
+ #{str_to_yield_invalid_envvar_errors("v", "ENV['test'] = v")}
+ end
+ exception_class = r.take
+ assert_equal(NilClass, exception_class)
+ assert_nil(r.take)
+ #{str_to_receive_invalid_envvar_errors("r")}
+ #{str_to_receive_invalid_envvar_errors("r")}
+ end;
+ end
+
+ def test_keys_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ a = ENV.keys
+ Ractor.yield a
+ end
+ a = r.take
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end;
+
+ end
+
+ def test_each_key_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.each_key {|k| Ractor.yield(k)}
+ Ractor.yield "finished"
+ end
+ while((x=r.take) != "finished")
+ assert_kind_of(String, x)
+ end
+ end;
+ end
+
+ def test_values_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ a = ENV.values
+ Ractor.yield a
+ end
+ a = r.take
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end;
+ end
+
+ def test_each_value_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.each_value {|k| Ractor.yield(k)}
+ Ractor.yield "finished"
+ end
+ while((x=r.take) != "finished")
+ assert_kind_of(String, x)
+ end
+ end;
+ end
+
+ def test_each_pair_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.each_pair {|k, v| Ractor.yield([k,v])}
+ Ractor.yield "finished"
+ end
+ while((k,v=r.take) != "finished")
+ assert_kind_of(String, k)
+ assert_kind_of(String, v)
+ end
+ end;
+ end
+
+ def test_reject_bang_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.reject! {|k, v| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ Ractor.yield [h1, h2]
+ Ractor.yield(ENV.reject! {|k, v| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" })
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_delete_if_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.delete_if {|k, v| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ Ractor.yield [h1, h2]
+ Ractor.yield (ENV.delete_if {|k, v| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }).object_id
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ assert_equal(ENV.object_id, r.take)
+ end;
+ end
+
+ def test_select_bang_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.select! {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ Ractor.yield [h1, h2]
+ Ractor.yield(ENV.select! {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" })
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_filter_bang_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.filter! {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ Ractor.yield [h1, h2]
+ Ractor.yield(ENV.filter! {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" })
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_keep_if_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.keep_if {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ Ractor.yield [h1, h2]
+ Ractor.yield (ENV.keep_if {|k, v| #{ignore_case_str} ? k.upcase != "TEST" : k != "test" }).object_id
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ assert_equal(ENV.object_id, r.take)
+ end;
+ end
+
+ def test_values_at_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV["test"] = "foo"
+ Ractor.yield ENV.values_at("test", "test")
+ end
+ assert_equal(["foo", "foo"], r.take)
+ end;
+ end
+
+ def test_select_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV["test"] = "foo"
+ h = ENV.select {|k| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }
+ Ractor.yield h.size
+ k = h.keys.first
+ v = h.values.first
+ Ractor.yield [k, v]
+ end
+ assert_equal(1, r.take)
+ k, v = r.take
+ if #{ignore_case_str}
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end;
+ end
+
+ def test_filter_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV["test"] = "foo"
+ h = ENV.filter {|k| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }
+ Ractor.yield(h.size)
+ k = h.keys.first
+ v = h.values.first
+ Ractor.yield [k, v]
+ end
+ assert_equal(1, r.take)
+ k, v = r.take
+ if #{ignore_case_str}
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end;
+ end
+
+ def test_slice_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV["bar"] = "rab"
+ Ractor.yield(ENV.slice())
+ Ractor.yield(ENV.slice(""))
+ Ractor.yield(ENV.slice("unknown"))
+ Ractor.yield(ENV.slice("foo", "baz"))
+ end
+ assert_equal({}, r.take)
+ assert_equal({}, r.take)
+ assert_equal({}, r.take)
+ assert_equal({"foo"=>"bar", "baz"=>"qux"}, r.take)
+ end;
+ end
+
+ def test_except_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV["bar"] = "rab"
+ Ractor.yield ENV.except()
+ Ractor.yield ENV.except("")
+ Ractor.yield ENV.except("unknown")
+ Ractor.yield ENV.except("foo", "baz")
+ end
+ assert_equal({"bar"=>"rab", "baz"=>"qux", "foo"=>"bar"}, r.take)
+ assert_equal({"bar"=>"rab", "baz"=>"qux", "foo"=>"bar"}, r.take)
+ assert_equal({"bar"=>"rab", "baz"=>"qux", "foo"=>"bar"}, r.take)
+ assert_equal({"bar"=>"rab"}, r.take)
+ end;
+ end
+
+ def test_clear_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ Ractor.yield ENV.size
+ end
+ assert_equal(0, r.take)
+ end;
+ end
+
+ def test_to_s_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.to_s
+ end
+ assert_equal("ENV", r.take)
+ end;
+ end
+
+ def test_inspect_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ s = ENV.inspect
+ Ractor.yield s
+ end
+ s = r.take
+ if #{ignore_case_str}
+ s = s.upcase
+ assert(s == '{"FOO"=>"BAR", "BAZ"=>"QUX"}' || s == '{"BAZ"=>"QUX", "FOO"=>"BAR"}')
+ else
+ assert(s == '{"foo"=>"bar", "baz"=>"qux"}' || s == '{"baz"=>"qux", "foo"=>"bar"}')
+ end
+ end;
+ end
+
+ def test_to_a_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.to_a
+ Ractor.yield a
+ end
+ a = r.take
+ assert_equal(2, a.size)
+ if #{ignore_case_str}
+ a = a.map {|x| x.map {|y| y.upcase } }
+ assert(a == [%w(FOO BAR), %w(BAZ QUX)] || a == [%w(BAZ QUX), %w(FOO BAR)])
+ else
+ assert(a == [%w(foo bar), %w(baz qux)] || a == [%w(baz qux), %w(foo bar)])
+ end
+ end;
+ end
+
+ def test_rehash_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.rehash
+ end
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_size_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ s = ENV.size
+ ENV["test"] = "foo"
+ Ractor.yield [s, ENV.size]
+ end
+ s, s2 = r.take
+ assert_equal(s + 1, s2)
+ end;
+ end
+
+ def test_empty_p_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ Ractor.yield ENV.empty?
+ ENV["test"] = "foo"
+ Ractor.yield ENV.empty?
+ end
+ assert r.take
+ assert !r.take
+ end;
+ end
+
+ def test_has_key_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ Ractor.yield ENV.has_key?("test")
+ ENV["test"] = "foo"
+ Ractor.yield ENV.has_key?("test")
+ #{str_to_yield_invalid_envvar_errors("v", "ENV.has_key?(v)")}
+ end
+ assert !r.take
+ assert r.take
+ #{str_to_receive_invalid_envvar_errors("r")}
+ end;
+ end
+
+ def test_assoc_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ Ractor.yield ENV.assoc("test")
+ ENV["test"] = "foo"
+ Ractor.yield ENV.assoc("test")
+ #{str_to_yield_invalid_envvar_errors("v", "ENV.assoc(v)")}
+ end
+ assert_nil(r.take)
+ k, v = r.take
+ if #{ignore_case_str}
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ #{str_to_receive_invalid_envvar_errors("r")}
+ encoding = /mswin|mingw/ =~ RUBY_PLATFORM ? Encoding::UTF_8 : Encoding.find("locale")
+ assert_equal(encoding, v.encoding)
+ end;
+ end
+
+ def test_has_value2_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ Ractor.yield ENV.has_value?("foo")
+ ENV["test"] = "foo"
+ Ractor.yield ENV.has_value?("foo")
+ end
+ assert !r.take
+ assert r.take
+ end;
+ end
+
+ def test_rassoc_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV.clear
+ Ractor.yield ENV.rassoc("foo")
+ ENV["foo"] = "bar"
+ ENV["test"] = "foo"
+ ENV["baz"] = "qux"
+ Ractor.yield ENV.rassoc("foo")
+ end
+ assert_nil(r.take)
+ k, v = r.take
+ if #{ignore_case_str}
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end;
+ end
+
+ def test_to_hash_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h = {}
+ ENV.each {|k, v| h[k] = v }
+ Ractor.yield [h, ENV.to_hash]
+ end
+ h, h2 = r.take
+ assert_equal(h, h2)
+ end;
+ end
+
+ def test_to_h_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ Ractor.yield [ENV.to_hash, ENV.to_h]
+ Ractor.yield [ENV.map {|k, v| ["$\#{k}", v.size]}.to_h, ENV.to_h {|k, v| ["$\#{k}", v.size]}]
+ end
+ a, b = r.take
+ assert_equal(a,b)
+ c, d = r.take
+ assert_equal(c,d)
+ end;
+ end
+
+ def test_reject_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ h2 = ENV.reject {|k, v| #{ignore_case_str} ? k.upcase == "TEST" : k == "test" }
+ Ractor.yield [h1, h2]
+ end
+ h1, h2 = r.take
+ assert_equal(h1, h2)
+ end;
+ end
+
+ def test_shift_in_ractor
+ assert_ractor(<<-"end;")
+ #{STR_DEFINITION_FOR_CHECK}
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.shift
+ b = ENV.shift
+ Ractor.yield [a,b]
+ Ractor.yield ENV.shift
+ end
+ a,b = r.take
+ check([a, b], [%w(foo bar), %w(baz qux)])
+ assert_nil(r.take)
+ end;
+ end
+
+ def test_invert_in_ractor
+ assert_ractor(<<-"end;")
+ #{STR_DEFINITION_FOR_CHECK}
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ Ractor.yield(ENV.invert)
+ end
+ check(r.take.to_a, [%w(bar foo), %w(qux baz)])
+ end;
+ end
+
+ def test_replace_in_ractor
+ assert_ractor(<<-"end;")
+ #{STR_DEFINITION_FOR_CHECK}
+ r = Ractor.new do
+ ENV["foo"] = "xxx"
+ ENV.replace({"foo"=>"bar", "baz"=>"qux"})
+ Ractor.yield ENV.to_hash
+ ENV.replace({"Foo"=>"Bar", "Baz"=>"Qux"})
+ Ractor.yield ENV.to_hash
+ end
+ check(r.take.to_a, [%w(foo bar), %w(baz qux)])
+ check(r.take.to_a, [%w(Foo Bar), %w(Baz Qux)])
+ end;
+ end
+
+ def test_update_in_ractor
+ assert_ractor(<<-"end;")
+ #{STR_DEFINITION_FOR_CHECK}
+ r = Ractor.new do
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"})
+ Ractor.yield ENV.to_hash
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| k + "_" + v1 + "_" + v2 }
+ Ractor.yield ENV.to_hash
+ end
+ check(r.take.to_a, [%w(foo bar), %w(baz quux), %w(a b)])
+ check(r.take.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)])
+ end;
+ end
+
+ def test_huge_value_in_ractor
+ assert_ractor(<<-"end;")
+ huge_value = "bar" * 40960
+ r = Ractor.new huge_value do |v|
+ ENV["foo"] = "bar"
+ #{str_for_yielding_exception_class("ENV['foo'] = v ")}
+ Ractor.yield ENV["foo"]
+ end
+
+ if /mswin|ucrt/ =~ RUBY_PLATFORM
+ #{str_for_assert_raise_on_yielded_exception_class(Errno::EINVAL, "r")}
+ result = r.take
+ assert_equal("bar", result)
+ else
+ exception_class = r.take
+ assert_equal(NilClass, exception_class)
+ result = r.take
+ assert_equal(huge_value, result)
+ end
+ end;
+ end
+
+ def test_frozen_env_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ #{str_for_yielding_exception_class("ENV.freeze")}
+ end
+ #{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")}
+ end;
+ end
+
+ def test_frozen_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ ENV["#{PATH_ENV}"] = "/"
+ ENV.each do |k, v|
+ Ractor.yield [k.frozen?]
+ Ractor.yield [v.frozen?]
+ end
+ ENV.each_key do |k|
+ Ractor.yield [k.frozen?]
+ end
+ ENV.each_value do |v|
+ Ractor.yield [v.frozen?]
+ end
+ ENV.each_key do |k|
+ Ractor.yield [ENV[k].frozen?, "[\#{k.dump}]"]
+ Ractor.yield [ENV.fetch(k).frozen?, "fetch(\#{k.dump})"]
+ end
+ Ractor.yield "finished"
+ end
+ while((params=r.take) != "finished")
+ assert(*params)
+ end
+ end;
+ end
+
+ def test_shared_substring_in_ractor
+ assert_ractor(<<-"end;")
+ r = Ractor.new do
+ bug12475 = '[ruby-dev:49655] [Bug #12475]'
+ n = [*"0".."9"].join("")*3
+ e0 = ENV[n0 = "E\#{n}"]
+ e1 = ENV[n1 = "E\#{n}."]
+ ENV[n0] = nil
+ ENV[n1] = nil
+ ENV[n1.chop] = "T\#{n}.".chop
+ ENV[n0], e0 = e0, ENV[n0]
+ ENV[n1], e1 = e1, ENV[n1]
+ Ractor.yield [n, e0, e1, bug12475]
+ end
+ n, e0, e1, bug12475 = r.take
+ assert_equal("T\#{n}", e0, bug12475)
+ assert_nil(e1, bug12475)
+ end;
+ end
+
+ def test_ivar_in_env_should_not_be_access_from_non_main_ractors
+ assert_ractor <<~RUBY
+ ENV.instance_eval{ @a = "hello" }
+ assert_equal "hello", ENV.instance_variable_get(:@a)
+
+ r_get = Ractor.new do
+ ENV.instance_variable_get(:@a)
+ rescue Ractor::IsolationError => e
+ e
+ end
+ assert_equal Ractor::IsolationError, r_get.take.class
+
+ r_get = Ractor.new do
+ ENV.instance_eval{ @a }
+ rescue Ractor::IsolationError => e
+ e
+ end
+
+ assert_equal Ractor::IsolationError, r_get.take.class
+
+ r_set = Ractor.new do
+ ENV.instance_eval{ @b = "hello" }
+ rescue Ractor::IsolationError => e
+ e
+ end
+
+ assert_equal Ractor::IsolationError, r_set.take.class
+ RUBY
+ end
+
if RUBY_PLATFORM =~ /bccwin|mswin|mingw/
def test_memory_leak_aset
bug9977 = '[ruby-dev:48323] [Bug #9977]'
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index bf551c68456..d55977c986f 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -219,6 +219,12 @@ class TestEval < Test::Unit::TestCase
end
end
+ def test_instance_exec_cvar
+ [Object.new, [], 7, :sym, true, false, nil].each do |obj|
+ assert_equal(13, obj.instance_exec{@@cvar})
+ end
+ end
+
def test_instance_eval_method
bug2788 = '[ruby-core:28324]'
[Object.new, [], nil, true, false].each do |o|
@@ -253,6 +259,70 @@ class TestEval < Test::Unit::TestCase
assert_equal(2, bar)
end
+ def test_instance_exec_block_basic
+ forall_TYPE do |o|
+ assert_equal nil, o.instance_exec { nil }
+ assert_equal true, o.instance_exec { true }
+ assert_equal false, o.instance_exec { false }
+ assert_equal o, o.instance_exec { self }
+ assert_equal 1, o.instance_exec { 1 }
+ assert_equal :sym, o.instance_exec { :sym }
+
+ assert_equal 11, o.instance_exec { 11 }
+ assert_equal 12, o.instance_exec { @ivar } unless o.frozen?
+ assert_equal 13, o.instance_exec { @@cvar }
+ assert_equal 14, o.instance_exec { $gvar__eval }
+ assert_equal 15, o.instance_exec { Const }
+ assert_equal 16, o.instance_exec { 7 + 9 }
+ assert_equal 17, o.instance_exec { 17.to_i }
+ assert_equal "18", o.instance_exec { "18" }
+ assert_equal "19", o.instance_exec { "1#{9}" }
+
+ 1.times {
+ assert_equal 12, o.instance_exec { @ivar } unless o.frozen?
+ assert_equal 13, o.instance_exec { @@cvar }
+ assert_equal 14, o.instance_exec { $gvar__eval }
+ assert_equal 15, o.instance_exec { Const }
+ }
+ end
+ end
+
+ def test_instance_exec_method_definition
+ klass = Class.new
+ o = klass.new
+
+ o.instance_exec do
+ def foo
+ :foo_result
+ end
+ end
+
+ assert_respond_to o, :foo
+ refute_respond_to klass, :foo
+ refute_respond_to klass.new, :foo
+
+ assert_equal :foo_result, o.foo
+ end
+
+ def test_instance_exec_eval_method_definition
+ klass = Class.new
+ o = klass.new
+
+ o.instance_exec do
+ eval %{
+ def foo
+ :foo_result
+ end
+ }
+ end
+
+ assert_respond_to o, :foo
+ refute_respond_to klass, :foo
+ refute_respond_to klass.new, :foo
+
+ assert_equal :foo_result, o.foo
+ end
+
#
# From ruby/test/ruby/test_eval.rb
#
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 67f38c2e91a..9908331689b 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -423,7 +423,7 @@ class TestException < Test::Unit::TestCase
end
def test_thread_signal_location
- skip
+ # pend('TODO: a known bug [Bug #14474]')
_, stderr, _ = EnvUtil.invoke_ruby(%w"--disable-gems -d", <<-RUBY, false, true)
Thread.start do
Thread.current.report_on_exception = false
@@ -561,7 +561,7 @@ end.join
end
def test_ensure_after_nomemoryerror
- skip "Forcing NoMemoryError causes problems in some environments"
+ omit "Forcing NoMemoryError causes problems in some environments"
assert_separately([], "$_ = 'a' * 1_000_000_000_000_000_000")
rescue NoMemoryError
assert_raise(NoMemoryError) do
@@ -1064,25 +1064,17 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
def test_warn_deprecated_backwards_compatibility_category
- warning = capture_warning_warn { Dir.exists?("non-existent") }
+ omit "no method to test"
+
+ warning = capture_warning_warn { }
assert_match(/deprecated/, warning[0])
end
def test_warn_deprecated_category
- warning = capture_warning_warn(category: true) { Dir.exists?("non-existent") }
-
- assert_equal :deprecated, warning[0][1]
- end
+ omit "no method to test"
- def test_warn_deprecated_to_remove_backwards_compatibility_category
- warning = capture_warning_warn { Object.new.tainted? }
-
- assert_match(/deprecated/, warning[0])
- end
-
- def test_warn_deprecated_to_remove_category
- warning = capture_warning_warn(category: true) { Object.new.tainted? }
+ warning = capture_warning_warn(category: true) { }
assert_equal :deprecated, warning[0][1]
end
@@ -1200,6 +1192,14 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
assert_empty warning
end
+ def test_undef_Warning_warn
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ Warning.undef_method(:warn)
+ assert_raise(NoMethodError) { warn "" }
+ end;
+ end
+
def test_undefined_backtrace
assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
begin;
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index 67fef33b85f..5825aaf6cc5 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -34,7 +34,7 @@ class TestFiber < Test::Unit::TestCase
end
def test_many_fibers
- skip 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ omit 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
max = 1000
assert_equal(max, max.times{
Fiber.new{}
@@ -50,7 +50,7 @@ class TestFiber < Test::Unit::TestCase
end
def test_many_fibers_with_threads
- assert_normal_exit <<-SRC, timeout: (/solaris/i =~ RUBY_PLATFORM ? 300 : 60)
+ assert_normal_exit <<-SRC, timeout: (/solaris/i =~ RUBY_PLATFORM ? 1000 : 60)
max = 1000
@cnt = 0
(1..100).map{|ti|
@@ -381,7 +381,7 @@ class TestFiber < Test::Unit::TestCase
def test_fork_from_fiber
- skip 'fork not supported' unless Process.respond_to?(:fork)
+ omit 'fork not supported' unless Process.respond_to?(:fork)
pid = nil
bug5700 = '[ruby-core:41456]'
assert_nothing_raised(bug5700) do
@@ -396,7 +396,7 @@ class TestFiber < Test::Unit::TestCase
Fiber.new {}.transfer
Fiber.new { Fiber.yield }
end
- exit!(0)
+ exit!(true)
end
}.transfer
_, status = Process.waitpid2(xpid)
@@ -405,8 +405,13 @@ class TestFiber < Test::Unit::TestCase
end.resume
end
pid, status = Process.waitpid2(pid)
- assert_equal(0, status.exitstatus, bug5700)
- assert_equal(false, status.signaled?, bug5700)
+ assert_not_predicate(status, :signaled?, bug5700)
+ assert_predicate(status, :success?, bug5700)
+
+ pid = Fiber.new {fork}.resume
+ pid, status = Process.waitpid2(pid)
+ assert_not_predicate(status, :signaled?)
+ assert_predicate(status, :success?)
end
def test_exit_in_fiber
diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb
index d570b6f6fbd..905416911a9 100644
--- a/test/ruby/test_file.rb
+++ b/test/ruby/test_file.rb
@@ -273,7 +273,7 @@ class TestFile < Test::Unit::TestCase
begin
File.symlink(tst, a)
rescue Errno::EACCES, Errno::EPERM
- skip "need privilege"
+ omit "need privilege"
end
assert_equal(File.join(realdir, tst), File.realpath(a))
File.unlink(a)
@@ -317,7 +317,7 @@ class TestFile < Test::Unit::TestCase
Dir.mktmpdir('rubytest-realpath') {|tmpdir|
Dir.chdir(tmpdir) do
Dir.mkdir('foo')
- skip "cannot run mklink" unless system('mklink /j bar foo > nul')
+ omit "cannot run mklink" unless system('mklink /j bar foo > nul')
assert_equal(File.realpath('foo'), File.realpath('bar'))
end
}
@@ -475,11 +475,11 @@ class TestFile < Test::Unit::TestCase
begin
io = File.open(tmpdir, File::RDWR | File::TMPFILE)
rescue Errno::EINVAL
- skip 'O_TMPFILE not supported (EINVAL)'
+ omit 'O_TMPFILE not supported (EINVAL)'
rescue Errno::EISDIR
- skip 'O_TMPFILE not supported (EISDIR)'
+ omit 'O_TMPFILE not supported (EISDIR)'
rescue Errno::EOPNOTSUPP
- skip 'O_TMPFILE not supported (EOPNOTSUPP)'
+ omit 'O_TMPFILE not supported (EOPNOTSUPP)'
end
io.write "foo"
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index 9dd05f6c934..2b274862c08 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -640,7 +640,7 @@ class TestFileExhaustive < Test::Unit::TestCase
end
def test_birthtime
- skip if RUBY_PLATFORM =~ /android/
+ omit if RUBY_PLATFORM =~ /android/
[regular_file, utf8_file].each do |file|
t1 = File.birthtime(file)
t2 = File.open(file) {|f| f.birthtime}
@@ -773,7 +773,7 @@ class TestFileExhaustive < Test::Unit::TestCase
def test_readlink_junction
base = File.basename(nofile)
err = IO.popen(%W"cmd.exe /c mklink /j #{base} .", chdir: @dir, err: %i[child out], &:read)
- skip err unless $?.success?
+ omit err unless $?.success?
assert_equal(@dir, File.readlink(nofile))
end
@@ -1119,7 +1119,7 @@ class TestFileExhaustive < Test::Unit::TestCase
def test_expand_path_for_existent_username
user = ENV['USER']
- skip "ENV['USER'] is not set" unless user
+ omit "ENV['USER'] is not set" unless user
assert_equal(ENV['HOME'], File.expand_path("~#{user}"))
end unless DRIVE
@@ -1408,21 +1408,24 @@ class TestFileExhaustive < Test::Unit::TestCase
end
def test_flock_exclusive
+ timeout = EnvUtil.apply_timeout_scale(0.1).to_s
File.open(regular_file, "r+") do |f|
f.flock(File::LOCK_EX)
- assert_separately(["-rtimeout", "-", regular_file], "#{<<~begin}#{<<~"end;"}")
- begin
+ assert_separately(["-rtimeout", "-", regular_file, timeout], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ timeout = ARGV[1].to_f
open(ARGV[0], "r") do |f|
- Timeout.timeout(0.1) do
+ Timeout.timeout(timeout) do
assert(!f.flock(File::LOCK_SH|File::LOCK_NB))
end
end
end;
- assert_separately(["-rtimeout", "-", regular_file], "#{<<~begin}#{<<~"end;"}")
- begin
+ assert_separately(["-rtimeout", "-", regular_file, timeout], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ timeout = ARGV[1].to_f
open(ARGV[0], "r") do |f|
assert_raise(Timeout::Error) do
- Timeout.timeout(0.1) do
+ Timeout.timeout(timeout) do
f.flock(File::LOCK_SH)
end
end
@@ -1434,21 +1437,24 @@ class TestFileExhaustive < Test::Unit::TestCase
end
def test_flock_shared
+ timeout = EnvUtil.apply_timeout_scale(0.1).to_s
File.open(regular_file, "r+") do |f|
f.flock(File::LOCK_SH)
- assert_separately(["-rtimeout", "-", regular_file], "#{<<~begin}#{<<~"end;"}")
- begin
+ assert_separately(["-rtimeout", "-", regular_file, timeout], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ timeout = ARGV[1].to_f
open(ARGV[0], "r") do |f|
- Timeout.timeout(0.1) do
+ Timeout.timeout(timeout) do
assert(f.flock(File::LOCK_SH))
end
end
end;
- assert_separately(["-rtimeout", "-", regular_file], "#{<<~begin}#{<<~"end;"}")
- begin
+ assert_separately(["-rtimeout", "-", regular_file, timeout], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ timeout = ARGV[1].to_f
open(ARGV[0], "r+") do |f|
assert_raise(Timeout::Error) do
- Timeout.timeout(0.1) do
+ Timeout.timeout(timeout) do
f.flock(File::LOCK_EX)
end
end
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index baf9971c483..788f2974b58 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -54,7 +54,7 @@ class TestGc < Test::Unit::TestCase
def test_start_full_mark
return unless use_rgengc?
- skip 'stress' if GC.stress
+ omit 'stress' if GC.stress
3.times { GC.start } # full mark and next time it should be minor mark
GC.start(full_mark: false)
@@ -65,7 +65,7 @@ class TestGc < Test::Unit::TestCase
end
def test_start_immediate_sweep
- skip 'stress' if GC.stress
+ omit 'stress' if GC.stress
GC.start(immediate_sweep: false)
assert_equal false, GC.latest_gc_info(:immediate_sweep)
@@ -117,7 +117,7 @@ class TestGc < Test::Unit::TestCase
end
def test_stat_single
- skip 'stress' if GC.stress
+ omit 'stress' if GC.stress
stat = GC.stat
assert_equal stat[:count], GC.stat(:count)
@@ -125,7 +125,7 @@ class TestGc < Test::Unit::TestCase
end
def test_stat_constraints
- skip 'stress' if GC.stress
+ omit 'stress' if GC.stress
stat = GC.stat
assert_equal stat[:total_allocated_pages], stat[:heap_allocated_pages] + stat[:total_freed_pages]
@@ -139,8 +139,74 @@ class TestGc < Test::Unit::TestCase
end
end
+ def test_stat_heap
+ omit 'stress' if GC.stress
+
+ stat_heap = {}
+ stat = {}
+ # Initialize to prevent GC in future calls
+ GC.stat_heap(0, stat_heap)
+ GC.stat(stat)
+
+ GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT].times do |i|
+ GC.stat_heap(i, stat_heap)
+ GC.stat(stat)
+
+ assert_equal GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] * (2**i), stat_heap[:slot_size]
+ assert_operator stat_heap[:heap_allocatable_pages], :<=, stat[:heap_allocatable_pages]
+ assert_operator stat_heap[:heap_eden_pages], :<=, stat[:heap_eden_pages]
+ assert_operator stat_heap[:heap_eden_slots], :>=, 0
+ assert_operator stat_heap[:heap_tomb_pages], :<=, stat[:heap_tomb_pages]
+ assert_operator stat_heap[:heap_tomb_slots], :>=, 0
+ end
+
+ GC.stat_heap(0, stat_heap)
+ assert_equal stat_heap[:slot_size], GC.stat_heap(0, :slot_size)
+ assert_equal stat_heap[:slot_size], GC.stat_heap(0)[:slot_size]
+
+ assert_raise(ArgumentError) { GC.stat_heap(-1) }
+ assert_raise(ArgumentError) { GC.stat_heap(GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT]) }
+ end
+
+ def test_stat_heap_all
+ stat_heap_all = {}
+ stat_heap = {}
+
+ 2.times do
+ GC.stat_heap(0, stat_heap)
+ GC.stat_heap(nil, stat_heap_all)
+ end
+
+ GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT].times do |i|
+ GC.stat_heap(i, stat_heap)
+
+ assert_equal stat_heap, stat_heap_all[i]
+ end
+
+ assert_raise(TypeError) { GC.stat_heap(nil, :slot_size) }
+ end
+
+ def test_stat_heap_constraints
+ omit 'stress' if GC.stress
+
+ stat = GC.stat
+ stat_heap = GC.stat_heap
+ GC.stat(stat)
+ GC.stat_heap(nil, stat_heap)
+
+ stat_heap_sum = Hash.new(0)
+ stat_heap.values.each do |hash|
+ hash.each { |k, v| stat_heap_sum[k] += v }
+ end
+
+ assert_equal stat[:heap_allocatable_pages], stat_heap_sum[:heap_allocatable_pages]
+ assert_equal stat[:heap_eden_pages], stat_heap_sum[:heap_eden_pages]
+ assert_equal stat[:heap_tomb_pages], stat_heap_sum[:heap_tomb_pages]
+ assert_equal stat[:heap_available_slots], stat_heap_sum[:heap_eden_slots] + stat_heap_sum[:heap_tomb_slots]
+ end
+
def test_latest_gc_info
- skip 'stress' if GC.stress
+ omit 'stress' if GC.stress
assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom'
GC.start
@@ -280,7 +346,7 @@ class TestGc < Test::Unit::TestCase
end
def test_profiler_clear
- skip "for now"
+ omit "for now"
assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom', timeout: 30
GC::Profiler.enable
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index 46683d0ed57..16b15b39ac8 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -3,16 +3,22 @@ require 'test/unit'
require 'fiddle'
require 'etc'
+if RUBY_PLATFORM =~ /s390x/
+ warn "Currently, it is known that the compaction does not work well on s390x; contribution is welcome https://github.com/ruby/ruby/pull/5077"
+ return
+end
+
class TestGCCompact < Test::Unit::TestCase
module SupportsCompact
def setup
- skip "autocompact not supported on this platform" unless supports_auto_compact?
+ omit "autocompact not supported on this platform" unless supports_auto_compact?
super
end
private
def supports_auto_compact?
+ return false if /wasm/ =~ RUBY_PLATFORM
return true unless defined?(Etc::SC_PAGE_SIZE)
begin
@@ -73,7 +79,7 @@ class TestGCCompact < Test::Unit::TestCase
n.times do
break if count < GC.stat(:compact_count)
list2 << Object.new
- end and skip "implicit compaction didn't happen within #{n} objects"
+ end and omit "implicit compaction didn't happen within #{n} objects"
compact_stats = GC.latest_compact_info
refute_predicate compact_stats[:considered], :empty?
refute_predicate compact_stats[:moved], :empty?
@@ -87,7 +93,7 @@ class TestGCCompact < Test::Unit::TestCase
end
def setup
- skip "autocompact not supported on this platform" unless supports_auto_compact?
+ omit "autocompact not supported on this platform" unless supports_auto_compact?
super
end
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index f79879c20a5..39376524fad 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -1048,14 +1048,14 @@ class TestHash < Test::Unit::TestCase
h = @cls.new {|hh, k| :foo }
h[1] = 2
assert_equal([1, 2], h.shift)
- assert_equal(:foo, h.shift)
- assert_equal(:foo, h.shift)
+ assert_nil(h.shift)
+ assert_nil(h.shift)
h = @cls.new(:foo)
h[1] = 2
assert_equal([1, 2], h.shift)
- assert_equal(:foo, h.shift)
- assert_equal(:foo, h.shift)
+ assert_nil(h.shift)
+ assert_nil(h.shift)
h =@cls[1=>2]
h.each { assert_equal([1, 2], h.shift) }
@@ -1066,7 +1066,7 @@ class TestHash < Test::Unit::TestCase
def h.default(k = nil)
super.upcase
end
- assert_equal("FOO", h.shift)
+ assert_nil(h.shift)
end
def test_reject_bang2
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index 9354514df07..a2b181c6422 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -299,6 +299,31 @@ class TestInteger < Test::Unit::TestCase
end
end
+ def test_times_bignum_redefine_plus_lt
+ assert_separately([], "#{<<-"begin;"}\n#{<<~"end;"}")
+ begin;
+ called = false
+ Integer.class_eval do
+ alias old_plus +
+ undef +
+ define_method(:+){|x| called = true; 1}
+ alias old_lt <
+ undef <
+ define_method(:<){|x| called = true}
+ end
+ big = 2**65
+ big.times{break 0}
+ Integer.class_eval do
+ undef +
+ alias + old_plus
+ undef <
+ alias < old_lt
+ end
+ bug18377 = "[ruby-core:106361]"
+ assert_equal(false, called, bug18377)
+ end;
+ end
+
def assert_int_equal(expected, result, mesg = nil)
assert_kind_of(Integer, result, mesg)
assert_equal(expected, result, mesg)
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index a90140fd0b3..ed0198321d7 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -476,6 +476,18 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_copy_stream_append_to_nonempty
+ with_srccontent("foobar") {|src, content|
+ preface = 'preface'
+ File.write('dst', preface)
+ File.open('dst', 'ab') do |dst|
+ ret = IO.copy_stream(src, dst)
+ assert_equal(content.bytesize, ret)
+ assert_equal(preface + content, File.read("dst"))
+ end
+ }
+ end
+
def test_copy_stream_smaller
with_srccontent {|src, content|
@@ -643,8 +655,8 @@ class TestIO < Test::Unit::TestCase
if have_nonblock?
def test_copy_stream_no_busy_wait
- skip "MJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
- skip "multiple threads already active" if Thread.list.size > 1
+ omit "MJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ omit "multiple threads already active" if Thread.list.size > 1
msg = 'r58534 [ruby-core:80969] [Backport #13533]'
IO.pipe do |r,w|
@@ -663,7 +675,7 @@ class TestIO < Test::Unit::TestCase
begin
w2.nonblock = true
rescue Errno::EBADF
- skip "nonblocking IO for pipe is not implemented"
+ omit "nonblocking IO for pipe is not implemented"
end
s = w2.syswrite("a" * 100000)
t = Thread.new { sleep 0.1; r2.read }
@@ -767,7 +779,7 @@ class TestIO < Test::Unit::TestCase
r1.nonblock = true
w2.nonblock = true
rescue Errno::EBADF
- skip "nonblocking IO for pipe is not implemented"
+ omit "nonblocking IO for pipe is not implemented"
end
t1 = Thread.new { w1 << megacontent; w1.close }
t2 = Thread.new { r2.read }
@@ -831,7 +843,7 @@ class TestIO < Test::Unit::TestCase
assert_equal("bcd", r.read)
end)
rescue NotImplementedError
- skip "pread(2) is not implemtented."
+ omit "pread(2) is not implemtented."
end
}
end
@@ -935,7 +947,7 @@ class TestIO < Test::Unit::TestCase
begin
s1.nonblock = true
rescue Errno::EBADF
- skip "nonblocking IO for pipe is not implemented"
+ omit "nonblocking IO for pipe is not implemented"
end
t1 = Thread.new { s2.read }
t2 = Thread.new {
@@ -959,7 +971,7 @@ class TestIO < Test::Unit::TestCase
begin
s1.nonblock = true
rescue Errno::EBADF
- skip "nonblocking IO for pipe is not implemented"
+ omit "nonblocking IO for pipe is not implemented"
end
trapping_usr2 do |rd|
nr = 30
@@ -1482,6 +1494,13 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_readpartial_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.readpartial(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_readpartial_buffer_error
with_pipe do |r, w|
s = ""
@@ -1527,6 +1546,13 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_read_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.read(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_read_buffer_error
with_pipe do |r, w|
s = ""
@@ -1564,6 +1590,13 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_read_nonblock_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.read_nonblock(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_write_nonblock_simple_no_exceptions
pipe(proc do |w|
w.write_nonblock('1', exception: false)
@@ -1598,7 +1631,7 @@ class TestIO < Test::Unit::TestCase
end if have_nonblock?
def test_read_nonblock_no_exceptions
- skip '[ruby-core:90895] MJIT worker may leave fd open in a forked child' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # TODO: consider acquiring GVL from MJIT worker.
+ omit '[ruby-core:90895] MJIT worker may leave fd open in a forked child' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # TODO: consider acquiring GVL from MJIT worker.
with_pipe {|r, w|
assert_equal :wait_readable, r.read_nonblock(4096, exception: false)
w.puts "HI!"
@@ -2246,7 +2279,7 @@ class TestIO < Test::Unit::TestCase
def test_autoclose_true_closed_by_finalizer
# http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1465760
# http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1469765
- skip 'this randomly fails with MJIT' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ omit 'this randomly fails with MJIT' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
feature2250 = '[ruby-core:26222]'
pre = 'ft2250'
@@ -2258,7 +2291,7 @@ class TestIO < Test::Unit::TestCase
t.close
rescue Errno::EBADF
end
- skip "expect IO object was GC'ed but not recycled yet"
+ omit "expect IO object was GC'ed but not recycled yet"
rescue WeakRef::RefError
assert_raise(Errno::EBADF, feature2250) {t.close}
end
@@ -2274,7 +2307,7 @@ class TestIO < Test::Unit::TestCase
begin
w.close
t.close
- skip "expect IO object was GC'ed but not recycled yet"
+ omit "expect IO object was GC'ed but not recycled yet"
rescue WeakRef::RefError
assert_nothing_raised(Errno::EBADF, feature2250) {t.close}
end
@@ -2637,7 +2670,7 @@ class TestIO < Test::Unit::TestCase
end
def test_puts_parallel
- skip "not portable"
+ omit "not portable"
pipe(proc do |w|
threads = []
100.times do
@@ -3271,7 +3304,7 @@ __END__
begin
f = File.open('/dev/tty')
rescue Errno::ENOENT, Errno::ENXIO => e
- skip e.message
+ omit e.message
else
tiocgwinsz=0x5413
winsize=""
@@ -3397,10 +3430,10 @@ __END__
with_pipe do |r,w|
# Linux 2.6.15 and earlier returned EINVAL instead of ESPIPE
assert_raise(Errno::ESPIPE, Errno::EINVAL) {
- r.advise(:willneed) or skip "fadvise(2) is not implemented"
+ r.advise(:willneed) or omit "fadvise(2) is not implemented"
}
assert_raise(Errno::ESPIPE, Errno::EINVAL) {
- w.advise(:willneed) or skip "fadvise(2) is not implemented"
+ w.advise(:willneed) or omit "fadvise(2) is not implemented"
}
end
end if /linux/ =~ RUBY_PLATFORM
@@ -3540,14 +3573,14 @@ __END__
f.write('1')
pos = f.tell
rescue Errno::ENOSPC
- skip "non-sparse file system"
+ omit "non-sparse file system"
rescue SystemCallError
else
assert_equal(0x1_0000_0000, pos, msg)
end
end;
rescue Timeout::Error
- skip "Timeout because of slow file writing"
+ omit "Timeout because of slow file writing"
end
}
end if /mswin|mingw/ =~ RUBY_PLATFORM
@@ -3847,30 +3880,6 @@ __END__
end
end;
end
-
- def test_write_no_garbage
- skip "multiple threads already active" if Thread.list.size > 1
- res = {}
- ObjectSpace.count_objects(res) # creates strings on first call
- [ 'foo'.b, '*' * 24 ].each do |buf|
- with_pipe do |r, w|
- GC.disable
- begin
- before = ObjectSpace.count_objects(res)[:T_STRING]
- n = w.write(buf)
- s = w.syswrite(buf)
- after = ObjectSpace.count_objects(res)[:T_STRING]
- ensure
- GC.enable
- end
- assert_equal before, after,
- "no strings left over after write [ruby-core:78898] [Bug #13085]: #{ before } strings before write -> #{ after } strings after write"
- assert_not_predicate buf, :frozen?, 'no inadvertent freeze'
- assert_equal buf.bytesize, n, 'IO#write wrote expected size'
- assert_equal s, n, 'IO#syswrite wrote expected size'
- end
- end
- end
end
def test_pread
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
new file mode 100644
index 00000000000..7e3b467ed59
--- /dev/null
+++ b/test/ruby/test_io_buffer.rb
@@ -0,0 +1,330 @@
+# frozen_string_literal: false
+
+require 'tempfile'
+
+class TestIOBuffer < Test::Unit::TestCase
+ experimental = Warning[:experimental]
+ begin
+ Warning[:experimental] = false
+ IO::Buffer.new(0)
+ ensure
+ Warning[:experimental] = experimental
+ end
+
+ def assert_negative(value)
+ assert(value < 0, "Expected #{value} to be negative!")
+ end
+
+ def assert_positive(value)
+ assert(value > 0, "Expected #{value} to be positive!")
+ end
+
+ def test_flags
+ assert_equal 1, IO::Buffer::EXTERNAL
+ assert_equal 2, IO::Buffer::INTERNAL
+ assert_equal 4, IO::Buffer::MAPPED
+
+ assert_equal 32, IO::Buffer::LOCKED
+ assert_equal 64, IO::Buffer::PRIVATE
+
+ assert_equal 128, IO::Buffer::READONLY
+ end
+
+ def test_endian
+ assert_equal 4, IO::Buffer::LITTLE_ENDIAN
+ assert_equal 8, IO::Buffer::BIG_ENDIAN
+ assert_equal 8, IO::Buffer::NETWORK_ENDIAN
+
+ assert_include [IO::Buffer::LITTLE_ENDIAN, IO::Buffer::BIG_ENDIAN], IO::Buffer::HOST_ENDIAN
+ end
+
+ def test_default_size
+ assert_equal IO::Buffer::DEFAULT_SIZE, IO::Buffer.new.size
+ end
+
+ def test_new_internal
+ buffer = IO::Buffer.new(1024, IO::Buffer::INTERNAL)
+ assert_equal 1024, buffer.size
+ refute buffer.external?
+ assert buffer.internal?
+ refute buffer.mapped?
+ end
+
+ def test_new_mapped
+ buffer = IO::Buffer.new(1024, IO::Buffer::MAPPED)
+ assert_equal 1024, buffer.size
+ refute buffer.external?
+ refute buffer.internal?
+ assert buffer.mapped?
+ end
+
+ def test_new_readonly
+ buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::READONLY)
+ assert buffer.readonly?
+
+ assert_raise IO::Buffer::AccessError do
+ buffer.set_string("")
+ end
+
+ assert_raise IO::Buffer::AccessError do
+ buffer.set_string("!", 1)
+ end
+ end
+
+ def test_file_mapped
+ buffer = File.open(__FILE__) {|file| IO::Buffer.map(file, nil, 0, IO::Buffer::READONLY)}
+ contents = buffer.get_string
+
+ assert_include contents, "Hello World"
+ assert_equal Encoding::BINARY, contents.encoding
+ end
+
+ def test_file_mapped_invalid
+ assert_raise NoMethodError do
+ IO::Buffer.map("foobar")
+ end
+ end
+
+ def test_string_mapped
+ string = "Hello World"
+ buffer = IO::Buffer.for(string)
+ refute buffer.readonly?
+
+ # Cannot modify string as it's locked by the buffer:
+ assert_raise RuntimeError do
+ string[0] = "h"
+ end
+
+ buffer.set_value(:U8, 0, "h".ord)
+
+ # Buffer releases it's ownership of the string:
+ buffer.free
+
+ assert_equal "hello World", string
+ string[0] = "H"
+ assert_equal "Hello World", string
+ end
+
+ def test_string_mapped_frozen
+ string = "Hello World".freeze
+ buffer = IO::Buffer.for(string)
+
+ assert buffer.readonly?
+ end
+
+ def test_non_string
+ not_string = Object.new
+
+ assert_raise TypeError do
+ IO::Buffer.for(not_string)
+ end
+ end
+
+ def test_resize_mapped
+ buffer = IO::Buffer.new
+
+ buffer.resize(2048)
+ assert_equal 2048, buffer.size
+
+ buffer.resize(4096)
+ assert_equal 4096, buffer.size
+ end
+
+ def test_resize_preserve
+ message = "Hello World"
+ buffer = IO::Buffer.new(1024)
+ buffer.set_string(message)
+ buffer.resize(2048)
+ assert_equal message, buffer.get_string(0, message.bytesize)
+ end
+
+ def test_compare_same_size
+ buffer1 = IO::Buffer.new(1)
+ assert_equal buffer1, buffer1
+
+ buffer2 = IO::Buffer.new(1)
+ buffer1.set_value(:U8, 0, 0x10)
+ buffer2.set_value(:U8, 0, 0x20)
+
+ assert_negative buffer1 <=> buffer2
+ assert_positive buffer2 <=> buffer1
+ end
+
+ def test_compare_different_size
+ buffer1 = IO::Buffer.new(3)
+ buffer2 = IO::Buffer.new(5)
+
+ assert_negative buffer1 <=> buffer2
+ assert_positive buffer2 <=> buffer1
+ end
+
+ def test_slice
+ buffer = IO::Buffer.new(128)
+ slice = buffer.slice(8, 32)
+ slice.set_string("Hello World")
+ assert_equal("Hello World", buffer.get_string(8, 11))
+ end
+
+ def test_slice_bounds
+ buffer = IO::Buffer.new(128)
+
+ assert_raise ArgumentError do
+ buffer.slice(128, 10)
+ end
+
+ # assert_raise RuntimeError do
+ # pp buffer.slice(-10, 10)
+ # end
+ end
+
+ def test_locked
+ buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::LOCKED)
+
+ assert_raise IO::Buffer::LockedError do
+ buffer.resize(256)
+ end
+
+ assert_equal 128, buffer.size
+
+ assert_raise IO::Buffer::LockedError do
+ buffer.free
+ end
+
+ assert_equal 128, buffer.size
+ end
+
+ def test_get_string
+ message = "Hello World 🤓"
+
+ buffer = IO::Buffer.new(128)
+ buffer.set_string(message)
+
+ chunk = buffer.get_string(0, message.bytesize, Encoding::UTF_8)
+ assert_equal message, chunk
+ assert_equal Encoding::UTF_8, chunk.encoding
+
+ chunk = buffer.get_string(0, message.bytesize, Encoding::BINARY)
+ assert_equal Encoding::BINARY, chunk.encoding
+ end
+
+ # We check that values are correctly round tripped.
+ RANGES = {
+ :U8 => [0, 2**8-1],
+ :S8 => [-2**7, 0, 2**7-1],
+
+ :U16 => [0, 2**16-1],
+ :S16 => [-2**15, 0, 2**15-1],
+ :u16 => [0, 2**16-1],
+ :s16 => [-2**15, 0, 2**15-1],
+
+ :U32 => [0, 2**32-1],
+ :S32 => [-2**31, 0, 2**31-1],
+ :u32 => [0, 2**32-1],
+ :s32 => [-2**31, 0, 2**31-1],
+
+ :U64 => [0, 2**64-1],
+ :S64 => [-2**63, 0, 2**63-1],
+ :u64 => [0, 2**64-1],
+ :s64 => [-2**63, 0, 2**63-1],
+
+ :F32 => [-1.0, 0.0, 0.5, 1.0, 128.0],
+ :F64 => [-1.0, 0.0, 0.5, 1.0, 128.0],
+ }
+
+ def test_get_set_primitives
+ buffer = IO::Buffer.new(128)
+
+ RANGES.each do |type, values|
+ values.each do |value|
+ buffer.set_value(type, 0, value)
+ assert_equal value, buffer.get_value(type, 0), "Converting #{value} as #{type}."
+ end
+ end
+ end
+
+ def test_clear
+ buffer = IO::Buffer.new(16)
+ buffer.set_string("Hello World!")
+ end
+
+ def test_invalidation
+ input, output = IO.pipe
+
+ # (1) rb_write_internal creates IO::Buffer object,
+ buffer = IO::Buffer.new(128)
+
+ # (2) it is passed to (malicious) scheduler
+ # (3) scheduler starts a thread which call system call with the buffer object
+ thread = Thread.new{buffer.locked{input.read}}
+
+ Thread.pass until thread.stop?
+
+ # (4) scheduler returns
+ # (5) rb_write_internal invalidate the buffer object
+ assert_raise IO::Buffer::LockedError do
+ buffer.free
+ end
+
+ # (6) the system call access the memory area after invalidation
+ output.write("Hello World")
+ output.close
+ thread.join
+
+ input.close
+ end
+
+ def test_read
+ io = Tempfile.new
+ io.write("Hello World")
+ io.seek(0)
+
+ buffer = IO::Buffer.new(128)
+ buffer.read(io, 5)
+
+ assert_equal "Hello", buffer.get_string(0, 5)
+ ensure
+ io.close!
+ end
+
+ def test_write
+ io = Tempfile.new
+
+ buffer = IO::Buffer.new(128)
+ buffer.set_string("Hello")
+ buffer.write(io, 5)
+
+ io.seek(0)
+ assert_equal "Hello", io.read(5)
+ ensure
+ io.close!
+ end
+
+ def test_pread
+ io = Tempfile.new
+ io.write("Hello World")
+ io.seek(0)
+
+ buffer = IO::Buffer.new(128)
+ buffer.pread(io, 5, 6)
+
+ assert_equal "World", buffer.get_string(0, 5)
+ assert_equal 0, io.tell
+ ensure
+ io.close!
+ end
+
+ def test_pwrite
+ io = Tempfile.new
+
+ buffer = IO::Buffer.new(128)
+ buffer.set_string("World")
+ buffer.pwrite(io, 5, 6)
+
+ assert_equal 0, io.tell
+
+ io.seek(6)
+ assert_equal "World", io.read(5)
+ ensure
+ io.close!
+ end
+end
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index edd131823e2..2a18ff02e17 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -10,13 +10,16 @@ class TestISeq < Test::Unit::TestCase
end
def compile(src, line = nil, opt = nil)
+ unless line
+ line = caller_locations(1).first.lineno
+ end
EnvUtil.suppress_warning do
ISeq.new(src, __FILE__, __FILE__, line, opt)
end
end
- def lines src
- body = compile(src).to_a[13]
+ def lines src, lines = nil
+ body = compile(src, lines).to_a[13]
body.find_all{|e| e.kind_of? Integer}
end
@@ -25,24 +28,22 @@ class TestISeq < Test::Unit::TestCase
end
def test_to_a_lines
- src = <<-EOS
+ assert_equal [__LINE__+1, __LINE__+2, __LINE__+4], lines(<<-EOS, __LINE__+1)
p __LINE__ # 1
p __LINE__ # 2
# 3
p __LINE__ # 4
EOS
- assert_equal [1, 2, 4], lines(src)
- src = <<-EOS
+ assert_equal [__LINE__+2, __LINE__+4], lines(<<-EOS, __LINE__+1)
# 1
p __LINE__ # 2
# 3
p __LINE__ # 4
# 5
EOS
- assert_equal [2, 4], lines(src)
- src = <<-EOS
+ assert_equal [__LINE__+3, __LINE__+4, __LINE__+7, __LINE__+9], lines(<<~EOS, __LINE__+1)
1 # should be optimized out
2 # should be optimized out
p __LINE__ # 3
@@ -53,10 +54,9 @@ class TestISeq < Test::Unit::TestCase
8 # should be optimized out
9
EOS
- assert_equal [3, 4, 7, 9], lines(src)
end
- def test_unsupport_type
+ def test_unsupported_type
ary = compile("p").to_a
ary[9] = :foobar
assert_raise_with_message(TypeError, /:foobar/) {ISeq.load(ary)}
@@ -86,7 +86,7 @@ class TestISeq < Test::Unit::TestCase
# CDHASH was not built properly when loading from binary and
# was causing opt_case_dispatch to clobber its stack canary
# for its "leaf" instruction attribute.
- iseq = compile(<<~EOF)
+ iseq = compile(<<~EOF, __LINE__+1)
case Class.new(String).new("foo")
when "foo"
42
@@ -95,16 +95,78 @@ class TestISeq < Test::Unit::TestCase
assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
end
+ def test_super_with_block
+ iseq = compile(<<~EOF, __LINE__+1)
+ def (Object.new).touch(*) # :nodoc:
+ foo { super }
+ end
+ 42
+ EOF
+ assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+ end
+
+ def test_super_with_block_hash_0
+ iseq = compile(<<~EOF, __LINE__+1)
+ # [Bug #18250] `req` specifically cause `Assertion failed: (key != 0), function hash_table_raw_insert`
+ def (Object.new).touch(req, *)
+ foo { super }
+ end
+ 42
+ EOF
+ assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+ end
+
+ def test_super_with_block_and_kwrest
+ iseq = compile(<<~EOF, __LINE__+1)
+ def (Object.new).touch(**) # :nodoc:
+ foo { super }
+ end
+ 42
+ EOF
+ assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+ end
+
def test_lambda_with_ractor_roundtrip
- iseq = compile(<<~EOF)
+ iseq = compile(<<~EOF, __LINE__+1)
x = 42
- y = lambda { x }
+ y = nil.instance_eval{ lambda { x } }
Ractor.make_shareable(y)
y.call
EOF
assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
end
+ def test_super_with_anonymous_block
+ iseq = compile(<<~EOF, __LINE__+1)
+ def (Object.new).touch(&) # :nodoc:
+ foo { super }
+ end
+ 42
+ EOF
+ assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+ end
+
+ def test_ractor_unshareable_outer_variable
+ name = "\u{2603 26a1}"
+ y = nil.instance_eval do
+ eval("proc {#{name} = nil; proc {|x| #{name} = x}}").call
+ end
+ assert_raise_with_message(ArgumentError, /\(#{name}\)/) do
+ Ractor.make_shareable(y)
+ end
+ y = nil.instance_eval do
+ eval("proc {#{name} = []; proc {|x| #{name}}}").call
+ end
+ assert_raise_with_message(Ractor::IsolationError, /`#{name}'/) do
+ Ractor.make_shareable(y)
+ end
+ obj = Object.new
+ def obj.foo(*) nil.instance_eval{ ->{super} } end
+ assert_raise_with_message(Ractor::IsolationError, /refer unshareable object \[\] from variable `\*'/) do
+ Ractor.make_shareable(obj.foo)
+ end
+ end
+
def test_disasm_encoding
src = "\u{3042} = 1; \u{3042}; \u{3043}"
asm = compile(src).disasm
@@ -147,16 +209,16 @@ class TestISeq < Test::Unit::TestCase
end
def test_line_trace
- iseq = compile \
- %q{ a = 1
+ iseq = compile(<<~EOF, __LINE__+1)
+ a = 1
b = 2
c = 3
# d = 4
e = 5
# f = 6
g = 7
+ EOF
- }
assert_equal([1, 2, 3, 5, 7], iseq.line_trace_all)
iseq.line_trace_specify(1, true) # line 2
iseq.line_trace_specify(3, true) # line 5
@@ -328,6 +390,30 @@ class TestISeq < Test::Unit::TestCase
end
end
+ def anon_star(*); end
+
+ def test_anon_rest_param_in_disasm
+ iseq = RubyVM::InstructionSequence.of(method(:anon_star))
+ param_names = iseq.to_a[iseq.to_a.index(:method) + 1]
+ assert_equal [:*], param_names
+ end
+
+ def anon_keyrest(**); end
+
+ def test_anon_keyrest_param_in_disasm
+ iseq = RubyVM::InstructionSequence.of(method(:anon_keyrest))
+ param_names = iseq.to_a[iseq.to_a.index(:method) + 1]
+ assert_equal [:**], param_names
+ end
+
+ def anon_block(&); end
+
+ def test_anon_block_param_in_disasm
+ iseq = RubyVM::InstructionSequence.of(method(:anon_block))
+ param_names = iseq.to_a[iseq.to_a.index(:method) + 1]
+ assert_equal [:&], param_names
+ end
+
def strip_lineno(source)
source.gsub(/^.*?: /, "")
end
@@ -453,7 +539,7 @@ class TestISeq < Test::Unit::TestCase
bin = assert_nothing_raised(mesg) do
iseq.to_binary
rescue RuntimeError => e
- skip e.message if /compile with coverage/ =~ e.message
+ omit e.message if /compile with coverage/ =~ e.message
raise
end
10.times do
@@ -464,6 +550,11 @@ class TestISeq < Test::Unit::TestCase
a1 = iseq.to_a
a2 = iseq2.to_a
assert_equal(a1, a2, message(mesg) {diff iseq.disassemble, iseq2.disassemble})
+ if iseq2.script_lines
+ assert_kind_of(Array, iseq2.script_lines)
+ else
+ assert_nil(iseq2.script_lines)
+ end
iseq2
end
@@ -635,4 +726,28 @@ class TestISeq < Test::Unit::TestCase
RubyVM::InstructionSequence.compile("", debug_level: 5)
end;
end
+
+ def test_mandatory_only
+ assert_separately [], <<~RUBY
+ at0 = Time.at(0)
+ assert_equal at0, Time.public_send(:at, 0, 0)
+ RUBY
+ end
+
+ def test_mandatory_only_redef
+ assert_separately ['-W0'], <<~RUBY
+ r = Ractor.new{
+ Float(10)
+ module Kernel
+ undef Float
+ def Float(n)
+ :new
+ end
+ end
+ GC.start
+ Float(30)
+ }
+ assert_equal :new, r.take
+ RUBY
+ end
end
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index 669dcf56e6f..3e3da24641d 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -64,7 +64,7 @@ class TestJIT < Test::Unit::TestCase
def setup
unless JITSupport.supported?
- skip 'JIT seems not supported on this platform'
+ omit 'JIT seems not supported on this platform'
end
self.class.setup
end
@@ -243,8 +243,8 @@ class TestJIT < Test::Unit::TestCase
end;
end
- def test_compile_insn_putstring_concatstrings_tostring
- assert_compile_once('"a#{}b" + "c"', result_inspect: '"abc"', insns: %i[putstring concatstrings tostring])
+ def test_compile_insn_putstring_concatstrings_objtostring
+ assert_compile_once('"a#{}b" + "c"', result_inspect: '"abc"', insns: %i[putstring concatstrings objtostring])
end
def test_compile_insn_toregexp
@@ -321,7 +321,7 @@ class TestJIT < Test::Unit::TestCase
end
def test_compile_insn_reput
- skip "write test"
+ omit "write test"
end
def test_compile_insn_setn
@@ -352,11 +352,11 @@ class TestJIT < Test::Unit::TestCase
end
def test_compile_insn_tracecoverage
- skip "write test"
+ omit "write test"
end
def test_compile_insn_defineclass
- skip "support this in mjit_compile (low priority)"
+ omit "support this in mjit_compile (low priority)"
end
def test_compile_insn_send
@@ -482,8 +482,8 @@ class TestJIT < Test::Unit::TestCase
end;
end
- def test_compile_insn_checktype
- assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"', insns: %i[checktype])
+ def test_compile_insn_objtostring
+ assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"', insns: %i[objtostring])
begin;
a = '2'
"4#{a}"
@@ -709,7 +709,7 @@ class TestJIT < Test::Unit::TestCase
if RUBY_PLATFORM.match?(/mswin/)
# "Permission Denied" error is preventing to remove so file on AppVeyor/RubyCI.
- skip 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
+ omit 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
else
# verify .c files are deleted on unload_units
assert_send([Dir, :empty?, dir], debug_info)
@@ -996,7 +996,7 @@ class TestJIT < Test::Unit::TestCase
def test_clean_so
if RUBY_PLATFORM.match?(/mswin/)
- skip 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
+ omit 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
end
Dir.mktmpdir("jit_test_clean_so_") do |dir|
code = "x = 0; 10.times {|i|x+=i}"
@@ -1010,7 +1010,7 @@ class TestJIT < Test::Unit::TestCase
def test_clean_objects_on_exec
if /mswin|mingw/ =~ RUBY_PLATFORM
# TODO: check call stack and close handle of code which is not on stack, and remove objects on best-effort basis
- skip 'Removing so file being used does not work on Windows'
+ omit 'Removing so file being used does not work on Windows'
end
Dir.mktmpdir("jit_test_clean_objects_on_exec_") do |dir|
eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
@@ -1108,7 +1108,7 @@ class TestJIT < Test::Unit::TestCase
def test_mjit_pause_wait
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 0, min_calls: 1)
begin;
- RubyVM::JIT.pause
+ RubyVM::MJIT.pause
proc {}.call
end;
end
@@ -1194,8 +1194,8 @@ class TestJIT < Test::Unit::TestCase
out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls, max_cache: max_cache)
success_actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
recompile_actual = err.scan(/^#{JIT_RECOMPILE_PREFIX}:/).size
- # Add --jit-verbose=2 logs for cl.exe because compiler's error message is suppressed
- # for cl.exe with --jit-verbose=1. See `start_process` in mjit_worker.c.
+ # Add --mjit-verbose=2 logs for cl.exe because compiler's error message is suppressed
+ # for cl.exe with --mjit-verbose=1. See `start_process` in mjit_worker.c.
if RUBY_PLATFORM.match?(/mswin/) && success_count != success_actual
out2, err2 = eval_with_jit(script, verbose: 2, min_calls: min_calls, max_cache: max_cache)
end
@@ -1231,7 +1231,9 @@ class TestJIT < Test::Unit::TestCase
end
def mark_tested_insn(insn, used_insns:, uplevel: 1)
- unless used_insns.include?(insn)
+ # Currently, this check emits a false-positive warning against opt_regexpmatch2,
+ # so the insn is excluded explicitly. See https://bugs.ruby-lang.org/issues/18269
+ if !used_insns.include?(insn) && insn != :opt_regexpmatch2
$stderr.puts
warn "'#{insn}' insn is not included in the script. Actual insns are: #{used_insns.join(' ')}\n", uplevel: uplevel
end
diff --git a/test/ruby/test_jit_debug.rb b/test/ruby/test_jit_debug.rb
index 50e52b4c2e1..b8dc9416efe 100644
--- a/test/ruby/test_jit_debug.rb
+++ b/test/ruby/test_jit_debug.rb
@@ -11,7 +11,7 @@ class TestJITDebug < TestJIT
def setup
super
- # let `#eval_with_jit` use --jit-debug
- @jit_debug = true
+ # let `#eval_with_jit` use --mjit-debug
+ @mjit_debug = true
end
end
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index 8c3256c0346..99dd3a0c56a 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -26,7 +26,7 @@ class TestRubyLiteral < Test::Unit::TestCase
assert_equal '5', 0b101.inspect
assert_instance_of Integer, 0b101
assert_raise(SyntaxError) { eval("0b") }
- assert_equal '123456789012345678901234567890', 123456789012345678901234567890.inspect
+ assert_equal '123456789012345678901234567890', 123456789012345678901234567890.to_s
assert_instance_of Integer, 123456789012345678901234567890
assert_instance_of Float, 1.3
assert_equal '2', eval("0x00+2").inspect
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index 6b0bc4de5ee..c00bf59e187 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -299,6 +299,9 @@ class TestM17N < Test::Unit::TestCase
orig_v, $VERBOSE = $VERBOSE, false
orig_int, Encoding.default_internal = Encoding.default_internal, nil
orig_ext = Encoding.default_external
+
+ omit "https://bugs.ruby-lang.org/issues/18338"
+
o = Object.new
Encoding.default_external = Encoding::UTF_16BE
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index daf0ec73ca1..caf8bebd356 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -199,6 +199,11 @@ class TestMethod < Test::Unit::TestCase
assert_equal(o.method(:foo), o.method(:foo))
assert_equal(o.method(:foo), o.method(:bar))
assert_not_equal(o.method(:foo), o.method(:baz))
+
+ class << o
+ private :bar
+ end
+ assert_not_equal(o.method(:foo), o.method(:bar))
end
def test_hash
@@ -566,9 +571,9 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c]], method(:mo5).parameters)
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:mo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:mo7).parameters)
- assert_equal([[:req, :a], [:opt, :b], [:rest], [:req, :d], [:block, :e]], method(:mo8).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :*], [:req, :d], [:block, :e]], method(:mo8).parameters)
assert_equal([[:req], [:block, :b]], method(:ma1).parameters)
- assert_equal([[:keyrest]], method(:mk1).parameters)
+ assert_equal([[:keyrest, :**]], method(:mk1).parameters)
assert_equal([[:keyrest, :o]], method(:mk2).parameters)
assert_equal([[:req, :a], [:keyrest, :o]], method(:mk3).parameters)
assert_equal([[:opt, :a], [:keyrest, :o]], method(:mk4).parameters)
@@ -592,9 +597,9 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c]], self.class.instance_method(:mo5).parameters)
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:mo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:mo7).parameters)
- assert_equal([[:req, :a], [:opt, :b], [:rest], [:req, :d], [:block, :e]], self.class.instance_method(:mo8).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :*], [:req, :d], [:block, :e]], self.class.instance_method(:mo8).parameters)
assert_equal([[:req], [:block, :b]], self.class.instance_method(:ma1).parameters)
- assert_equal([[:keyrest]], self.class.instance_method(:mk1).parameters)
+ assert_equal([[:keyrest, :**]], self.class.instance_method(:mk1).parameters)
assert_equal([[:keyrest, :o]], self.class.instance_method(:mk2).parameters)
assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:mk3).parameters)
assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:mk4).parameters)
@@ -619,7 +624,7 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).parameters)
assert_equal([[:req], [:block, :b]], method(:pma1).parameters)
- assert_equal([[:keyrest]], method(:pmk1).parameters)
+ assert_equal([[:keyrest, :**]], method(:pmk1).parameters)
assert_equal([[:keyrest, :o]], method(:pmk2).parameters)
assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).parameters)
assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).parameters)
@@ -643,7 +648,7 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:pmo7).parameters)
assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters)
assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters)
- assert_equal([[:keyrest]], self.class.instance_method(:pmk1).parameters)
+ assert_equal([[:keyrest, :**]], self.class.instance_method(:pmk1).parameters)
assert_equal([[:keyrest, :o]], self.class.instance_method(:pmk2).parameters)
assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:pmk3).parameters)
assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:pmk4).parameters)
@@ -1181,6 +1186,50 @@ class TestMethod < Test::Unit::TestCase
assert_nil(super_method)
end
+ def test_method_visibility_predicates
+ v = Visibility.new
+ assert_equal(true, v.method(:mv1).public?)
+ assert_equal(true, v.method(:mv2).private?)
+ assert_equal(true, v.method(:mv3).protected?)
+ assert_equal(false, v.method(:mv2).public?)
+ assert_equal(false, v.method(:mv3).private?)
+ assert_equal(false, v.method(:mv1).protected?)
+ end
+
+ def test_unbound_method_visibility_predicates
+ assert_equal(true, Visibility.instance_method(:mv1).public?)
+ assert_equal(true, Visibility.instance_method(:mv2).private?)
+ assert_equal(true, Visibility.instance_method(:mv3).protected?)
+ assert_equal(false, Visibility.instance_method(:mv2).public?)
+ assert_equal(false, Visibility.instance_method(:mv3).private?)
+ assert_equal(false, Visibility.instance_method(:mv1).protected?)
+ end
+
+ class VisibilitySub < Visibility
+ protected :mv1
+ public :mv2
+ private :mv3
+ end
+
+ def test_method_visibility_predicates_with_subclass_visbility_change
+ v = VisibilitySub.new
+ assert_equal(false, v.method(:mv1).public?)
+ assert_equal(false, v.method(:mv2).private?)
+ assert_equal(false, v.method(:mv3).protected?)
+ assert_equal(true, v.method(:mv2).public?)
+ assert_equal(true, v.method(:mv3).private?)
+ assert_equal(true, v.method(:mv1).protected?)
+ end
+
+ def test_unbound_method_visibility_predicates_with_subclass_visbility_change
+ assert_equal(false, VisibilitySub.instance_method(:mv1).public?)
+ assert_equal(false, VisibilitySub.instance_method(:mv2).private?)
+ assert_equal(false, VisibilitySub.instance_method(:mv3).protected?)
+ assert_equal(true, VisibilitySub.instance_method(:mv2).public?)
+ assert_equal(true, VisibilitySub.instance_method(:mv3).private?)
+ assert_equal(true, VisibilitySub.instance_method(:mv1).protected?)
+ end
+
def rest_parameter(*rest)
rest
end
@@ -1188,7 +1237,7 @@ class TestMethod < Test::Unit::TestCase
def test_splat_long_array
if File.exist?('/etc/os-release') && File.read('/etc/os-release').include?('openSUSE Leap')
# For RubyCI's openSUSE machine http://rubyci.s3.amazonaws.com/opensuseleap/ruby-trunk/recent.html, which tends to die with NoMemoryError here.
- skip 'do not exhaust memory on RubyCI openSUSE Leap machine'
+ omit 'do not exhaust memory on RubyCI openSUSE Leap machine'
end
n = 10_000_000
assert_equal n , rest_parameter(*(1..n)).size, '[Feature #10440]'
@@ -1390,7 +1439,7 @@ class TestMethod < Test::Unit::TestCase
# use_symbol = Object.instance_methods[0].is_a?(Symbol)
nummodule = nummethod = 0
mods = []
- ObjectSpace.each_object(Module) {|m| mods << m if m.name }
+ ObjectSpace.each_object(Module) {|m| mods << m if String === m.name }
mods = mods.sort_by {|m| m.name }
mods.each {|mod|
nummodule += 1
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index be23b84c462..e7441217187 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -475,6 +475,15 @@ class TestModule < Test::Unit::TestCase
assert_not_include(mod.ancestor_list, BasicObject)
end
+ def test_module_collected_extended_object
+ m1 = labeled_module("m1")
+ m2 = labeled_module("m2")
+ Object.new.extend(m1)
+ GC.start
+ m1.include(m2)
+ assert_equal([m1, m2], m1.ancestors)
+ end
+
def test_dup
OtherSetup.call
@@ -519,6 +528,16 @@ class TestModule < Test::Unit::TestCase
assert_raise(ArgumentError) { Module.new { include } }
end
+ def test_include_before_initialize
+ m = Class.new(Module) do
+ def initialize(...)
+ include Enumerable
+ super
+ end
+ end.new
+ assert_operator(m, :<, Enumerable)
+ end
+
def test_prepend_self
m = Module.new
assert_equal([m], m.ancestors)
@@ -1014,6 +1033,28 @@ class TestModule < Test::Unit::TestCase
assert_raise(NoMethodError, /protected method/) {o.aClass2}
end
+ def test_visibility_method_return_value
+ no_arg_results = nil
+ c = Module.new do
+ singleton_class.send(:public, :public, :private, :protected, :module_function)
+ def foo; end
+ def bar; end
+ no_arg_results = [public, private, protected, module_function]
+ end
+
+ assert_equal([nil]*4, no_arg_results)
+
+ assert_equal(:foo, c.private(:foo))
+ assert_equal(:foo, c.public(:foo))
+ assert_equal(:foo, c.protected(:foo))
+ assert_equal(:foo, c.module_function(:foo))
+
+ assert_equal([:foo, :bar], c.private(:foo, :bar))
+ assert_equal([:foo, :bar], c.public(:foo, :bar))
+ assert_equal([:foo, :bar], c.protected(:foo, :bar))
+ assert_equal([:foo, :bar], c.module_function(:foo, :bar))
+ end
+
def test_s_constants
c1 = Module.constants
Object.module_eval "WALTER = 99"
@@ -1643,6 +1684,45 @@ class TestModule < Test::Unit::TestCase
assert_match(/::X\u{df}:/, c.new.to_s)
end
+
+ def test_const_added
+ eval(<<~RUBY)
+ module TestConstAdded
+ @memo = []
+ class << self
+ attr_accessor :memo
+
+ def const_added(sym)
+ memo << sym
+ end
+ end
+ CONST = 1
+ module SubModule
+ end
+
+ class SubClass
+ end
+ end
+ TestConstAdded::OUTSIDE_CONST = 2
+ module TestConstAdded::OutsideSubModule; end
+ class TestConstAdded::OutsideSubClass; end
+ RUBY
+ TestConstAdded.const_set(:CONST_SET, 3)
+ assert_equal [
+ :CONST,
+ :SubModule,
+ :SubClass,
+ :OUTSIDE_CONST,
+ :OutsideSubModule,
+ :OutsideSubClass,
+ :CONST_SET,
+ ], TestConstAdded.memo
+ ensure
+ if self.class.const_defined? :TestConstAdded
+ self.class.send(:remove_const, :TestConstAdded)
+ end
+ end
+
def test_method_added
memo = []
mod = Module.new do
diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb
index 24a190b2dfc..e0f9eecd119 100644
--- a/test/ruby/test_objectspace.rb
+++ b/test/ruby/test_objectspace.rb
@@ -219,7 +219,7 @@ End
assert_same(new_obj, found[0])
end
- def test_each_object_no_gabage
+ def test_each_object_no_garbage
assert_separately([], <<-End)
GC.disable
eval('begin; 1.times{}; rescue; ensure; end')
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index cbae6d5e8c3..80c3c3860b7 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -510,7 +510,7 @@ class TestRubyOptimization < Test::Unit::TestCase
end
def test_tailcall_not_to_grow_stack
- skip 'currently JIT-ed code always creates a new stack frame' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ omit 'currently JIT-ed code always creates a new stack frame' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
bug16161 = '[ruby-core:94881]'
tailcall("#{<<-"begin;"}\n#{<<~"end;"}")
@@ -903,4 +903,34 @@ class TestRubyOptimization < Test::Unit::TestCase
raise "END"
end;
end
+
+ class Objtostring
+ end
+
+ def test_objtostring
+ assert_raise(NoMethodError){"#{BasicObject.new}"}
+ assert_redefine_method('Symbol', 'to_s', <<-'end')
+ assert_match %r{\A#<Symbol:0x[0-9a-f]+>\z}, "#{:foo}"
+ end
+ assert_redefine_method('NilClass', 'to_s', <<-'end')
+ assert_match %r{\A#<NilClass:0x[0-9a-f]+>\z}, "#{nil}"
+ end
+ assert_redefine_method('TrueClass', 'to_s', <<-'end')
+ assert_match %r{\A#<TrueClass:0x[0-9a-f]+>\z}, "#{true}"
+ end
+ assert_redefine_method('FalseClass', 'to_s', <<-'end')
+ assert_match %r{\A#<FalseClass:0x[0-9a-f]+>\z}, "#{false}"
+ end
+ assert_redefine_method('Integer', 'to_s', <<-'end')
+ (-1..10).each { |i|
+ assert_match %r{\A#<Integer:0x[0-9a-f]+>\z}, "#{i}"
+ }
+ end
+ assert_equal "TestRubyOptimization::Objtostring", "#{Objtostring}"
+ assert_match %r{\A#<Class:0x[0-9a-f]+>\z}, "#{Class.new}"
+ assert_match %r{\A#<Module:0x[0-9a-f]+>\z}, "#{Module.new}"
+ o = Object.new
+ def o.to_s; 1; end
+ assert_match %r{\A#<Object:0x[0-9a-f]+>\z}, "#{o}"
+ end
end
diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb
index af45adb2b23..9738f82b7e2 100644
--- a/test/ruby/test_pack.rb
+++ b/test/ruby/test_pack.rb
@@ -638,6 +638,14 @@ EXPECTED
end;
end
+ def test_bug_18343
+ bug18343 = '[ruby-core:106096] [Bug #18343]'
+ assert_separately(%W[- #{bug18343}], <<-'end;')
+ bug = ARGV.shift
+ assert_raise(ArgumentError, bug){[0].pack('c', {})}
+ end;
+ end
+
def test_pack_unpack_m0
assert_equal("", [""].pack("m0"))
assert_equal("AA==", ["\0"].pack("m0"))
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 3120016e60d..d697a29c1c8 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -1044,7 +1044,7 @@ x = __ENCODING__
end;
assert_syntax_error("def\nf(000)end", /^ \^~~/)
- assert_syntax_error("def\nf(&)end", /^ \^/)
+ assert_syntax_error("def\nf(&0)end", /^ \^/)
end
def test_method_location_in_rescue
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 16efd13d7c5..392b6be665f 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -412,6 +412,11 @@ class TestProc < Test::Unit::TestCase
assert_equal(:foo, bc.foo)
end
+ def test_dup_subclass
+ c1 = Class.new(Proc)
+ assert_equal c1, c1.new{}.dup.class, '[Bug #17545]'
+ end
+
def test_binding
b = proc {|x, y, z| proc {}.binding }.call(1, 2, 3)
class << b; attr_accessor :foo; end
@@ -1261,7 +1266,7 @@ class TestProc < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).to_proc.parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).to_proc.parameters)
assert_equal([[:req], [:block, :b]], method(:pma1).to_proc.parameters)
- assert_equal([[:keyrest]], method(:pmk1).to_proc.parameters)
+ assert_equal([[:keyrest, :**]], method(:pmk1).to_proc.parameters)
assert_equal([[:keyrest, :o]], method(:pmk2).to_proc.parameters)
assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).to_proc.parameters)
assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).to_proc.parameters)
@@ -1597,18 +1602,24 @@ class TestProc < Test::Unit::TestCase
def test_isolate
assert_raise_with_message ArgumentError, /\(a\)/ do
a = :a
- Proc.new{p a}.isolate.call
+ Proc.new{p a}.isolate
end
assert_raise_with_message ArgumentError, /\(a\)/ do
a = :a
1.times{
- Proc.new{p a}.isolate.call
+ Proc.new{p a}.isolate
}
end
assert_raise_with_message ArgumentError, /yield/ do
- Proc.new{yield}.isolate.call
+ Proc.new{yield}.isolate
+ end
+
+
+ name = "\u{2603 26a1}"
+ assert_raise_with_message(ArgumentError, /\(#{name}\)/) do
+ eval("#{name} = :#{name}; Proc.new {p #{name}}").isolate
end
# binding
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index 636871f8223..c4888598a89 100644
--- a/test/ruby/test_process.rb
+++ b/test/ruby/test_process.rb
@@ -169,7 +169,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_pgroup
- skip "system(:pgroup) is not supported" if windows?
+ omit "system(:pgroup) is not supported" if windows?
assert_nothing_raised { system(*TRUECOMMAND, :pgroup=>false) }
io = IO.popen([RUBY, "-e", "print Process.getpgrp"])
@@ -208,39 +208,39 @@ class TestProcess < Test::Unit::TestCase
n = max
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
- assert_equal("[#{n}, #{n}]\n", io.read)
+ "puts Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("#{n}\n#{n}\n", io.read)
}
n = 0
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
- assert_equal("[#{n}, #{n}]\n", io.read)
+ "puts Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("#{n}\n#{n}\n", io.read)
}
n = max
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE)", :rlimit_core=>[n]]) {|io|
- assert_equal("[#{n}, #{n}]", io.read.chomp)
+ "puts Process.getrlimit(:CORE)", :rlimit_core=>[n]]) {|io|
+ assert_equal("#{n}\n#{n}\n", io.read)
}
m, n = 0, max
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
- assert_equal("[#{m}, #{n}]", io.read.chomp)
+ "puts Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("#{m}\n#{n}\n", io.read)
}
m, n = 0, 0
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
- assert_equal("[#{m}, #{n}]", io.read.chomp)
+ "puts Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("#{m}\n#{n}\n", io.read)
}
n = max
IO.popen([RUBY, "-e",
- "p Process.getrlimit(:CORE), Process.getrlimit(:CPU)",
+ "puts Process.getrlimit(:CORE), Process.getrlimit(:CPU)",
:rlimit_core=>n, :rlimit_cpu=>3600]) {|io|
- assert_equal("[#{n}, #{n}]\n[3600, 3600]", io.read.chomp)
+ assert_equal("#{n}\n#{n}\n""3600\n3600\n", io.read)
}
assert_raise(ArgumentError) do
@@ -511,7 +511,7 @@ class TestProcess < Test::Unit::TestCase
UMASK = [RUBY, '-e', 'printf "%04o\n", File.umask']
def test_execopts_umask
- skip "umask is not supported" if windows?
+ omit "umask is not supported" if windows?
IO.popen([*UMASK, :umask => 0]) {|io|
assert_equal("0000", io.read.chomp)
}
@@ -837,7 +837,7 @@ class TestProcess < Test::Unit::TestCase
STDERR=>"out", STDOUT=>[:child, STDERR])
assert_equal("errout", File.read("out"))
- skip "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
+ omit "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
Process.wait spawn(RUBY, "-e", "STDERR.print 'err'; STDOUT.print 'out'",
STDOUT=>"out",
STDERR=>[:child, 3],
@@ -889,7 +889,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_popen_extra_fd
- skip "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
+ omit "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
with_tmpchdir {|d|
with_pipe {|r, w|
IO.popen([RUBY, '-e', 'IO.new(3, "w").puts("a"); puts "b"', 3=>w]) {|io|
@@ -918,7 +918,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_fd_inheritance
- skip "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
+ omit "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
with_pipe {|r, w|
system(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts(:ba)', w.fileno.to_s, w=>w)
w.close
@@ -964,7 +964,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_close_others
- skip "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
+ omit "inheritance of fd other than stdin,stdout and stderr is not supported" if windows?
with_tmpchdir {|d|
with_pipe {|r, w|
system(RUBY, '-e', 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i, "w").puts("ma")', w.fileno.to_s, :close_others=>true)
@@ -1058,7 +1058,7 @@ class TestProcess < Test::Unit::TestCase
}
}
rescue NotImplementedError
- skip "IO#close_on_exec= is not supported"
+ omit "IO#close_on_exec= is not supported"
end
end unless windows? # passing non-stdio fds is not supported on Windows
@@ -1610,7 +1610,7 @@ class TestProcess < Test::Unit::TestCase
else
assert_kind_of(Integer, max)
assert_predicate(max, :positive?)
- skip "not limited to NGROUPS_MAX" if /darwin/ =~ RUBY_PLATFORM
+ omit "not limited to NGROUPS_MAX" if /darwin/ =~ RUBY_PLATFORM
gs = Process.groups
assert_operator(gs.size, :<=, max)
gs[0] ||= 0
@@ -1637,7 +1637,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_setegid
- skip "root can use Process.egid on Android platform" if RUBY_PLATFORM =~ /android/
+ omit "root can use Process.egid on Android platform" if RUBY_PLATFORM =~ /android/
assert_nothing_raised(TypeError) {Process.egid += 0}
rescue NotImplementedError
end
@@ -1698,7 +1698,7 @@ class TestProcess < Test::Unit::TestCase
if /freebsd|openbsd/ =~ RUBY_PLATFORM
# this relates #4173
# When ruby can use 2 cores, signal and wait4 may miss the signal.
- skip "this fails on FreeBSD and OpenBSD on multithreaded environment"
+ omit "this fails on FreeBSD and OpenBSD on multithreaded environment"
end
signal_received = []
IO.pipe do |sig_r, sig_w|
@@ -1718,7 +1718,7 @@ class TestProcess < Test::Unit::TestCase
Process.wait pid
assert_send [sig_r, :wait_readable, 5], 'self-pipe not readable'
end
- if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # checking -DMJIT_FORCE_ENABLE. It may trigger extra SIGCHLD.
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # checking -DMJIT_FORCE_ENABLE. It may trigger extra SIGCHLD.
assert_equal [true], signal_received.uniq, "[ruby-core:19744]"
else
assert_equal [true], signal_received, "[ruby-core:19744]"
@@ -1733,7 +1733,7 @@ class TestProcess < Test::Unit::TestCase
def test_no_curdir
if /solaris/i =~ RUBY_PLATFORM
- skip "Temporary skip to avoid CI failures after commit to use realpath on required files"
+ omit "Temporary omit to avoid CI failures after commit to use realpath on required files"
end
with_tmpchdir {|d|
Dir.mkdir("vd")
@@ -1775,7 +1775,7 @@ class TestProcess < Test::Unit::TestCase
def test_aspawn_too_long_path
if /solaris/i =~ RUBY_PLATFORM && !defined?(Process::RLIMIT_NPROC)
- skip "Too exhaustive test on platforms without Process::RLIMIT_NPROC such as Solaris 10"
+ omit "Too exhaustive test on platforms without Process::RLIMIT_NPROC such as Solaris 10"
end
bug4315 = '[ruby-core:34833] #7904 [ruby-core:52628] #11613'
assert_fail_too_long_path(%w"echo |", bug4315)
@@ -1958,7 +1958,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_uid
- skip "root can use uid option of Kernel#system on Android platform" if RUBY_PLATFORM =~ /android/
+ omit "root can use uid option of Kernel#system on Android platform" if RUBY_PLATFORM =~ /android/
feature6975 = '[ruby-core:47414]'
[30000, [Process.uid, ENV["USER"]]].each do |uid, user|
@@ -1989,8 +1989,8 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_gid
- skip "Process.groups not implemented on Windows platform" if windows?
- skip "root can use Process.groups on Android platform" if RUBY_PLATFORM =~ /android/
+ omit "Process.groups not implemented on Windows platform" if windows?
+ omit "root can use Process.groups on Android platform" if RUBY_PLATFORM =~ /android/
feature6975 = '[ruby-core:47414]'
groups = Process.groups.map do |g|
@@ -2511,7 +2511,7 @@ EOS
end
def test_forked_child_handles_signal
- skip "fork not supported" unless Process.respond_to?(:fork)
+ omit "fork not supported" unless Process.respond_to?(:fork)
assert_normal_exit(<<-"end;", '[ruby-core:82883] [Bug #13916]')
require 'timeout'
pid = fork { sleep }
diff --git a/test/ruby/test_rand.rb b/test/ruby/test_rand.rb
index 13b7329269f..f066433f6a1 100644
--- a/test/ruby/test_rand.rb
+++ b/test/ruby/test_rand.rb
@@ -317,7 +317,7 @@ class TestRand < Test::Unit::TestCase
assert_equal(r1, r2, bug5661)
assert_fork_status(1, '[ruby-core:82100] [Bug #13753]') do
- Random::DEFAULT.rand(4)
+ Random.rand(4)
end
rescue NotImplementedError
end
@@ -395,8 +395,8 @@ class TestRand < Test::Unit::TestCase
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
verbose, $VERBOSE = $VERBOSE, nil
- seed = Random::DEFAULT::seed
- rand1 = Random::DEFAULT::rand
+ seed = Random.seed
+ rand1 = Random.rand
$VERBOSE = verbose
rand2 = Random.new(seed).rand
assert_equal(rand1, rand2)
diff --git a/test/ruby/test_random_formatter.rb b/test/ruby/test_random_formatter.rb
new file mode 100644
index 00000000000..a5072099e1b
--- /dev/null
+++ b/test/ruby/test_random_formatter.rb
@@ -0,0 +1,123 @@
+require 'test/unit'
+require 'random/formatter'
+
+module Random::Formatter
+ module FormatterTest
+ def test_random_bytes
+ assert_equal(16, @it.random_bytes.size)
+ assert_equal(Encoding::ASCII_8BIT, @it.random_bytes.encoding)
+ 65.times do |idx|
+ assert_equal(idx, @it.random_bytes(idx).size)
+ end
+ end
+
+ def test_hex
+ s = @it.hex
+ assert_equal(16 * 2, s.size)
+ assert_match(/\A\h+\z/, s)
+ 33.times do |idx|
+ s = @it.hex(idx)
+ assert_equal(idx * 2, s.size)
+ assert_match(/\A\h*\z/, s)
+ end
+ end
+
+ def test_hex_encoding
+ assert_equal(Encoding::US_ASCII, @it.hex.encoding)
+ end
+
+ def test_base64
+ assert_equal(16, @it.base64.unpack1('m*').size)
+ 17.times do |idx|
+ assert_equal(idx, @it.base64(idx).unpack1('m*').size)
+ end
+ end
+
+ def test_urlsafe_base64
+ safe = /[\n+\/]/
+ 65.times do |idx|
+ assert_not_match(safe, @it.urlsafe_base64(idx))
+ end
+ # base64 can include unsafe byte
+ assert((0..10000).any? {|idx| safe =~ @it.base64(idx)}, "None of base64(0..10000) is url-safe")
+ end
+
+ def test_random_number_float
+ 101.times do
+ v = @it.random_number
+ assert_in_range(0.0...1.0, v)
+ end
+ end
+
+ def test_random_number_float_by_zero
+ 101.times do
+ v = @it.random_number(0)
+ assert_in_range(0.0...1.0, v)
+ end
+ end
+
+ def test_random_number_int
+ 101.times do |idx|
+ next if idx.zero?
+ v = @it.random_number(idx)
+ assert_in_range(0...idx, v)
+ end
+ end
+
+ def test_uuid
+ uuid = @it.uuid
+ assert_equal(36, uuid.size)
+
+ # Check time_hi_and_version and clock_seq_hi_res bits (RFC 4122 4.4)
+ assert_equal('4', uuid[14])
+ assert_include(%w'8 9 a b', uuid[19])
+
+ assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
+ end
+
+ def test_alphanumeric
+ 65.times do |n|
+ an = @it.alphanumeric(n)
+ assert_match(/\A[0-9a-zA-Z]*\z/, an)
+ assert_equal(n, an.length)
+ end
+ end
+
+ def assert_in_range(range, result, mesg = nil)
+ assert(range.cover?(result), build_message(mesg, "Expected #{result} to be in #{range}"))
+ end
+ end
+
+ module NotDefaultTest
+ def test_random_number_not_default
+ msg = "random_number should not be affected by srand"
+ seed = srand(0)
+ x = @it.random_number(1000)
+ 10.times do|i|
+ srand(0)
+ return unless @it.random_number(1000) == x
+ end
+ srand(0)
+ assert_not_equal(x, @it.random_number(1000), msg)
+ ensure
+ srand(seed) if seed
+ end
+ end
+
+ class TestClassMethods < Test::Unit::TestCase
+ include FormatterTest
+
+ def setup
+ @it = Random
+ end
+ end
+
+ class TestInstanceMethods < Test::Unit::TestCase
+ include FormatterTest
+ include NotDefaultTest
+
+ def setup
+ @it = Random.new
+ end
+ end
+end
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 19857b035c0..c0754d8cf0b 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -225,7 +225,7 @@ class TestRefinement < Test::Unit::TestCase
end
end
def test_method_should_use_refinements
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
foo = Foo.new
assert_raise(NameError) { foo.method(:z) }
@@ -248,7 +248,7 @@ class TestRefinement < Test::Unit::TestCase
end
end
def test_instance_method_should_use_refinements
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
foo = Foo.new
assert_raise(NameError) { Foo.instance_method(:z) }
@@ -754,134 +754,30 @@ class TestRefinement < Test::Unit::TestCase
$VERBOSE = verbose
end
- module IncludeIntoRefinement
- class C
- def bar
- return "C#bar"
- end
-
- def baz
- return "C#baz"
- end
- end
-
- module Mixin
- def foo
- return "Mixin#foo"
- end
-
- def bar
- return super << " Mixin#bar"
- end
-
- def baz
- return super << " Mixin#baz"
- end
- end
-
- module M
- refine C do
- TestRefinement.suppress_verbose do
- include Mixin
- end
-
- def baz
- return super << " M#baz"
- end
- end
- end
- end
-
- eval <<-EOF, Sandbox::BINDING
- using TestRefinement::IncludeIntoRefinement::M
-
- module TestRefinement::IncludeIntoRefinement::User
- def self.invoke_foo_on(x)
- x.foo
- end
-
- def self.invoke_bar_on(x)
- x.bar
- end
-
- def self.invoke_baz_on(x)
- x.baz
- end
- end
- EOF
-
def test_include_into_refinement
- x = IncludeIntoRefinement::C.new
- assert_equal("Mixin#foo", IncludeIntoRefinement::User.invoke_foo_on(x))
- assert_equal("C#bar Mixin#bar",
- IncludeIntoRefinement::User.invoke_bar_on(x))
- assert_equal("C#baz Mixin#baz M#baz",
- IncludeIntoRefinement::User.invoke_baz_on(x))
- end
-
- module PrependIntoRefinement
- class C
- def bar
- return "C#bar"
- end
-
- def baz
- return "C#baz"
- end
- end
-
- module Mixin
- def foo
- return "Mixin#foo"
- end
-
- def bar
- return super << " Mixin#bar"
- end
-
- def baz
- return super << " Mixin#baz"
- end
- end
-
- module M
- refine C do
- TestRefinement.suppress_verbose do
- prepend Mixin
- end
+ assert_raise(TypeError) do
+ c = Class.new
+ mixin = Module.new
- def baz
- return super << " M#baz"
+ Module.new do
+ refine c do
+ include mixin
end
end
end
end
- eval <<-EOF, Sandbox::BINDING
- using TestRefinement::PrependIntoRefinement::M
-
- module TestRefinement::PrependIntoRefinement::User
- def self.invoke_foo_on(x)
- x.foo
- end
-
- def self.invoke_bar_on(x)
- x.bar
- end
+ def test_prepend_into_refinement
+ assert_raise(TypeError) do
+ c = Class.new
+ mixin = Module.new
- def self.invoke_baz_on(x)
- x.baz
+ Module.new do
+ refine c do
+ prepend mixin
+ end
end
end
- EOF
-
- def test_prepend_into_refinement
- x = PrependIntoRefinement::C.new
- assert_equal("Mixin#foo", PrependIntoRefinement::User.invoke_foo_on(x))
- assert_equal("C#bar Mixin#bar",
- PrependIntoRefinement::User.invoke_bar_on(x))
- assert_equal("C#baz M#baz Mixin#baz",
- PrependIntoRefinement::User.invoke_baz_on(x))
end
PrependAfterRefine_CODE = <<-EOC
@@ -923,7 +819,7 @@ class TestRefinement < Test::Unit::TestCase
def test_prepend_after_refine_wb_miss
if /\A(arm|mips)/ =~ RUBY_PLATFORM
- skip "too slow cpu"
+ omit "too slow cpu"
end
assert_normal_exit %Q{
GC.stress = true
@@ -1791,6 +1687,8 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_a
end
+
+ RefA.const_set(:REF, self)
end
end
@@ -1798,6 +1696,8 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_b
end
+
+ RefB.const_set(:REF, self)
end
end
@@ -1807,23 +1707,28 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_c
end
+
+ RefC.const_set(:REF, self)
end
end
module Foo
using RefB
USED_MODS = Module.used_modules
+ USED_REFS = Module.used_refinements
end
module Bar
using RefC
USED_MODS = Module.used_modules
+ USED_REFS = Module.used_refinements
end
module Combined
using RefA
using RefB
USED_MODS = Module.used_modules
+ USED_REFS = Module.used_refinements
end
end
@@ -1835,6 +1740,41 @@ class TestRefinement < Test::Unit::TestCase
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS
end
+ def test_used_refinements
+ ref = VisibleRefinements
+ assert_equal [], Module.used_refinements
+ assert_equal [ref::RefB::REF], ref::Foo::USED_REFS
+ assert_equal [ref::RefC::REF], ref::Bar::USED_REFS
+ assert_equal [ref::RefB::REF, ref::RefA::REF], ref::Combined::USED_REFS
+ end
+
+ def test_refinements
+ int_refinement = nil
+ str_refinement = nil
+ m = Module.new {
+ refine Integer do
+ int_refinement = self
+ end
+
+ refine String do
+ str_refinement = self
+ end
+ }
+ assert_equal([int_refinement, str_refinement], m.refinements)
+ end
+
+ def test_refined_class
+ refinements = Module.new {
+ refine Integer do
+ end
+
+ refine String do
+ end
+ }.refinements
+ assert_equal(Integer, refinements[0].refined_class)
+ assert_equal(String, refinements[1].refined_class)
+ end
+
def test_warn_setconst_in_refinmenet
bug10103 = '[ruby-core:64143] [Bug #10103]'
warnings = [
@@ -1979,10 +1919,10 @@ class TestRefinement < Test::Unit::TestCase
m = Module.new do
r = refine(String) {def test;:ok end}
end
- assert_raise_with_message(ArgumentError, /refinement/, bug) do
+ assert_raise_with_message(TypeError, /refinement/, bug) do
m.module_eval {include r}
end
- assert_raise_with_message(ArgumentError, /refinement/, bug) do
+ assert_raise_with_message(TypeError, /refinement/, bug) do
m.module_eval {prepend r}
end
end
@@ -2626,18 +2566,6 @@ class TestRefinement < Test::Unit::TestCase
end
end
- module D
- refine A do
- TestRefinement.suppress_verbose do
- include B
- end
-
- def foo
- "refined"
- end
- end
- end
-
module UsingC
using C
@@ -2645,19 +2573,10 @@ class TestRefinement < Test::Unit::TestCase
A.new.bar
end
end
-
- module UsingD
- using D
-
- def self.call_bar
- A.new.bar
- end
- end
end
def test_import_methods
assert_equal("refined:bar", TestImport::UsingC.call_bar)
- assert_equal("original:bar", TestImport::UsingD.call_bar)
assert_raise(ArgumentError) do
Module.new do
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 7a9faf18f9a..5a24cb1ba54 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -93,7 +93,7 @@ class TestRequire < Test::Unit::TestCase
begin
require_path = File.join(tmp, dir, 'foo.rb').encode(encoding)
rescue
- skip "cannot convert path encoding to #{encoding}"
+ omit "cannot convert path encoding to #{encoding}"
end
Dir.mkdir(File.dirname(require_path))
open(require_path, "wb") {|f| f.puts '$:.push __FILE__'}
@@ -175,7 +175,7 @@ class TestRequire < Test::Unit::TestCase
t.close
path = File.expand_path(t.path).sub(/\A(\w):/, '//127.0.0.1/\1$')
- skip "local drive #$1: is not shared" unless File.exist?(path)
+ omit "local drive #$1: is not shared" unless File.exist?(path)
args = ['--disable-gems', "-I#{File.dirname(path)}"]
assert_in_out_err(args, "#{<<~"END;"}", [path], [])
begin
@@ -367,6 +367,38 @@ class TestRequire < Test::Unit::TestCase
}
end
+ def test_load_into_module
+ Tempfile.create(["test_ruby_test_require", ".rb"]) {|t|
+ t.puts "def b; 1 end"
+ t.puts "class Foo"
+ t.puts " def c; 2 end"
+ t.puts "end"
+ t.close
+
+ m = Module.new
+ load(t.path, m)
+ assert_equal([:b], m.private_instance_methods(false))
+ c = Class.new do
+ include m
+ public :b
+ end
+ assert_equal(1, c.new.b)
+ assert_equal(2, m::Foo.new.c)
+ }
+ end
+
+ def test_load_wrap_nil
+ Dir.mktmpdir do |tmp|
+ File.write("#{tmp}/1.rb", "class LoadWrapNil; end\n")
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ path = ""#{tmp.dump}"/1.rb"
+ begin;
+ load path, nil
+ assert_instance_of(Class, LoadWrapNil)
+ end;
+ end
+ end
+
def test_load_ospath
bug = '[ruby-list:49994] path in ospath'
base = "test_load\u{3042 3044 3046 3048 304a}".encode(Encoding::Windows_31J)
@@ -428,7 +460,7 @@ class TestRequire < Test::Unit::TestCase
result = IO.popen([EnvUtil.rubybin, "b/tst.rb"], &:read)
assert_equal("a/lib.rb\n", result, "[ruby-dev:40040]")
rescue NotImplementedError, Errno::EACCES
- skip "File.symlink is not implemented"
+ omit "File.symlink is not implemented"
end
}
}
@@ -454,7 +486,7 @@ class TestRequire < Test::Unit::TestCase
result = IO.popen([EnvUtil.rubybin, "c.rb"], &:read)
assert_equal("1", result, "bug17885 [ruby-core:104010]")
rescue NotImplementedError, Errno::EACCES
- skip "File.symlink is not implemented"
+ omit "File.symlink is not implemented"
end
}
}
@@ -818,7 +850,7 @@ class TestRequire < Test::Unit::TestCase
end if File.respond_to?(:mkfifo)
def test_loading_fifo_fd_leak
- skip if RUBY_PLATFORM =~ /android/ # https://rubyci.org/logs/rubyci.s3.amazonaws.com/android29-x86_64/ruby-master/log/20200419T124100Z.fail.html.gz
+ omit if RUBY_PLATFORM =~ /android/ # https://rubyci.org/logs/rubyci.s3.amazonaws.com/android29-x86_64/ruby-master/log/20200419T124100Z.fail.html.gz
Tempfile.create(%w'fifo .rb') {|f|
f.close
@@ -879,7 +911,7 @@ class TestRequire < Test::Unit::TestCase
begin
File.symlink "real", File.join(tmp, "symlink")
rescue NotImplementedError, Errno::EACCES
- skip "File.symlink is not implemented"
+ omit "File.symlink is not implemented"
end
File.write(File.join(tmp, "real/test_symlink_load_path.rb"), "print __FILE__")
result = IO.popen([EnvUtil.rubybin, "-I#{tmp}/symlink", "-e", "require 'test_symlink_load_path.rb'"], &:read)
diff --git a/test/ruby/test_require_lib.rb b/test/ruby/test_require_lib.rb
index 6b2846c8fd1..95fa3f29e12 100644
--- a/test/ruby/test_require_lib.rb
+++ b/test/ruby/test_require_lib.rb
@@ -18,7 +18,7 @@ class TestRequireLib < Test::Unit::TestCase
begin
require #{lib.dump}
rescue Exception
- skip $!
+ omit $!
end
assert_equal n, Thread.list.size
end;
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 579d0cb3624..2cbd902f1fb 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -7,10 +7,12 @@ require 'tempfile'
require_relative '../lib/jit_support'
class TestRubyOptions < Test::Unit::TestCase
+ def self.yjit_enabled? = defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
+
NO_JIT_DESCRIPTION =
- if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # checking -DMJIT_FORCE_ENABLE
- RUBY_DESCRIPTION.sub(/\+JIT /, '')
- elsif defined?(YJIT.enabled?) && YJIT.enabled? # checking -DYJIT_FORCE_ENABLE
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # checking -DMJIT_FORCE_ENABLE
+ RUBY_DESCRIPTION.sub(/\+MJIT /, '')
+ elsif yjit_enabled? # checking -DYJIT_FORCE_ENABLE
RUBY_DESCRIPTION.sub(/\+YJIT /, '')
else
RUBY_DESCRIPTION
@@ -119,6 +121,8 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(["--disable-gems", "--debug", "-e", "p $DEBUG"],
"", %w(true), [])
+
+ assert_in_out_err(["--disable-gems", "--debug-", "-e", "p $DEBUG"], "", %w(), /invalid option --debug-/)
end
q = Regexp.method(:quote)
@@ -135,7 +139,7 @@ class TestRubyOptions < Test::Unit::TestCase
VERSION_PATTERN_WITH_JIT =
case RUBY_ENGINE
when 'ruby'
- /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+JIT \[#{q[RUBY_PLATFORM]}\]$/
+ /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+MJIT \[#{q[RUBY_PLATFORM]}\]$/
else
VERSION_PATTERN
end
@@ -144,9 +148,9 @@ class TestRubyOptions < Test::Unit::TestCase
def test_verbose
assert_in_out_err([{'RUBY_YJIT_ENABLE' => nil}, "-vve", ""]) do |r, e|
assert_match(VERSION_PATTERN, r[0])
- if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? && !mjit_force_enabled? # checking -DMJIT_FORCE_ENABLE
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? && !mjit_force_enabled? # checking -DMJIT_FORCE_ENABLE
assert_equal(NO_JIT_DESCRIPTION, r[0])
- elsif defined?(YJIT.enabled?) && YJIT.enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
+ elsif self.class.yjit_enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
assert_equal(NO_JIT_DESCRIPTION, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
@@ -212,7 +216,7 @@ class TestRubyOptions < Test::Unit::TestCase
assert_match(VERSION_PATTERN, r[0])
if ENV['RUBY_YJIT_ENABLE'] == '1'
assert_equal(NO_JIT_DESCRIPTION, r[0])
- elsif defined?(RubyVM::JIT) && RubyVM::JIT.enabled? || defined?(YJIT.enabled?) && YJIT.enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
+ elsif defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
assert_equal(EnvUtil.invoke_ruby(['-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
@@ -224,9 +228,14 @@ class TestRubyOptions < Test::Unit::TestCase
return if yjit_force_enabled?
[
- %w(--version --jit --disable=jit),
- %w(--version --enable=jit --disable=jit),
- %w(--version --enable-jit --disable-jit),
+ %w(--version --mjit --disable=mjit),
+ %w(--version --enable=mjit --disable=mjit),
+ %w(--version --enable-mjit --disable-mjit),
+ *([
+ %w(--version --jit --disable=jit),
+ %w(--version --enable=jit --disable=jit),
+ %w(--version --enable-jit --disable-jit),
+ ] unless JITSupport.yjit_supported?),
].each do |args|
assert_in_out_err([env] + args) do |r, e|
assert_match(VERSION_PATTERN, r[0])
@@ -237,16 +246,21 @@ class TestRubyOptions < Test::Unit::TestCase
if JITSupport.supported?
[
- %w(--version --jit),
- %w(--version --enable=jit),
- %w(--version --enable-jit),
+ %w(--version --mjit),
+ %w(--version --enable=mjit),
+ %w(--version --enable-mjit),
+ *([
+ %w(--version --jit),
+ %w(--version --enable=jit),
+ %w(--version --enable-jit),
+ ] unless JITSupport.yjit_supported?),
].each do |args|
assert_in_out_err([env] + args) do |r, e|
assert_match(VERSION_PATTERN_WITH_JIT, r[0])
- if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # checking -DMJIT_FORCE_ENABLE
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # checking -DMJIT_FORCE_ENABLE
assert_equal(RUBY_DESCRIPTION, r[0])
else
- assert_equal(EnvUtil.invoke_ruby([env, '--jit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
+ assert_equal(EnvUtil.invoke_ruby([env, '--mjit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
end
assert_equal([], e)
end
@@ -662,7 +676,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_set_program_name
- skip "platform dependent feature" unless defined?(PSCMD) and PSCMD
+ omit "platform dependent feature" unless defined?(PSCMD) and PSCMD
with_tmpchdir do
write_file("test-script", "$0 = 'hello world'; /test-script/ =~ Process.argv0 or $0 = 'Process.argv0 changed!'; sleep 60")
@@ -685,7 +699,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_setproctitle
- skip "platform dependent feature" unless defined?(PSCMD) and PSCMD
+ omit "platform dependent feature" unless defined?(PSCMD) and PSCMD
assert_separately([], "#{<<-"{#"}\n#{<<-'};'}")
{#
@@ -760,7 +774,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def assert_segv(args, message=nil)
- skip if ENV['RUBY_ON_BUG']
+ omit if ENV['RUBY_ON_BUG']
test_stdin = ""
opt = SEGVTest::ExecOptions.dup
@@ -845,7 +859,7 @@ class TestRubyOptions < Test::Unit::TestCase
Process.wait pid
}
rescue RuntimeError
- skip $!
+ omit $!
end
}
assert_equal("", result, '[ruby-dev:37798]')
@@ -895,7 +909,7 @@ class TestRubyOptions < Test::Unit::TestCase
name = c.chr(Encoding::UTF_8)
expected = name.encode("locale") rescue nil
}
- skip "can't make locale name"
+ omit "can't make locale name"
end
name << ".rb"
expected << ".rb"
@@ -1103,7 +1117,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_null_script
- skip "#{IO::NULL} is not a character device" unless File.chardev?(IO::NULL)
+ omit "#{IO::NULL} is not a character device" unless File.chardev?(IO::NULL)
assert_in_out_err([IO::NULL], success: true)
end
@@ -1111,7 +1125,7 @@ class TestRubyOptions < Test::Unit::TestCase
# mswin uses prebuilt precompiled header. Thus it does not show a pch compilation log to check "-O0 -O1".
if JITSupport.supported? && !RUBY_PLATFORM.match?(/mswin/)
env = { 'MJIT_SEARCH_BUILD_DIR' => 'true' }
- assert_in_out_err([env, "--disable-yjit", "--jit-debug=-O0 -O1", "--jit-verbose=2", "" ], "", [], /-O0 -O1/)
+ assert_in_out_err([env, "--disable-yjit", "--mjit-debug=-O0 -O1", "--mjit-verbose=2", "" ], "", [], /-O0 -O1/)
end
end
diff --git a/test/ruby/test_rubyvm_jit.rb b/test/ruby/test_rubyvm_jit.rb
index 2104ce3d184..5449c6226dd 100644
--- a/test/ruby/test_rubyvm_jit.rb
+++ b/test/ruby/test_rubyvm_jit.rb
@@ -9,7 +9,7 @@ class TestRubyVMJIT < Test::Unit::TestCase
def setup
unless JITSupport.supported?
- skip 'JIT seems not supported on this platform'
+ omit 'JIT seems not supported on this platform'
end
end
@@ -20,13 +20,13 @@ class TestRubyVMJIT < Test::Unit::TestCase
eval("def mjit#{i}; end; mjit#{i}")
i += 1
end
- print RubyVM::JIT.pause
- print RubyVM::JIT.pause
+ print RubyVM::MJIT.pause
+ print RubyVM::MJIT.pause
while i < 10
eval("def mjit#{i}; end; mjit#{i}")
i += 1
end
- print RubyVM::JIT.pause # no JIT here
+ print RubyVM::MJIT.pause # no JIT here
EOS
assert_equal('truefalsefalse', out)
assert_equal(
@@ -39,7 +39,7 @@ class TestRubyVMJIT < Test::Unit::TestCase
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
def a() end; a
def b() end; b
- RubyVM::JIT.pause
+ RubyVM::MJIT.pause
EOS
assert_equal(
2, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
@@ -58,7 +58,7 @@ class TestRubyVMJIT < Test::Unit::TestCase
eval("def mjit#{i}; end; mjit#{i}")
i += 1
end
- print RubyVM::JIT.pause
+ print RubyVM::MJIT.pause
EOS
assert_equal('true', out)
end
@@ -70,8 +70,8 @@ class TestRubyVMJIT < Test::Unit::TestCase
eval("def mjit#{i}; end; mjit#{i}")
i += 1
end
- print RubyVM::JIT.pause(wait: false)
- print RubyVM::JIT.pause(wait: false)
+ print RubyVM::MJIT.pause(wait: false)
+ print RubyVM::MJIT.pause(wait: false)
EOS
assert_equal('truefalse', out)
assert_equal(true, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size < 10)
@@ -79,11 +79,11 @@ class TestRubyVMJIT < Test::Unit::TestCase
def test_resume
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- print RubyVM::JIT.resume
- print RubyVM::JIT.pause
- print RubyVM::JIT.resume
- print RubyVM::JIT.resume
- print RubyVM::JIT.pause
+ print RubyVM::MJIT.resume
+ print RubyVM::MJIT.pause
+ print RubyVM::MJIT.resume
+ print RubyVM::MJIT.resume
+ print RubyVM::MJIT.pause
EOS
assert_equal('falsetruetruefalsetrue', out)
assert_equal(0, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size)
diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
index c6955467c47..0524c35873c 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -108,6 +108,10 @@ class TestSetTraceFunc < Test::Unit::TestCase
events.shift)
assert_equal(["line", 4, __method__, self.class],
events.shift)
+ assert_equal(["c-call", 4, :const_added, Module],
+ events.shift)
+ assert_equal(["c-return", 4, :const_added, Module],
+ events.shift)
assert_equal(["c-call", 4, :inherited, Class],
events.shift)
assert_equal(["c-return", 4, :inherited, Class],
@@ -345,6 +349,8 @@ class TestSetTraceFunc < Test::Unit::TestCase
[["c-return", 2, :add_trace_func, Thread],
["line", 3, __method__, self.class],
+ ["c-call", 3, :const_added, Module],
+ ["c-return", 3, :const_added, Module],
["c-call", 3, :inherited, Class],
["c-return", 3, :inherited, Class],
["class", 3, nil, nil],
@@ -393,7 +399,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
[["c-return", 3, :set_trace_func, Kernel],
["line", 6, __method__, self.class],
["call", 1, :foobar, FooBar],
- ["return", 6, :foobar, FooBar],
+ ["return", 1, :foobar, FooBar],
["line", 7, __method__, self.class],
["c-call", 7, :set_trace_func, Kernel]].each{|e|
assert_equal(e, events.shift)
@@ -487,6 +493,8 @@ class TestSetTraceFunc < Test::Unit::TestCase
[:line, 5, 'xyzzy', self.class, method, self, :inner, :nothing],
[:c_return, 4, "xyzzy", Integer, :times, 1, :outer, 1],
[:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing],
+ [:c_call, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, :outer, :nothing],
+ [:c_return, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, :outer, nil],
[:c_call, 7, "xyzzy", Class, :inherited, Object, :outer, :nothing],
[:c_return, 7, "xyzzy", Class, :inherited, Object, :outer, nil],
[:class, 7, "xyzzy", nil, nil, xyzzy.class, nil, :nothing],
@@ -565,7 +573,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
end
# Bug #18264
- def test_tracpoint_memory_leak
+ def test_tracepoint_memory_leak
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc { TracePoint.new(:line) { } }
1_000.times(&code)
@@ -620,6 +628,8 @@ CODE
[:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing],
[:c_call, 7, "xyzzy", Class, :inherited, Object, :outer, :nothing],
[:c_return, 7, "xyzzy", Class, :inherited, Object, :outer, nil],
+ [:c_call, 7, "xyzzy", Class, :const_added, Object, :outer, :nothing],
+ [:c_return, 7, "xyzzy", Class, :const_added, Object, :outer, nil],
[:class, 7, "xyzzy", nil, nil, xyzzy.class, nil, :nothing],
[:line, 8, "xyzzy", nil, nil, xyzzy.class, nil, :nothing],
[:line, 9, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
@@ -1951,7 +1961,7 @@ CODE
end
define_method(:f_break_defined) do
- return :f_break_defined
+ break :f_break_defined
end
define_method(:f_raise_defined) do
@@ -1972,27 +1982,44 @@ CODE
tp_return_value(:f_last_defined),
'[Bug #13369]'
- assert_equal [[:b_return, :f_return_defined, nil], # current limitation
+ assert_equal [[:b_return, :f_return_defined, :f_return_defined],
[:return, :f_return_defined, :f_return_defined]],
tp_return_value(:f_return_defined),
'[Bug #13369]'
- assert_equal [[:b_return, :f_break_defined, nil],
+ assert_equal [[:b_return, :f_break_defined, :f_break_defined],
[:return, :f_break_defined, :f_break_defined]],
tp_return_value(:f_break_defined),
'[Bug #13369]'
- assert_equal [[:b_return, :f_raise_defined, nil],
+ assert_equal [[:b_return, :f_raise_defined, f_raise_defined],
[:return, :f_raise_defined, f_raise_defined]],
tp_return_value(:f_raise_defined),
'[Bug #13369]'
- assert_equal [[:b_return, :f_break_in_rescue_defined, nil],
+ assert_equal [[:b_return, :f_break_in_rescue_defined, f_break_in_rescue_defined],
[:return, :f_break_in_rescue_defined, f_break_in_rescue_defined]],
tp_return_value(:f_break_in_rescue_defined),
'[Bug #13369]'
end
+ define_method(:just_yield) do |&block|
+ block.call
+ end
+
+ define_method(:unwind_multiple_bmethods) do
+ just_yield { return :unwind_multiple_bmethods }
+ end
+
+ def test_non_local_return_across_multiple_define_methods
+ assert_equal [[:b_return, :unwind_multiple_bmethods, nil],
+ [:b_return, :just_yield, nil],
+ [:return, :just_yield, nil],
+ [:b_return, :unwind_multiple_bmethods, :unwind_multiple_bmethods],
+ [:return, :unwind_multiple_bmethods, :unwind_multiple_bmethods]],
+ tp_return_value(:unwind_multiple_bmethods)
+ end
+
def f_iter
yield
end
@@ -2089,7 +2116,7 @@ CODE
Thread.pass until t.status == 'sleep'
# When MJIT thread exists, t.status becomes 'sleep' even if it does not reach m2t_q.pop.
# This sleep forces it to reach m2t_q.pop for --jit-wait.
- sleep 1 if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
t.add_trace_func proc{|ev, file, line, *args|
if file == __FILE__
@@ -2354,7 +2381,7 @@ CODE
}
assert_equal [], events, 'script_compiled event should not be invoked on compile error'
- skip "TODO: test for requires"
+ omit "TODO: test for requires"
events.clear
tp.enable{
@@ -2403,6 +2430,99 @@ CODE
assert_equal Array.new(2){th}, events
end
+ def test_return_bmethod_location
+ bug13392 = "[ruby-core:80515] incorrect bmethod return location"
+ actual = nil
+ obj = Object.new
+ expected = __LINE__ + 1
+ obj.define_singleton_method(:t){}
+ tp = TracePoint.new(:return) do
+ next unless target_thread?
+ actual = tp.lineno
+ end
+ tp.enable {obj.t}
+ assert_equal(expected, actual, bug13392)
+ end
+
+ def test_b_tracepoints_going_away
+ # test that call and return TracePoints continue to work
+ # when b_call and b_return TracePoints stop
+ events = []
+ record_events = ->(tp) do
+ next unless target_thread?
+ events << [tp.event, tp.method_id]
+ end
+
+ call_ret_tp = TracePoint.new(:call, :return, &record_events)
+ block_call_ret_tp = TracePoint.new(:b_call, :b_return, &record_events)
+
+ obj = Object.new
+ obj.define_singleton_method(:foo) {} # a bmethod
+
+ foo = obj.method(:foo)
+ call_ret_tp.enable(target: foo) do
+ block_call_ret_tp.enable(target: foo) do
+ obj.foo
+ end
+ obj.foo
+ end
+
+ assert_equal(
+ [
+ [:call, :foo],
+ [:b_call, :foo],
+ [:b_return, :foo],
+ [:return, :foo],
+ [:call, :foo],
+ [:return, :foo],
+ ],
+ events,
+ )
+ end
+
+ def test_target_different_bmethod_same_iseq
+ # make two bmethods that share the same block iseq
+ block = Proc.new {}
+ obj = Object.new
+ obj.define_singleton_method(:one, &block)
+ obj.define_singleton_method(:two, &block)
+
+ events = []
+ record_events = ->(tp) do
+ next unless target_thread?
+ events << [tp.event, tp.method_id]
+ end
+ tp_one = TracePoint.new(:call, :return, &record_events)
+ tp_two = TracePoint.new(:call, :return, &record_events)
+
+ tp_one.enable(target: obj.method(:one)) do
+ obj.one
+ obj.two # not targeted
+ end
+ assert_equal([[:call, :one], [:return, :one]], events)
+ events.clear
+
+ tp_one.enable(target: obj.method(:one)) do
+ obj.one
+ tp_two.enable(target: obj.method(:two)) do
+ obj.two
+ end
+ obj.two
+ obj.one
+ end
+ assert_equal(
+ [
+ [:call, :one],
+ [:return, :one],
+ [:call, :two],
+ [:return, :two],
+ [:call, :one],
+ [:return, :one],
+ ],
+ events
+ )
+ end
+
def test_return_event_with_rescue
obj = Object.new
def obj.example
@@ -2465,4 +2585,28 @@ CODE
}
assert_equal [__LINE__ - 5, __LINE__ - 4, __LINE__ - 3], lines, 'Bug #17868'
end
+
+ def test_allow_reentry
+ event_lines = []
+ _l1 = _l2 = _l3 = _l4 = nil
+ TracePoint.new(:line) do |tp|
+ next unless target_thread?
+
+ event_lines << tp.lineno
+ next if (__LINE__ + 2 .. __LINE__ + 4).cover?(tp.lineno)
+ TracePoint.allow_reentry do
+ _a = 1; _l3 = __LINE__
+ _b = 2; _l4 = __LINE__
+ end
+ end.enable do
+ _c = 3; _l1 = __LINE__
+ _d = 4; _l2 = __LINE__
+ end
+
+ assert_equal [_l1, _l3, _l4, _l2, _l3, _l4], event_lines
+
+ assert_raise RuntimeError do
+ TracePoint.allow_reentry{}
+ end
+ end
end
diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb
index a62537d59dc..c5043eea599 100644
--- a/test/ruby/test_signal.rb
+++ b/test/ruby/test_signal.rb
@@ -291,7 +291,8 @@ class TestSignal < Test::Unit::TestCase
if trap = Signal.list['TRAP']
bug9820 = '[ruby-dev:48592] [Bug #9820]'
- status = assert_in_out_err(['-e', 'Process.kill(:TRAP, $$)'])
+ no_core = "Process.setrlimit(Process::RLIMIT_CORE, 0); " if defined?(Process.setrlimit) && defined?(Process::RLIMIT_CORE)
+ status = assert_in_out_err(['-e', "#{no_core}Process.kill(:TRAP, $$)"])
assert_predicate(status, :signaled?, bug9820)
assert_equal(trap, status.termsig, bug9820)
end
@@ -323,7 +324,7 @@ class TestSignal < Test::Unit::TestCase
end
def test_sigchld_ignore
- skip 'no SIGCHLD' unless Signal.list['CHLD']
+ omit 'no SIGCHLD' unless Signal.list['CHLD']
old = trap(:CHLD, 'IGNORE')
cmd = [ EnvUtil.rubybin, '--disable=gems', '-e' ]
assert(system(*cmd, 'exit!(0)'), 'no ECHILD')
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index 7986e9d141a..f2e73eb58dc 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -528,19 +528,4 @@ class TestSprintf < Test::Unit::TestCase
sprintf("%*s", RbConfig::LIMITS["INT_MIN"], "")
end
end
-
- def test_no_hidden_garbage
- skip unless Thread.list.size == 1
-
- fmt = [4, 2, 2].map { |x| "%0#{x}d" }.join('-') # defeats optimization
- ObjectSpace.count_objects(res = {}) # creates strings on first call
- GC.disable
- before = ObjectSpace.count_objects(res)[:T_STRING]
- val = sprintf(fmt, 1970, 1, 1)
- after = ObjectSpace.count_objects(res)[:T_STRING]
- assert_equal before + 1, after, 'only new string is the created one'
- assert_equal '1970-01-01', val
- ensure
- GC.enable
- end
end
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 3f7c06e0756..95fbf637025 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -83,7 +83,7 @@ class TestString < Test::Unit::TestCase
end
def test_initialize_shared
- String.new(str = "mystring" * 10).__send__(:initialize, capacity: str.bytesize)
+ S(str = "mystring" * 10).__send__(:initialize, capacity: str.bytesize)
assert_equal("mystring", str[0, 8])
end
@@ -97,6 +97,8 @@ class TestString < Test::Unit::TestCase
end
def test_initialize_memory_leak
+ return unless @cls == String
+
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc {('x'*100000).__send__(:initialize, '')}
1_000.times(&code)
@@ -107,6 +109,8 @@ CODE
# Bug #18154
def test_initialize_nofree_memory_leak
+ return unless @cls == String
+
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc {0.to_s.__send__(:initialize, capacity: 10000)}
1_000.times(&code)
@@ -240,23 +244,23 @@ CODE
assert_equal(-1, S("ABCDEF") <=> S("abcdef"))
- assert_nil("foo" <=> Object.new)
+ assert_nil(S("foo") <=> Object.new)
o = Object.new
def o.to_str; "bar"; end
- assert_equal(1, "foo" <=> o)
+ assert_equal(1, S("foo") <=> o)
class << o;remove_method :to_str;end
def o.<=>(x); nil; end
- assert_nil("foo" <=> o)
+ assert_nil(S("foo") <=> o)
class << o;remove_method :<=>;end
def o.<=>(x); 1; end
- assert_equal(-1, "foo" <=> o)
+ assert_equal(-1, S("foo") <=> o)
class << o;remove_method :<=>;end
def o.<=>(x); 2**100; end
- assert_equal(-1, "foo" <=> o)
+ assert_equal(-1, S("foo") <=> o)
end
def test_EQUAL # '=='
@@ -270,10 +274,10 @@ CODE
o = Object.new
def o.to_str; end
def o.==(x); false; end
- assert_equal(false, "foo" == o)
+ assert_equal(false, S("foo") == o)
class << o;remove_method :==;end
def o.==(x); true; end
- assert_equal(true, "foo" == o)
+ assert_equal(true, S("foo") == o)
end
def test_LSHIFT # '<<'
@@ -648,12 +652,12 @@ CODE
result << 0x0300
expected = S("\u0300".encode(Encoding::UTF_16LE))
assert_equal(expected, result, bug7090)
- assert_raise(TypeError) { 'foo' << :foo }
- assert_raise(FrozenError) { 'foo'.freeze.concat('bar') }
+ assert_raise(TypeError) { S('foo') << :foo }
+ assert_raise(FrozenError) { S('foo').freeze.concat('bar') }
end
def test_concat_literals
- s="." * 50
+ s=S("." * 50)
assert_equal(Encoding::UTF_8, "#{s}x".encoding)
end
@@ -664,18 +668,18 @@ CODE
assert_equal(4, a.count(S("hello"), S("^l")))
assert_equal(4, a.count(S("ej-m")))
assert_equal(0, S("y").count(S("a\\-z")))
- assert_equal(5, "abc\u{3042 3044 3046}".count("^a"))
- assert_equal(1, "abc\u{3042 3044 3046}".count("\u3042"))
- assert_equal(5, "abc\u{3042 3044 3046}".count("^\u3042"))
- assert_equal(2, "abc\u{3042 3044 3046}".count("a-z", "^a"))
- assert_equal(0, "abc\u{3042 3044 3046}".count("a", "\u3042"))
- assert_equal(0, "abc\u{3042 3044 3046}".count("\u3042", "a"))
- assert_equal(0, "abc\u{3042 3044 3046}".count("\u3042", "\u3044"))
- assert_equal(4, "abc\u{3042 3044 3046}".count("^a", "^\u3044"))
- assert_equal(4, "abc\u{3042 3044 3046}".count("^\u3044", "^a"))
- assert_equal(4, "abc\u{3042 3044 3046}".count("^\u3042", "^\u3044"))
+ assert_equal(5, S("abc\u{3042 3044 3046}").count("^a"))
+ assert_equal(1, S("abc\u{3042 3044 3046}").count("\u3042"))
+ assert_equal(5, S("abc\u{3042 3044 3046}").count("^\u3042"))
+ assert_equal(2, S("abc\u{3042 3044 3046}").count("a-z", "^a"))
+ assert_equal(0, S("abc\u{3042 3044 3046}").count("a", "\u3042"))
+ assert_equal(0, S("abc\u{3042 3044 3046}").count("\u3042", "a"))
+ assert_equal(0, S("abc\u{3042 3044 3046}").count("\u3042", "\u3044"))
+ assert_equal(4, S("abc\u{3042 3044 3046}").count("^a", "^\u3044"))
+ assert_equal(4, S("abc\u{3042 3044 3046}").count("^\u3044", "^a"))
+ assert_equal(4, S("abc\u{3042 3044 3046}").count("^\u3042", "^\u3044"))
- assert_raise(ArgumentError) { "foo".count }
+ assert_raise(ArgumentError) { S("foo").count }
end
def crypt_supports_des_crypt?
@@ -717,17 +721,17 @@ CODE
assert_equal(S("hell"), S("hello").delete(S("aeiou"), S("^e")))
assert_equal(S("ho"), S("hello").delete(S("ej-m")))
- assert_equal("a".hash, "a\u0101".delete("\u0101").hash, '[ruby-talk:329267]')
- assert_equal(true, "a\u0101".delete("\u0101").ascii_only?)
- assert_equal(true, "a\u3041".delete("\u3041").ascii_only?)
- assert_equal(false, "a\u3041\u3042".delete("\u3041").ascii_only?)
+ assert_equal(S("a").hash, S("a\u0101").delete("\u0101").hash, '[ruby-talk:329267]')
+ assert_equal(true, S("a\u0101").delete("\u0101").ascii_only?)
+ assert_equal(true, S("a\u3041").delete("\u3041").ascii_only?)
+ assert_equal(false, S("a\u3041\u3042").delete("\u3041").ascii_only?)
- assert_equal("a", "abc\u{3042 3044 3046}".delete("^a"))
- assert_equal("bc\u{3042 3044 3046}", "abc\u{3042 3044 3046}".delete("a"))
- assert_equal("\u3042", "abc\u{3042 3044 3046}".delete("^\u3042"))
+ assert_equal("a", S("abc\u{3042 3044 3046}").delete("^a"))
+ assert_equal("bc\u{3042 3044 3046}", S("abc\u{3042 3044 3046}").delete("a"))
+ assert_equal("\u3042", S("abc\u{3042 3044 3046}").delete("^\u3042"))
bug6160 = '[ruby-dev:45374]'
- assert_equal("", '\\'.delete('\\'), bug6160)
+ assert_equal("", S('\\').delete('\\'), bug6160)
end
def test_delete!
@@ -832,10 +836,10 @@ CODE
assert_equal(Encoding::UTF_8, S('"\\u3042"').encode(Encoding::EUC_JP).undump.encoding)
assert_equal("abc".encode(Encoding::UTF_16LE),
- '"a\x00b\x00c\x00".force_encoding("UTF-16LE")'.undump)
+ S('"a\x00b\x00c\x00".force_encoding("UTF-16LE")').undump)
- assert_equal('\#', '"\\\\#"'.undump)
- assert_equal('\#{', '"\\\\\#{"'.undump)
+ assert_equal('\#', S('"\\\\#"').undump)
+ assert_equal('\#{', S('"\\\\\#{"').undump)
assert_raise(RuntimeError) { S('\u3042').undump }
assert_raise(RuntimeError) { S('"\x82\xA0\u3042"'.force_encoding("SJIS")).undump }
@@ -867,7 +871,7 @@ CODE
assert_raise(RuntimeError) { S('"\\"').undump }
assert_raise(RuntimeError) { S(%("\0")).undump }
assert_raise_with_message(RuntimeError, /invalid/) {
- '"\\u{007F}".xxxxxx'.undump
+ S('"\\u{007F}".xxxxxx').undump
}
end
@@ -1047,9 +1051,9 @@ CODE
g = g.encode(enc)
assert_equal g.chars, g.grapheme_clusters
end
- assert_equal ["a", "b", "c"], "abc".b.grapheme_clusters
+ assert_equal ["a", "b", "c"], S("abc").b.grapheme_clusters
- s = "ABC".b
+ s = S("ABC").b
res = []
assert_same s, s.grapheme_clusters {|x| res << x }
assert_equal(3, res.size)
@@ -1095,7 +1099,7 @@ CODE
$/ = save
s = nil
- "foo\nbar".each_line(nil) {|s2| s = s2 }
+ S("foo\nbar").each_line(nil) {|s2| s = s2 }
assert_equal("foo\nbar", s)
assert_equal "hello\n", S("hello\nworld").each_line.next
@@ -1103,7 +1107,7 @@ CODE
bug7646 = "[ruby-dev:46827]"
assert_nothing_raised(bug7646) do
- "\n\u0100".each_line("\n") {}
+ S("\n\u0100").each_line("\n") {}
end
ensure
$/ = save
@@ -1137,7 +1141,7 @@ CODE
assert_equal(S("a"), res[0])
s = nil
- "foo\nbar".each_line(nil, chomp: true) {|s2| s = s2 }
+ S("foo\nbar").each_line(nil, chomp: true) {|s2| s = s2 }
assert_equal("foo\nbar", s)
assert_equal "hello", S("hello\nworld").each_line(chomp: true).next
@@ -1202,9 +1206,9 @@ CODE
S("hello").gsub(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 })
assert_equal(S("<>h<>e<>l<>l<>o<>"), S("hello").gsub(S(''), S('<\0>')))
- assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug")
+ assert_equal("z", S("abc").gsub(/./, "a" => "z"), "moved from btest/knownbug")
- assert_raise(ArgumentError) { "foo".gsub }
+ assert_raise(ArgumentError) { S("foo").gsub }
end
def test_gsub_encoding
@@ -1251,23 +1255,23 @@ CODE
end
def test_sub_hash
- assert_equal('azc', 'abc'.sub(/b/, "b" => "z"))
- assert_equal('ac', 'abc'.sub(/b/, {}))
- assert_equal('a1c', 'abc'.sub(/b/, "b" => 1))
- assert_equal('aBc', 'abc'.sub(/b/, Hash.new {|h, k| k.upcase }))
- assert_equal('a[\&]c', 'abc'.sub(/b/, "b" => '[\&]'))
- assert_equal('aBcabc', 'abcabc'.sub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
- assert_equal('aBcdef', 'abcdef'.sub(/de|b/, "b" => "B", "de" => "DE"))
+ assert_equal('azc', S('abc').sub(/b/, "b" => "z"))
+ assert_equal('ac', S('abc').sub(/b/, {}))
+ assert_equal('a1c', S('abc').sub(/b/, "b" => 1))
+ assert_equal('aBc', S('abc').sub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', S('abc').sub(/b/, "b" => '[\&]'))
+ assert_equal('aBcabc', S('abcabc').sub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcdef', S('abcdef').sub(/de|b/, "b" => "B", "de" => "DE"))
end
def test_gsub_hash
- assert_equal('azc', 'abc'.gsub(/b/, "b" => "z"))
- assert_equal('ac', 'abc'.gsub(/b/, {}))
- assert_equal('a1c', 'abc'.gsub(/b/, "b" => 1))
- assert_equal('aBc', 'abc'.gsub(/b/, Hash.new {|h, k| k.upcase }))
- assert_equal('a[\&]c', 'abc'.gsub(/b/, "b" => '[\&]'))
- assert_equal('aBcaBc', 'abcabc'.gsub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
- assert_equal('aBcDEf', 'abcdef'.gsub(/de|b/, "b" => "B", "de" => "DE"))
+ assert_equal('azc', S('abc').gsub(/b/, "b" => "z"))
+ assert_equal('ac', S('abc').gsub(/b/, {}))
+ assert_equal('a1c', S('abc').gsub(/b/, "b" => 1))
+ assert_equal('aBc', S('abc').gsub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', S('abc').gsub(/b/, "b" => '[\&]'))
+ assert_equal('aBcaBc', S('abcabc').gsub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcDEf', S('abcdef').gsub(/de|b/, "b" => "B", "de" => "DE"))
end
def test_hash
@@ -1329,10 +1333,10 @@ CODE
o = Object.new
def o.to_str; "bar"; end
- assert_equal(3, "foobarbarbaz".index(o))
- assert_raise(TypeError) { "foo".index(Object.new) }
+ assert_equal(3, S("foobarbarbaz").index(o))
+ assert_raise(TypeError) { S("foo").index(Object.new) }
- assert_nil("foo".index(//, -100))
+ assert_nil(S("foo").index(//, -100))
assert_nil($~)
assert_equal(2, S("abcdbce").index(/b\Kc/))
@@ -1442,16 +1446,16 @@ CODE
b = a.replace(S("xyz"))
assert_equal(S("xyz"), b)
- s = "foo" * 100
+ s = S("foo") * 100
s2 = ("bar" * 100).dup
s.replace(s2)
assert_equal(s2, s)
- s2 = ["foo"].pack("p")
+ s2 = [S("foo")].pack("p")
s.replace(s2)
assert_equal(s2, s)
- fs = "".freeze
+ fs = S("").freeze
assert_raise(FrozenError) { fs.replace("a") }
assert_raise(FrozenError) { fs.replace(fs) }
assert_raise(ArgumentError) { fs.replace() }
@@ -1500,13 +1504,13 @@ CODE
o = Object.new
def o.to_str; "bar"; end
- assert_equal(6, "foobarbarbaz".rindex(o))
- assert_raise(TypeError) { "foo".rindex(Object.new) }
+ assert_equal(6, S("foobarbarbaz").rindex(o))
+ assert_raise(TypeError) { S("foo").rindex(Object.new) }
- assert_nil("foo".rindex(//, -100))
+ assert_nil(S("foo").rindex(//, -100))
assert_nil($~)
- assert_equal(3, "foo".rindex(//))
+ assert_equal(3, S("foo").rindex(//))
assert_equal([3, 3], $~.offset(0))
assert_equal(5, S("abcdbce").rindex(/b\Kc/))
@@ -1689,7 +1693,8 @@ CODE
assert_equal(S("Bar"), a.slice!(S("Bar")))
assert_equal(S("Foo"), a)
- assert_raise(ArgumentError) { "foo".slice! }
+ a = S("foo")
+ assert_raise(ArgumentError) { a.slice! }
end
def test_split
@@ -1714,7 +1719,7 @@ CODE
assert_equal([S("a"), S(""), S("b"), S("c")], S("a||b|c|").split(S('|')))
assert_equal([S("a"), S(""), S("b"), S("c"), S("")], S("a||b|c|").split(S('|'), -1))
- assert_equal([], "".split(//, 1))
+ assert_equal([], S("").split(//, 1))
ensure
EnvUtil.suppress_warning {$; = fs}
end
@@ -1753,16 +1758,18 @@ CODE
result = []; S("a||b|c|").split(S('|'), -1) {|s| result << s}
assert_equal([S("a"), S(""), S("b"), S("c"), S("")], result)
- result = []; "".split(//, 1) {|s| result << s}
+ result = []; S("").split(//, 1) {|s| result << s}
assert_equal([], result)
- result = []; "aaa,bbb,ccc,ddd".split(/,/) {|s| result << s.gsub(/./, "A")}
+ result = []; S("aaa,bbb,ccc,ddd").split(/,/) {|s| result << s.gsub(/./, "A")}
assert_equal(["AAA"]*4, result)
ensure
EnvUtil.suppress_warning {$; = fs}
end
def test_fs
+ return unless @cls == String
+
assert_raise_with_message(TypeError, /\$;/) {
$; = []
}
@@ -1856,9 +1863,9 @@ CODE
bug5536 = '[ruby-core:40623]'
assert_raise(TypeError, bug5536) {S("str").start_with? :not_convertible_to_string}
- assert_equal(true, "hello".start_with?(/hel/))
+ assert_equal(true, S("hello").start_with?(/hel/))
assert_equal("hel", $&)
- assert_equal(false, "hello".start_with?(/el/))
+ assert_equal(false, S("hello").start_with?(/el/))
assert_nil($&)
end
@@ -1868,9 +1875,9 @@ CODE
assert_equal(S("x"), S("\x00x\x00").strip)
assert_equal("0b0 ".force_encoding("UTF-16BE"),
- "\x00 0b0 ".force_encoding("UTF-16BE").strip)
+ S("\x00 0b0 ").force_encoding("UTF-16BE").strip)
assert_equal("0\x000b0 ".force_encoding("UTF-16BE"),
- "0\x000b0 ".force_encoding("UTF-16BE").strip)
+ S("0\x000b0 ").force_encoding("UTF-16BE").strip)
end
def test_strip!
@@ -1935,17 +1942,17 @@ CODE
o = Object.new
def o.to_str; "bar"; end
- assert_equal("fooBARbaz", "foobarbaz".sub(o, "BAR"))
+ assert_equal("fooBARbaz", S("foobarbaz").sub(o, "BAR"))
- assert_raise(TypeError) { "foo".sub(Object.new, "") }
+ assert_raise(TypeError) { S("foo").sub(Object.new, "") }
- assert_raise(ArgumentError) { "foo".sub }
+ assert_raise(ArgumentError) { S("foo").sub }
assert_raise(IndexError) { "foo"[/(?:(o$)|(x))/, 2] = 'bar' }
o = Object.new
def o.to_s; self; end
- assert_match(/^foo#<Object:0x.*>baz$/, "foobarbaz".sub("bar") { o })
+ assert_match(/^foo#<Object:0x.*>baz$/, S("foobarbaz").sub("bar") { o })
assert_equal(S("Abc"), S("abc").sub("a", "A"))
m = nil
@@ -1954,7 +1961,7 @@ CODE
assert_equal(/a/, m.regexp)
bug = '[ruby-core:78686] [Bug #13042] other than regexp has no name references'
assert_raise_with_message(IndexError, /oops/, bug) {
- 'hello'.gsub('hello', '\k<oops>')
+ S('hello').gsub('hello', '\k<oops>')
}
end
@@ -2001,18 +2008,18 @@ CODE
assert_equal(S("AAAAA000"), S("ZZZZ999").succ)
assert_equal(S("*+"), S("**").succ)
- assert_equal("abce", "abcd".succ)
- assert_equal("THX1139", "THX1138".succ)
- assert_equal("<\<koalb>>", "<\<koala>>".succ)
- assert_equal("2000aaa", "1999zzz".succ)
- assert_equal("AAAA0000", "ZZZ9999".succ)
- assert_equal("**+", "***".succ)
+ assert_equal("abce", S("abcd").succ)
+ assert_equal("THX1139", S("THX1138").succ)
+ assert_equal("<\<koalb>>", S("<\<koala>>").succ)
+ assert_equal("2000aaa", S("1999zzz").succ)
+ assert_equal("AAAA0000", S("ZZZ9999").succ)
+ assert_equal("**+", S("***").succ)
- assert_equal("!", " ".succ)
- assert_equal("", "".succ)
+ assert_equal("!", S(" ").succ)
+ assert_equal("", S("").succ)
bug = '[ruby-core:83062] [Bug #13952]'
- s = "\xff".b
+ s = S("\xff").b
assert_not_predicate(s, :ascii_only?)
assert_predicate(s.succ, :ascii_only?, bug)
end
@@ -2064,8 +2071,8 @@ CODE
assert_equal(S(""), a.succ!)
assert_equal(S(""), a)
- assert_equal("aaaaaaaaaaaa", "zzzzzzzzzzz".succ!)
- assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzzzzzzzzzzzzzzzzzzz".succ!)
+ assert_equal("aaaaaaaaaaaa", S("zzzzzzzzzzz").succ!)
+ assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", S("zzzzzzzzzzzzzzzzzzzzzzz").succ!)
end
def test_sum
@@ -2087,8 +2094,8 @@ CODE
end
def test_sum_2
- assert_equal(0, "".sum)
- assert_equal(294, "abc".sum)
+ assert_equal(0, S("").sum)
+ assert_equal(294, S("abc").sum)
check_sum("abc")
check_sum("\x80")
-3.upto(70) {|bits|
@@ -2135,39 +2142,39 @@ CODE
def test_to_i
assert_equal(1480, S("1480ft/sec").to_i)
assert_equal(0, S("speed of sound in water @20C = 1480ft/sec)").to_i)
- assert_equal(0, " 0".to_i)
- assert_equal(0, "+0".to_i)
- assert_equal(0, "-0".to_i)
- assert_equal(0, "--0".to_i)
- assert_equal(16, "0x10".to_i(0))
- assert_equal(16, "0X10".to_i(0))
- assert_equal(2, "0b10".to_i(0))
- assert_equal(2, "0B10".to_i(0))
- assert_equal(8, "0o10".to_i(0))
- assert_equal(8, "0O10".to_i(0))
- assert_equal(10, "0d10".to_i(0))
- assert_equal(10, "0D10".to_i(0))
- assert_equal(8, "010".to_i(0))
- assert_raise(ArgumentError) { "010".to_i(-10) }
+ assert_equal(0, S(" 0").to_i)
+ assert_equal(0, S("+0").to_i)
+ assert_equal(0, S("-0").to_i)
+ assert_equal(0, S("--0").to_i)
+ assert_equal(16, S("0x10").to_i(0))
+ assert_equal(16, S("0X10").to_i(0))
+ assert_equal(2, S("0b10").to_i(0))
+ assert_equal(2, S("0B10").to_i(0))
+ assert_equal(8, S("0o10").to_i(0))
+ assert_equal(8, S("0O10").to_i(0))
+ assert_equal(10, S("0d10").to_i(0))
+ assert_equal(10, S("0D10").to_i(0))
+ assert_equal(8, S("010").to_i(0))
+ assert_raise(ArgumentError) { S("010").to_i(-10) }
2.upto(36) {|radix|
- assert_equal(radix, "10".to_i(radix))
- assert_equal(radix**2, "100".to_i(radix))
+ assert_equal(radix, S("10").to_i(radix))
+ assert_equal(radix**2, S("100").to_i(radix))
}
- assert_raise(ArgumentError) { "0".to_i(1) }
- assert_raise(ArgumentError) { "0".to_i(37) }
- assert_equal(0, "z".to_i(10))
- assert_equal(12, "1_2".to_i(10))
- assert_equal(0x40000000, "1073741824".to_i(10))
- assert_equal(0x4000000000000000, "4611686018427387904".to_i(10))
- assert_equal(1, "1__2".to_i(10))
- assert_equal(1, "1_z".to_i(10))
+ assert_raise(ArgumentError) { S("0").to_i(1) }
+ assert_raise(ArgumentError) { S("0").to_i(37) }
+ assert_equal(0, S("z").to_i(10))
+ assert_equal(12, S("1_2").to_i(10))
+ assert_equal(0x40000000, S("1073741824").to_i(10))
+ assert_equal(0x4000000000000000, S("4611686018427387904").to_i(10))
+ assert_equal(1, S("1__2").to_i(10))
+ assert_equal(1, S("1_z").to_i(10))
bug6192 = '[ruby-core:43566]'
- assert_raise(Encoding::CompatibilityError, bug6192) {"0".encode("utf-16be").to_i}
- assert_raise(Encoding::CompatibilityError, bug6192) {"0".encode("utf-16le").to_i}
- assert_raise(Encoding::CompatibilityError, bug6192) {"0".encode("utf-32be").to_i}
- assert_raise(Encoding::CompatibilityError, bug6192) {"0".encode("utf-32le").to_i}
- assert_raise(Encoding::CompatibilityError, bug6192) {"0".encode("iso-2022-jp").to_i}
+ assert_raise(Encoding::CompatibilityError, bug6192) {S("0".encode("utf-16be")).to_i}
+ assert_raise(Encoding::CompatibilityError, bug6192) {S("0".encode("utf-16le")).to_i}
+ assert_raise(Encoding::CompatibilityError, bug6192) {S("0".encode("utf-32be")).to_i}
+ assert_raise(Encoding::CompatibilityError, bug6192) {S("0".encode("utf-32le")).to_i}
+ assert_raise(Encoding::CompatibilityError, bug6192) {S("0".encode("iso-2022-jp")).to_i}
end
def test_to_s
@@ -2199,13 +2206,13 @@ CODE
assert_equal(S("*e**o"), S("hello").tr(S("^aeiou"), S("*")))
assert_equal(S("hal"), S("ibm").tr(S("b-z"), S("a-z")))
- a = "abc".force_encoding(Encoding::US_ASCII)
+ a = S("abc".force_encoding(Encoding::US_ASCII))
assert_equal(Encoding::US_ASCII, a.tr(S("z"), S("\u0101")).encoding, '[ruby-core:22326]')
- assert_equal("a".hash, "a".tr("a", "\u0101").tr("\u0101", "a").hash, '[ruby-core:22328]')
- assert_equal(true, "\u0101".tr("\u0101", "a").ascii_only?)
- assert_equal(true, "\u3041".tr("\u3041", "a").ascii_only?)
- assert_equal(false, "\u3041\u3042".tr("\u3041", "a").ascii_only?)
+ assert_equal("a".hash, S("a").tr("a", "\u0101").tr("\u0101", "a").hash, '[ruby-core:22328]')
+ assert_equal(true, S("\u0101").tr("\u0101", "a").ascii_only?)
+ assert_equal(true, S("\u3041").tr("\u3041", "a").ascii_only?)
+ assert_equal(false, S("\u3041\u3042").tr("\u3041", "a").ascii_only?)
bug6156 = '[ruby-core:43335]'
bug13950 = '[ruby-core:83056] [Bug #13950]'
@@ -2236,7 +2243,7 @@ CODE
assert_nil(a.tr!(S("B-Z"), S("A-Z")))
assert_equal(S("ibm"), a)
- a = "abc".force_encoding(Encoding::US_ASCII)
+ a = S("abc".force_encoding(Encoding::US_ASCII))
assert_nil(a.tr!(S("z"), S("\u0101")), '[ruby-core:22326]')
assert_equal(Encoding::US_ASCII, a.encoding, '[ruby-core:22326]')
end
@@ -2244,8 +2251,8 @@ CODE
def test_tr_s
assert_equal(S("hypo"), S("hello").tr_s(S("el"), S("yp")))
assert_equal(S("h*o"), S("hello").tr_s(S("el"), S("*")))
- assert_equal("a".hash, "\u0101\u0101".tr_s("\u0101", "a").hash)
- assert_equal(true, "\u3041\u3041".tr("\u3041", "a").ascii_only?)
+ assert_equal("a".hash, S("\u0101\u0101").tr_s("\u0101", "a").hash)
+ assert_equal(true, S("\u3041\u3041").tr("\u3041", "a").ascii_only?)
end
def test_tr_s!
@@ -2418,6 +2425,8 @@ CODE
class S2 < String
end
def test_str_new4
+ return unless @cls == String
+
s = (0..54).to_a.join # length = 100
s2 = S2.new(s[10,90])
s3 = s2[10,80]
@@ -2426,7 +2435,7 @@ CODE
end
def test_rb_str_new4
- s = "a" * 100
+ s = S("a" * 100)
s2 = s[10,90]
assert_equal("a" * 90, s2)
s3 = s2[10,80]
@@ -2444,11 +2453,11 @@ CODE
end
def test_rb_str_to_str
- assert_equal("ab", "a" + StringLike.new("b"))
+ assert_equal("ab", S("a") + StringLike.new("b"))
end
def test_rb_str_shared_replace
- s = "a" * 100
+ s = S("a" * 100)
s.succ!
assert_equal("a" * 99 + "b", s)
s = ""
@@ -2472,12 +2481,12 @@ CODE
def test_times2
s1 = ''
100.times {|n|
- s2 = "a" * n
+ s2 = S("a") * n
assert_equal(s1, s2)
s1 << 'a'
}
- assert_raise(ArgumentError) { "foo" * (-1) }
+ assert_raise(ArgumentError) { S("foo") * (-1) }
end
def test_respond_to
@@ -2485,41 +2494,41 @@ CODE
def o.respond_to?(arg) [:to_str].include?(arg) ? nil : super end
def o.to_str() "" end
def o.==(other) "" == other end
- assert_equal(false, "" == o)
+ assert_equal(false, S("") == o)
end
def test_match_method
- assert_equal("bar", "foobarbaz".match(/bar/).to_s)
+ assert_equal("bar", S("foobarbaz").match(/bar/).to_s)
o = Regexp.new('foo')
def o.match(x, y, z); x + y + z; end
- assert_equal("foobarbaz", "foo".match(o, "bar", "baz"))
+ assert_equal("foobarbaz", S("foo").match(o, "bar", "baz"))
x = nil
- "foo".match(o, "bar", "baz") {|y| x = y }
+ S("foo").match(o, "bar", "baz") {|y| x = y }
assert_equal("foobarbaz", x)
- assert_raise(ArgumentError) { "foo".match }
+ assert_raise(ArgumentError) { S("foo").match }
end
def test_match_p_regexp
/backref/ =~ 'backref'
# must match here, but not in a separate method, e.g., assert_send,
# to check if $~ is affected or not.
- assert_equal(true, "".match?(//))
+ assert_equal(true, S("").match?(//))
assert_equal(true, :abc.match?(/.../))
- assert_equal(true, 'abc'.match?(/b/))
- assert_equal(true, 'abc'.match?(/b/, 1))
- assert_equal(true, 'abc'.match?(/../, 1))
- assert_equal(true, 'abc'.match?(/../, -2))
- assert_equal(false, 'abc'.match?(/../, -4))
- assert_equal(false, 'abc'.match?(/../, 4))
- assert_equal(true, "\u3042xx".match?(/../, 1))
- assert_equal(false, "\u3042x".match?(/../, 1))
- assert_equal(true, ''.match?(/\z/))
- assert_equal(true, 'abc'.match?(/\z/))
- assert_equal(true, 'Ruby'.match?(/R.../))
- assert_equal(false, 'Ruby'.match?(/R.../, 1))
- assert_equal(false, 'Ruby'.match?(/P.../))
+ assert_equal(true, S('abc').match?(/b/))
+ assert_equal(true, S('abc').match?(/b/, 1))
+ assert_equal(true, S('abc').match?(/../, 1))
+ assert_equal(true, S('abc').match?(/../, -2))
+ assert_equal(false, S('abc').match?(/../, -4))
+ assert_equal(false, S('abc').match?(/../, 4))
+ assert_equal(true, S("\u3042xx").match?(/../, 1))
+ assert_equal(false, S("\u3042x").match?(/../, 1))
+ assert_equal(true, S('').match?(/\z/))
+ assert_equal(true, S('abc').match?(/\z/))
+ assert_equal(true, S('Ruby').match?(/R.../))
+ assert_equal(false, S('Ruby').match?(/R.../, 1))
+ assert_equal(false, S('Ruby').match?(/P.../))
assert_equal('backref', $&)
end
@@ -2527,21 +2536,21 @@ CODE
/backref/ =~ 'backref'
# must match here, but not in a separate method, e.g., assert_send,
# to check if $~ is affected or not.
- assert_equal(true, "".match?(''))
+ assert_equal(true, S("").match?(''))
assert_equal(true, :abc.match?('...'))
- assert_equal(true, 'abc'.match?('b'))
- assert_equal(true, 'abc'.match?('b', 1))
- assert_equal(true, 'abc'.match?('..', 1))
- assert_equal(true, 'abc'.match?('..', -2))
- assert_equal(false, 'abc'.match?('..', -4))
- assert_equal(false, 'abc'.match?('..', 4))
- assert_equal(true, "\u3042xx".match?('..', 1))
- assert_equal(false, "\u3042x".match?('..', 1))
- assert_equal(true, ''.match?('\z'))
- assert_equal(true, 'abc'.match?('\z'))
- assert_equal(true, 'Ruby'.match?('R...'))
- assert_equal(false, 'Ruby'.match?('R...', 1))
- assert_equal(false, 'Ruby'.match?('P...'))
+ assert_equal(true, S('abc').match?('b'))
+ assert_equal(true, S('abc').match?('b', 1))
+ assert_equal(true, S('abc').match?('..', 1))
+ assert_equal(true, S('abc').match?('..', -2))
+ assert_equal(false, S('abc').match?('..', -4))
+ assert_equal(false, S('abc').match?('..', 4))
+ assert_equal(true, S("\u3042xx").match?('..', 1))
+ assert_equal(false, S("\u3042x").match?('..', 1))
+ assert_equal(true, S('').match?('\z'))
+ assert_equal(true, S('abc').match?('\z'))
+ assert_equal(true, S('Ruby').match?('R...'))
+ assert_equal(false, S('Ruby').match?('R...', 1))
+ assert_equal(false, S('Ruby').match?('P...'))
assert_equal('backref', $&)
end
@@ -2561,18 +2570,18 @@ CODE
def test_inspect_nul
bug8290 = '[ruby-core:54458]'
- s = "\0" + "12"
+ s = S("\0") + "12"
assert_equal '"\u000012"', s.inspect, bug8290
- s = "\0".b + "12"
+ s = S("\0".b) + "12"
assert_equal '"\x0012"', s.inspect, bug8290
end
def test_partition
- assert_equal(%w(he l lo), "hello".partition(/l/))
- assert_equal(%w(he l lo), "hello".partition("l"))
- assert_raise(TypeError) { "hello".partition(1) }
+ assert_equal(%w(he l lo), S("hello").partition(/l/))
+ assert_equal(%w(he l lo), S("hello").partition("l"))
+ assert_raise(TypeError) { S("hello").partition(1) }
def (hyphen = Object.new).to_str; "-"; end
- assert_equal(%w(foo - bar), "foo-bar".partition(hyphen), '[ruby-core:23540]')
+ assert_equal(%w(foo - bar), S("foo-bar").partition(hyphen), '[ruby-core:23540]')
bug6206 = '[ruby-dev:45441]'
Encoding.list.each do |enc|
@@ -2582,24 +2591,24 @@ CODE
end
assert_equal(["\u30E6\u30FC\u30B6", "@", "\u30C9\u30E1.\u30A4\u30F3"],
- "\u30E6\u30FC\u30B6@\u30C9\u30E1.\u30A4\u30F3".partition(/[@.]/))
+ S("\u30E6\u30FC\u30B6@\u30C9\u30E1.\u30A4\u30F3").partition(/[@.]/))
bug = '[ruby-core:82911]'
- hello = "hello"
+ hello = S("hello")
hello.partition("hi").map(&:upcase!)
assert_equal("hello", hello, bug)
- assert_equal(["", "", "foo"], "foo".partition(/^=*/))
+ assert_equal(["", "", "foo"], S("foo").partition(/^=*/))
assert_equal([S("ab"), S("c"), S("dbce")], S("abcdbce").partition(/b\Kc/))
end
def test_rpartition
- assert_equal(%w(hel l o), "hello".rpartition(/l/))
- assert_equal(%w(hel l o), "hello".rpartition("l"))
- assert_raise(TypeError) { "hello".rpartition(1) }
+ assert_equal(%w(hel l o), S("hello").rpartition(/l/))
+ assert_equal(%w(hel l o), S("hello").rpartition("l"))
+ assert_raise(TypeError) { S("hello").rpartition(1) }
def (hyphen = Object.new).to_str; "-"; end
- assert_equal(%w(foo - bar), "foo-bar".rpartition(hyphen), '[ruby-core:23540]')
+ assert_equal(%w(foo - bar), S("foo-bar").rpartition(hyphen), '[ruby-core:23540]')
bug6206 = '[ruby-dev:45441]'
Encoding.list.each do |enc|
@@ -2610,7 +2619,7 @@ CODE
bug8138 = '[ruby-dev:47183]'
assert_equal(["\u30E6\u30FC\u30B6@\u30C9\u30E1", ".", "\u30A4\u30F3"],
- "\u30E6\u30FC\u30B6@\u30C9\u30E1.\u30A4\u30F3".rpartition(/[@.]/), bug8138)
+ S("\u30E6\u30FC\u30B6@\u30C9\u30E1.\u30A4\u30F3").rpartition(/[@.]/), bug8138)
bug = '[ruby-core:82911]'
hello = "hello"
@@ -2620,10 +2629,13 @@ CODE
assert_equal([S("abcdb"), S("c"), S("e")], S("abcdbce").rpartition(/b\Kc/))
end
- def test_setter
+ def test_fs_setter
+ return unless @cls == String
+
assert_raise(TypeError) { $/ = 1 }
name = "\u{5206 884c}"
- assert_separately([], <<-"end;") # do
+ assert_separately([], "#{<<~"do;"}\n#{<<~"end;"}")
+ do;
alias $#{name} $/
assert_raise_with_message(TypeError, /\\$#{name}/) { $#{name} = 1 }
end;
@@ -2656,16 +2668,19 @@ CODE
end
def test_gsub_enumerator
- assert_normal_exit %q{"abc".gsub(/./).next}, "[ruby-dev:34828]"
+ e = S("abc").gsub(/./)
+ assert_equal("a", e.next, "[ruby-dev:34828]")
+ assert_equal("b", e.next)
+ assert_equal("c", e.next)
end
def test_clear_nonasciicompat
- assert_equal("", "\u3042".encode("ISO-2022-JP").clear)
+ assert_equal("", S("\u3042".encode("ISO-2022-JP")).clear)
end
def test_try_convert
- assert_equal(nil, String.try_convert(1))
- assert_equal("foo", String.try_convert("foo"))
+ assert_equal(nil, @cls.try_convert(1))
+ assert_equal("foo", @cls.try_convert("foo"))
end
def test_substr_negative_begin
@@ -2674,55 +2689,55 @@ CODE
=begin
def test_compare_different_encoding_string
- s1 = "\xff".force_encoding("UTF-8")
- s2 = "\xff".force_encoding("ISO-2022-JP")
+ s1 = S("\xff".force_encoding("UTF-8"))
+ s2 = S("\xff".force_encoding("ISO-2022-JP"))
assert_equal([-1, 1], [s1 <=> s2, s2 <=> s1].sort)
end
=end
def test_casecmp
- assert_equal(0, "FoO".casecmp("fOO"))
- assert_equal(1, "FoO".casecmp("BaR"))
- assert_equal(-1, "baR".casecmp("FoO"))
- assert_equal(1, "\u3042B".casecmp("\u3042a"))
- assert_equal(-1, "foo".casecmp("foo\0"))
+ assert_equal(0, S("FoO").casecmp("fOO"))
+ assert_equal(1, S("FoO").casecmp("BaR"))
+ assert_equal(-1, S("baR").casecmp("FoO"))
+ assert_equal(1, S("\u3042B").casecmp("\u3042a"))
+ assert_equal(-1, S("foo").casecmp("foo\0"))
- assert_nil("foo".casecmp(:foo))
- assert_nil("foo".casecmp(Object.new))
+ assert_nil(S("foo").casecmp(:foo))
+ assert_nil(S("foo").casecmp(Object.new))
o = Object.new
def o.to_str; "fOO"; end
- assert_equal(0, "FoO".casecmp(o))
+ assert_equal(0, S("FoO").casecmp(o))
end
def test_casecmp?
- assert_equal(true, 'FoO'.casecmp?('fOO'))
- assert_equal(false, 'FoO'.casecmp?('BaR'))
- assert_equal(false, 'baR'.casecmp?('FoO'))
- assert_equal(true, 'äöü'.casecmp?('ÄÖÜ'))
- assert_equal(false, "foo".casecmp?("foo\0"))
+ assert_equal(true, S('FoO').casecmp?('fOO'))
+ assert_equal(false, S('FoO').casecmp?('BaR'))
+ assert_equal(false, S('baR').casecmp?('FoO'))
+ assert_equal(true, S('äöü').casecmp?('ÄÖÜ'))
+ assert_equal(false, S("foo").casecmp?("foo\0"))
- assert_nil("foo".casecmp?(:foo))
- assert_nil("foo".casecmp?(Object.new))
+ assert_nil(S("foo").casecmp?(:foo))
+ assert_nil(S("foo").casecmp?(Object.new))
o = Object.new
def o.to_str; "fOO"; end
- assert_equal(true, "FoO".casecmp?(o))
+ assert_equal(true, S("FoO").casecmp?(o))
end
def test_upcase2
- assert_equal("\u3042AB", "\u3042aB".upcase)
+ assert_equal("\u3042AB", S("\u3042aB").upcase)
end
def test_downcase2
- assert_equal("\u3042ab", "\u3042aB".downcase)
+ assert_equal("\u3042ab", S("\u3042aB").downcase)
end
def test_rstrip
- assert_equal(" hello", " hello ".rstrip)
- assert_equal("\u3042", "\u3042 ".rstrip)
- assert_equal("\u3042", "\u3042\u0000".rstrip)
- assert_raise(Encoding::CompatibilityError) { "\u3042".encode("ISO-2022-JP").rstrip }
+ assert_equal(" hello", S(" hello ").rstrip)
+ assert_equal("\u3042", S("\u3042 ").rstrip)
+ assert_equal("\u3042", S("\u3042\u0000").rstrip)
+ assert_raise(Encoding::CompatibilityError) { S("\u3042".encode("ISO-2022-JP")).rstrip }
end
def test_rstrip_bang
@@ -2746,13 +2761,13 @@ CODE
assert_equal("\u3042", s5.rstrip!)
assert_equal("\u3042", s5)
- assert_raise(Encoding::CompatibilityError) { "\u3042".encode("ISO-2022-JP").rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S("\u3042".encode("ISO-2022-JP")).rstrip! }
end
def test_lstrip
- assert_equal("hello ", " hello ".lstrip)
- assert_equal("\u3042", " \u3042".lstrip)
- assert_equal("hello ", "\x00hello ".lstrip)
+ assert_equal("hello ", S(" hello ").lstrip)
+ assert_equal("\u3042", S(" \u3042").lstrip)
+ assert_equal("hello ", S("\x00hello ").lstrip)
end
def test_lstrip_bang
@@ -2779,9 +2794,9 @@ CODE
end
def test_delete_prefix
- assert_raise(TypeError) { 'hello'.delete_prefix(nil) }
- assert_raise(TypeError) { 'hello'.delete_prefix(1) }
- assert_raise(TypeError) { 'hello'.delete_prefix(/hel/) }
+ assert_raise(TypeError) { S('hello').delete_prefix(nil) }
+ assert_raise(TypeError) { S('hello').delete_prefix(1) }
+ assert_raise(TypeError) { S('hello').delete_prefix(/hel/) }
s = S("hello")
assert_equal("lo", s.delete_prefix('hel'))
@@ -2825,9 +2840,9 @@ CODE
end
def test_delete_prefix_bang
- assert_raise(TypeError) { 'hello'.delete_prefix!(nil) }
- assert_raise(TypeError) { 'hello'.delete_prefix!(1) }
- assert_raise(TypeError) { 'hello'.delete_prefix!(/hel/) }
+ assert_raise(TypeError) { S('hello').delete_prefix!(nil) }
+ assert_raise(TypeError) { S('hello').delete_prefix!(1) }
+ assert_raise(TypeError) { S('hello').delete_prefix!(/hel/) }
s = S("hello")
assert_equal("lo", s.delete_prefix!('hel'))
@@ -2878,9 +2893,9 @@ CODE
end
def test_delete_suffix
- assert_raise(TypeError) { 'hello'.delete_suffix(nil) }
- assert_raise(TypeError) { 'hello'.delete_suffix(1) }
- assert_raise(TypeError) { 'hello'.delete_suffix(/hel/) }
+ assert_raise(TypeError) { S('hello').delete_suffix(nil) }
+ assert_raise(TypeError) { S('hello').delete_suffix(1) }
+ assert_raise(TypeError) { S('hello').delete_suffix(/hel/) }
s = S("hello")
assert_equal("hel", s.delete_suffix('lo'))
@@ -2929,9 +2944,9 @@ CODE
end
def test_delete_suffix_bang
- assert_raise(TypeError) { 'hello'.delete_suffix!(nil) }
- assert_raise(TypeError) { 'hello'.delete_suffix!(1) }
- assert_raise(TypeError) { 'hello'.delete_suffix!(/hel/) }
+ assert_raise(TypeError) { S('hello').delete_suffix!(nil) }
+ assert_raise(TypeError) { S('hello').delete_suffix!(1) }
+ assert_raise(TypeError) { S('hello').delete_suffix!(/hel/) }
s = S("hello").freeze
assert_raise_with_message(FrozenError, /frozen/) {s.delete_suffix!('lo')}
@@ -3020,7 +3035,7 @@ CODE
end
def test_shared_force_encoding
- s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
+ s = S("\u{3066}\u{3059}\u{3068}").gsub(//, '')
h = {}
h[s] = nil
k = h.keys[0]
@@ -3035,16 +3050,16 @@ CODE
def test_ascii_incomat_inspect
bug4081 = '[ruby-core:33283]'
WIDE_ENCODINGS.each do |e|
- assert_equal('"abc"', "abc".encode(e).inspect)
- assert_equal('"\\u3042\\u3044\\u3046"', "\u3042\u3044\u3046".encode(e).inspect)
- assert_equal('"ab\\"c"', "ab\"c".encode(e).inspect, bug4081)
+ assert_equal('"abc"', S("abc".encode(e)).inspect)
+ assert_equal('"\\u3042\\u3044\\u3046"', S("\u3042\u3044\u3046".encode(e)).inspect)
+ assert_equal('"ab\\"c"', S("ab\"c".encode(e)).inspect, bug4081)
end
begin
verbose, $VERBOSE = $VERBOSE, nil
ext = Encoding.default_external
Encoding.default_external = "us-ascii"
$VERBOSE = verbose
- i = "abc\"\\".force_encoding("utf-8").inspect
+ i = S("abc\"\\".force_encoding("utf-8")).inspect
ensure
$VERBOSE = nil
Encoding.default_external = ext
@@ -3055,11 +3070,11 @@ CODE
def test_dummy_inspect
assert_equal('"\e\x24\x42\x22\x4C\x22\x68\e\x28\x42"',
- "\u{ffe2}\u{2235}".encode("cp50220").inspect)
+ S("\u{ffe2}\u{2235}".encode("cp50220")).inspect)
end
def test_prepend
- assert_equal(S("hello world!"), "!".prepend("hello ", "world"))
+ assert_equal(S("hello world!"), S("!").prepend("hello ", "world"))
b = S("ue")
assert_equal(S("ueueue"), b.prepend(b, b))
@@ -3067,7 +3082,7 @@ CODE
def foo.to_str
"b"
end
- assert_equal(S("ba"), "a".prepend(foo))
+ assert_equal(S("ba"), S("a").prepend(foo))
a = S("world")
b = S("hello ")
@@ -3081,34 +3096,34 @@ CODE
end
def test_byteslice
- assert_equal("h", "hello".byteslice(0))
- assert_equal(nil, "hello".byteslice(5))
- assert_equal("o", "hello".byteslice(-1))
- assert_equal(nil, "hello".byteslice(-6))
-
- assert_equal("", "hello".byteslice(0, 0))
- assert_equal("hello", "hello".byteslice(0, 6))
- assert_equal("hello", "hello".byteslice(0, 6))
- assert_equal("", "hello".byteslice(5, 1))
- assert_equal("o", "hello".byteslice(-1, 6))
- assert_equal(nil, "hello".byteslice(-6, 1))
- assert_equal(nil, "hello".byteslice(0, -1))
-
- assert_equal("h", "hello".byteslice(0..0))
- assert_equal("", "hello".byteslice(5..0))
- assert_equal("o", "hello".byteslice(4..5))
- assert_equal(nil, "hello".byteslice(6..0))
- assert_equal("", "hello".byteslice(-1..0))
- assert_equal("llo", "hello".byteslice(-3..5))
-
- assert_equal(u("\x81"), "\u3042".byteslice(1))
- assert_equal(u("\x81\x82"), "\u3042".byteslice(1, 2))
- assert_equal(u("\x81\x82"), "\u3042".byteslice(1..2))
-
- assert_equal(u("\x82")+("\u3042"*9), ("\u3042"*10).byteslice(2, 28))
+ assert_equal("h", S("hello").byteslice(0))
+ assert_equal(nil, S("hello").byteslice(5))
+ assert_equal("o", S("hello").byteslice(-1))
+ assert_equal(nil, S("hello").byteslice(-6))
+
+ assert_equal("", S("hello").byteslice(0, 0))
+ assert_equal("hello", S("hello").byteslice(0, 6))
+ assert_equal("hello", S("hello").byteslice(0, 6))
+ assert_equal("", S("hello").byteslice(5, 1))
+ assert_equal("o", S("hello").byteslice(-1, 6))
+ assert_equal(nil, S("hello").byteslice(-6, 1))
+ assert_equal(nil, S("hello").byteslice(0, -1))
+
+ assert_equal("h", S("hello").byteslice(0..0))
+ assert_equal("", S("hello").byteslice(5..0))
+ assert_equal("o", S("hello").byteslice(4..5))
+ assert_equal(nil, S("hello").byteslice(6..0))
+ assert_equal("", S("hello").byteslice(-1..0))
+ assert_equal("llo", S("hello").byteslice(-3..5))
+
+ assert_equal(u("\x81"), S("\u3042").byteslice(1))
+ assert_equal(u("\x81\x82"), S("\u3042").byteslice(1, 2))
+ assert_equal(u("\x81\x82"), S("\u3042").byteslice(1..2))
+
+ assert_equal(u("\x82")+("\u3042"*9), S("\u3042"*10).byteslice(2, 28))
bug7954 = '[ruby-dev:47108]'
- assert_equal(false, "\u3042".byteslice(0, 2).valid_encoding?, bug7954)
+ assert_equal(false, S("\u3042").byteslice(0, 2).valid_encoding?, bug7954)
assert_equal(false, ("\u3042"*10).byteslice(0, 20).valid_encoding?, bug7954)
end
@@ -3123,6 +3138,8 @@ CODE
end
def test_eq_tilde_can_be_overridden
+ return unless @cls == String
+
assert_separately([], <<-RUBY)
class String
undef =~
@@ -3140,7 +3157,7 @@ CODE
end
def test_regexp_match_subclass
- s = Bug9581.new("abc")
+ s = Bug9581.new(S("abc"))
r = /abc/
assert_equal(:foo, s =~ r)
assert_equal(:foo, s.send(:=~, r))
@@ -3150,6 +3167,7 @@ CODE
def test_LSHIFT_neary_long_max
return unless @cls == String
+
assert_ruby_status([], <<-'end;', '[ruby-core:61886] [Bug #9709]', timeout: 20)
begin
a = "a" * 0x4000_0000
@@ -3161,6 +3179,8 @@ CODE
# enable only when string size range is smaller than memory space
def test_uplus_minus
+ return unless @cls == String
+
str = "foo"
assert_not_predicate(str, :frozen?)
assert_not_predicate(+str, :frozen?)
@@ -3182,6 +3202,8 @@ CODE
end
def test_uminus_frozen
+ return unless @cls == String
+
# embedded
str1 = ("foobar" * 3).freeze
str2 = ("foobar" * 3).freeze
@@ -3198,37 +3220,37 @@ CODE
end
def test_uminus_no_freeze_not_bare
- str = @cls.new("foo")
+ str = S("foo")
assert_instance_of(@cls, -str)
assert_equal(false, str.frozen?)
- str = @cls.new("foo")
+ str = S("foo")
str.instance_variable_set(:@iv, 1)
assert_instance_of(@cls, -str)
assert_equal(false, str.frozen?)
assert_equal(1, str.instance_variable_get(:@iv))
- str = @cls.new("foo")
+ str = S("foo")
assert_instance_of(@cls, -str)
assert_equal(false, str.frozen?)
end
def test_ord
- assert_equal(97, "a".ord)
- assert_equal(97, "abc".ord)
- assert_equal(0x3042, "\u3042\u3043".ord)
- assert_raise(ArgumentError) { "".ord }
+ assert_equal(97, S("a").ord)
+ assert_equal(97, S("abc").ord)
+ assert_equal(0x3042, S("\u3042\u3043").ord)
+ assert_raise(ArgumentError) { S("").ord }
end
def test_chr
- assert_equal("a", "abcde".chr)
- assert_equal("a", "a".chr)
- assert_equal("\u3042", "\u3042\u3043".chr)
- assert_equal('', ''.chr)
+ assert_equal("a", S("abcde").chr)
+ assert_equal("a", S("a").chr)
+ assert_equal("\u3042", S("\u3042\u3043").chr)
+ assert_equal('', S('').chr)
end
def test_substr_code_range
- data = "\xff" + "a"*200
+ data = S("\xff" + "a"*200)
assert_not_predicate(data, :valid_encoding?)
assert_predicate(data[100..-1], :valid_encoding?)
end
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index 19577266c74..5b7b8c72557 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -362,9 +362,8 @@ module TestStruct
end
def test_keyword_args_warning
- warning = /warning: Passing only keyword arguments to Struct#initialize will behave differently from Ruby 3\.2\./
- assert_warn(warning) { assert_equal({a: 1}, @Struct.new(:a).new(a: 1).a) }
- assert_warn(warning) { assert_equal({a: 1}, @Struct.new(:a, keyword_init: nil).new(a: 1).a) }
+ assert_warn('') { assert_equal(1, @Struct.new(:a).new(a: 1).a) }
+ assert_warn('') { assert_equal(1, @Struct.new(:a, keyword_init: nil).new(a: 1).a) }
assert_warn('') { assert_equal({a: 1}, @Struct.new(:a).new({a: 1}).a) }
assert_warn('') { assert_equal({a: 1}, @Struct.new(:a, :b).new(1, a: 1).b) }
assert_warn('') { assert_equal(1, @Struct.new(:a, keyword_init: true).new(a: 1).a) }
@@ -489,6 +488,43 @@ module TestStruct
}
end
+ def test_public_send
+ klass = @Struct.new(:a)
+ x = klass.new(1)
+ assert_equal(1, x.public_send("a"))
+ assert_equal(42, x.public_send("a=", 42))
+ assert_equal(42, x.public_send("a"))
+ end
+
+ def test_arity
+ klass = @Struct.new(:a)
+ assert_equal 0, klass.instance_method(:a).arity
+ assert_equal 1, klass.instance_method(:a=).arity
+
+ klass.module_eval do
+ define_method(:b=, instance_method(:a=))
+ alias c= a=
+ end
+
+ assert_equal 1, klass.instance_method(:b=).arity
+ assert_equal 1, klass.instance_method(:c=).arity
+ end
+
+ def test_parameters
+ klass = @Struct.new(:a)
+ assert_equal [], klass.instance_method(:a).parameters
+ # NOTE: :_ may not be a spec.
+ assert_equal [[:req, :_]], klass.instance_method(:a=).parameters
+
+ klass.module_eval do
+ define_method(:b=, instance_method(:a=))
+ alias c= a=
+ end
+
+ assert_equal [[:req, :_]], klass.instance_method(:b=).parameters
+ assert_equal [[:req, :_]], klass.instance_method(:c=).parameters
+ end
+
class TopStruct < Test::Unit::TestCase
include TestStruct
diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb
index d94f4679d32..6a575b88c51 100644
--- a/test/ruby/test_super.rb
+++ b/test/ruby/test_super.rb
@@ -521,6 +521,43 @@ class TestSuper < Test::Unit::TestCase
assert_equal(%w[B A], result, bug9721)
end
+ # [Bug #18329]
+ def test_super_missing_prepended_module
+ a = Module.new do
+ def probe(*methods)
+ prepend(probing_module(methods))
+ end
+
+ def probing_module(methods)
+ Module.new do
+ methods.each do |method|
+ define_method(method) do |*args, **kwargs, &block|
+ super(*args, **kwargs, &block)
+ end
+ end
+ end
+ end
+ end
+
+ b = Class.new do
+ extend a
+
+ probe :danger!, :missing
+
+ def danger!; end
+ end
+
+ o = b.new
+ o.danger!
+ begin
+ original_gc_stress = GC.stress
+ GC.stress = true
+ 2.times { o.missing rescue NoMethodError }
+ ensure
+ GC.stress = original_gc_stress
+ end
+ end
+
def test_from_eval
bug10263 = '[ruby-core:65122] [Bug #10263a]'
a = Class.new do
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index fc40a7f21a9..622527dafee 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -66,6 +66,46 @@ class TestSyntax < Test::Unit::TestCase
f&.close!
end
+ def test_anonymous_block_forwarding
+ assert_syntax_error("def b; c(&); end", /no anonymous block parameter/)
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ def b(&); c(&) end
+ def c(&); yield 1 end
+ a = nil
+ b{|c| a = c}
+ assert_equal(1, a)
+ end;
+ end
+
+ def test_anonymous_rest_forwarding
+ assert_syntax_error("def b; c(*); end", /no anonymous rest parameter/)
+ assert_syntax_error("def b; c(1, *); end", /no anonymous rest parameter/)
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ def b(*); c(*) end
+ def c(*a); a end
+ def d(*); b(*, *) end
+ assert_equal([1, 2], b(1, 2))
+ assert_equal([1, 2, 1, 2], d(1, 2))
+ end;
+ end
+
+ def test_anonymous_keyword_rest_forwarding
+ assert_syntax_error("def b; c(**); end", /no anonymous keyword rest parameter/)
+ assert_syntax_error("def b; c(k: 1, **); end", /no anonymous keyword rest parameter/)
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ def b(**); c(**) end
+ def c(**kw); kw end
+ def d(**); b(k: 1, **) end
+ def e(**); b(**, k: 1) end
+ assert_equal({a: 1, k: 3}, b(a: 1, k: 3))
+ assert_equal({a: 1, k: 3}, d(a: 1, k: 3))
+ assert_equal({a: 1, k: 1}, e(a: 1, k: 3))
+ end;
+ end
+
def test_newline_in_block_parameters
bug = '[ruby-dev:45292]'
["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params|
@@ -1575,6 +1615,15 @@ eom
def test_argument_forwarding
assert_valid_syntax('def foo(...) bar(...) end')
assert_valid_syntax('def foo(...) end')
+ assert_valid_syntax('def foo(a, ...) bar(...) end')
+ assert_valid_syntax("def foo ...\n bar(...)\nend")
+ assert_valid_syntax("def foo a, ...\n bar(...)\nend")
+ assert_valid_syntax("def foo b = 1, ...\n bar(...)\nend")
+ assert_valid_syntax("def foo ...; bar(...); end")
+ assert_valid_syntax("def foo a, ...; bar(...); end")
+ assert_valid_syntax("def foo b = 1, ...; bar(...); end")
+ assert_valid_syntax("(def foo ...\n bar(...)\nend)")
+ assert_valid_syntax("(def foo ...; bar(...); end)")
assert_valid_syntax('def ==(...) end')
assert_valid_syntax('def [](...) end')
assert_valid_syntax('def nil(...) end')
@@ -1604,7 +1653,11 @@ eom
[args, kws]
end
end
+ obj4 = obj1.clone
+ obj5 = obj1.clone
obj1.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
+ obj4.instance_eval("def foo ...\n bar(...)\n""end", __FILE__, __LINE__)
+ obj5.instance_eval("def foo ...; bar(...); end", __FILE__, __LINE__)
klass = Class.new {
def foo(*args, **kws, &block)
@@ -1633,7 +1686,7 @@ eom
end
obj3.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
- [obj1, obj2, obj3].each do |obj|
+ [obj1, obj2, obj3, obj4, obj5].each do |obj|
assert_warning('') {
assert_equal([[1, 2, 3], {k1: 4, k2: 5}], obj.foo(1, 2, 3, k1: 4, k2: 5) {|*x| x})
}
@@ -1766,6 +1819,29 @@ eom
assert_equal [[4, 1, 5, 2], {a: 1}], obj.foo(4, 5, 2, a: 1)
assert_equal [[4, 1, 5, 2, 3], {a: 1}], obj.foo(4, 5, 2, 3, a: 1)
assert_equal [[4, 1, 5, 2, 3], {a: 1}], obj.foo(4, 5, 2, 3, a: 1){|args, kws| [args, kws]}
+
+ obj.singleton_class.send(:remove_method, :foo)
+ obj.instance_eval("def foo a, ...\n bar(a, ...)\n"" end", __FILE__, __LINE__)
+ assert_equal [[4], {}], obj.foo(4)
+ assert_equal [[4, 2], {}], obj.foo(4, 2)
+ assert_equal [[4, 2, 3], {}], obj.foo(4, 2, 3)
+ assert_equal [[4], {a: 1}], obj.foo(4, a: 1)
+ assert_equal [[4, 2], {a: 1}], obj.foo(4, 2, a: 1)
+ assert_equal [[4, 2, 3], {a: 1}], obj.foo(4, 2, 3, a: 1)
+ assert_equal [[4, 2, 3], {a: 1}], obj.foo(4, 2, 3, a: 1){|args, kws| [args, kws]}
+
+ obj.singleton_class.send(:remove_method, :foo)
+ obj.instance_eval("def foo a, ...; bar(a, ...); end", __FILE__, __LINE__)
+ assert_equal [[4], {}], obj.foo(4)
+ assert_equal [[4, 2], {}], obj.foo(4, 2)
+ assert_equal [[4, 2, 3], {}], obj.foo(4, 2, 3)
+ assert_equal [[4], {a: 1}], obj.foo(4, a: 1)
+ assert_equal [[4, 2], {a: 1}], obj.foo(4, 2, a: 1)
+ assert_equal [[4, 2, 3], {a: 1}], obj.foo(4, 2, 3, a: 1)
+ assert_equal [[4, 2, 3], {a: 1}], obj.foo(4, 2, 3, a: 1){|args, kws| [args, kws]}
+
+ exp = eval("-> (a: nil) {a...1}")
+ assert_equal 0...1, exp.call(a: 0)
end
def test_cdhash
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 7b37aeb202e..2c91eca583e 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -317,7 +317,7 @@ class TestThread < Test::Unit::TestCase
s += 1
end
Thread.pass until t.stop?
- sleep 1 if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
+ sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
assert_equal(1, s)
t.wakeup
Thread.pass while t.alive?
@@ -500,7 +500,7 @@ class TestThread < Test::Unit::TestCase
def test_ignore_deadlock
if /mswin|mingw/ =~ RUBY_PLATFORM
- skip "can't trap a signal from another process on Windows"
+ omit "can't trap a signal from another process on Windows"
end
assert_in_out_err([], <<-INPUT, %w(false :sig), [], :signal=>:INT, timeout: 1, timeout_error: nil)
p Thread.ignore_deadlock
@@ -731,7 +731,7 @@ class TestThread < Test::Unit::TestCase
end
def test_no_valid_cfp
- skip 'with win32ole, cannot run this testcase because win32ole redefines Thread#initialize' if defined?(WIN32OLE)
+ omit 'with win32ole, cannot run this testcase because win32ole redefines Thread#initialize' if defined?(WIN32OLE)
bug5083 = '[ruby-dev:44208]'
assert_equal([], Thread.new(&Module.method(:nesting)).value, bug5083)
assert_instance_of(Thread, Thread.new(:to_s, &Class.new.method(:undef_method)).join, bug5083)
@@ -1256,7 +1256,7 @@ q.pop
end if Process.respond_to?(:fork)
def test_fork_while_parent_locked
- skip 'needs fork' unless Process.respond_to?(:fork)
+ omit 'needs fork' unless Process.respond_to?(:fork)
m = Thread::Mutex.new
nr = 1
thrs = []
@@ -1277,7 +1277,7 @@ q.pop
end
def test_fork_while_mutex_locked_by_forker
- skip 'needs fork' unless Process.respond_to?(:fork)
+ omit 'needs fork' unless Process.respond_to?(:fork)
m = Thread::Mutex.new
m.synchronize do
pid = fork do
@@ -1345,7 +1345,7 @@ q.pop
end
def test_thread_native_thread_id
- skip "don't support native_thread_id" unless Thread.method_defined?(:native_thread_id)
+ omit "don't support native_thread_id" unless Thread.method_defined?(:native_thread_id)
assert_instance_of Integer, Thread.main.native_thread_id
th1 = Thread.start{sleep}
@@ -1369,7 +1369,7 @@ q.pop
opts = { timeout: 5, timeout_error: nil }
# prevent SIGABRT from slow shutdown with MJIT
- opts[:reprieve] = 3 if defined?(RubyVM::JIT) && RubyVM::JIT.enabled?
+ opts[:reprieve] = 3 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
assert_normal_exit(<<-_end, '[Bug #8996]', **opts)
Thread.report_on_exception = false
@@ -1384,7 +1384,7 @@ q.pop
def test_signal_at_join
if /mswin|mingw/ =~ RUBY_PLATFORM
- skip "can't trap a signal from another process on Windows"
+ omit "can't trap a signal from another process on Windows"
# opt = {new_pgroup: true}
end
assert_separately([], "#{<<~"{#"}\n#{<<~'};'}", timeout: 120)
diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb
index 3fa0eae2c17..69cb40711c5 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -580,10 +580,10 @@ class TestThreadQueue < Test::Unit::TestCase
def test_queue_with_trap
if ENV['APPVEYOR'] == 'True' && RUBY_PLATFORM.match?(/mswin/)
- skip 'This test fails too often on AppVeyor vs140'
+ omit 'This test fails too often on AppVeyor vs140'
end
if RUBY_PLATFORM.match?(/mingw/)
- skip 'This test fails too often on MinGW'
+ omit 'This test fails too often on MinGW'
end
assert_in_out_err([], <<-INPUT, %w(INT INT exit), [])
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index fc21c740789..445518ab579 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -37,8 +37,11 @@ class TestTime < Test::Unit::TestCase
end
def test_new
+ assert_equal(Time.new(2000,1,1,0,0,0), Time.new(2000))
+ assert_equal(Time.new(2000,2,1,0,0,0), Time.new("2000", "Feb"))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, 3600*11))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,9, 13,0,0, -3600*11))
+ assert_equal(Time.utc(2000,2,29,23,0,0), Time.new(2000, 3, 1, 0, 0, 0, 3600))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, "+11:00"))
assert_equal(Rational(1,2), Time.new(2000,2,10, 11,0,5.5, "+11:00").subsec)
bug4090 = '[ruby-dev:42631]'
@@ -46,7 +49,10 @@ class TestTime < Test::Unit::TestCase
t = Time.new(*tm, "-12:00")
assert_equal([2001,2,28,23,59,30,-43200], [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.gmt_offset], bug4090)
assert_raise(ArgumentError) { Time.new(2000,1,1, 0,0,0, "+01:60") }
- assert_raise(ArgumentError) { Time.new(2021, 1, 1, "+09:99") }
+ msg = /invalid value for Integer/
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, 1, "+09:99") }
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, "+09:99") }
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, "+09:99") }
end
def test_time_add()
@@ -110,7 +116,7 @@ class TestTime < Test::Unit::TestCase
assert_equal(946684800, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
# Giveup to try 2nd test because some state is changed.
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
assert_equal(0x7fffffff, Time.utc(2038, 1, 19, 3, 14, 7).tv_sec)
assert_equal(0x80000000, Time.utc(2038, 1, 19, 3, 14, 8).tv_sec)
@@ -240,6 +246,10 @@ class TestTime < Test::Unit::TestCase
assert_equal(1, Time.at(0, 0.001).nsec)
end
+ def test_at_splat
+ assert_equal(Time.at(1, 2), Time.at(*[1, 2]))
+ end
+
def test_at_with_unit
assert_equal(123456789, Time.at(0, 123456789, :nanosecond).nsec)
assert_equal(123456789, Time.at(0, 123456789, :nsec).nsec)
@@ -379,6 +389,11 @@ class TestTime < Test::Unit::TestCase
end
end
+ def test_marshal_broken_month
+ data = "\x04\x08u:\tTime\r\x20\x7c\x1e\xc0\x00\x00\x00\x00"
+ assert_equal(Time.utc(2022, 4, 1), Marshal.load(data))
+ end
+
def test_marshal_distant_past
assert_marshal_roundtrip(Time.utc(1890, 1, 1))
assert_marshal_roundtrip(Time.utc(-4.5e9, 1, 1))
@@ -1168,7 +1183,7 @@ class TestTime < Test::Unit::TestCase
def test_2038
# Giveup to try 2nd test because some state is changed.
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
if no_leap_seconds?
assert_equal(0x80000000, Time.utc(2038, 1, 19, 3, 14, 8).tv_sec)
@@ -1281,22 +1296,6 @@ class TestTime < Test::Unit::TestCase
assert_equal("366", t.strftime("%j"))
end
- def test_strftime_no_hidden_garbage
- skip unless Thread.list.size == 1
-
- fmt = %w(Y m d).map { |x| "%#{x}" }.join('-') # defeats optimization
- t = Time.at(0).getutc
- ObjectSpace.count_objects(res = {}) # creates strings on first call
- GC.disable
- before = ObjectSpace.count_objects(res)[:T_STRING]
- val = t.strftime(fmt)
- after = ObjectSpace.count_objects(res)[:T_STRING]
- assert_equal before + 1, after, 'only new string is the created one'
- assert_equal '1970-01-01', val
- ensure
- GC.enable
- end
-
def test_num_exact_error
bad = EnvUtil.labeled_class("BadValue").new
x = EnvUtil.labeled_class("Inexact") do
@@ -1309,8 +1308,8 @@ class TestTime < Test::Unit::TestCase
def test_memsize
# Time objects are common in some code, try to keep them small
- skip "Time object size test" if /^(?:i.?86|x86_64)-linux/ !~ RUBY_PLATFORM
- skip "GC is in debug" if GC::INTERNAL_CONSTANTS[:DEBUG]
+ omit "Time object size test" if /^(?:i.?86|x86_64)-linux/ !~ RUBY_PLATFORM
+ omit "GC is in debug" if GC::INTERNAL_CONSTANTS[:DEBUG]
require 'objspace'
t = Time.at(0)
size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
@@ -1324,6 +1323,6 @@ class TestTime < Test::Unit::TestCase
end
assert_equal expect, ObjectSpace.memsize_of(t)
rescue LoadError => e
- skip "failed to load objspace: #{e.message}"
+ omit "failed to load objspace: #{e.message}"
end
end
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index fdc9e114b53..6ae12dea5de 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -112,7 +112,7 @@ class TestTimeTZ < Test::Unit::TestCase
t = with_tz("America/Los_Angeles") {
Time.local(2000, 1, 1)
}
- skip "force_tz_test is false on this environment" unless t
+ omit "force_tz_test is false on this environment" unless t
z1 = t.zone
z2 = with_tz(tz="Asia/Singapore") {
t.localtime.zone
diff --git a/test/ruby/test_undef.rb b/test/ruby/test_undef.rb
index e0add7c3aba..074b92be558 100644
--- a/test/ruby/test_undef.rb
+++ b/test/ruby/test_undef.rb
@@ -35,4 +35,20 @@ class TestUndef < Test::Unit::TestCase
end
end
end
+
+ def test_singleton_undef
+ klass = Class.new do
+ def foo
+ :ok
+ end
+ end
+
+ klass.new.foo
+
+ klass.new.instance_eval do
+ undef foo
+ end
+
+ klass.new.foo
+ end
end
diff --git a/test/ruby/test_vm_dump.rb b/test/ruby/test_vm_dump.rb
index 679ce94b91b..9c06ec14fb2 100644
--- a/test/ruby/test_vm_dump.rb
+++ b/test/ruby/test_vm_dump.rb
@@ -3,7 +3,7 @@ require 'test/unit'
class TestVMDump < Test::Unit::TestCase
def assert_darwin_vm_dump_works(args)
- skip if RUBY_PLATFORM !~ /darwin/
+ omit if RUBY_PLATFORM !~ /darwin/
assert_in_out_err(args, "", [], /^\[IMPORTANT\]/)
end
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index 3b9eef770aa..4c91661f865 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -59,7 +59,7 @@ class TestWeakMap < Test::Unit::TestCase
assert_weak_include(m, k)
end
GC.start
- skip('TODO: failure introduced from r60440')
+ pend('TODO: failure introduced from 837fd5e494731d7d44786f29e7d6e8c27029806f')
assert_not_send([@wm, m, k])
end
alias test_member? test_include?
@@ -73,6 +73,15 @@ class TestWeakMap < Test::Unit::TestCase
@wm.inspect)
end
+ def test_inspect_garbage
+ 1000.times do |i|
+ @wm[i] = Object.new
+ @wm.inspect
+ end
+ assert_match(/\A\#<#{@wm.class.name}:[^:]++:(?:\s\d+\s=>\s\#<(?:Object|collected):[^:<>]*+>(?:,|>\z))+/,
+ @wm.inspect)
+ end
+
def test_each
m = __callee__[/test_(.*)/, 1]
x1 = Object.new
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 7b8cde6c0cd..88f8e428135 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -2,8 +2,9 @@
require 'test/unit'
require 'envutil'
require 'tmpdir'
+require_relative '../lib/jit_support'
-return unless defined?(YJIT) && YJIT.enabled?
+return unless defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
# Tests for YJIT with assertions on compilation and side exits
# insipired by the MJIT tests in test/ruby/test_jit.rb
@@ -21,27 +22,49 @@ class TestYJIT < Test::Unit::TestCase
%w(--version --disable=yjit --yjit),
%w(--version --disable=yjit --enable-yjit),
%w(--version --disable=yjit --enable=yjit),
+ *([
+ %w(--version --jit),
+ %w(--version --disable-jit --jit),
+ %w(--version --disable-jit --enable-jit),
+ %w(--version --disable-jit --enable=jit),
+ %w(--version --disable=jit --yjit),
+ %w(--version --disable=jit --enable-jit),
+ %w(--version --disable=jit --enable=jit),
+ ] if JITSupport.yjit_supported?),
].each do |version_args|
assert_in_out_err(version_args) do |stdout, stderr|
- assert_equal([RUBY_DESCRIPTION], stdout)
+ assert_equal(RUBY_DESCRIPTION, stdout.first)
assert_equal([], stderr)
end
end
end
def test_command_line_switches
- assert_in_out_err('--yjit-', '', [], /invalid option --yjit-/)
- assert_in_out_err('--yjithello', '', [], /invalid option --yjithello/)
- assert_in_out_err('--yjit-call-threshold', '', [], /--yjit-call-threshold needs an argument/)
- assert_in_out_err('--yjit-call-threshold=', '', [], /--yjit-call-threshold needs an argument/)
- assert_in_out_err('--yjit-greedy-versioning=1', '', [], /warning: argument to --yjit-greedy-versioning is ignored/)
+ assert_in_out_err('--yjit-', '', [], /invalid option --yjit-/)
+ assert_in_out_err('--yjithello', '', [], /invalid option --yjithello/)
+ assert_in_out_err('--yjit-call-threshold', '', [], /--yjit-call-threshold needs an argument/)
+ assert_in_out_err('--yjit-call-threshold=', '', [], /--yjit-call-threshold needs an argument/)
+ assert_in_out_err('--yjit-greedy-versioning=1', '', [], /warning: argument to --yjit-greedy-versioning is ignored/)
+ end
+
+ def test_yjit_stats_and_v_no_error
+ _stdout, stderr, _status = EnvUtil.invoke_ruby(%w(-v --yjit-stats), '', true, true)
+ refute_includes(stderr, "NoMethodError")
end
def test_enable_from_env_var
yjit_child_env = {'RUBY_YJIT_ENABLE' => '1'}
- assert_in_out_err([yjit_child_env, '--version'], '', [RUBY_DESCRIPTION])
+ assert_in_out_err([yjit_child_env, '--version'], '') do |stdout, stderr|
+ assert_equal(RUBY_DESCRIPTION, stdout.first)
+ assert_equal([], stderr)
+ end
assert_in_out_err([yjit_child_env, '-e puts RUBY_DESCRIPTION'], '', [RUBY_DESCRIPTION])
- assert_in_out_err([yjit_child_env, '-e p YJIT.enabled?'], '', ['true'])
+ assert_in_out_err([yjit_child_env, '-e p RubyVM::YJIT.enabled?'], '', ['true'])
+ end
+
+ def test_compile_setclassvariable
+ script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo'
+ assert_compiles(script, insns: %i[setclassvariable], result: 1)
end
def test_compile_getclassvariable
@@ -234,6 +257,11 @@ class TestYJIT < Test::Unit::TestCase
assert_no_exits('/#{true}/')
end
+ def test_compile_dynamic_symbol
+ assert_compiles(':"#{"foo"}"', insns: %i[intern])
+ assert_compiles('s = "bar"; :"foo#{s}"', insns: %i[intern])
+ end
+
def test_getlocal_with_level
assert_compiles(<<~RUBY, insns: %i[getlocal opt_plus], result: [[7]])
def foo(foo, bar)
@@ -369,7 +397,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_string_interpolation
- assert_compiles(<<~'RUBY', insns: %i[checktype concatstrings], result: "foobar", min_calls: 2)
+ assert_compiles(<<~'RUBY', insns: %i[objtostring anytostring concatstrings], result: "foobar", min_calls: 2)
def make_str(foo, bar)
"#{foo}#{bar}"
end
@@ -380,7 +408,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_string_interpolation_cast
- assert_compiles(<<~'RUBY', insns: %i[checktype concatstrings tostring], result: "123")
+ assert_compiles(<<~'RUBY', insns: %i[objtostring anytostring concatstrings], result: "123")
def make_str(foo, bar)
"#{foo}#{bar}"
end
@@ -389,7 +417,30 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
- def test_invokebuiltin
+ def test_checkkeyword
+ assert_compiles(<<~'RUBY', insns: %i[checkkeyword], result: [2, 5])
+ def foo(foo: 1+1)
+ foo
+ end
+
+ [foo, foo(foo: 5)]
+ RUBY
+ end
+
+ def test_struct_aref
+ assert_compiles(<<~RUBY)
+ def foo(obj)
+ obj.foo
+ obj.bar
+ end
+
+ Foo = Struct.new(:foo, :bar)
+ foo(Foo.new(123))
+ foo(Foo.new(123))
+ RUBY
+ end
+
+ def test_struct_aset
assert_compiles(<<~RUBY)
def foo(obj)
obj.foo = 123
@@ -461,6 +512,24 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_optarg_and_kwarg
+ assert_no_exits(<<~'RUBY')
+ def opt_and_kwarg(a, b=nil, c: nil)
+ end
+
+ 2.times do
+ opt_and_kwarg(1, 2, c: 3)
+ end
+ RUBY
+ end
+
+ def test_cfunc_kwarg
+ assert_no_exits('{}.store(:value, foo: 123)')
+ assert_no_exits('{}.store(:value, foo: 123, bar: 456, baz: 789)')
+ assert_no_exits('{}.merge(foo: 123)')
+ assert_no_exits('{}.merge(foo: 123, bar: 456, baz: 789)')
+ end
+
def test_ctx_different_mappings
# regression test simplified from URI::Generic#hostname=
assert_compiles(<<~'RUBY', frozen_string_literal: true)
@@ -490,7 +559,7 @@ class TestYJIT < Test::Unit::TestCase
objects[1].foo
}
- stats = YJIT.runtime_stats
+ stats = RubyVM::YJIT.runtime_stats
return :ok unless stats[:all_stats]
return :ok if stats[:invalidation_count] < 10
@@ -505,12 +574,12 @@ class TestYJIT < Test::Unit::TestCase
ANY = Object.new
def assert_compiles(test_script, insns: [], min_calls: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil)
reset_stats = <<~RUBY
- YJIT.runtime_stats
- YJIT.reset_stats!
+ RubyVM::YJIT.runtime_stats
+ RubyVM::YJIT.reset_stats!
RUBY
write_results = <<~RUBY
- stats = YJIT.runtime_stats
+ stats = RubyVM::YJIT.runtime_stats
def collect_blocks(blocks)
blocks.sort_by(&:address).map { |b| [b.iseq_start_index, b.iseq_end_index] }
@@ -519,7 +588,7 @@ class TestYJIT < Test::Unit::TestCase
def collect_iseqs(iseq)
iseq_array = iseq.to_a
insns = iseq_array.last.grep(Array)
- blocks = YJIT.blocks_for(iseq)
+ blocks = RubyVM::YJIT.blocks_for(iseq)
h = {
name: iseq_array[5],
insns: insns,
diff --git a/test/rubygems/encrypted_private_key.pem b/test/rubygems/encrypted_private_key.pem
index 868f332b7ce..d9667689a62 100644
--- a/test/rubygems/encrypted_private_key.pem
+++ b/test/rubygems/encrypted_private_key.pem
@@ -1,30 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-CBC,4E38D58B5A059DB6
+DEK-Info: AES-256-CBC,CB6FD0B173EF450C6EE21A01DD785C1D
-IgWLfnHVnkErKkhysrUMoE0ubkRDtJXZv9KR02jGGFk/kGqWyTqPk08uzhwVNM+l
-eOk0qfPykkJM3KZgqTsD6xfA1D5WqFp5mLoFXVVTn9I3acSZsqOY0FweCipwdVpI
-x+9Fl+v62kIW06dOjyWLE1abed9hHiXesGGsD87/RJSywy4OBxOcrhR1fJLK4ElR
-ya0UzI7rWnmZMChjaZBssfzT1DR79/dARXhon2m5EiIJDjMpc8BKGYlQy5RHCHwA
-cnrhUTTvsggZbQtmLZ/yVx8FSJ273XpYR0pmwbw4j1R+zeXQRK5MroBnCfOGcYa7
-rmpERmDW3VAuxXR20SUAGdo1XOMTDe1uLbaotn6e56pXghIaYROTPS+HsuOkAZGY
-OYWEkUoyog4l4n+h/C1umFfTFGvKNATLgDugONFvTw/PLbjvl+sWMy2QfqH0MlNB
-DIUPxhEVCFD9oB4nfB86WDAmPp1DH9/IBet/21kbQ2eTIzakTdG3XiC+xzAQRu68
-EOCTbasFWGxlCix66gt4xWMLksEg8UhWSpjS3/HsifrKyNMB8sfUFYmZmOYMW4mf
-NuEtpBL3AdHNObN8nQ75HfehukzNpbYVRsLzWrVgtxvXHVpnvoCCpCvQBMHeRZxK
-6m028mhH1m6yYE/uGFiRKLrN7BKAttbUiqnGgVIg/lQQilFWwylxQ6aXqJGmNgxa
-oihzWZRlXivIhhrM7VMnLoKAF/YfmWpP3zahGpBQGfObtPtm44R0ezXPdtsivnyu
-CmFOPGzRNMKZtH/lwVhuIIK3AFIGDsRRP9ySN4YfjQZnTdu2sRlxBnANP9m8W9T2
-p+C4zVkDYAbsuWq2HpHwsdL8gqIiXeptsHLqkNw+ulSSLyeBCgM9fpV3RsNGjwqu
-k8QLb1CYp2VX46CE8UKvOd/nyFnEsD+EAc3WangEwA41m2IaXcbs9Au7xsG9oacZ
-DrxlJVNxlxO9YyP9dNOTfP0fHIiygKQQY2aU3y3oRneu7ogYES5V2mUNH7cYUWVL
-CHPXAoUXJErvDQ/opW2DroA9Eqv9sST6WqBf6LXRcWU0ntfzcFUbEqgmCmB7Cbu2
-8udEn6iWilQahLyDoAShLkU7+Tk78Z1c6RuqjyY4VboZPzxrTYK8YIXzwX+jj9bG
-KIIGS5eghK185+AjlwtzJ7MBdoL323YIik6uOZluhnJHLaxjxUXGa1VqDgsyqGi7
-ISRMTpVTrbR+UtoEi4ZhMjobtFUr7lGkt24VkXwBKdoyryj4RPHGdp7Tf6XDJufQ
-+KKhqt8QrpOTPiMskFN2disOSF5/YZCmtT84nkhU7Hf1lkQ2kfx1zfNk0GqYYXOW
-zHOAczy8gWBRetDMnhRYohDzQGWn//b+2Wr2n1RD8D9kyjMRhpFMYfQGfRcuPGjW
-91k/T0XFcjcjeZPL9s+HITmrh7zg5WxbCfTEp91j3Oy1bns196SY77TE0BzUsqR2
-geJggcUMEfyvHiiCMtijmSSD9nf8tNIxLVL8Jaf1coA6e1CrlHnYAu2f/Q3GIcvU
-EEEmw+cZRwsk4fffYzh5psxxGdXKBv1KcQ/CeBhZL0WJsCp2y5oxwg==
+KqHn2Df8hSuwNE+W+60MnGtc6xpoXmF3iN25iVwcN67krYn+N6cBhjFeXwXccYwJ
+2gHSu4iEK9Qe32vK0yuv8N9h/fmsabZl0TotnEem/pqO5T8W4LxyK+Rw0s6RB30S
+C+mUisRADTanAxyBxsNU8xR8OAUNMAAxV1me6It0W2lfNE3t5jg/Kr0NWMoRUNRx
+dkE6WlD5D8jBeC3QdZ6OuE7QXOCEAWAjcFMc0d1WJq2t2r3TrLVfTH7EOoRyvL1H
+rrFRx/dEW1UJfM6P11wB5R0nhg3rDXF7oDFszjwO/3tzARke0NZuN37l301lYRl1
+aolO6sShJLa0Ml/TgNcJw0S6rc6a1Z52gTfQKztKcL1UX4HLZg75zKmn6qfatMBC
+iXn+pQRYNsOPQ5h4r7lBBqvuV+gBw+rN768tYpZ2/YVDaygxETHcZAFCdAw/JNbP
+d0XPIbP79NRrCgzSo58LKQGuOQf3Hh0vp1YS+MilMtm/eogoj1enSPM+ymStHRwG
+i+D00xCQ6blSOZ2eUUBJXt11YzP22GYnv+XTR/5kGKkTIvoRMfd+39bQyR32IEv2
+Z+yweAGQInD94eifT9ObbIayJ47y01KP0+Vj6hz4RCFsmJKsYiai5JiKlmf7lV9w
+7zH3TtCOx/xSyomesXVRkqvFkdyeguU72kXc5tiMPaDXGCOeV0GWyR1GU1DUX9/K
+60E7ym0Wx77WGMKk2fkirZzBdOeliyCRUXd7ccN2rBCjTwtjAUIk27lwzdUaTUv7
+EmjauDvSMFtir58c+zjlLmBaSQOzKcj0KXMp0Oucls9bD85WGGbGyzGhTa0AZ+/+
+cCEJt7RAwW0kTEO/uO+BAZe/zBoi9ek+QBn54FK3E7CXfS4Oi9Qbc3fwlVyTlVmz
+ZGrCncO0TIVGErFWK24Z7lX8rBnk8enfnamrPfKtwn4LG9aDfhSj8DtisjlRUVT5
+chDQ+CCi9rh3wXh28lyS+nXJ3yFidCzRgcsc3PpN/c4DNRggZc+C/KDw+J2FW+8Y
+p65OliBQHQcG0PnCa2xRyCGevytPG0rfNDgyaY33dPEo90mBLVcwLbzGiSGBHgFl
+pr8A/rqbnFpRO39NYbACeRFCqPpzyzfARCCcjcDoFrENdIaJui0fjlBkoV3B/KiK
+EVjDcgwt1HAtz8bV2YJ+OpQbhD7E90e2vTRMuXAH21Ygo32VOS0LRlCRc9ZyZW4z
+PTyO/6a+FbXZ1zhVJxu/0bmBERZ14WVmWq56oxQav8knpxYeYPgpEmIZnrHnJ1Ko
+UoXcc8Hy4NKtaBmDcaF8TCobNsRZTxO/htqpdyNsOrBSsnX2kP5D/O1l1vuVYi1/
+RYfUqL9dvGzvfsFuuDDjDlQ/fIA6pFzJV3fy4KJHlF1r33qaE/lNMdpKljBwvUII
+Vog4cGmzxssqK5q9kuogcuyeOuFODjBNW4qt0WylSi9bwwy3ZwaZLRqhngz6+tCV
+Jp45Gk881XiVe3aVU0l+4DmJJ9/5vwqjH5Vo/GJqFU6gzB+Zv/0plYeNkuE0Xo2z
+ecdxnGKVPl42q44lvczjDw2KX0ahxQrfrbcl48//zR295u9POzCL97d6zpioI2NR
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb
index 504e25ea52e..d97d930476b 100644
--- a/test/rubygems/helper.rb
+++ b/test/rubygems/helper.rb
@@ -16,16 +16,6 @@ begin
rescue Gem::LoadError
end
-begin
- require 'simplecov'
- SimpleCov.start do
- add_filter "/test/"
- add_filter "/bundler/"
- add_filter "/lib/rubygems/resolver/molinillo"
- end
-rescue LoadError
-end
-
if File.exist?(bundler_gemspec)
require_relative '../../bundler/lib/bundler'
else
@@ -255,16 +245,14 @@ class Gem::TestCase < Test::Unit::TestCase
output.scan(/^#{Regexp.escape make_command}(?:[[:blank:]].*)?$/)
end
- def parse_make_command_line(line)
- command, *args = line.shellsplit
+ def parse_make_command_line_targets(line)
+ args = line.sub(/^#{Regexp.escape make_command}/, "").shellsplit
targets = []
- macros = {}
args.each do |arg|
case arg
when /\A(\w+)=/
- macros[$1] = $'
else
targets << arg
end
@@ -272,11 +260,7 @@ class Gem::TestCase < Test::Unit::TestCase
targets << '' if targets.empty?
- {
- :command => command,
- :targets => targets,
- :macros => macros,
- }
+ targets
end
def assert_contains_make_command(target, output, msg = nil)
@@ -289,7 +273,7 @@ class Gem::TestCase < Test::Unit::TestCase
)
else
msg = build_message(msg,
- 'Expected make command "%s": %s' % [
+ 'Expected make command "%s", but was "%s"' % [
('%s %s' % [make_command, target]).rstrip,
output,
]
@@ -297,10 +281,9 @@ class Gem::TestCase < Test::Unit::TestCase
end
assert scan_make_command_lines(output).any? {|line|
- make = parse_make_command_line(line)
+ targets = parse_make_command_line_targets(line)
- if make[:targets].include?(target)
- yield make, line if block_given?
+ if targets.include?(target)
true
else
false
@@ -356,10 +339,10 @@ class Gem::TestCase < Test::Unit::TestCase
ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache'
@orig_ruby = if ENV['RUBY']
- ruby = Gem.ruby
- Gem.ruby = ENV['RUBY']
- ruby
- end
+ ruby = Gem.ruby
+ Gem.ruby = ENV['RUBY']
+ ruby
+ end
@git = ENV['GIT'] || (win_platform? ? 'git.exe' : 'git')
@@ -407,6 +390,14 @@ class Gem::TestCase < Test::Unit::TestCase
@orig_bindir = RbConfig::CONFIG["bindir"]
RbConfig::CONFIG["bindir"] = File.join @gemhome, "bin"
+ @orig_sitelibdir = RbConfig::CONFIG["sitelibdir"]
+ new_sitelibdir = @orig_sitelibdir.sub(RbConfig::CONFIG["prefix"], @gemhome)
+ $LOAD_PATH.insert(Gem.load_path_insert_index, new_sitelibdir)
+ RbConfig::CONFIG["sitelibdir"] = new_sitelibdir
+
+ @orig_mandir = RbConfig::CONFIG["mandir"]
+ RbConfig::CONFIG["mandir"] = File.join @gemhome, "share", "man"
+
Gem::Specification.unresolved_deps.clear
Gem.use_paths(@gemhome)
@@ -478,6 +469,8 @@ class Gem::TestCase < Test::Unit::TestCase
Gem.ruby = @orig_ruby if @orig_ruby
+ RbConfig::CONFIG['mandir'] = @orig_mandir
+ RbConfig::CONFIG['sitelibdir'] = @orig_sitelibdir
RbConfig::CONFIG['bindir'] = @orig_bindir
Gem.instance_variable_set :@default_specifications_dir, nil
@@ -487,7 +480,6 @@ class Gem::TestCase < Test::Unit::TestCase
Gem.instance_variable_set :@default_dir, nil
end
- Gem::Specification._clear_load_cache
Gem::Specification.unresolved_deps.clear
Gem::refresh
@@ -693,10 +685,10 @@ class Gem::TestCase < Test::Unit::TestCase
# Load a YAML string, the psych 3 way
def load_yaml(yaml)
- if YAML.respond_to?(:unsafe_load)
- YAML.unsafe_load(yaml)
+ if Psych.respond_to?(:unsafe_load)
+ Psych.unsafe_load(yaml)
else
- YAML.load(yaml)
+ Psych.load(yaml)
end
end
@@ -704,10 +696,10 @@ class Gem::TestCase < Test::Unit::TestCase
# Load a YAML file, the psych 3 way
def load_yaml_file(file)
- if YAML.respond_to?(:unsafe_load_file)
- YAML.unsafe_load_file(file)
+ if Psych.respond_to?(:unsafe_load_file)
+ Psych.unsafe_load_file(file)
else
- YAML.load_file(file)
+ Psych.load_file(file)
end
end
@@ -1082,19 +1074,23 @@ Also, a list:
@fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip
@fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
- v = Gem.marshal_version
-
- all_specs.each do |spec|
- path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
- data = Marshal.dump spec
- data_deflate = Zlib::Deflate.deflate data
- @fetcher.data[path] = data_deflate
- end
+ write_marshalled_gemspecs(*all_specs)
end
nil # force errors
end
+ def write_marshalled_gemspecs(*all_specs)
+ v = Gem.marshal_version
+
+ all_specs.each do |spec|
+ path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
+ data = Marshal.dump spec
+ data_deflate = Zlib::Deflate.deflate data
+ @fetcher.data[path] = data_deflate
+ end
+ end
+
##
# Deflates +data+
@@ -1304,6 +1300,22 @@ Also, a list:
Gem.instance_variable_set :@ruby, orig_ruby
end
+ def with_internal_encoding(encoding)
+ int_enc = Encoding.default_internal
+ silence_warnings { Encoding.default_internal = encoding }
+
+ yield
+ ensure
+ silence_warnings { Encoding.default_internal = int_enc }
+ end
+
+ def silence_warnings
+ old_verbose, $VERBOSE = $VERBOSE, false
+ yield
+ ensure
+ $VERBOSE = old_verbose
+ end
+
class << self
# :nodoc:
##
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 3c95982d4be..cc4772a0c6d 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -354,41 +354,6 @@ class TestGem < Gem::TestCase
assert status.success?, output
end
- def test_activate_bin_path_gives_proper_error_for_bundler
- bundler = util_spec 'bundler', '2' do |s|
- s.executables = ['bundle']
- end
-
- install_specs bundler
-
- File.open("Gemfile.lock", "w") do |f|
- f.write <<-L.gsub(/ {8}/, "")
- GEM
- remote: https://rubygems.org/
- specs:
-
- PLATFORMS
- ruby
-
- DEPENDENCIES
-
- BUNDLED WITH
- 9999
- L
- end
-
- File.open("Gemfile", "w") {|f| f.puts('source "https://rubygems.org"') }
-
- e = assert_raise Gem::GemNotFoundException do
- load Gem.activate_bin_path("bundler", "bundle", ">= 0.a")
- end
-
- assert_includes e.message, "Could not find 'bundler' (9999) required by your #{File.expand_path("Gemfile.lock")}."
- assert_includes e.message, "To update to the latest version installed on your system, run `bundle update --bundler`."
- assert_includes e.message, "To install the missing version, run `gem install bundler:9999`"
- refute_includes e.message, "can't find gem bundler (>= 0.a) with executable bundle"
- end
-
def test_activate_bin_path_selects_exact_bundler_version_if_present
bundler_latest = util_spec 'bundler', '2.0.1' do |s|
s.executables = ['bundle']
@@ -888,6 +853,27 @@ class TestGem < Gem::TestCase
assert_equal gems['a-2'], spec
end
+ def test_self_latest_spec_for_multiple_sources
+ uri = 'https://example.sample.com/'
+ source = Gem::Source.new(uri)
+ source_list = Gem::SourceList.new
+ source_list << Gem::Source.new(@uri)
+ source_list << source
+ Gem.sources.replace source_list
+
+ spec_fetcher(uri) do |fetcher|
+ fetcher.spec 'a', 1.1
+ end
+
+ gems = spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', '3.a'
+ fetcher.spec 'a', 2
+ end
+ spec = Gem.latest_spec_for 'a'
+ assert_equal gems['a-2'], spec
+ end
+
def test_self_latest_rubygems_version
spec_fetcher do |fetcher|
fetcher.spec 'rubygems-update', '1.8.23'
@@ -912,6 +898,29 @@ class TestGem < Gem::TestCase
assert_equal Gem::Version.new(2), version
end
+ def test_self_latest_version_for_multiple_sources
+ uri = 'https://example.sample.com/'
+ source = Gem::Source.new(uri)
+ source_list = Gem::SourceList.new
+ source_list << Gem::Source.new(@uri)
+ source_list << source
+ Gem.sources.replace source_list
+
+ spec_fetcher(uri) do |fetcher|
+ fetcher.spec 'a', 1.1
+ end
+
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 2
+ fetcher.spec 'a', '3.a'
+ end
+
+ version = Gem.latest_version_for 'a'
+
+ assert_equal Gem::Version.new(2), version
+ end
+
def test_self_loaded_specs
foo = util_spec 'foo'
install_gem foo
@@ -2013,6 +2022,8 @@ You may need to `bundle install` to install missing gems
ENV['SOURCE_DATE_EPOCH'] = old_epoch
end
+ private
+
def ruby_install_name(name)
with_clean_path_to_ruby do
orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name']
diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb
index e971e6ae29a..7494a94d6e8 100644
--- a/test/rubygems/test_gem_bundler_version_finder.rb
+++ b/test/rubygems/test_gem_bundler_version_finder.rb
@@ -48,30 +48,31 @@ class TestGemBundlerVersionFinder < Gem::TestCase
end
def test_bundler_version_with_lockfile
- bvf.stub(:lockfile_contents, [nil, ""]) do
+ bvf.stub(:lockfile_contents, "") do
assert_nil bvf.bundler_version
end
- bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do
+ bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do
assert_equal v("1.1.1.1"), bvf.bundler_version
end
- bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n"]) do
+ bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n") do
assert_nil bvf.bundler_version
end
end
- def test_bundler_version_with_reason
- assert_nil bvf.bundler_version_with_reason
- bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do
- assert_equal ["1.1.1.1", "your lockfile"], bvf.bundler_version_with_reason
+ def test_bundler_version
+ assert_nil bvf.bundler_version
+ bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do
+ assert_equal "1.1.1.1", bvf.bundler_version.to_s
$0 = "bundle"
ARGV.replace %w[update --bundler]
- assert_nil bvf.bundler_version_with_reason
+ assert_nil bvf.bundler_version
+
ARGV.replace %w[update --bundler=1.1.1.2]
- assert_equal ["1.1.1.2", "`bundle update --bundler`"], bvf.bundler_version_with_reason
+ assert_equal "1.1.1.2", bvf.bundler_version.to_s
ENV["BUNDLER_VERSION"] = "1.1.1.3"
- assert_equal ["1.1.1.3", "`$BUNDLER_VERSION`"], bvf.bundler_version_with_reason
+ assert_equal "1.1.1.3", bvf.bundler_version.to_s
end
end
@@ -90,57 +91,35 @@ class TestGemBundlerVersionFinder < Gem::TestCase
Dir.chdir(orig_dir)
end
- assert_nil bvf.bundler_version_with_reason
- end
-
- def test_compatible
- assert bvf.compatible?(util_spec("foo"))
- assert bvf.compatible?(util_spec("bundler", 1.1))
-
- bvf.stub(:bundler_version, v("1.1.1.1")) do
- assert bvf.compatible?(util_spec("foo"))
- assert bvf.compatible?(util_spec("bundler", "1.1.1.1"))
- assert bvf.compatible?(util_spec("bundler", "1.1.1.a"))
- assert bvf.compatible?(util_spec("bundler", "1.999"))
- refute bvf.compatible?(util_spec("bundler", "2.999"))
- end
-
- bvf.stub(:bundler_version, v("2.1.1.1")) do
- assert bvf.compatible?(util_spec("foo"))
- assert bvf.compatible?(util_spec("bundler", "2.1.1.1"))
- assert bvf.compatible?(util_spec("bundler", "2.1.1.a"))
- assert bvf.compatible?(util_spec("bundler", "2.999"))
- refute bvf.compatible?(util_spec("bundler", "1.999"))
- refute bvf.compatible?(util_spec("bundler", "3.0.0"))
- end
+ assert_nil bvf.bundler_version
end
- def test_filter
+ def test_prioritize
versions = %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1]
specs = versions.map {|v| util_spec("bundler", v) }
- assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
bvf.stub(:bundler_version, v("2.1.1.1")) do
- assert_equal %w[2 2.a 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
end
bvf.stub(:bundler_version, v("1.1.1.1")) do
- assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
end
bvf.stub(:bundler_version, v("1")) do
- assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
end
bvf.stub(:bundler_version, v("2.a")) do
- assert_equal %w[2.a 2 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[2.a 1 1.0 1.0.1.1 2 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
end
bvf.stub(:bundler_version, v("3")) do
- assert_equal %w[3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
+ assert_equal %w[3 1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3.a 3.0 3.1.1], util_prioritize_specs(specs)
end
end
- def util_filter_specs(specs)
+ def util_prioritize_specs(specs)
specs = specs.dup
- bvf.filter!(specs)
- specs
+ bvf.prioritize!(specs)
+ specs.map(&:version).map(&:to_s)
end
end
diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb
index 43ce6ea39f5..65b9b040b77 100644
--- a/test/rubygems/test_gem_command.rb
+++ b/test/rubygems/test_gem_command.rb
@@ -118,7 +118,7 @@ class TestGemCommand < Gem::TestCase
use_ui @ui do
@cmd.when_invoked { true }
- ex = assert_raise OptionParser::InvalidOption do
+ ex = assert_raise Gem::OptionParser::InvalidOption do
@cmd.invoke('-zzz')
end
diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb
index f6a82908b33..ff1f955c6c5 100644
--- a/test/rubygems/test_gem_command_manager.rb
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -36,6 +36,18 @@ class TestGemCommandManager < Gem::TestCase
assert_kind_of Gem::Commands::InstallCommand, command
end
+ def test_find_login_alias_command
+ command = @command_manager.find_command 'login'
+
+ assert_kind_of Gem::Commands::SigninCommand, command
+ end
+
+ def test_find_logout_alias_comamnd
+ command = @command_manager.find_command 'logout'
+
+ assert_kind_of Gem::Commands::SignoutCommand, command
+ end
+
def test_find_command_ambiguous_exact
ins_command = Class.new
Gem::Commands.send :const_set, :InsCommand, ins_command
@@ -240,7 +252,7 @@ class TestGemCommandManager < Gem::TestCase
Gem::Deprecate.skip_during do
@command_manager.process_args %w[query]
end
- assert_equal(//, check_options[:name])
+ assert_nil(check_options[:name])
assert_equal :local, check_options[:domain]
assert_equal false, check_options[:details]
diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb
index 077be11d55e..901bf5aed62 100644
--- a/test/rubygems/test_gem_commands_cert_command.rb
+++ b/test/rubygems/test_gem_commands_cert_command.rb
@@ -745,7 +745,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
def test_handle_options_add_bad
nonexistent = File.join @tempdir, 'nonexistent'
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--add #{nonexistent}]
end
@@ -755,7 +755,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
bad = File.join @tempdir, 'bad'
FileUtils.touch bad
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--add #{bad}]
end
@@ -765,7 +765,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
def test_handle_options_certificate
nonexistent = File.join @tempdir, 'nonexistent'
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--certificate #{nonexistent}]
end
@@ -775,7 +775,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
bad = File.join @tempdir, 'bad'
FileUtils.touch bad
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--certificate #{bad}]
end
@@ -786,7 +786,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
def test_handle_options_key_bad
nonexistent = File.join @tempdir, 'nonexistent'
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--private-key #{nonexistent}]
end
@@ -797,14 +797,14 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
bad = File.join @tempdir, 'bad'
FileUtils.touch bad
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--private-key #{bad}]
end
assert_equal "invalid argument: --private-key #{bad}: invalid RSA, DSA, or EC key",
e.message
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[--private-key #{PUBLIC_KEY_FILE}]
end
@@ -851,7 +851,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
def test_handle_options_sign_nonexistent
nonexistent = File.join @tempdir, 'nonexistent'
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %W[
--private-key #{ALTERNATE_KEY_FILE}
diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb
index 35ee00f7638..7d4c77afaa3 100644
--- a/test/rubygems/test_gem_commands_fetch_command.rb
+++ b/test/rubygems/test_gem_commands_fetch_command.rb
@@ -79,6 +79,42 @@ class TestGemCommandsFetchCommand < Gem::TestCase
"#{a2.full_name} not fetched")
end
+ def test_execute_platform
+ a2_spec, a2 = util_gem("a", "2")
+
+ a2_universal_darwin_spec, a2_universal_darwin = util_gem("a", "2") do |s|
+ s.platform = 'universal-darwin'
+ end
+
+ Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
+
+ write_marshalled_gemspecs(a2_spec, a2_universal_darwin_spec)
+
+ @cmd.options[:args] = %w[a]
+
+ @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = util_gzip(Marshal.dump([
+ Gem::NameTuple.new(a2_spec.name, a2_spec.version, a2_spec.platform),
+ Gem::NameTuple.new(a2_universal_darwin_spec.name, a2_universal_darwin_spec.version, a2_universal_darwin_spec.platform),
+ ]))
+
+ @fetcher.data["#{@gem_repo}gems/#{a2_spec.file_name}"] = Gem.read_binary(a2)
+ FileUtils.cp a2, a2_spec.cache_file
+
+ @fetcher.data["#{@gem_repo}gems/#{a2_universal_darwin_spec.file_name}"] = Gem.read_binary(a2_universal_darwin)
+ FileUtils.cp a2_universal_darwin, a2_universal_darwin_spec.cache_file
+
+ util_set_arch 'arm64-darwin20' do
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+ end
+
+ assert_path_exist(File.join(@tempdir, a2_universal_darwin_spec.file_name),
+ "#{a2_universal_darwin_spec.full_name} not fetched")
+ end
+
def test_execute_specific_prerelease
specs = spec_fetcher do |fetcher|
fetcher.gem 'a', 2
@@ -121,4 +157,101 @@ class TestGemCommandsFetchCommand < Gem::TestCase
assert_path_exist(File.join(@tempdir, a1.file_name),
"#{a1.full_name} not fetched")
end
+
+ def test_execute_version_specified_by_colon
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ end
+
+ @cmd.options[:args] = %w[a:1]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a1 = specs['a-1']
+
+ assert_path_exist(File.join(@tempdir, a1.file_name),
+ "#{a1.full_name} not fetched")
+ end
+
+ def test_execute_two_version
+ @cmd.options[:args] = %w[a b]
+ @cmd.options[:version] = Gem::Requirement.new '1'
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::TermError, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ msg = "ERROR: Can't use --version with multiple gems. You can specify multiple gems with" \
+ " version requirements using `gem fetch 'my_gem:1.0.0' 'my_other_gem:~>2.0.0'`"
+
+ assert_empty @ui.output
+ assert_equal msg, @ui.error.chomp
+ end
+
+ def test_execute_two_version_specified_by_colon
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'b', 1
+ end
+
+ @cmd.options[:args] = %w[a:1 b:1]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a1 = specs['a-1']
+ b1 = specs['b-1']
+
+ assert_path_exist(File.join(@tempdir, a1.file_name),
+ "#{a1.full_name} not fetched")
+ assert_path_exist(File.join(@tempdir, b1.file_name),
+ "#{b1.full_name} not fetched")
+ end
+
+ def test_execute_version_nonexistent
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', 1
+ end
+
+ @cmd.options[:args] = %w[foo:2]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'foo' (2) in any repository
+ERROR: Possible alternatives: foo
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_nonexistent_hint_disabled
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', 1
+ end
+
+ @cmd.options[:args] = %w[foo:2]
+ @cmd.options[:suggest_alternate] = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'foo' (2) in any repository
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
end
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
index 535180983b1..47a97dae4be 100644
--- a/test/rubygems/test_gem_commands_install_command.rb
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -277,6 +277,22 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a
assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error)
end
+ def test_execute_nonexistent_force
+ spec_fetcher
+
+ @cmd.options[:args] = %w[nonexistent]
+ @cmd.options[:force] = true
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error)
+ end
+
def test_execute_dependency_nonexistent
spec_fetcher do |fetcher|
fetcher.spec 'foo', 2, 'bar' => '0.5'
@@ -782,6 +798,39 @@ ERROR: Possible alternatives: non_existent_with_hint
assert_match "1 gem installed", @ui.output
end
+ def test_execute_remote_truncates_existing_gemspecs
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ end
+
+ @cmd.options[:domain] = :remote
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_match "1 gem installed", @ui.output
+
+ a1_gemspec = File.join(@gemhome, 'specifications', "a-1.gemspec")
+
+ initial_a1_gemspec_content = File.read(a1_gemspec)
+ modified_a1_gemspec_content = initial_a1_gemspec_content + "\n # AAAAAAA\n"
+ File.write(a1_gemspec, modified_a1_gemspec_content)
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal initial_a1_gemspec_content, File.read(a1_gemspec)
+ end
+
def test_execute_remote_ignores_files
specs = spec_fetcher do |fetcher|
fetcher.gem 'a', 1
diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb
index 2d62149cc43..29cff1ed974 100644
--- a/test/rubygems/test_gem_commands_open_command.rb
+++ b/test/rubygems/test_gem_commands_open_command.rb
@@ -21,7 +21,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
def test_execute
@cmd.options[:args] = %w[foo]
- @cmd.options[:editor] = "#{Gem.ruby} -eexit --"
+ @cmd.options[:editor] = "#{ruby_with_rubygems_in_load_path} -eexit --"
gem 'foo', '1.0.0'
spec = gem 'foo', '1.0.1'
diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb
index 09cec63c155..96c328f93fa 100644
--- a/test/rubygems/test_gem_commands_server_command.rb
+++ b/test/rubygems/test_gem_commands_server_command.rb
@@ -9,53 +9,11 @@ class TestGemCommandsServerCommand < Gem::TestCase
@cmd = Gem::Commands::ServerCommand.new
end
- def test_handle_options
- @cmd.send :handle_options, %w[-p 8808 --no-daemon]
-
- assert_equal false, @cmd.options[:daemon]
- assert_equal [], @cmd.options[:gemdir]
- assert_equal 8808, @cmd.options[:port]
-
- @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon]
-
- assert_equal true, @cmd.options[:daemon]
- assert_equal [File.expand_path('/nonexistent')], @cmd.options[:gemdir]
- assert_equal 9999, @cmd.options[:port]
- end
-
- def test_handle_options_gemdir
- @cmd.send :handle_options, %w[--dir a --dir b]
-
- assert_equal [File.expand_path('a'), File.expand_path('b')],
- @cmd.options[:gemdir]
- end
-
- def test_handle_options_port
- @cmd.send :handle_options, %w[-p 0]
- assert_equal 0, @cmd.options[:port]
-
- @cmd.send :handle_options, %w[-p 65535]
- assert_equal 65535, @cmd.options[:port]
-
- begin
- @cmd.send :handle_options, %w[-p discard]
- assert_equal 9, @cmd.options[:port]
- rescue OptionParser::InvalidArgument
- # for container environment on GitHub Actions
- end
-
- e = assert_raise OptionParser::InvalidArgument do
- @cmd.send :handle_options, %w[-p nonexistent]
- end
-
- assert_equal 'invalid argument: -p nonexistent: no such named service',
- e.message
-
- e = assert_raise OptionParser::InvalidArgument do
- @cmd.send :handle_options, %w[-p 65536]
+ def test_execute
+ use_ui @ui do
+ @cmd.execute
end
- assert_equal 'invalid argument: -p 65536: not a port number',
- e.message
+ assert_match %r{Install the rubygems-server}i, @ui.error
end
end
diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb
index 3aa6bfa2fe5..5cf94a1dc99 100644
--- a/test/rubygems/test_gem_commands_setup_command.rb
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -14,9 +14,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
def setup
super
- @install_dir = File.join @tempdir, 'install'
@cmd = Gem::Commands::SetupCommand.new
- @cmd.options[:prefix] = @install_dir
filelist = %w[
bin/gem
@@ -158,6 +156,21 @@ class TestGemCommandsSetupCommand < Gem::TestCase
assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_bin_path)
end
+ def test_destdir_flag_does_not_try_to_write_to_the_default_gem_home
+ FileUtils.chmod "-w", File.join(@gemhome, "plugins")
+
+ destdir = File.join(@tempdir, 'foo')
+
+ @cmd.options[:destdir] = destdir
+ @cmd.execute
+
+ spec = Gem::Specification.load("bundler/bundler.gemspec")
+
+ spec.executables.each do |e|
+ assert_path_exist File.join destdir, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'gems', spec.full_name, spec.bindir, e
+ end
+ end
+
def test_files_in
assert_equal %w[rubygems.rb rubygems/requirement.rb rubygems/ssl_certs/rubygems.org/foo.pem],
@cmd.files_in('lib').sort
@@ -227,27 +240,62 @@ class TestGemCommandsSetupCommand < Gem::TestCase
f.puts 'echo "hello"'
end
- bindir(bin_dir) do
- @cmd.options[:force] = true
+ @cmd.options[:force] = true
- @cmd.install_default_bundler_gem bin_dir
-
- bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
- default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
- spec = Gem::Specification.load(default_spec_path)
+ @cmd.install_default_bundler_gem bin_dir
- spec.executables.each do |e|
- if Gem.win_platform?
- assert_path_exist File.join(bin_dir, "#{e}.bat")
- end
+ bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
+ default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
+ spec = Gem::Specification.load(default_spec_path)
- assert_path_exist File.join bin_dir, e
+ spec.executables.each do |e|
+ if Gem.win_platform?
+ assert_path_exist File.join(bin_dir, "#{e}.bat")
end
+
+ assert_path_exist File.join bin_dir, e
+ end
+ end
+
+ def test_install_default_bundler_gem_with_destdir_flag
+ @cmd.extend FileUtils
+
+ FileUtils.chmod "-w", @gemhome
+
+ destdir = File.join(@tempdir, 'foo')
+ bin_dir = File.join(destdir, 'bin')
+
+ @cmd.options[:destdir] = destdir
+
+ @cmd.install_default_bundler_gem bin_dir
+
+ spec = Gem::Specification.load("bundler/bundler.gemspec")
+
+ spec.executables.each do |e|
+ assert_path_exist File.join destdir, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'gems', spec.full_name, spec.bindir, e
+ end
+ end
+
+ def test_install_default_bundler_gem_with_destdir_and_prefix_flags
+ @cmd.extend FileUtils
+
+ destdir = File.join(@tempdir, 'foo')
+ bin_dir = File.join(destdir, 'bin')
+
+ @cmd.options[:destdir] = destdir
+ @cmd.options[:prefix] = "/"
+
+ @cmd.install_default_bundler_gem bin_dir
+
+ spec = Gem::Specification.load("bundler/bundler.gemspec")
+
+ spec.executables.each do |e|
+ assert_path_exist File.join destdir, 'gems', spec.full_name, spec.bindir, e
end
end
def test_remove_old_lib_files
- lib = File.join @install_dir, 'lib'
+ lib = RbConfig::CONFIG["sitelibdir"]
lib_rubygems = File.join lib, 'rubygems'
lib_bundler = File.join lib, 'bundler'
lib_rubygems_defaults = File.join lib_rubygems, 'defaults'
@@ -278,7 +326,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
def test_remove_old_man_files
- man = File.join @install_dir, 'man'
+ man = File.join RbConfig::CONFIG['mandir'], 'man'
ruby_1 = File.join man, 'man1', 'ruby.1'
bundle_b_1 = File.join man, 'man1', 'bundle-b.1'
@@ -384,14 +432,14 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
def default_gem_bin_path
- File.join @install_dir, 'bin', 'gem'
+ File.join RbConfig::CONFIG['bindir'], 'gem'
end
def default_bundle_bin_path
- File.join @install_dir, 'bin', 'bundle'
+ File.join RbConfig::CONFIG['bindir'], 'bundle'
end
def default_bundler_bin_path
- File.join @install_dir, 'bin', 'bundler'
+ File.join RbConfig::CONFIG['bindir'], 'bundler'
end
end unless Gem.java_platform?
diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb
index eaf32886b34..0f856a53ba4 100644
--- a/test/rubygems/test_gem_commands_signin_command.rb
+++ b/test/rubygems/test_gem_commands_signin_command.rb
@@ -80,7 +80,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_excute_with_key_name_and_scope
+ def test_execute_with_key_name_and_scope
email = 'you@example.com'
password = 'secret'
api_key = '1234'
diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb
index 55f1049266b..5bd2c40d593 100644
--- a/test/rubygems/test_gem_commands_uninstall_command.rb
+++ b/test/rubygems/test_gem_commands_uninstall_command.rb
@@ -436,7 +436,7 @@ WARNING: Use your OS package manager to uninstall vendor gems
def test_handle_options_vendor_missing
vendordir(nil) do
- e = assert_raise OptionParser::InvalidOption do
+ e = assert_raise Gem::OptionParser::InvalidOption do
@cmd.handle_options %w[--vendor]
end
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
index e9264f6d148..c765e9a8df0 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -106,6 +106,31 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out
end
+ def test_execute_system_when_latest_does_not_support_your_ruby
+ spec_fetcher do |fetcher|
+ fetcher.download 'rubygems-update', 9 do |s|
+ s.files = %w[setup.rb]
+ s.required_ruby_version = '> 9'
+ end
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_empty out
+
+ err = @ui.error.split "\n"
+ assert_equal "ERROR: Error installing rubygems-update:", err.shift
+ assert_equal "\trubygems-update-9 requires Ruby version > 9. The current ruby version is #{Gem.ruby_version}.", err.shift
+ assert_empty err
+ end
+
def test_execute_system_multiple
spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 8 do |s|
@@ -132,6 +157,40 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out
end
+ def test_execute_system_update_installed
+ spec_fetcher do |fetcher|
+ fetcher.download 'rubygems-update', 8 do |s|
+ s.files = %w[setup.rb]
+ end
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ @cmd.execute
+
+ spec_fetcher do |fetcher|
+ fetcher.download 'rubygems-update', 9 do |s|
+ s.files = %w[setup.rb]
+ end
+ end
+
+ @cmd = Gem::Commands::UpdateCommand.new
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Installing RubyGems 9", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
def test_execute_system_specific
spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 8 do |s|
diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb
index 3b0956e1c41..b798eb3689e 100644
--- a/test/rubygems/test_gem_commands_yank_command.rb
+++ b/test/rubygems/test_gem_commands_yank_command.rb
@@ -35,7 +35,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
def test_handle_options_missing_argument
%w[-v --version -p --platform].each do |option|
- assert_raise OptionParser::MissingArgument do
+ assert_raise Gem::OptionParser::MissingArgument do
@cmd.handle_options %W[a #{option}]
end
end
diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb
index 1ca0fc378ce..5551966da24 100644
--- a/test/rubygems/test_gem_dependency.rb
+++ b/test/rubygems/test_gem_dependency.rb
@@ -358,16 +358,12 @@ class TestGemDependency < Gem::TestCase
assert_equal [b, b_1], dep.to_specs
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["3.5", "reason"]) do
- e = assert_raise Gem::MissingSpecVersionError do
- dep.to_specs
- end
-
- assert_match "Could not find 'bundler' (3.5) required by reason.\nTo update to the latest version installed on your system, run `bundle update --bundler`.\nTo install the missing version, run `gem install bundler:3.5`\n", e.message
+ Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do
+ assert_equal [b_1, b], dep.to_specs
end
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["2.0.0.pre.1", "reason"]) do
- assert_equal [b], dep.to_specs
+ Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("2.0.0.pre.1")) do
+ assert_equal [b, b_1], dep.to_specs
end
end
diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb
index 70833f35cfc..10a544cbbc4 100644
--- a/test/rubygems/test_gem_ext_ext_conf_builder.rb
+++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb
@@ -66,8 +66,11 @@ class TestGemExtExtConfBuilder < Gem::TestCase
end
end
- def test_class_build_env_make
- env_make = ENV.delete 'MAKE'
+ def test_class_build_env_MAKE
+ env_make = ENV.delete 'make'
+ ENV['make'] = nil
+
+ env_MAKE = ENV.delete 'MAKE'
ENV['MAKE'] = 'anothermake'
if java_platform?
@@ -89,7 +92,8 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_contains_make_command 'clean', output[4]
end
ensure
- ENV['MAKE'] = env_make
+ ENV['MAKE'] = env_MAKE
+ ENV['make'] = env_make
end
def test_class_build_extconf_fail
diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb
index 33cb5c08bfd..a499c2be3be 100644
--- a/test/rubygems/test_gem_install_update_options.rb
+++ b/test/rubygems/test_gem_install_update_options.rb
@@ -104,7 +104,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
@cmd.add_install_update_options
- e = assert_raise OptionParser::InvalidArgument do
+ e = assert_raise Gem::OptionParser::InvalidArgument do
@cmd.handle_options %w[-P UnknownSecurity]
end
assert_includes e.message, "UnknownSecurity"
@@ -169,7 +169,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
def test_vendor_missing
vendordir(nil) do
- e = assert_raise OptionParser::InvalidOption do
+ e = assert_raise Gem::OptionParser::InvalidOption do
@cmd.handle_options %w[--vendor]
end
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index 988f14146d7..c90fdab283a 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -18,11 +18,12 @@ class TestGemInstaller < Gem::InstallerTestCase
end
def test_app_script_text
- installer = setup_base_installer
+ load_relative "no" do
+ installer = setup_base_installer
- util_make_exec @spec, ''
+ util_make_exec @spec, ''
- expected = <<-EOF
+ expected = <<-EOF
#!#{Gem.ruby}
#
# This file was generated by RubyGems.
@@ -52,10 +53,11 @@ else
gem "a", version
load Gem.bin_path("a", "executable", version)
end
- EOF
+ EOF
- wrapper = installer.app_script_text 'executable'
- assert_equal expected, wrapper
+ wrapper = installer.app_script_text 'executable'
+ assert_equal expected, wrapper
+ end
end
def test_check_executable_overwrite
@@ -724,17 +726,19 @@ gem 'other', version
def test_generate_bin_uses_default_shebang
pend "Symlinks not supported or not enabled" unless symlink_supported?
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- installer.wrappers = true
- util_make_exec
+ installer.wrappers = true
+ util_make_exec
- installer.generate_bin
+ installer.generate_bin
- default_shebang = Gem.ruby
- shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
- assert_match(/\A#!/, shebang_line)
- assert_match(/#{default_shebang}/, shebang_line)
+ default_shebang = Gem.ruby
+ shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
+ assert_match(/\A#!/, shebang_line)
+ assert_match(/#{default_shebang}/, shebang_line)
+ end
end
def test_generate_bin_with_dangling_symlink
@@ -948,7 +952,6 @@ gem 'other', version
Gem.pre_install do
assert_path_not_exist cache_file, 'cache file must not exist yet'
- assert_path_not_exist spec_file, 'spec file must not exist yet'
true
end
@@ -956,13 +959,11 @@ gem 'other', version
assert_path_exist gemdir, 'gem install dir must exist'
assert_path_exist rakefile, 'gem executable must exist'
assert_path_not_exist stub_exe, 'gem executable must not exist'
- assert_path_not_exist spec_file, 'spec file must not exist yet'
true
end
Gem.post_install do
assert_path_exist cache_file, 'cache file must exist'
- assert_path_exist spec_file, 'spec file must exist'
end
@newspec = nil
@@ -1237,7 +1238,11 @@ gem 'other', version
end
def test_install_post_build_false
- installer = setup_base_installer
+ @spec = util_spec 'a'
+
+ util_build_gem @spec
+
+ installer = util_installer @spec, @gemhome
Gem.post_build do
false
@@ -1279,7 +1284,11 @@ gem 'other', version
end
def test_install_pre_install_false
- installer = setup_base_installer
+ @spec = util_spec 'a'
+
+ util_build_gem @spec
+
+ installer = util_installer @spec, @gemhome
Gem.pre_install do
false
@@ -1799,13 +1808,15 @@ gem 'other', version
end
def test_shebang
- installer = setup_base_installer
+ load_relative "no" do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/ruby"
+ util_make_exec @spec, "#!/usr/bin/ruby"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_process_options
@@ -1839,42 +1850,80 @@ gem 'other', version
end
def test_shebang_arguments
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/ruby -ws"
+ util_make_exec @spec, "#!/usr/bin/ruby -ws"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+ end
- assert_equal "#!#{Gem.ruby} -ws", shebang
+ def test_shebang_arguments_with_load_relative
+ load_relative 'yes' do
+ installer = setup_base_installer
+
+ util_make_exec @spec, "#!/usr/bin/ruby -ws"
+
+ shebang = installer.shebang 'executable'
+
+ shebang_lines = shebang.split "\n"
+
+ assert_equal "#!/bin/sh", shebang_lines.shift
+ assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
+ end
end
def test_shebang_empty
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, ''
+ util_make_exec @spec, ''
- shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ shebang = installer.shebang 'executable'
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_shebang_env
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/env ruby"
+ util_make_exec @spec, "#!/usr/bin/env ruby"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_shebang_env_arguments
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/env ruby -ws"
+ util_make_exec @spec, "#!/usr/bin/env ruby -ws"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby} -ws", shebang
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+ end
+
+ def test_shebang_env_arguments_with_load_relative
+ load_relative 'yes' do
+ installer = setup_base_installer
+
+ util_make_exec @spec, "#!/usr/bin/env ruby -ws"
+
+ shebang = installer.shebang 'executable'
+
+ shebang_lines = shebang.split "\n"
+
+ assert_equal "#!/bin/sh", shebang_lines.shift
+ assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
+ end
end
def test_shebang_env_shebang
@@ -1892,63 +1941,120 @@ gem 'other', version
end
def test_shebang_nested
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/opt/local/ruby/bin/ruby"
+ util_make_exec @spec, "#!/opt/local/ruby/bin/ruby"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_shebang_nested_arguments
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
+ util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+ end
- assert_equal "#!#{Gem.ruby} -ws", shebang
+ def test_shebang_nested_arguments_with_load_relative
+ load_relative 'yes' do
+ installer = setup_base_installer
+
+ util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
+
+ shebang = installer.shebang 'executable'
+
+ shebang_lines = shebang.split "\n"
+
+ assert_equal "#!/bin/sh", shebang_lines.shift
+ assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
+ end
end
def test_shebang_version
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/ruby18"
+ util_make_exec @spec, "#!/usr/bin/ruby18"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_shebang_version_arguments
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
+ util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+ end
+
+ def test_shebang_version_arguments_with_load_relative
+ load_relative 'yes' do
+ installer = setup_base_installer
+
+ util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
- assert_equal "#!#{Gem.ruby} -ws", shebang
+ shebang = installer.shebang 'executable'
+
+ shebang_lines = shebang.split "\n"
+
+ assert_equal "#!/bin/sh", shebang_lines.shift
+ assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
+ end
end
def test_shebang_version_env
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/env ruby18"
+ util_make_exec @spec, "#!/usr/bin/env ruby18"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
- assert_equal "#!#{Gem.ruby}", shebang
+ assert_equal "#!#{Gem.ruby}", shebang
+ end
end
def test_shebang_version_env_arguments
- installer = setup_base_installer
+ load_relative 'no' do
+ installer = setup_base_installer
- util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
+ util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
- shebang = installer.shebang 'executable'
+ shebang = installer.shebang 'executable'
+
+ assert_equal "#!#{Gem.ruby} -ws", shebang
+ end
+ end
+
+ def test_shebang_version_env_arguments_with_load_relative
+ load_relative 'yes' do
+ installer = setup_base_installer
+
+ util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
+
+ shebang = installer.shebang 'executable'
+
+ shebang_lines = shebang.split "\n"
- assert_equal "#!#{Gem.ruby} -ws", shebang
+ assert_equal "#!/bin/sh", shebang_lines.shift
+ assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
+ end
end
def test_shebang_custom
@@ -2254,6 +2360,8 @@ gem 'other', version
assert_kind_of(String, installer.gem)
end
+ private
+
def util_execless
@spec = util_spec 'z'
util_build_gem @spec
@@ -2276,4 +2384,13 @@ gem 'other', version
def mask
0100755
end
+
+ def load_relative(value)
+ orig_LIBRUBY_RELATIVE = RbConfig::CONFIG['LIBRUBY_RELATIVE']
+ RbConfig::CONFIG['LIBRUBY_RELATIVE'] = value
+
+ yield
+ ensure
+ RbConfig::CONFIG['LIBRUBY_RELATIVE'] = orig_LIBRUBY_RELATIVE
+ end
end
diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb
index 48dcbee9f1f..9172b7eef58 100644
--- a/test/rubygems/test_gem_package.rb
+++ b/test/rubygems/test_gem_package.rb
@@ -822,7 +822,7 @@ class TestGemPackage < Gem::Package::TarTestCase
}
tar.add_file 'checksums.yaml.gz', 0444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
- gz_io.write YAML.dump bogus_checksums
+ gz_io.write Psych.dump bogus_checksums
end
end
end
@@ -868,7 +868,7 @@ class TestGemPackage < Gem::Package::TarTestCase
tar.add_file 'checksums.yaml.gz', 0444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
- gz_io.write YAML.dump checksums
+ gz_io.write Psych.dump checksums
end
end
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index 5ce420b91a8..3ce9be7c90a 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -173,6 +173,21 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert_equal 'hello', File.read(path)
end
+ def test_cache_update_path_with_utf8_internal_encoding
+ with_internal_encoding('UTF-8') do
+ uri = URI 'http://example/file'
+ path = File.join @tempdir, 'file'
+ data = String.new("\xC8").force_encoding(Encoding::BINARY)
+
+ fetcher = util_fuck_with_fetcher data
+
+ written_data = fetcher.cache_update_path uri, path
+
+ assert_equal data, written_data
+ assert_equal data, File.binread(path)
+ end
+ end
+
def test_cache_update_path_no_update
uri = URI 'http://example/file'
path = File.join @tempdir, 'file'
diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb
index 66477be7bc0..47654f6fa41 100644
--- a/test/rubygems/test_gem_request.rb
+++ b/test/rubygems/test_gem_request.rb
@@ -354,30 +354,36 @@ class TestGemRequest < Gem::TestCase
def test_verify_certificate
pend if Gem.java_platform?
+
+ error_number = OpenSSL::X509::V_ERR_OUT_OF_MEM
+
store = OpenSSL::X509::Store.new
context = OpenSSL::X509::StoreContext.new store
- context.error = OpenSSL::X509::V_ERR_OUT_OF_MEM
+ context.error = error_number
use_ui @ui do
Gem::Request.verify_certificate context
end
- assert_equal "ERROR: SSL verification error at depth 0: out of memory (17)\n",
+ assert_equal "ERROR: SSL verification error at depth 0: out of memory (#{error_number})\n",
@ui.error
end
def test_verify_certificate_extra_message
pend if Gem.java_platform?
+
+ error_number = OpenSSL::X509::V_ERR_INVALID_CA
+
store = OpenSSL::X509::Store.new
context = OpenSSL::X509::StoreContext.new store
- context.error = OpenSSL::X509::V_ERR_INVALID_CA
+ context.error = error_number
use_ui @ui do
Gem::Request.verify_certificate context
end
expected = <<-ERROR
-ERROR: SSL verification error at depth 0: invalid CA certificate (24)
+ERROR: SSL verification error at depth 0: invalid CA certificate (#{error_number})
ERROR: Certificate is an invalid CA certificate
ERROR
diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb
index eb798ad557a..ea9f9049ceb 100644
--- a/test/rubygems/test_gem_resolver.rb
+++ b/test/rubygems/test_gem_resolver.rb
@@ -266,14 +266,14 @@ class TestGemResolver < Gem::TestCase
res = Gem::Resolver.new [a_dep], Gem::Resolver::IndexSet.new
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
res.resolve
end
refute_empty e.errors
end
- def test_no_overlap_specificly
+ def test_no_overlap_specifically
a = util_spec "a", '1'
b = util_spec "b", "1"
@@ -469,7 +469,7 @@ class TestGemResolver < Gem::TestCase
r = Gem::Resolver.new([ad], set)
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
r.resolve
end
@@ -486,7 +486,7 @@ class TestGemResolver < Gem::TestCase
r = Gem::Resolver.new([ad], set(a1))
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
r.resolve
end
@@ -499,7 +499,7 @@ class TestGemResolver < Gem::TestCase
r = Gem::Resolver.new([ad], set(a1))
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
r.resolve
end
@@ -516,7 +516,7 @@ class TestGemResolver < Gem::TestCase
r = Gem::Resolver.new([ad], set(a1))
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
r.resolve
end
@@ -781,7 +781,7 @@ class TestGemResolver < Gem::TestCase
r = Gem::Resolver.new([ad], set(a1))
- e = assert_raise Gem::UnsatisfiableDepedencyError do
+ e = assert_raise Gem::UnsatisfiableDependencyError do
r.resolve
end
diff --git a/test/rubygems/test_gem_security.rb b/test/rubygems/test_gem_security.rb
index d04bd4a8bd8..415ec2b5f64 100644
--- a/test/rubygems/test_gem_security.rb
+++ b/test/rubygems/test_gem_security.rb
@@ -196,7 +196,7 @@ class TestGemSecurity < Gem::TestCase
def test_class_sign
issuer = PUBLIC_CERT.subject
- signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example"
+ signee = OpenSSL::X509::Name.new([["CN", "signee"], ["DC", "example"]])
key = PRIVATE_KEY
cert = OpenSSL::X509::Certificate.new
diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb
deleted file mode 100644
index f6aa99fb02e..00000000000
--- a/test/rubygems/test_gem_server.rb
+++ /dev/null
@@ -1,608 +0,0 @@
-# frozen_string_literal: true
-require_relative 'helper'
-require 'rubygems/server'
-require 'stringio'
-
-class Gem::Server
- attr_reader :server
-end
-
-class TestGemServer < Gem::TestCase
- def process_based_port
- 0
- end
-
- def setup
- super
-
- @a1 = quick_gem 'a', '1'
- @a2 = quick_gem 'a', '2'
- @a3_p = quick_gem 'a', '3.a'
-
- @server = Gem::Server.new Gem.dir, process_based_port, false
- @req = WEBrick::HTTPRequest.new :Logger => nil
- @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
- end
-
- def test_doc_root_3
- orig_rdoc_version = Gem::RDoc.rdoc_version
- Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12')
-
- assert_equal '/doc_root/X-1/rdoc/index.html', @server.doc_root('X-1')
-
- ensure
- Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
- end
-
- def test_doc_root_4
- orig_rdoc_version = Gem::RDoc.rdoc_version
- Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('4.0')
-
- assert_equal '/doc_root/X-1/', @server.doc_root('X-1')
-
- ensure
- Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
- end
-
- def test_have_rdoc_4_plus_eh
- orig_rdoc_version = Gem::RDoc.rdoc_version
- Gem::RDoc.instance_variable_set(:@rdoc_version, Gem::Version.new('4.0'))
-
- server = Gem::Server.new Gem.dir, 0, false
- assert server.have_rdoc_4_plus?
-
- Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12')
-
- server = Gem::Server.new Gem.dir, 0, false
- refute server.have_rdoc_4_plus?
-
- Gem::RDoc.instance_variable_set(:@rdoc_version,
- Gem::Version.new('4.0.0.preview2'))
-
- server = Gem::Server.new Gem.dir, 0, false
- assert server.have_rdoc_4_plus?
- ensure
- Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
- end
-
- def test_spec_dirs
- s = Gem::Server.new Gem.dir, process_based_port, false
-
- assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs
-
- s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false
-
- assert_equal [File.join(Gem.dir, 'specifications'),
- File.join(Gem.dir, 'specifications')], s.spec_dirs
- end
-
- def test_latest_specs
- data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
- @req.parse data
-
- Gem::Deprecate.skip_during do
- @server.latest_specs @req, @res
- end
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/octet-stream', @res['content-type']
- assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
- Marshal.load(@res.body)
- end
-
- def test_latest_specs_gemdirs
- data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'z', 9
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.latest_specs @req, @res
-
- assert_equal 200, @res.status
-
- assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body)
- end
-
- def test_latest_specs_gz
- data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- Gem::Deprecate.skip_during do
- @server.latest_specs @req, @res
- end
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/x-gzip', @res['content-type']
- assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
- Marshal.load(Gem::Util.gunzip(@res.body))
- end
-
- def test_listen
- util_listen
-
- capture_output do
- @server.listen
- end
-
- assert_equal 1, @server.server.listeners.length
- end
-
- def test_listen_addresses
- util_listen
-
- capture_output do
- @server.listen %w[a b]
- end
-
- assert_equal 2, @server.server.listeners.length
- end
-
- def test_prerelease_specs
- data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
- @req.parse data
-
- Gem::Deprecate.skip_during do
- @server.prerelease_specs @req, @res
- end
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/octet-stream', @res['content-type']
- assert_equal [['a', v('3.a'), Gem::Platform::RUBY]],
- Marshal.load(@res.body)
- end
-
- def test_prerelease_specs_gz
- data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- Gem::Deprecate.skip_during do
- @server.prerelease_specs @req, @res
- end
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/x-gzip', @res['content-type']
- assert_equal [['a', v('3.a'), Gem::Platform::RUBY]],
- Marshal.load(Gem::Util.gunzip(@res.body))
- end
-
- def test_quick_gemdirs
- data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.quick @req, @res
-
- assert_equal 404, @res.status
-
- spec = util_spec 'z', 9
-
- specs_dir = File.join dir, 'specifications'
-
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- data.rewind
-
- req = WEBrick::HTTPRequest.new :Logger => nil
- res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
- req.parse data
-
- server.quick req, res
-
- assert_equal 200, res.status
- end
-
- def test_quick_missing
- data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 404, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'text/plain', @res['content-type']
- assert_equal 'No gems found matching "z-9"', @res.body
- assert_equal 404, @res.status
- end
-
- def test_quick_marshal_a_1_gemspec_rz
- data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert @res['date']
- assert_equal 'application/x-deflate', @res['content-type']
-
- spec = Marshal.load Gem::Util.inflate(@res.body)
- assert_equal 'a', spec.name
- assert_equal Gem::Version.new(1), spec.version
- end
-
- def test_quick_marshal_a_1_mswin32_gemspec_rz
- quick_gem 'a', '1' do |s|
- s.platform = Gem::Platform.local
- end
-
- data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert @res['date']
- assert_equal 'application/x-deflate', @res['content-type']
-
- spec = Marshal.load Gem::Util.inflate(@res.body)
- assert_equal 'a', spec.name
- assert_equal Gem::Version.new(1), spec.version
- assert_equal Gem::Platform.local, spec.platform
- end
-
- def test_quick_marshal_a_3_a_gemspec_rz
- data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-3.a.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert @res['date']
- assert_equal 'application/x-deflate', @res['content-type']
-
- spec = Marshal.load Gem::Util.inflate(@res.body)
- assert_equal 'a', spec.name
- assert_equal v('3.a'), spec.version
- end
-
- def test_quick_marshal_a_b_3_a_gemspec_rz
- quick_gem 'a-b', '3.a'
-
- data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-3.a.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert @res['date']
- assert_equal 'application/x-deflate', @res['content-type']
-
- spec = Marshal.load Gem::Util.inflate(@res.body)
- assert_equal 'a-b', spec.name
- assert_equal v('3.a'), spec.version
- end
-
- def test_quick_marshal_a_b_1_3_a_gemspec_rz
- quick_gem 'a-b-1', '3.a'
-
- data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-1-3.a.gemspec.rz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.quick @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert @res['date']
- assert_equal 'application/x-deflate', @res['content-type']
-
- spec = Marshal.load Gem::Util.inflate(@res.body)
- assert_equal 'a-b-1', spec.name
- assert_equal v('3.a'), spec.version
- end
-
- def test_rdoc
- data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.rdoc @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{No documentation found}, @res.body
- assert_equal 'text/html', @res['content-type']
- end
-
- def test_root
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.root @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'text/html', @res['content-type']
- end
-
- def test_root_gemdirs
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'z', 9
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.root @req, @res
-
- assert_equal 200, @res.status
- assert_match 'z 9', @res.body
- end
-
- def test_xss_homepage_fix_289313
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'xsshomepagegem', 1
- spec.homepage = "javascript:confirm(document.domain)"
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.root @req, @res
-
- assert_equal 200, @res.status
- assert_match 'xsshomepagegem 1', @res.body
-
- # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a
- # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here,
- # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be
- # validated in future versions of Gem::Specification.
- #
- # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex:
- #
- # Variant #1 - rdoc not installed
- #
- # <b>xsshomepagegem 1</b>
- #
- #
- # <span title="rdoc not installed">[rdoc]</span>
- #
- #
- #
- # <a href="." title=".">[www]</a>
- #
- # Variant #2 - rdoc installed
- #
- # <b>xsshomepagegem 1</b>
- #
- #
- # <a href="\/doc_root\/xsshomepagegem-1\/">\[rdoc\]<\/a>
- #
- #
- #
- # <a href="." title=".">[www]</a>
- regex_match = /xsshomepagegem 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/xsshomepagegem-1\/">\[rdoc\]<\/a>)\s+<a href="\." title="\.">\[www\]<\/a>/
- assert_match regex_match, @res.body
- end
-
- def test_invalid_homepage
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'invalidhomepagegem', 1
- spec.homepage = "notavalidhomepageurl"
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.root @req, @res
-
- assert_equal 200, @res.status
- assert_match 'invalidhomepagegem 1', @res.body
-
- # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a
- # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here,
- # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be
- # validated in future versions of Gem::Specification.
- #
- # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex:
- #
- # Variant #1 - rdoc not installed
- #
- # <b>invalidhomepagegem 1</b>
- #
- #
- # <span title="rdoc not installed">[rdoc]</span>
- #
- #
- #
- # <a href="." title=".">[www]</a>
- #
- # Variant #2 - rdoc installed
- #
- # <b>invalidhomepagegem 1</b>
- #
- #
- # <a href="\/doc_root\/invalidhomepagegem-1\/">\[rdoc\]<\/a>
- #
- #
- #
- # <a href="." title=".">[www]</a>
- regex_match = /invalidhomepagegem 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/invalidhomepagegem-1\/">\[rdoc\]<\/a>)\s+<a href="\." title="\.">\[www\]<\/a>/
- assert_match regex_match, @res.body
- end
-
- def test_valid_homepage_http
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'validhomepagegemhttp', 1
- spec.homepage = "http://rubygems.org"
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.root @req, @res
-
- assert_equal 200, @res.status
- assert_match 'validhomepagegemhttp 1', @res.body
-
- regex_match = /validhomepagegemhttp 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/validhomepagegemhttp-1\/">\[rdoc\]<\/a>)\s+<a href="http:\/\/rubygems\.org" title="http:\/\/rubygems\.org">\[www\]<\/a>/
- assert_match regex_match, @res.body
- end
-
- def test_valid_homepage_https
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'validhomepagegemhttps', 1
- spec.homepage = "https://rubygems.org"
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.root @req, @res
-
- assert_equal 200, @res.status
- assert_match 'validhomepagegemhttps 1', @res.body
-
- regex_match = /validhomepagegemhttps 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/validhomepagegemhttps-1\/">\[rdoc\]<\/a>)\s+<a href="https:\/\/rubygems\.org" title="https:\/\/rubygems\.org">\[www\]<\/a>/
- assert_match regex_match, @res.body
- end
-
- def test_specs
- data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.specs @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/octet-stream', @res['content-type']
-
- assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
- ['a', Gem::Version.new(2), Gem::Platform::RUBY],
- ['a', v('3.a'), Gem::Platform::RUBY]],
- Marshal.load(@res.body)
- end
-
- def test_specs_gemdirs
- data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
- dir = "#{@gemhome}2"
-
- spec = util_spec 'z', 9
-
- specs_dir = File.join dir, 'specifications'
- FileUtils.mkdir_p specs_dir
-
- File.open File.join(specs_dir, spec.spec_name), 'w' do |io|
- io.write spec.to_ruby
- end
-
- server = Gem::Server.new dir, process_based_port, false
-
- @req.parse data
-
- server.specs @req, @res
-
- assert_equal 200, @res.status
-
- assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body)
- end
-
- def test_specs_gz
- data = StringIO.new "GET /specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.specs @req, @res
-
- assert_equal 200, @res.status, @res.body
- assert_match %r{ \d\d:\d\d:\d\d }, @res['date']
- assert_equal 'application/x-gzip', @res['content-type']
-
- assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
- ['a', Gem::Version.new(2), Gem::Platform::RUBY],
- ['a', v('3.a'), Gem::Platform::RUBY]],
- Marshal.load(Gem::Util.gunzip(@res.body))
- end
-
- def test_uri_encode
- url_safe = @server.uri_encode 'http://rubyonrails.org/">malicious_content</a>'
- assert_equal url_safe, 'http://rubyonrails.org/%22%3Emalicious_content%3C/a%3E'
- end
-
- # Regression test for issue #1793: incorrect URL encoding.
- # Checking that no URLs have had '://' incorrectly encoded
- def test_regression_1793
- data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
- @req.parse data
-
- @server.root @req, @res
-
- refute_match %r{%3A%2F%2F}, @res.body
- end
-
- def util_listen
- webrick = Object.new
- webrick.instance_variable_set :@listeners, []
- def webrick.listeners() @listeners end
- def webrick.listen(host, port)
- socket = Object.new
- socket.instance_variable_set :@host, host
- socket.instance_variable_set :@port, port
- def socket.addr() [nil, @port, @host] end
- @listeners << socket
- end
-
- @server.instance_variable_set :@server, webrick
- end
-end
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index 582813c01dd..8b4a07d23bb 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -147,6 +147,7 @@ end
end
def test_find_in_unresolved_tree_is_not_exponentiental
+ pend "currently slower in CI on TruffleRuby" if RUBY_ENGINE == 'truffleruby'
num_of_pkg = 7
num_of_version_per_pkg = 3
packages = (0..num_of_pkg).map do |pkgi|
@@ -873,24 +874,21 @@ dependencies: []
end
def test_self_load_utf8_with_ascii_encoding
- int_enc = Encoding.default_internal
- silence_warnings { Encoding.default_internal = 'US-ASCII' }
-
- spec2 = @a2.dup
- bin = "\u5678".dup
- spec2.authors = [bin]
- full_path = spec2.spec_file
- write_file full_path do |io|
- io.write spec2.to_ruby_for_cache.force_encoding('BINARY').sub("\\u{5678}", bin.force_encoding('BINARY'))
- end
+ with_internal_encoding('US-ASCII') do
+ spec2 = @a2.dup
+ bin = "\u5678".dup
+ spec2.authors = [bin]
+ full_path = spec2.spec_file
+ write_file full_path do |io|
+ io.write spec2.to_ruby_for_cache.force_encoding('BINARY').sub("\\u{5678}", bin.force_encoding('BINARY'))
+ end
- spec = Gem::Specification.load full_path
+ spec = Gem::Specification.load full_path
- spec2.files.clear
+ spec2.files.clear
- assert_equal spec2, spec
- ensure
- silence_warnings { Encoding.default_internal = int_enc }
+ assert_equal spec2, spec
+ end
end
def test_self_load_legacy_ruby
@@ -944,7 +942,7 @@ dependencies: []
end
def test_self_outdated_and_latest_remotes
- specs = spec_fetcher do |fetcher|
+ spec_fetcher do |fetcher|
fetcher.download 'a', 4
fetcher.download 'b', 3
@@ -953,8 +951,8 @@ dependencies: []
end
expected = [
- [specs['a-3.a'], v(4)],
- [specs['b-2'], v(3)],
+ [Gem::Specification.stubs.find {|s| s.full_name == 'a-3.a' }, v(4)],
+ [Gem::Specification.stubs.find {|s| s.full_name == 'b-2' }, v(3)],
]
assert_equal expected, Gem::Specification.outdated_and_latest_version.to_a
@@ -3066,6 +3064,17 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING
end
+ def test_validate_license_ref
+ util_setup_validate
+
+ use_ui @ui do
+ @a1.licenses = ['LicenseRef-LICENSE.md']
+ @a1.validate
+ end
+
+ assert_empty @ui.error
+ end
+
def test_validate_license_values_plus
util_setup_validate
@@ -3734,11 +3743,4 @@ end
end
end
end
-
- def silence_warnings
- old_verbose, $VERBOSE = $VERBOSE, false
- yield
- ensure
- $VERBOSE = old_verbose
- end
end
diff --git a/test/rubygems/test_gem_stream_ui.rb b/test/rubygems/test_gem_stream_ui.rb
index dc245c342af..04de6dd36aa 100644
--- a/test/rubygems/test_gem_stream_ui.rb
+++ b/test/rubygems/test_gem_stream_ui.rb
@@ -5,7 +5,7 @@ require 'timeout'
class TestGemStreamUI < Gem::TestCase
# increase timeout with MJIT for --jit-wait testing
- mjit_enabled = defined?(RubyVM::JIT) ? RubyVM::JIT.enabled? : defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ mjit_enabled = defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !mjit_enabled) ? 0.1 : 1.0
module IsTty
diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb
index e008391ef72..e01d5cad8c1 100644
--- a/test/rubygems/test_gem_stub_specification.rb
+++ b/test/rubygems/test_gem_stub_specification.rb
@@ -180,22 +180,6 @@ class TestStubSpecification < Gem::TestCase
assert bar.to_spec
end
- def test_to_spec_activated
- assert @foo.to_spec.is_a?(Gem::Specification)
- assert_equal "foo", @foo.to_spec.name
- refute @foo.to_spec.instance_variable_get :@ignored
- end
-
- def test_to_spec_missing_extensions
- stub = stub_with_extension
-
- capture_output do
- stub.contains_requirable_file? 'nonexistent'
- end
-
- assert stub.to_spec.instance_variable_get :@ignored
- end
-
def stub_with_version
spec = File.join @gemhome, 'specifications', 'stub_e-2.gemspec'
File.open spec, 'w' do |io|
diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb
index 422e1ee86c1..f8066ecbb8c 100644
--- a/test/rubygems/test_gem_version.rb
+++ b/test/rubygems/test_gem_version.rb
@@ -154,6 +154,10 @@ class TestGemVersion < Gem::TestCase
assert_equal(-1, v("5.a") <=> v("5.0.0.rc2"))
assert_equal(1, v("5.x") <=> v("5.0.0.rc2"))
+ assert_equal(0, v("1.9.3") <=> "1.9.3")
+ assert_equal(1, v("1.9.3") <=> "1.9.2.99")
+ assert_equal(-1, v("1.9.3") <=> "1.9.3.1")
+
assert_nil v("1.0") <=> "whatever"
end
diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb
index dee36d05ee8..4efa7e075dd 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -117,20 +117,8 @@ class TestKernel < Gem::TestCase
assert $:.any? {|p| %r{bundler-1/lib} =~ p }
end
- def test_gem_bundler_missing_bundler_version
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do
- quick_gem 'bundler', '1'
- quick_gem 'bundler', '2.a'
-
- e = assert_raise Gem::MissingSpecVersionError do
- gem('bundler')
- end
- assert_match "Could not find 'bundler' (55) required by reason.", e.message
- end
- end
-
def test_gem_bundler_inferred_bundler_version
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do
+ Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do
quick_gem 'bundler', '1'
quick_gem 'bundler', '2.a'
diff --git a/test/rubygems/test_project_sanity.rb b/test/rubygems/test_project_sanity.rb
index e9e3bfd1bad..38c2541df6e 100644
--- a/test/rubygems/test_project_sanity.rb
+++ b/test/rubygems/test_project_sanity.rb
@@ -13,7 +13,7 @@ class TestProjectSanity < Gem::TestCase
end
def test_require_rubygems_package
- err, status = Open3.capture2e(*ruby_with_rubygems_in_load_path, "--disable-gems", "-e", "'require \"rubygems/package\"'")
+ err, status = Open3.capture2e(*ruby_with_rubygems_in_load_path, "--disable-gems", "-e", "require \"rubygems/package\"")
assert status.success?, err
end
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index 07e412cc765..5b826d052be 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -24,16 +24,6 @@ class TestGemRequire < Gem::TestCase
end
end
- def setup
- super
-
- @old_loaded_features = $LOADED_FEATURES.dup
- assert_raise LoadError do
- require 'test_gem_require_a'
- end
- $LOADED_FEATURES.replace @old_loaded_features
- end
-
def assert_require(path)
assert require(path), "'#{path}' was already required"
end
@@ -88,8 +78,6 @@ class TestGemRequire < Gem::TestCase
FileUtils.mkdir_p File.dirname c_rb
File.open(c_rb, 'w') {|f| f.write "class Object; HELLO = 'world' end" }
- lp = $LOAD_PATH.dup
-
# Pretend to provide a commandline argument that overrides a file in gem b
$LOAD_PATH.unshift dash_i_arg
@@ -98,7 +86,6 @@ class TestGemRequire < Gem::TestCase
assert_equal "world", ::Object::HELLO
assert_equal %w[a-1 b-1], loaded_spec_names
ensure
- $LOAD_PATH.replace lp
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
end
@@ -132,8 +119,6 @@ class TestGemRequire < Gem::TestCase
assert_require 'test_gem_require_a'
- lp = $LOAD_PATH.dup
-
# Pretend to provide a commandline argument that overrides a file in gem b
$LOAD_PATH.unshift dash_i_arg
@@ -142,7 +127,6 @@ class TestGemRequire < Gem::TestCase
assert_equal "world", ::Object::HELLO
assert_equal %w[a-1 b-1], loaded_spec_names
ensure
- $LOAD_PATH.replace lp
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
end
@@ -153,16 +137,10 @@ class TestGemRequire < Gem::TestCase
dash_i_ext_arg = util_install_extension_file('a')
dash_i_lib_arg = util_install_ruby_file('a')
- lp = $LOAD_PATH.dup
-
- begin
- $LOAD_PATH.unshift dash_i_lib_arg
- $LOAD_PATH.unshift dash_i_ext_arg
- assert_require 'a'
- assert_match(/a\.rb$/, $LOADED_FEATURES.last)
- ensure
- $LOAD_PATH.replace lp
- end
+ $LOAD_PATH.unshift dash_i_lib_arg
+ $LOAD_PATH.unshift dash_i_ext_arg
+ assert_require 'a'
+ assert_match(/a\.rb$/, $LOADED_FEATURES.last)
end
def test_concurrent_require
@@ -466,8 +444,7 @@ class TestGemRequire < Gem::TestCase
end
def test_realworld_default_gem
- testing_ruby_repo = !ENV["GEM_COMMAND"].nil?
- pend "this test can't work under ruby-core setup" if testing_ruby_repo || java_platform?
+ omit "this test can't work under ruby-core setup" if testing_ruby_repo?
cmd = <<-RUBY
$stderr = $stdout
@@ -480,8 +457,7 @@ class TestGemRequire < Gem::TestCase
end
def test_realworld_upgraded_default_gem
- testing_ruby_repo = !ENV["GEM_COMMAND"].nil?
- pend "this test can't work under ruby-core setup" if testing_ruby_repo
+ omit "this test can't work under ruby-core setup" if testing_ruby_repo?
newer_json = util_spec("json", "999.99.9", nil, ["lib/json.rb"])
install_gem newer_json
@@ -620,31 +596,6 @@ class TestGemRequire < Gem::TestCase
assert_empty unresolved_names
end
- def test_require_bundler_missing_bundler_version
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do
- b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb")
- b2a = util_spec('bundler', '2.a', nil, "lib/bundler/setup.rb")
- install_specs b1, b2a
-
- e = assert_raise Gem::MissingSpecVersionError do
- gem('bundler')
- end
- assert_match "Could not find 'bundler' (55) required by reason.", e.message
- end
- end
-
- def test_require_bundler_with_bundler_version
- Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do
- b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb")
- b2 = util_spec('bundler', '2', nil, "lib/bundler/setup.rb")
- install_specs b1, b2
-
- $:.clear
- assert_require 'bundler/setup'
- assert_equal %w[bundler-1.999999999], loaded_spec_names
- end
- end
-
# uplevel is 2.5+ only
if RUBY_VERSION >= "2.5"
["", "Kernel."].each do |prefix|
@@ -720,11 +671,8 @@ class TestGemRequire < Gem::TestCase
private
- def silence_warnings
- old_verbose, $VERBOSE = $VERBOSE, false
- yield
- ensure
- $VERBOSE = old_verbose
+ def testing_ruby_repo?
+ !ENV["GEM_COMMAND"].nil?
end
def util_install_extension_file(name)
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
index 493b9fdf4a3..26c5f1e0fd6 100644
--- a/test/rubygems/test_rubygems.rb
+++ b/test/rubygems/test_rubygems.rb
@@ -22,6 +22,33 @@ class GemTest < Gem::TestCase
"the problem and ask for help."
end
+ def test_operating_system_customizing_default_dir
+ pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby'
+ pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby'
+
+ # On a non existing default dir, there should be no gems
+
+ path = util_install_operating_system_rb <<-RUBY
+ module Gem
+ def self.default_dir
+ File.expand_path("foo")
+ end
+ end
+ RUBY
+
+ output = Gem::Util.popen(
+ *ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
+ '-e',
+ "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)",
+ {:err => [:child, :out]}
+ ).strip
+ begin
+ assert_empty output
+ rescue Test::Unit::AssertionFailedError
+ pend "Temporary pending custom default_dir test"
+ end
+ end
+
private
def util_install_operating_system_rb(content)
diff --git a/test/rubygems/utilities.rb b/test/rubygems/utilities.rb
index 20416fe70b8..613cf6c0ee3 100644
--- a/test/rubygems/utilities.rb
+++ b/test/rubygems/utilities.rb
@@ -135,10 +135,10 @@ class Gem::FakeFetcher
def download(spec, source_uri, install_dir = Gem.dir)
name = File.basename spec.cache_file
path = if Dir.pwd == install_dir # see fetch_command
- install_dir
- else
- File.join install_dir, "cache"
- end
+ install_dir
+ else
+ File.join install_dir, "cache"
+ end
path = File.join path, name
diff --git a/test/runner.rb b/test/runner.rb
index a24cfa31c63..1b1ae0956a8 100644
--- a/test/runner.rb
+++ b/test/runner.rb
@@ -4,6 +4,8 @@
ENV["GEM_SKIP"] = ENV["GEM_HOME"] = ENV["GEM_PATH"] = "".freeze
ENV.delete("RUBY_CODESIGN")
+Warning[:experimental] = false
+
# Get bundled gems on load path
Dir.glob("#{__dir__}/../.bundle/gems/*/*.gemspec")
.reject {|f| f =~ /minitest|test-unit|power_assert/ }
diff --git a/test/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb
index 5bd34cd5eb8..bdf1f7649ee 100644
--- a/test/socket/test_addrinfo.rb
+++ b/test/socket/test_addrinfo.rb
@@ -588,7 +588,7 @@ class TestSocketAddrinfo < Test::Unit::TestCase
assert(ai.ipv4? || ai.send(meth), "ai=#{addr_exp}; ai.ipv4? || .#{meth}")
rescue Test::Unit::AssertionFailedError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in IN6_IS_ADDR_V4COMPAT and IN6_IS_ADDR_V4MAPPED on AIX"
+ omit "Known bug in IN6_IS_ADDR_V4COMPAT and IN6_IS_ADDR_V4MAPPED on AIX"
end
raise $!
end
diff --git a/test/socket/test_basicsocket.rb b/test/socket/test_basicsocket.rb
index 02e393d4e8f..8c1b434a83b 100644
--- a/test/socket/test_basicsocket.rb
+++ b/test/socket/test_basicsocket.rb
@@ -35,7 +35,7 @@ class TestSocket_BasicSocket < Test::Unit::TestCase
rescue Test::Unit::AssertionFailedError
s.close
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in getsockopt(2) on AIX"
+ omit "Known bug in getsockopt(2) on AIX"
end
raise $!
end
diff --git a/test/socket/test_nonblock.rb b/test/socket/test_nonblock.rb
index 5d455934397..d9d1e186b2c 100644
--- a/test/socket/test_nonblock.rb
+++ b/test/socket/test_nonblock.rb
@@ -279,7 +279,7 @@ class TestSocketNonblock < Test::Unit::TestCase
s1.sendmsg_nonblock("a" * 100000)
}
rescue NotImplementedError, Errno::ENOSYS
- skip "sendmsg not implemented on this platform: #{$!}"
+ omit "sendmsg not implemented on this platform: #{$!}"
rescue Errno::EMSGSIZE
# UDP has 64K limit (if no Jumbograms). No problem.
rescue Errno::EWOULDBLOCK
@@ -308,7 +308,7 @@ class TestSocketNonblock < Test::Unit::TestCase
end
end
rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT
- skip "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
+ omit "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
end
def test_sendmsg_nonblock_no_exception
@@ -329,7 +329,7 @@ class TestSocketNonblock < Test::Unit::TestCase
end
end
rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT
- skip "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
+ omit "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
end
end
@@ -338,7 +338,7 @@ class TestSocketNonblock < Test::Unit::TestCase
begin
s1.recvmsg_nonblock(4096)
rescue NotImplementedError
- skip "recvmsg not implemented on this platform."
+ omit "recvmsg not implemented on this platform."
rescue Errno::EWOULDBLOCK
assert_kind_of(IO::WaitReadable, $!)
end
diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb
index 9807db36743..2c945aa9b99 100644
--- a/test/socket/test_socket.rb
+++ b/test/socket/test_socket.rb
@@ -1,9 +1,5 @@
# frozen_string_literal: true
-# tentatively disabled due to IPv6 configuration issue on Solaris CI
-# http://rubyci.s3.amazonaws.com/solaris10-gcc/ruby-master/log/20210729T040002Z.fail.html.gz
-return if /solaris/ =~ RUBY_PLATFORM
-
begin
require "socket"
require "tmpdir"
@@ -347,7 +343,7 @@ class TestSocket < Test::Unit::TestCase
begin
ifaddrs = Socket.getifaddrs
rescue NotImplementedError
- skip "Socket.getifaddrs not implemented"
+ omit "Socket.getifaddrs not implemented"
end
ifconfig = nil
@@ -441,10 +437,10 @@ class TestSocket < Test::Unit::TestCase
}
rescue NotImplementedError, Errno::ENOSYS
skipped = true
- skip "need sendmsg and recvmsg: #{$!}"
+ omit "need sendmsg and recvmsg: #{$!}"
rescue RuntimeError
skipped = true
- skip "UDP server is no response: #{$!}"
+ omit "UDP server is no response: #{$!}"
ensure
if th
if skipped
@@ -490,7 +486,7 @@ class TestSocket < Test::Unit::TestCase
end while IO.select([r], nil, nil, 0.1).nil?
n
end
- timeout = (defined?(RubyVM::JIT) && RubyVM::JIT.enabled? ? 120 : 30) # for --jit-wait
+ timeout = (defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? ? 120 : 30) # for --jit-wait
assert_equal([[s1],[],[]], IO.select([s1], nil, nil, timeout))
msg, _, _, stamp = s1.recvmsg
assert_equal("a", msg)
diff --git a/test/socket/test_sockopt.rb b/test/socket/test_sockopt.rb
index f166027d26a..7e343e8c36b 100644
--- a/test/socket/test_sockopt.rb
+++ b/test/socket/test_sockopt.rb
@@ -34,7 +34,7 @@ class TestSocketOption < Test::Unit::TestCase
}
rescue TypeError
if /aix/ =~ RUBY_PLATFORM
- skip "Known bug in getsockopt(2) on AIX"
+ omit "Known bug in getsockopt(2) on AIX"
end
raise $!
end
diff --git a/test/socket/test_udp.rb b/test/socket/test_udp.rb
index f060b65f2c9..4b2b7ab976d 100644
--- a/test/socket/test_udp.rb
+++ b/test/socket/test_udp.rb
@@ -25,7 +25,7 @@ class TestSocket_UDPSocket < Test::Unit::TestCase
assert_match(/AF_INET6\b/, sock.inspect)
}
rescue Errno::EAFNOSUPPORT
- skip 'AF_INET6 not supported by kernel'
+ omit 'AF_INET6 not supported by kernel'
end
end
end
diff --git a/test/test_find.rb b/test/test_find.rb
index 0e691214c5d..f2dad053242 100644
--- a/test/test_find.rb
+++ b/test/test_find.rb
@@ -60,7 +60,7 @@ class TestFind < Test::Unit::TestCase
begin
File.symlink("#{d}/b", "#{d}/c")
rescue NotImplementedError, Errno::EACCES
- skip "symlink is not supported."
+ omit "symlink is not supported."
end
a = []
Find.find(d) {|f| a << f }
@@ -103,8 +103,8 @@ class TestFind < Test::Unit::TestCase
end
def test_unreadable_dir
- skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
- skip "because root can read anything" if Process.uid == 0
+ omit "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "because root can read anything" if Process.uid == 0
Dir.mktmpdir {|d|
Dir.mkdir(dir = "#{d}/dir")
@@ -158,8 +158,8 @@ class TestFind < Test::Unit::TestCase
Find.find(d, ignore_error: true).each {|f| a << f }
assert_equal([d, dir, file], a)
- skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
- skip "skipped because root can read anything" if Process.uid == 0
+ omit "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "skipped because root can read anything" if Process.uid == 0
a = []
assert_raise_with_message(Errno::EACCES, /#{Regexp.quote(file)}/) do
@@ -185,7 +185,7 @@ class TestFind < Test::Unit::TestCase
begin
File.symlink("foo", "#{d}/bar")
rescue NotImplementedError, Errno::EACCES
- skip "symlink is not supported."
+ omit "symlink is not supported."
end
a = []
Find.find(d) {|f| a << f }
@@ -199,7 +199,7 @@ class TestFind < Test::Unit::TestCase
begin
File.symlink("foo", "#{d}/bar")
rescue NotImplementedError, Errno::EACCES
- skip "symlink is not supported."
+ omit "symlink is not supported."
end
assert_raise(Errno::ENOENT) {
Find.find(d) {|f| File.stat(f) }
@@ -245,7 +245,7 @@ class TestFind < Test::Unit::TestCase
begin
File.symlink("d1", dir_1)
rescue NotImplementedError, Errno::EACCES
- skip "symlink is not supported."
+ omit "symlink is not supported."
end
end
}
diff --git a/test/test_getoptlong.rb b/test/test_getoptlong.rb
new file mode 100644
index 00000000000..0cd370b6c75
--- /dev/null
+++ b/test/test_getoptlong.rb
@@ -0,0 +1,163 @@
+require 'test/unit'
+require 'getoptlong'
+
+class TestGetoptLong < Test::Unit::TestCase
+
+ def verify(test_argv, expected_remaining_argv, expected_options)
+ # Save ARGV and replace it with a test ARGV.
+ argv_saved = ARGV.dup
+ ARGV.replace(test_argv)
+ # Define options.
+ opts = GetoptLong.new(
+ ['--xxx', '-x', '--aaa', '-a', GetoptLong::REQUIRED_ARGUMENT],
+ ['--yyy', '-y', '--bbb', '-b', GetoptLong::OPTIONAL_ARGUMENT],
+ ['--zzz', '-z', '--ccc', '-c', GetoptLong::NO_ARGUMENT]
+ )
+ opts.quiet = true
+ # Gather options.
+ actual_options = []
+ opts.each do |opt, arg|
+ actual_options << "#{opt}: #{arg}"
+ end
+ # Save remaining test ARGV and restore original ARGV.
+ actual_remaining_argv = ARGV.dup
+ ARGV.replace(argv_saved)
+ # Assert.
+ assert_equal(expected_remaining_argv, actual_remaining_argv, 'ARGV')
+ assert_equal(expected_options, actual_options, 'Options')
+ end
+
+ def test_no_options
+ expected_options = []
+ expected_argv = %w[foo bar]
+ argv = %w[foo bar]
+ verify(argv, expected_argv, expected_options)
+ end
+
+ def test_required_argument
+ expected_options = [
+ '--xxx: arg'
+ ]
+ expected_argv = %w[foo bar]
+ options = %w[--xxx --xx --x -x --aaa --aa --a -a]
+ options.each do |option|
+ argv = ['foo', option, 'arg', 'bar']
+ verify(argv, expected_argv, expected_options)
+ end
+ end
+
+ def test_required_argument_missing
+ options = %w[--xxx --xx --x -x --aaa --aa --a -a]
+ options.each do |option|
+ argv = [option]
+ e = assert_raise(GetoptLong::MissingArgument) do
+ verify(argv, [], [])
+ end
+ assert_match('requires an argument', e.message)
+ end
+ end
+
+ def test_optional_argument
+ expected_options = [
+ '--yyy: arg'
+ ]
+ expected_argv = %w[foo bar]
+ options = %w[--yyy --y --y -y --bbb --bb --b -b]
+ options.each do |option|
+ argv = ['foo', 'bar', option, 'arg']
+ verify(argv, expected_argv, expected_options)
+ end
+ end
+
+ def test_optional_argument_missing
+ expected_options = [
+ '--yyy: '
+ ]
+ expected_argv = %w[foo bar]
+ options = %w[--yyy --y --y -y --bbb --bb --b -b]
+ options.each do |option|
+ argv = ['foo', 'bar', option]
+ verify(argv, expected_argv, expected_options)
+ end
+ end
+
+ def test_no_argument
+ expected_options = [
+ '--zzz: '
+ ]
+ expected_argv = %w[foo bar]
+ options = %w[--zzz --zz --z -z --ccc --cc --c -c]
+ options.each do |option|
+ argv = ['foo', option, 'bar']
+ verify(argv, expected_argv, expected_options)
+ end
+ end
+
+ def test_new_with_empty_array
+ e = assert_raise(ArgumentError) do
+ GetoptLong.new([])
+ end
+ assert_match(/no argument-flag/, e.message)
+ end
+
+ def test_new_with_bad_array
+ e = assert_raise(ArgumentError) do
+ GetoptLong.new('foo')
+ end
+ assert_match(/option list contains non-Array argument/, e.message)
+ end
+
+ def test_new_with_empty_subarray
+ e = assert_raise(ArgumentError) do
+ GetoptLong.new([[]])
+ end
+ assert_match(/no argument-flag/, e.message)
+ end
+
+ def test_new_with_bad_subarray
+ e = assert_raise(ArgumentError) do
+ GetoptLong.new([1])
+ end
+ assert_match(/no option name/, e.message)
+ end
+
+ def test_new_with_invalid_option
+ invalid_options = %w[verbose -verbose -- +]
+ invalid_options.each do |invalid_option|
+ e = assert_raise(ArgumentError, invalid_option.to_s) do
+ arguments = [
+ [invalid_option, '-v', GetoptLong::NO_ARGUMENT]
+ ]
+ GetoptLong.new(*arguments)
+ end
+ assert_match(/invalid option/, e.message)
+ end
+ end
+
+ def test_new_with_invalid_alias
+ invalid_aliases = %w[v - -- +]
+ invalid_aliases.each do |invalid_alias|
+ e = assert_raise(ArgumentError, invalid_alias.to_s) do
+ arguments = [
+ ['--verbose', invalid_alias, GetoptLong::NO_ARGUMENT]
+ ]
+ GetoptLong.new(*arguments)
+ end
+ assert_match(/invalid option/, e.message)
+ end
+ end
+
+ def test_new_with_invalid_flag
+ invalid_flags = ['foo']
+ invalid_flags.each do |invalid_flag|
+ e = assert_raise(ArgumentError, invalid_flag.to_s) do
+ arguments = [
+ ['--verbose', '-v', invalid_flag]
+ ]
+ GetoptLong.new(*arguments)
+ end
+ assert_match(/no argument-flag/, e.message)
+ end
+ end
+
+end
diff --git a/test/test_open3.rb b/test/test_open3.rb
index 47d471c031a..a06697a37b1 100644
--- a/test/test_open3.rb
+++ b/test/test_open3.rb
@@ -2,7 +2,10 @@
require 'test/unit'
require 'open3'
-require_relative 'lib/jit_support'
+
+if RUBY_ENGINE == 'ruby'
+ require_relative 'lib/jit_support'
+end
class TestOpen3 < Test::Unit::TestCase
RUBY = EnvUtil.rubybin
@@ -92,7 +95,7 @@ class TestOpen3 < Test::Unit::TestCase
end
def test_numeric_file_descriptor3
- skip "passing FDs bigger than 2 is not supported on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "passing FDs bigger than 2 is not supported on Windows" if /mswin|mingw/ =~ RbConfig::CONFIG['host_os']
with_pipe {|r, w|
Open3.popen3(RUBY, '-e', 'IO.open(3).puts "foo"', 3 => w) {|i,o,e,t|
assert_equal("foo\n", r.gets, "[GH-808] [ruby-core:67347] [Bug #10699]")
@@ -127,7 +130,11 @@ class TestOpen3 < Test::Unit::TestCase
i.close
STDERR.reopen(old)
assert_equal("zo", o.read)
- assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
+ if defined?(JITSupport)
+ assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
+ else
+ assert_equal("ze", r.read)
+ end
}
}
}
diff --git a/test/test_pp.rb b/test/test_pp.rb
index 4aa31954552..9cef555d79f 100644
--- a/test/test_pp.rb
+++ b/test/test_pp.rb
@@ -3,6 +3,16 @@
require 'pp'
require 'delegate'
require 'test/unit'
+require 'ruby2_keywords'
+
+# Define bind_call for Ruby 2.6 and earlier, to allow testing on JRuby 9.3
+class UnboundMethod
+ unless public_method_defined?(:bind_call)
+ def bind_call(obj, *args, &block)
+ bind(obj).call(*args, &block)
+ end
+ end
+end
module PPTestModule
@@ -158,7 +168,7 @@ class PPCycleTest < Test::Unit::TestCase
a << HasInspect.new(a)
assert_equal("[<inspect:[...]>]\n", PP.pp(a, ''.dup))
assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup))
- end
+ end unless RUBY_VERSION < "2.7" # temporary mask to test on JRuby 9.3 (2.6 equivalent)
def test_share_nil
begin
diff --git a/test/test_pty.rb b/test/test_pty.rb
index 9e40a3d2fb0..1c0c6fb3e87 100644
--- a/test/test_pty.rb
+++ b/test/test_pty.rb
@@ -14,7 +14,7 @@ class TestPTY < Test::Unit::TestCase
def test_spawn_without_block
r, w, pid = PTY.spawn(RUBY, '-e', 'puts "a"')
rescue RuntimeError
- skip $!
+ omit $!
else
assert_equal("a\r\n", r.gets)
ensure
@@ -34,7 +34,7 @@ class TestPTY < Test::Unit::TestCase
end
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_commandline
@@ -49,7 +49,7 @@ class TestPTY < Test::Unit::TestCase
end
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_argv0
@@ -63,13 +63,13 @@ class TestPTY < Test::Unit::TestCase
end
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_open_without_block
ret = PTY.open
rescue RuntimeError
- skip $!
+ omit $!
else
assert_kind_of(Array, ret)
assert_equal(2, ret.length)
@@ -100,7 +100,7 @@ class TestPTY < Test::Unit::TestCase
x
}
rescue RuntimeError
- skip $!
+ omit $!
else
assert(r[0].closed?)
assert(r[1].closed?)
@@ -115,7 +115,7 @@ class TestPTY < Test::Unit::TestCase
assert(master.closed?)
}
rescue RuntimeError
- skip $!
+ omit $!
else
assert_nothing_raised {
PTY.open {|master, slave|
@@ -133,7 +133,7 @@ class TestPTY < Test::Unit::TestCase
assert_equal("bar", slave.gets.chomp)
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_stat_slave
@@ -143,7 +143,7 @@ class TestPTY < Test::Unit::TestCase
assert_equal(0600, s.mode & 0777)
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_close_master
@@ -152,7 +152,7 @@ class TestPTY < Test::Unit::TestCase
assert_raise(EOFError) { slave.readpartial(10) }
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_close_slave
@@ -165,7 +165,7 @@ class TestPTY < Test::Unit::TestCase
) { master.readpartial(10) }
}
rescue RuntimeError
- skip $!
+ omit $!
end
def test_getpty_nonexistent
@@ -175,7 +175,7 @@ class TestPTY < Test::Unit::TestCase
begin
PTY.getpty(File.join(tmpdir, "no-such-command"))
rescue RuntimeError
- skip $!
+ omit $!
end
}
end
@@ -194,7 +194,7 @@ class TestPTY < Test::Unit::TestCase
end until st2 = PTY.check(pid)
end
rescue RuntimeError
- skip $!
+ omit $!
else
assert_nil(st1)
assert_equal(pid, st2.pid)
@@ -212,7 +212,7 @@ class TestPTY < Test::Unit::TestCase
st2 = assert_raise(PTY::ChildExited, bug2642) {PTY.check(pid, true)}.status
end
rescue RuntimeError
- skip $!
+ omit $!
else
assert_nil(st1)
assert_equal(pid, st2.pid)
@@ -234,6 +234,6 @@ class TestPTY < Test::Unit::TestCase
end
}
rescue RuntimeError
- skip $!
+ omit $!
end
end if defined? PTY
diff --git a/test/test_securerandom.rb b/test/test_securerandom.rb
index ab96952e370..e4a0e17365e 100644
--- a/test/test_securerandom.rb
+++ b/test/test_securerandom.rb
@@ -1,22 +1,17 @@
# frozen_string_literal: false
require 'test/unit'
require 'securerandom'
-require 'tempfile'
+require_relative 'ruby/test_random_formatter'
# This testcase does NOT aim to test cryptographically strongness and randomness.
class TestSecureRandom < Test::Unit::TestCase
+ include Random::Formatter::FormatterTest
+ include Random::Formatter::NotDefaultTest
+
def setup
@it = SecureRandom
end
- def test_s_random_bytes
- assert_equal(16, @it.random_bytes.size)
- assert_equal(Encoding::ASCII_8BIT, @it.random_bytes.encoding)
- 65.times do |idx|
- assert_equal(idx, @it.random_bytes(idx).size)
- end
- end
-
# This test took 2 minutes on my machine.
# And 65536 times loop could not be enough for forcing PID recycle.
if false
@@ -70,114 +65,6 @@ if false
end
end
- def test_s_hex
- s = @it.hex
- assert_equal(16 * 2, s.size)
- assert_match(/\A\h+\z/, s)
- 33.times do |idx|
- s = @it.hex(idx)
- assert_equal(idx * 2, s.size)
- assert_match(/\A\h*\z/, s)
- end
- end
-
- def test_hex_encoding
- assert_equal(Encoding::US_ASCII, @it.hex.encoding)
- end
-
- def test_s_base64
- assert_equal(16, @it.base64.unpack('m*')[0].size)
- 17.times do |idx|
- assert_equal(idx, @it.base64(idx).unpack('m*')[0].size)
- end
- end
-
- def test_s_urlsafe_base64
- safe = /[\n+\/]/
- 65.times do |idx|
- assert_not_match(safe, @it.urlsafe_base64(idx))
- end
- # base64 can include unsafe byte
- assert((0..10000).any? {|idx| safe =~ @it.base64(idx)}, "None of base64(0..10000) is url-safe")
- end
-
- def test_s_random_number_float
- 101.times do
- v = @it.random_number
- assert_in_range(0.0...1.0, v)
- end
- end
-
- def test_s_random_number_float_by_zero
- 101.times do
- v = @it.random_number(0)
- assert_in_range(0.0...1.0, v)
- end
- end
-
- def test_s_random_number_int
- 101.times do |idx|
- next if idx.zero?
- v = @it.random_number(idx)
- assert_in_range(0...idx, v)
- end
- end
-
- def test_s_random_number_not_default
- msg = "SecureRandom#random_number should not be affected by srand"
- seed = srand(0)
- x = @it.random_number(1000)
- 10.times do|i|
- srand(0)
- return unless @it.random_number(1000) == x
- end
- srand(0)
- assert_not_equal(x, @it.random_number(1000), msg)
- ensure
- srand(seed) if seed
- end
-
- def test_uuid
- uuid = @it.uuid
- assert_equal(36, uuid.size)
-
- # Check time_hi_and_version and clock_seq_hi_res bits (RFC 4122 4.4)
- assert_equal('4', uuid[14])
- assert_include(%w'8 9 a b', uuid[19])
-
- assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
- end
-
- def test_alphanumeric
- 65.times do |n|
- an = @it.alphanumeric(n)
- assert_match(/\A[0-9a-zA-Z]*\z/, an)
- assert_equal(n, an.length)
- end
- end
-
- def protect
- begin
- yield
- rescue NotImplementedError
- # ignore
- end
- end
-
- def remove_feature(basename)
- $LOADED_FEATURES.delete_if { |path|
- if File.basename(path) == basename
- $LOAD_PATH.any? { |dir|
- File.exist?(File.join(dir, basename))
- }
- end
- }
- end
-
- def assert_in_range(range, result, mesg = nil)
- assert(range.cover?(result), build_message(mesg, "Expected #{result} to be in #{range}"))
- end
-
def test_with_openssl
begin
require 'openssl'
diff --git a/test/test_tmpdir.rb b/test/test_tmpdir.rb
index 7ef9f59b54a..0be2176bd95 100644
--- a/test/test_tmpdir.rb
+++ b/test/test_tmpdir.rb
@@ -12,7 +12,7 @@ class TestTmpdir < Test::Unit::TestCase
end
def test_world_writable
- skip "no meaning on this platform" if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "no meaning on this platform" if /mswin|mingw/ =~ RUBY_PLATFORM
Dir.mktmpdir do |tmpdir|
# ToDo: fix for parallel test
envs = %w[TMPDIR TMP TEMP]
diff --git a/test/win32ole/test_err_in_callback.rb b/test/win32ole/test_err_in_callback.rb
index 2c2b4a61a17..9ffaf9125fd 100644
--- a/test/win32ole/test_err_in_callback.rb
+++ b/test/win32ole/test_err_in_callback.rb
@@ -38,7 +38,7 @@ if defined?(WIN32OLE)
end
def test_err_in_callback
- skip "'ADODB.Connection' is not available" unless available_adodb?
+ omit "'ADODB.Connection' is not available" unless available_adodb?
if @ruby
Dir.mktmpdir do |tmpdir|
logfile = File.join(tmpdir, "test_err_in_callback.log")
diff --git a/test/win32ole/test_win32ole.rb b/test/win32ole/test_win32ole.rb
index 39417805285..e5f9d35e249 100644
--- a/test/win32ole/test_win32ole.rb
+++ b/test/win32ole/test_win32ole.rb
@@ -101,7 +101,7 @@ if defined?(WIN32OLE)
assert_include(mnames, 'Count')
end
- def test_ole_mehtod_help
+ def test_ole_method_help
minfo = @dict1.ole_method_help("Add")
assert_equal(2, minfo.size_params)
end
diff --git a/test/win32ole/test_win32ole_event.rb b/test/win32ole/test_win32ole_event.rb
index 742bff4f7a5..f02df53be7a 100644
--- a/test/win32ole/test_win32ole_event.rb
+++ b/test/win32ole/test_win32ole_event.rb
@@ -65,12 +65,13 @@ if defined?(WIN32OLE_EVENT)
if watch_ivar
# wait until event is proceeded
tries = 0
+ seconds = EnvUtil.apply_timeout_scale(1)
while tries < 5 && instance_variable_get(watch_ivar) == orig_ivar
- seconds = 2 ** tries # sleep at most 31s in total
$stderr.puts "test_win32ole_event.rb: retrying and sleeping #{seconds}s until #{watch_ivar} is changed from #{orig_ivar.inspect}..."
WIN32OLE_EVENT.message_loop
sleep(seconds)
tries += 1
+ seconds *= 2 # sleep at most 31s in total
end
end
end
@@ -135,7 +136,7 @@ if defined?(WIN32OLE_EVENT)
@wmi.ExecNotificationQueryAsync(@sws, @sql)
rescue => e
if /OLE error code:80041008 in SWbemServicesEx/ =~ e.message
- skip "No administrator privilege?"
+ omit "No administrator privilege?"
end
raise
end
diff --git a/test/win32ole/test_win32ole_method_event.rb b/test/win32ole/test_win32ole_method_event.rb
index 6dad6ff2b47..77581688725 100644
--- a/test/win32ole/test_win32ole_method_event.rb
+++ b/test/win32ole/test_win32ole_method_event.rb
@@ -10,7 +10,7 @@ if defined?(WIN32OLE_METHOD)
class TestWIN32OLE_METHOD_EVENT < Test::Unit::TestCase
unless AvailableOLE.sysmon_available?
def test_dummy_for_skip_message
- skip 'System Monitor Control is not available'
+ omit 'System Monitor Control is not available'
end
else
def setup
diff --git a/test/win32ole/test_win32ole_param_event.rb b/test/win32ole/test_win32ole_param_event.rb
index 64812e567db..a659a6d0f3e 100644
--- a/test/win32ole/test_win32ole_param_event.rb
+++ b/test/win32ole/test_win32ole_param_event.rb
@@ -23,7 +23,7 @@ if defined?(WIN32OLE_PARAM)
end
else
def test_dummy_for_skip_message
- skip 'ActiveX Data Object Library and MS XML not found'
+ omit 'ActiveX Data Object Library and MS XML not found'
end
end
end
diff --git a/test/win32ole/test_win32ole_record.rb b/test/win32ole/test_win32ole_record.rb
index 7d6c3fb4af8..65fd5f6a3ca 100644
--- a/test/win32ole/test_win32ole_record.rb
+++ b/test/win32ole/test_win32ole_record.rb
@@ -76,7 +76,7 @@ if defined?(WIN32OLE_RECORD)
class TestWIN32OLE_RECORD_BY_RBCOMTEST < Test::Unit::TestCase
unless rbcomtest_exist?
def test_dummy_for_skip_message
- skip "#{PROGID_RBCOMTEST} for WIN32OLE_RECORD test is not installed"
+ omit "#{PROGID_RBCOMTEST} for WIN32OLE_RECORD test is not installed"
end
else
def setup
diff --git a/test/win32ole/test_win32ole_type_event.rb b/test/win32ole/test_win32ole_type_event.rb
index ad2de54e59f..ec46245cae9 100644
--- a/test/win32ole/test_win32ole_type_event.rb
+++ b/test/win32ole/test_win32ole_type_event.rb
@@ -12,7 +12,7 @@ if defined?(WIN32OLE_TYPE)
class TestWIN32OLE_TYPE_EVENT < Test::Unit::TestCase
unless AvailableOLE.sysmon_available?
def test_dummy_for_skip_message
- skip 'System Monitor Control is not available'
+ omit 'System Monitor Control is not available'
end
else
diff --git a/test/win32ole/test_win32ole_variable.rb b/test/win32ole/test_win32ole_variable.rb
index 826029e0a8d..8af3f987a8f 100644
--- a/test/win32ole/test_win32ole_variable.rb
+++ b/test/win32ole/test_win32ole_variable.rb
@@ -16,6 +16,10 @@ if defined?(WIN32OLE_VARIABLE)
@var2 = variables.find {|v| v.name == 'UILevel'}
end
+ def test_initialize
+ assert_raise(TypeError) {WIN32OLE_VARIABLE.new}
+ end
+
def test_name
assert_equal('ssfDESKTOP', @var1.name)
end
diff --git a/test/win32ole/test_win32ole_variant.rb b/test/win32ole/test_win32ole_variant.rb
index 390534b5e10..1cedf55ef3b 100644
--- a/test/win32ole/test_win32ole_variant.rb
+++ b/test/win32ole/test_win32ole_variant.rb
@@ -434,7 +434,7 @@ if defined?(WIN32OLE_VARIANT)
begin
WIN32OLE.locale = 0x0411 # set locale Japanese
rescue WIN32OLERuntimeError
- skip("Japanese locale is not installed")
+ omit("Japanese locale is not installed")
end
if WIN32OLE.locale == 0x0411
obj = WIN32OLE_VARIANT.new("\\10,000", WIN32OLE::VARIANT::VT_CY)
diff --git a/test/win32ole/test_win32ole_variant_outarg.rb b/test/win32ole/test_win32ole_variant_outarg.rb
index aa5793b84cb..f50b04aaf55 100644
--- a/test/win32ole/test_win32ole_variant_outarg.rb
+++ b/test/win32ole/test_win32ole_variant_outarg.rb
@@ -42,7 +42,7 @@ if defined?(WIN32OLE_VARIANT)
def test_variant_ref_and_argv
if !ado_csv_installed?
- skip("ActiveX Data Object Library not found")
+ omit("ActiveX Data Object Library not found")
end
sql = "INSERT INTO data.csv VALUES (5, 'E')"
@db.execute(sql, -1)
diff --git a/test/win32ole/test_word.rb b/test/win32ole/test_word.rb
index b1cdb273cce..a23757f6208 100644
--- a/test/win32ole/test_word.rb
+++ b/test/win32ole/test_word.rb
@@ -35,7 +35,7 @@ if defined?(WIN32OLE)
class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase
unless word_installed?
def test_dummy_for_skip_message
- skip "Microsoft Word is not installed"
+ omit "Microsoft Word is not installed"
end
else
def setup
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index a629c0c902a..a9de827ca8b 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -538,30 +538,36 @@ if defined? Zlib
end
def test_recursive_deflate
+ original_gc_stress = GC.stress
+ GC.stress = true
zd = Zlib::Deflate.new
s = SecureRandom.random_bytes(1024**2)
- assert_raise(Zlib::BufError) do
+ assert_raise(Zlib::InProgressError) do
zd.deflate(s) do
zd.deflate(s)
end
end
ensure
+ GC.stress = original_gc_stress
zd&.finish
zd&.close
end
def test_recursive_inflate
+ original_gc_stress = GC.stress
+ GC.stress = true
zi = Zlib::Inflate.new
s = Zlib.deflate(SecureRandom.random_bytes(1024**2))
- assert_raise(Zlib::DataError) do
+ assert_raise(Zlib::InProgressError) do
zi.inflate(s) do
zi.inflate(s)
end
end
ensure
+ GC.stress = original_gc_stress
zi&.close
end
end
@@ -806,11 +812,11 @@ if defined? Zlib
gz1.close
end
rescue Errno::EINVAL
- skip 'O_TMPFILE not supported (EINVAL)'
+ omit 'O_TMPFILE not supported (EINVAL)'
rescue Errno::EISDIR
- skip 'O_TMPFILE not supported (EISDIR)'
+ omit 'O_TMPFILE not supported (EISDIR)'
rescue Errno::EOPNOTSUPP
- skip 'O_TMPFILE not supported (EOPNOTSUPP)'
+ omit 'O_TMPFILE not supported (EOPNOTSUPP)'
end
end
end
@@ -1318,10 +1324,10 @@ if defined? Zlib
begin
assert_equal(0x02820145, Zlib.adler32_combine(one, two, 1))
rescue NotImplementedError
- skip "adler32_combine is not implemented"
+ omit "adler32_combine is not implemented"
rescue Test::Unit::AssertionFailedError
if /aix/ =~ RUBY_PLATFORM
- skip "zconf.h in zlib does not handle _LARGE_FILES in AIX. Skip until it is fixed"
+ omit "zconf.h in zlib does not handle _LARGE_FILES in AIX. Skip until it is fixed"
end
raise $!
end
@@ -1353,10 +1359,10 @@ if defined? Zlib
begin
assert_equal(0x8c736521, Zlib.crc32_combine(one, two, 1))
rescue NotImplementedError
- skip "crc32_combine is not implemented"
+ omit "crc32_combine is not implemented"
rescue Test::Unit::AssertionFailedError
if /aix/ =~ RUBY_PLATFORM
- skip "zconf.h in zlib does not handle _LARGE_FILES in AIX. Skip until it is fixed"
+ omit "zconf.h in zlib does not handle _LARGE_FILES in AIX. Skip until it is fixed"
end
raise $!
end