summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/bignum/test_big2str.rb38
-rw-r--r--test/-ext-/bignum/test_bigzero.rb20
-rw-r--r--test/-ext-/bignum/test_div.rb38
-rw-r--r--test/-ext-/bignum/test_mul.rb260
-rw-r--r--test/-ext-/bignum/test_pack.rb653
-rw-r--r--test/-ext-/bignum/test_str2big.rb52
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb7
-rw-r--r--test/-ext-/float/test_nextafter.rb2
-rw-r--r--test/-ext-/funcall/test_funcall.rb11
-rw-r--r--test/-ext-/funcall/test_passing_block.rb5
-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-/string/test_capacity.rb11
-rw-r--r--test/-ext-/string/test_fstring.rb14
-rw-r--r--test/-ext-/string/test_set_len.rb10
-rw-r--r--test/-ext-/test_abi.rb43
-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_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.rb27
-rw-r--r--test/date/test_date_ractor.rb2
-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/did_you_mean/test_ractor_compatibility.rb117
-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/excludes/TestGem.rb4
-rw-r--r--test/excludes/TestThread.rb12
-rw-r--r--test/excludes/TestThreadQueue.rb9
-rw-r--r--test/fiber/autoload.rb3
-rw-r--r--test/fiber/scheduler.rb96
-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.rb22
-rw-r--r--test/fileutils/clobber.rb5
-rw-r--r--test/fileutils/test_dryrun.rb2
-rw-r--r--test/fileutils/test_nowrite.rb2
-rw-r--r--test/fileutils/test_verbose.rb2
-rw-r--r--test/fileutils/visibility_tests.rb5
-rw-r--r--test/io/console/test_io_console.rb19
-rw-r--r--test/io/nonblock/test_flush.rb2
-rw-r--r--test/io/wait/test_io_wait_uncommon.rb2
-rw-r--r--test/irb/test_cmd.rb7
-rw-r--r--test/irb/test_context.rb6
-rw-r--r--test/irb/test_ruby_lex.rb25
-rw-r--r--test/json/json_addition_test.rb2
-rw-r--r--test/json/json_parser_test.rb1
-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/mkmf/base.rb225
-rw-r--r--test/mkmf/test_config.rb16
-rw-r--r--test/mkmf/test_constant.rb56
-rw-r--r--test/mkmf/test_convertible.rb48
-rw-r--r--test/mkmf/test_egrep_cpp.rb14
-rw-r--r--test/mkmf/test_find_executable.rb82
-rw-r--r--test/mkmf/test_flags.rb92
-rw-r--r--test/mkmf/test_framework.rb70
-rw-r--r--test/mkmf/test_have_func.rb18
-rw-r--r--test/mkmf/test_have_library.rb84
-rw-r--r--test/mkmf/test_have_macro.rb46
-rw-r--r--test/mkmf/test_install.rb38
-rw-r--r--test/mkmf/test_libs.rb156
-rw-r--r--test/mkmf/test_mkmf.rb14
-rw-r--r--test/mkmf/test_pkg_config.rb66
-rw-r--r--test/mkmf/test_signedness.rb38
-rw-r--r--test/mkmf/test_sizeof.rb74
-rw-r--r--test/net/http/test_http.rb84
-rw-r--r--test/net/http/test_httpresponse.rb250
-rw-r--r--test/net/http/test_https.rb12
-rw-r--r--test/net/http/test_https_proxy.rb2
-rw-r--r--test/objspace/test_objspace.rb93
-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.rb85
-rw-r--r--test/optparse/test_acceptable.rb2
-rw-r--r--test/optparse/test_autoconf.rb4
-rw-r--r--test/optparse/test_bash_completion.rb4
-rw-r--r--test/optparse/test_cclass.rb2
-rw-r--r--test/optparse/test_did_you_mean.rb12
-rw-r--r--test/optparse/test_getopts.rb4
-rw-r--r--test/optparse/test_kwargs.rb4
-rw-r--r--test/optparse/test_noarg.rb6
-rw-r--r--test/optparse/test_optarg.rb2
-rw-r--r--test/optparse/test_placearg.rb2
-rw-r--r--test/optparse/test_reqarg.rb10
-rw-r--r--test/optparse/test_summary.rb2
-rw-r--r--test/optparse/test_zsh_completion.rb4
-rw-r--r--test/ostruct/test_ostruct.rb7
-rw-r--r--test/pathname/test_pathname.rb31
-rw-r--r--test/psych/test_numeric.rb11
-rw-r--r--test/psych/test_scalar_scanner.rb25
-rw-r--r--test/racc/case.rb3
-rw-r--r--test/rdoc/helper.rb6
-rw-r--r--test/rdoc/support/test_case.rb2
-rw-r--r--test/rdoc/test_rdoc_alias.rb3
-rw-r--r--test/rdoc/test_rdoc_any_method.rb2
-rw-r--r--test/rdoc/test_rdoc_class_module.rb7
-rw-r--r--test/rdoc/test_rdoc_code_object.rb2
-rw-r--r--test/rdoc/test_rdoc_constant.rb2
-rw-r--r--test/rdoc/test_rdoc_context.rb4
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb58
-rw-r--r--test/rdoc/test_rdoc_extend.rb11
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb22
-rw-r--r--test/rdoc/test_rdoc_include.rb14
-rw-r--r--test/rdoc/test_rdoc_markdown.rb5
-rw-r--r--test/rdoc/test_rdoc_markdown_test.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb2
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb9
-rw-r--r--test/rdoc/test_rdoc_method_attr.rb3
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb7
-rw-r--r--test/rdoc/test_rdoc_normal_module.rb3
-rw-r--r--test/rdoc/test_rdoc_options.rb54
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb55
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb15
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb1
-rw-r--r--test/rdoc/test_rdoc_require.rb3
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb4
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb10
-rw-r--r--test/rdoc/test_rdoc_store.rb8
-rw-r--r--test/rdoc/test_rdoc_task.rb1
-rw-r--r--test/rdoc/test_rdoc_top_level.rb7
-rw-r--r--test/rdoc/xref_data.rb17
-rw-r--r--test/rdoc/xref_test_case.rb8
-rw-r--r--test/readline/test_readline.rb33
-rw-r--r--test/reline/helper.rb13
-rw-r--r--test/reline/test_config.rb40
-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_repl12
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb2
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb150
-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.rb207
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb117
-rw-r--r--test/ruby/enc/test_regex_casefold.rb2
-rw-r--r--test/ruby/test_alias.rb39
-rw-r--r--test/ruby/test_argf.rb4
-rw-r--r--test/ruby/test_arity.rb44
-rw-r--r--test/ruby/test_array.rb10
-rw-r--r--test/ruby/test_assignment.rb108
-rw-r--r--test/ruby/test_ast.rb105
-rw-r--r--test/ruby/test_autoload.rb49
-rw-r--r--test/ruby/test_backtrace.rb29
-rw-r--r--test/ruby/test_bignum.rb4
-rw-r--r--test/ruby/test_class.rb36
-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.rb6
-rw-r--r--test/ruby/test_enum.rb13
-rw-r--r--test/ruby/test_env.rb888
-rw-r--r--test/ruby/test_eval.rb70
-rw-r--r--test/ruby/test_exception.rb92
-rw-r--r--test/ruby/test_fiber.rb15
-rw-r--r--test/ruby/test_file.rb10
-rw-r--r--test/ruby/test_file_exhaustive.rb48
-rw-r--r--test/ruby/test_float.rb18
-rw-r--r--test/ruby/test_gc.rb82
-rw-r--r--test/ruby/test_gc_compact.rb63
-rw-r--r--test/ruby/test_hash.rb23
-rw-r--r--test/ruby/test_inlinecache.rb2
-rw-r--r--test/ruby/test_integer.rb25
-rw-r--r--test/ruby/test_io.rb67
-rw-r--r--test/ruby/test_io_buffer.rb243
-rw-r--r--test/ruby/test_iseq.rb45
-rw-r--r--test/ruby/test_jit_debug.rb17
-rw-r--r--test/ruby/test_keyword.rb49
-rw-r--r--test/ruby/test_literal.rb2
-rw-r--r--test/ruby/test_m17n.rb2
-rw-r--r--test/ruby/test_method.rb76
-rw-r--r--test/ruby/test_mjit.rb (renamed from test/ruby/test_jit.rb)38
-rw-r--r--test/ruby/test_mjit_debug.rb17
-rw-r--r--test/ruby/test_module.rb97
-rw-r--r--test/ruby/test_optimization.rb2
-rw-r--r--test/ruby/test_parse.rb4
-rw-r--r--test/ruby/test_pattern_matching.rb20
-rw-r--r--test/ruby/test_proc.rb116
-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_range.rb4
-rw-r--r--test/ruby/test_refinement.rb207
-rw-r--r--test/ruby/test_regexp.rb83
-rw-r--r--test/ruby/test_require.rb12
-rw-r--r--test/ruby/test_require_lib.rb2
-rw-r--r--test/ruby/test_rubyoptions.rb59
-rw-r--r--test/ruby/test_rubyvm.rb6
-rw-r--r--test/ruby/test_rubyvm_mjit.rb (renamed from test/ruby/test_rubyvm_jit.rb)28
-rw-r--r--test/ruby/test_settracefunc.rb251
-rw-r--r--test/ruby/test_signal.rb5
-rw-r--r--test/ruby/test_string.rb753
-rw-r--r--test/ruby/test_struct.rb39
-rw-r--r--test/ruby/test_syntax.rb107
-rw-r--r--test/ruby/test_thread.rb73
-rw-r--r--test/ruby/test_thread_queue.rb4
-rw-r--r--test/ruby/test_time.rb42
-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.rb196
-rw-r--r--test/rubygems/helper.rb71
-rw-r--r--test/rubygems/package/tar_test_case.rb2
-rw-r--r--test/rubygems/test_gem.rb103
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb65
-rw-r--r--test/rubygems/test_gem_command_manager.rb24
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb97
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb53
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb21
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb111
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb90
-rw-r--r--test/rubygems/test_gem_config_file.rb6
-rw-r--r--test/rubygems/test_gem_dependency.rb12
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb4
-rw-r--r--test/rubygems/test_gem_ext_builder.rb2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb147
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore1
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock374
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs30
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore1
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock374
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec8
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs42
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb2
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb8
-rw-r--r--test/rubygems/test_gem_installer.rb251
-rw-r--r--test/rubygems/test_gem_package.rb6
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb45
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb2
-rw-r--r--test/rubygems/test_gem_resolver.rb2
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb2
-rw-r--r--test/rubygems/test_gem_security.rb2
-rw-r--r--test/rubygems/test_gem_source_git.rb1
-rw-r--r--test/rubygems/test_gem_specification.rb65
-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.rb4
-rw-r--r--test/rubygems/test_require.rb90
-rw-r--r--test/rubygems/test_rubygems.rb33
-rw-r--r--test/rubygems/utilities.rb8
-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_ipaddr.rb27
-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_set.rb39
-rw-r--r--test/test_timeout.rb33
-rw-r--r--test/test_tmpdir.rb2
-rw-r--r--test/uri/test_common.rb92
-rw-r--r--test/uri/test_parser.rb9
-rw-r--r--test/uri/test_wss.rb71
-rw-r--r--test/win32ole/test_err_in_callback.rb2
-rw-r--r--test/win32ole/test_win32ole_event.rb2
-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.rb16
305 files changed, 9650 insertions, 3228 deletions
diff --git a/test/-ext-/bignum/test_big2str.rb b/test/-ext-/bignum/test_big2str.rb
index f8d6320338..88e35a7294 100644
--- a/test/-ext-/bignum/test_big2str.rb
+++ b/test/-ext-/bignum/test_big2str.rb
@@ -2,29 +2,27 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestBig2str < Test::Unit::TestCase
+class TestBignum_Big2str < Test::Unit::TestCase
- SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
- BITSPERDIG = Bug::Bignum::BITSPERDIG
- BDIGMAX = (1 << BITSPERDIG) - 1
+ SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
+ BITSPERDIG = Bug::Bignum::BITSPERDIG
+ BDIGMAX = (1 << BITSPERDIG) - 1
- def test_big2str_generic
- x = 10**1000
- assert_equal("1" + "0" * 1000, Bug::Bignum.big2str_generic(x, 10))
- end
-
- def test_big2str_poweroftwo
- e = BITSPERDIG*2
- x = 0b10**e
- assert_equal("1" + "0" * e, Bug::Bignum.big2str_poweroftwo(x, 2))
- end
+ def test_big2str_generic
+ x = 10**1000
+ assert_equal("1" + "0" * 1000, Bug::Bignum.big2str_generic(x, 10))
+ end
- def test_big2str_gmp
- x = 10**1000
- assert_equal("1" + "0" * 1000, Bug::Bignum.big2str_gmp(x, 10))
- rescue NotImplementedError
- end
+ def test_big2str_poweroftwo
+ e = BITSPERDIG*2
+ x = 0b10**e
+ assert_equal("1" + "0" * e, Bug::Bignum.big2str_poweroftwo(x, 2))
+ end
+ def test_big2str_gmp
+ x = 10**1000
+ assert_equal("1" + "0" * 1000, Bug::Bignum.big2str_gmp(x, 10))
+ rescue NotImplementedError
end
+
end
diff --git a/test/-ext-/bignum/test_bigzero.rb b/test/-ext-/bignum/test_bigzero.rb
index cf34964acd..6dfa3486c1 100644
--- a/test/-ext-/bignum/test_bigzero.rb
+++ b/test/-ext-/bignum/test_bigzero.rb
@@ -2,19 +2,17 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestBigZero < Test::Unit::TestCase
- def test_equal_0
- bug8204 = '[ruby-core:53893] [Bug #8204]'
- (0..10).each do |i|
- assert_equal(0, Bug::Bignum.zero(i), "#{bug8204} Bignum.zero(#{i})")
- end
+class TestBignum_BigZero < Test::Unit::TestCase
+ def test_equal_0
+ bug8204 = '[ruby-core:53893] [Bug #8204]'
+ (0..10).each do |i|
+ assert_equal(0, Bug::Bignum.zero(i), "#{bug8204} Bignum.zero(#{i})")
end
+ end
- def test_zero?
- (0..10).each do |i|
- assert_equal(true, Bug::Bignum.zero(i).zero?)
- end
+ def test_zero?
+ (0..10).each do |i|
+ assert_equal(true, Bug::Bignum.zero(i).zero?)
end
end
end
diff --git a/test/-ext-/bignum/test_div.rb b/test/-ext-/bignum/test_div.rb
index e61fc2ced5..0c6f635ae8 100644
--- a/test/-ext-/bignum/test_div.rb
+++ b/test/-ext-/bignum/test_div.rb
@@ -2,28 +2,26 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestDiv < Test::Unit::TestCase
+class TestBignum_Div < Test::Unit::TestCase
- SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
- BITSPERDIG = Bug::Bignum::BITSPERDIG
- BDIGMAX = (1 << BITSPERDIG) - 1
+ SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
+ BITSPERDIG = Bug::Bignum::BITSPERDIG
+ BDIGMAX = (1 << BITSPERDIG) - 1
- def test_divrem_normal
- x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3
- y = (1 << BITSPERDIG) | 1
- q = (1 << BITSPERDIG) | 1
- r = 2
- assert_equal([q, r], Bug::Bignum.big_divrem_normal(x, y))
- end
+ def test_divrem_normal
+ x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3
+ y = (1 << BITSPERDIG) | 1
+ q = (1 << BITSPERDIG) | 1
+ r = 2
+ assert_equal([q, r], Bug::Bignum.big_divrem_normal(x, y))
+ end
- def test_divrem_gmp
- x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3
- y = (1 << BITSPERDIG) | 1
- q = (1 << BITSPERDIG) | 1
- r = 2
- assert_equal([q, r], Bug::Bignum.big_divrem_gmp(x, y))
- rescue NotImplementedError
- end
+ def test_divrem_gmp
+ x = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 3
+ y = (1 << BITSPERDIG) | 1
+ q = (1 << BITSPERDIG) | 1
+ r = 2
+ assert_equal([q, r], Bug::Bignum.big_divrem_gmp(x, y))
+ rescue NotImplementedError
end
end
diff --git a/test/-ext-/bignum/test_mul.rb b/test/-ext-/bignum/test_mul.rb
index 7653a8e37a..95186bbf76 100644
--- a/test/-ext-/bignum/test_mul.rb
+++ b/test/-ext-/bignum/test_mul.rb
@@ -2,137 +2,135 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestMul < Test::Unit::TestCase
-
- SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
- BITSPERDIG = Bug::Bignum::BITSPERDIG
- BDIGMAX = (1 << BITSPERDIG) - 1
-
- def test_mul_normal
- x = (1 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG) | 1
- z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
- end
-
- def test_mul_normal_zero_in_x
- x = (1 << (2*BITSPERDIG)) | 1
- y = (1 << BITSPERDIG) | 1
- z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
- end
-
- def test_mul_normal_zero_in_y
- x = (1 << BITSPERDIG) | 1
- y = (1 << (2*BITSPERDIG)) | 1
- z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
- end
-
- def test_mul_normal_max_max
- x = (1 << (2*BITSPERDIG)) - 1
- y = (1 << (2*BITSPERDIG)) - 1
- z = (1 << (4*BITSPERDIG)) - (1 << (2*BITSPERDIG+1)) + 1
- assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
- end
-
- def test_sq_fast
- x = (1 << BITSPERDIG) | 1
- z = (1 << 2*BITSPERDIG) | (2 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_sq_fast(x))
- end
-
- def test_sq_fast_max2
- x = (BDIGMAX << BITSPERDIG) | BDIGMAX
- assert_equal(Bug::Bignum.big_mul_normal(x, x), Bug::Bignum.big_sq_fast(x))
- end
-
- def test_sq_fast_zero_in_middle
- x = (BDIGMAX << 2*BITSPERDIG) | BDIGMAX
- assert_equal(Bug::Bignum.big_mul_normal(x, x), Bug::Bignum.big_sq_fast(x))
- end
-
- def test_mul_balance
- x = (1 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG) | 1
- z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_mul_balance(x, y))
- end
-
- def test_mul_balance_2x16
- x = (1 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG*16) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_balance(x, y))
- end
-
- def test_mul_balance_2x17
- x = (1 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG*17) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_balance(x, y))
- end
-
- def test_mul_karatsuba
- x = (1 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG) | 1
- z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
- assert_equal(z, Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_odd_y
- x = (1 << BITSPERDIG) | 1
- y = (1 << (2*BITSPERDIG)) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_odd_xy
- x = (1 << (2*BITSPERDIG)) | 1
- y = (1 << (2*BITSPERDIG)) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_x1_gt_x0
- x = (2 << BITSPERDIG) | 1
- y = (1 << BITSPERDIG) | 2
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_y1_gt_y0
- x = (1 << BITSPERDIG) | 2
- y = (2 << BITSPERDIG) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_x1_gt_x0_and_y1_gt_y0
- x = (2 << BITSPERDIG) | 1
- y = (2 << BITSPERDIG) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_carry2
- x = (1 << BITSPERDIG) | BDIGMAX
- y = (1 << BITSPERDIG) | BDIGMAX
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_karatsuba_borrow
- x = (BDIGMAX << BITSPERDIG) | 1
- y = (BDIGMAX << BITSPERDIG) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
- end
-
- def test_mul_toom3
- x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
- y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_toom3(x, y))
- end
-
- def test_mul_gmp
- x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
- y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
- assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_gmp(x, y))
- rescue NotImplementedError
- end
+class TestBignum_Mul < Test::Unit::TestCase
+ SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
+ BITSPERDIG = Bug::Bignum::BITSPERDIG
+ BDIGMAX = (1 << BITSPERDIG) - 1
+
+ def test_mul_normal
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG) | 1
+ z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
+ end
+
+ def test_mul_normal_zero_in_x
+ x = (1 << (2*BITSPERDIG)) | 1
+ y = (1 << BITSPERDIG) | 1
+ z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
+ end
+
+ def test_mul_normal_zero_in_y
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << (2*BITSPERDIG)) | 1
+ z = (1 << (BITSPERDIG*3)) | (1 << (BITSPERDIG*2)) | (1 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
+ end
+
+ def test_mul_normal_max_max
+ x = (1 << (2*BITSPERDIG)) - 1
+ y = (1 << (2*BITSPERDIG)) - 1
+ z = (1 << (4*BITSPERDIG)) - (1 << (2*BITSPERDIG+1)) + 1
+ assert_equal(z, Bug::Bignum.big_mul_normal(x, y))
+ end
+
+ def test_sq_fast
+ x = (1 << BITSPERDIG) | 1
+ z = (1 << 2*BITSPERDIG) | (2 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_sq_fast(x))
+ end
+
+ def test_sq_fast_max2
+ x = (BDIGMAX << BITSPERDIG) | BDIGMAX
+ assert_equal(Bug::Bignum.big_mul_normal(x, x), Bug::Bignum.big_sq_fast(x))
+ end
+
+ def test_sq_fast_zero_in_middle
+ x = (BDIGMAX << 2*BITSPERDIG) | BDIGMAX
+ assert_equal(Bug::Bignum.big_mul_normal(x, x), Bug::Bignum.big_sq_fast(x))
+ end
+
+ def test_mul_balance
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG) | 1
+ z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_mul_balance(x, y))
+ end
+
+ def test_mul_balance_2x16
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG*16) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_balance(x, y))
+ end
+
+ def test_mul_balance_2x17
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG*17) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_balance(x, y))
+ end
+
+ def test_mul_karatsuba
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG) | 1
+ z = (1 << (BITSPERDIG*2)) | (2 << BITSPERDIG) | 1
+ assert_equal(z, Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_odd_y
+ x = (1 << BITSPERDIG) | 1
+ y = (1 << (2*BITSPERDIG)) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_odd_xy
+ x = (1 << (2*BITSPERDIG)) | 1
+ y = (1 << (2*BITSPERDIG)) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_x1_gt_x0
+ x = (2 << BITSPERDIG) | 1
+ y = (1 << BITSPERDIG) | 2
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_y1_gt_y0
+ x = (1 << BITSPERDIG) | 2
+ y = (2 << BITSPERDIG) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_x1_gt_x0_and_y1_gt_y0
+ x = (2 << BITSPERDIG) | 1
+ y = (2 << BITSPERDIG) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_carry2
+ x = (1 << BITSPERDIG) | BDIGMAX
+ y = (1 << BITSPERDIG) | BDIGMAX
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
+ end
+
+ def test_mul_karatsuba_borrow
+ x = (BDIGMAX << BITSPERDIG) | 1
+ y = (BDIGMAX << BITSPERDIG) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_karatsuba(x, y))
end
+
+ def test_mul_toom3
+ x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
+ y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_toom3(x, y))
+ end
+
+ def test_mul_gmp
+ x = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
+ y = (1 << 2*BITSPERDIG) | (1 << BITSPERDIG) | 1
+ assert_equal(Bug::Bignum.big_mul_normal(x, y), Bug::Bignum.big_mul_gmp(x, y))
+ rescue NotImplementedError
+ end
+
end
diff --git a/test/-ext-/bignum/test_pack.rb b/test/-ext-/bignum/test_pack.rb
index d5605236f7..b7aea9ab68 100644
--- a/test/-ext-/bignum/test_pack.rb
+++ b/test/-ext-/bignum/test_pack.rb
@@ -4,348 +4,346 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestPack < Test::Unit::TestCase
-
- MSWORD_FIRST = Bug::Bignum::INTEGER_PACK_MSWORD_FIRST
- LSWORD_FIRST = Bug::Bignum::INTEGER_PACK_LSWORD_FIRST
- MSBYTE_FIRST = Bug::Bignum::INTEGER_PACK_MSBYTE_FIRST
- LSBYTE_FIRST = Bug::Bignum::INTEGER_PACK_LSBYTE_FIRST
- NATIVE_BYTE_ORDER = Bug::Bignum::INTEGER_PACK_NATIVE_BYTE_ORDER
- TWOCOMP = Bug::Bignum::INTEGER_PACK_2COMP
- LITTLE_ENDIAN = Bug::Bignum::INTEGER_PACK_LITTLE_ENDIAN
- BIG_ENDIAN = Bug::Bignum::INTEGER_PACK_BIG_ENDIAN
- NEGATIVE = Bug::Bignum::INTEGER_PACK_NEGATIVE
- GENERIC = Bug::Bignum::INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
-
- def test_pack_zero
- assert_equal([0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, BIG_ENDIAN))
- end
-
- def test_pack_argument_check
- assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 2, 1, 0, MSBYTE_FIRST) }
- assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 1, 0, MSWORD_FIRST) }
- assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 0, 0, BIG_ENDIAN) }
- assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 1, 8, BIG_ENDIAN) }
-
- # assume sizeof(ssize_t) == sizeof(intptr_t)
- assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) }
- end
-
- def test_pack_wordsize
- assert_equal([1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, BIG_ENDIAN))
- assert_equal([1, "\x00\x01"], Bug::Bignum.test_pack(1, 1, 2, 0, BIG_ENDIAN))
- assert_equal([1, "\x00\x00\x01"], Bug::Bignum.test_pack(1, 1, 3, 0, BIG_ENDIAN))
- assert_equal([1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, LITTLE_ENDIAN))
- assert_equal([1, "\x01\x00"], Bug::Bignum.test_pack(1, 1, 2, 0, LITTLE_ENDIAN))
- assert_equal([1, "\x01\x00\x00"], Bug::Bignum.test_pack(1, 1, 3, 0, LITTLE_ENDIAN))
- end
-
- def test_pack_fixed_buffer
- assert_equal([0, "\x00\x00"], Bug::Bignum.test_pack(0, 2, 1, 0, BIG_ENDIAN))
- assert_equal([1, "\x00\x01"], Bug::Bignum.test_pack(0x01, 2, 1, 0, BIG_ENDIAN))
- assert_equal([1, "\x02\x01"], Bug::Bignum.test_pack(0x0201, 2, 1, 0, BIG_ENDIAN))
- assert_equal([2, "\x02\x01"], Bug::Bignum.test_pack(0x030201, 2, 1, 0, BIG_ENDIAN))
- assert_equal([2, "\x02\x01"], Bug::Bignum.test_pack(0x04030201, 2, 1, 0, BIG_ENDIAN))
- assert_equal([0, "\x00\x00"], Bug::Bignum.test_pack(0, 2, 1, 0, LITTLE_ENDIAN))
- assert_equal([1, "\x01\x00"], Bug::Bignum.test_pack(0x01, 2, 1, 0, LITTLE_ENDIAN))
- assert_equal([1, "\x01\x02"], Bug::Bignum.test_pack(0x0201, 2, 1, 0, LITTLE_ENDIAN))
- assert_equal([2, "\x01\x02"], Bug::Bignum.test_pack(0x030201, 2, 1, 0, LITTLE_ENDIAN))
- assert_equal([2, "\x01\x02"], Bug::Bignum.test_pack(0x04030201, 2, 1, 0, LITTLE_ENDIAN))
- end
-
- def test_pack_wordorder_and_endian
- assert_equal([1, "\x12\x34\x56\x78"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST))
- assert_equal([1, "\x34\x12\x78\x56"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST))
- assert_equal([1, "\x56\x78\x12\x34"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST))
- assert_equal([1, "\x78\x56\x34\x12"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST))
- end
-
- def test_pack_native_endian
- assert_equal([1, [0x1234].pack("S!")], Bug::Bignum.test_pack(0x1234, 1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER))
- end
-
- def test_pack_nail
- assert_equal([1, "\x01\x00\x00\x00\x01\x01"], Bug::Bignum.test_pack(0b100011, 6, 1, 7, BIG_ENDIAN))
- assert_equal([1, "\x01\x02\x03\x04\x05\x06\x07\x08"], Bug::Bignum.test_pack(0x12345678, 8, 1, 4, BIG_ENDIAN))
- assert_equal([1, "\x00\x12\x00\x34\x00\x56\x00\x78"], Bug::Bignum.test_pack(0x12345678, 4, 2, 8, BIG_ENDIAN))
- end
-
- def test_pack_overflow
- assert_equal([-2, "\x1"], Bug::Bignum.test_pack((-0x11), 1, 1, 4, BIG_ENDIAN))
- assert_equal([-2, "\x0"], Bug::Bignum.test_pack((-0x10), 1, 1, 4, BIG_ENDIAN))
- assert_equal([-1, "\xF"], Bug::Bignum.test_pack((-0x0F), 1, 1, 4, BIG_ENDIAN))
- assert_equal([+1, "\xF"], Bug::Bignum.test_pack((+0x0F), 1, 1, 4, BIG_ENDIAN))
- assert_equal([+2, "\x0"], Bug::Bignum.test_pack((+0x10), 1, 1, 4, BIG_ENDIAN))
- assert_equal([+2, "\x1"], Bug::Bignum.test_pack((+0x11), 1, 1, 4, BIG_ENDIAN))
-
- assert_equal([-2, "\x01"], Bug::Bignum.test_pack((-0x101), 1, 1, 0, BIG_ENDIAN))
- assert_equal([-2, "\x00"], Bug::Bignum.test_pack((-0x100), 1, 1, 0, BIG_ENDIAN))
- assert_equal([-1, "\xFF"], Bug::Bignum.test_pack((-0x0FF), 1, 1, 0, BIG_ENDIAN))
- assert_equal([+1, "\xFF"], Bug::Bignum.test_pack((+0x0FF), 1, 1, 0, BIG_ENDIAN))
- assert_equal([+2, "\x00"], Bug::Bignum.test_pack((+0x100), 1, 1, 0, BIG_ENDIAN))
- assert_equal([+2, "\x01"], Bug::Bignum.test_pack((+0x101), 1, 1, 0, BIG_ENDIAN))
-
- assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((-0x10000000000000001), 2, 4, 0, BIG_ENDIAN))
- assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((-0x10000000000000000), 2, 4, 0, BIG_ENDIAN))
- assert_equal([-1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((-0x0FFFFFFFFFFFFFFFF), 2, 4, 0, BIG_ENDIAN))
- assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((+0x0FFFFFFFFFFFFFFFF), 2, 4, 0, BIG_ENDIAN))
- assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((+0x10000000000000000), 2, 4, 0, BIG_ENDIAN))
- assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((+0x10000000000000001), 2, 4, 0, BIG_ENDIAN))
-
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- n = 256**w
- assert_equal([-2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, BIG_ENDIAN))
- assert_equal([-2, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, BIG_ENDIAN))
- assert_equal([-1, "\xFF"*w], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, BIG_ENDIAN))
- assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, BIG_ENDIAN))
- assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, BIG_ENDIAN))
- assert_equal([+2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, BIG_ENDIAN))
- }
- }
+class TestBignum_Pack < Test::Unit::TestCase
+
+ MSWORD_FIRST = Bug::Bignum::INTEGER_PACK_MSWORD_FIRST
+ LSWORD_FIRST = Bug::Bignum::INTEGER_PACK_LSWORD_FIRST
+ MSBYTE_FIRST = Bug::Bignum::INTEGER_PACK_MSBYTE_FIRST
+ LSBYTE_FIRST = Bug::Bignum::INTEGER_PACK_LSBYTE_FIRST
+ NATIVE_BYTE_ORDER = Bug::Bignum::INTEGER_PACK_NATIVE_BYTE_ORDER
+ TWOCOMP = Bug::Bignum::INTEGER_PACK_2COMP
+ LITTLE_ENDIAN = Bug::Bignum::INTEGER_PACK_LITTLE_ENDIAN
+ BIG_ENDIAN = Bug::Bignum::INTEGER_PACK_BIG_ENDIAN
+ NEGATIVE = Bug::Bignum::INTEGER_PACK_NEGATIVE
+ GENERIC = Bug::Bignum::INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
+
+ def test_pack_zero
+ assert_equal([0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, BIG_ENDIAN))
+ end
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- n = 256**w
- assert_equal([-2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, LITTLE_ENDIAN))
- assert_equal([-2, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, LITTLE_ENDIAN))
- assert_equal([-1, "\xFF"*w], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, LITTLE_ENDIAN))
- assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, LITTLE_ENDIAN))
- assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, LITTLE_ENDIAN))
- assert_equal([+2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, LITTLE_ENDIAN))
- }
+ def test_pack_argument_check
+ assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 2, 1, 0, MSBYTE_FIRST) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 1, 0, MSWORD_FIRST) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 0, 0, BIG_ENDIAN) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 0, 1, 8, BIG_ENDIAN) }
+
+ # assume sizeof(ssize_t) == sizeof(intptr_t)
+ assert_raise(ArgumentError) { Bug::Bignum.test_pack_raw(0, "", 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) }
+ end
+
+ def test_pack_wordsize
+ assert_equal([1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, BIG_ENDIAN))
+ assert_equal([1, "\x00\x01"], Bug::Bignum.test_pack(1, 1, 2, 0, BIG_ENDIAN))
+ assert_equal([1, "\x00\x00\x01"], Bug::Bignum.test_pack(1, 1, 3, 0, BIG_ENDIAN))
+ assert_equal([1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, LITTLE_ENDIAN))
+ assert_equal([1, "\x01\x00"], Bug::Bignum.test_pack(1, 1, 2, 0, LITTLE_ENDIAN))
+ assert_equal([1, "\x01\x00\x00"], Bug::Bignum.test_pack(1, 1, 3, 0, LITTLE_ENDIAN))
+ end
+
+ def test_pack_fixed_buffer
+ assert_equal([0, "\x00\x00"], Bug::Bignum.test_pack(0, 2, 1, 0, BIG_ENDIAN))
+ assert_equal([1, "\x00\x01"], Bug::Bignum.test_pack(0x01, 2, 1, 0, BIG_ENDIAN))
+ assert_equal([1, "\x02\x01"], Bug::Bignum.test_pack(0x0201, 2, 1, 0, BIG_ENDIAN))
+ assert_equal([2, "\x02\x01"], Bug::Bignum.test_pack(0x030201, 2, 1, 0, BIG_ENDIAN))
+ assert_equal([2, "\x02\x01"], Bug::Bignum.test_pack(0x04030201, 2, 1, 0, BIG_ENDIAN))
+ assert_equal([0, "\x00\x00"], Bug::Bignum.test_pack(0, 2, 1, 0, LITTLE_ENDIAN))
+ assert_equal([1, "\x01\x00"], Bug::Bignum.test_pack(0x01, 2, 1, 0, LITTLE_ENDIAN))
+ assert_equal([1, "\x01\x02"], Bug::Bignum.test_pack(0x0201, 2, 1, 0, LITTLE_ENDIAN))
+ assert_equal([2, "\x01\x02"], Bug::Bignum.test_pack(0x030201, 2, 1, 0, LITTLE_ENDIAN))
+ assert_equal([2, "\x01\x02"], Bug::Bignum.test_pack(0x04030201, 2, 1, 0, LITTLE_ENDIAN))
+ end
+
+ def test_pack_wordorder_and_endian
+ assert_equal([1, "\x12\x34\x56\x78"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST))
+ assert_equal([1, "\x34\x12\x78\x56"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST))
+ assert_equal([1, "\x56\x78\x12\x34"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST))
+ assert_equal([1, "\x78\x56\x34\x12"], Bug::Bignum.test_pack(0x12345678, 2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST))
+ end
+
+ def test_pack_native_endian
+ assert_equal([1, [0x1234].pack("S!")], Bug::Bignum.test_pack(0x1234, 1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER))
+ end
+
+ def test_pack_nail
+ assert_equal([1, "\x01\x00\x00\x00\x01\x01"], Bug::Bignum.test_pack(0b100011, 6, 1, 7, BIG_ENDIAN))
+ assert_equal([1, "\x01\x02\x03\x04\x05\x06\x07\x08"], Bug::Bignum.test_pack(0x12345678, 8, 1, 4, BIG_ENDIAN))
+ assert_equal([1, "\x00\x12\x00\x34\x00\x56\x00\x78"], Bug::Bignum.test_pack(0x12345678, 4, 2, 8, BIG_ENDIAN))
+ end
+
+ def test_pack_overflow
+ assert_equal([-2, "\x1"], Bug::Bignum.test_pack((-0x11), 1, 1, 4, BIG_ENDIAN))
+ assert_equal([-2, "\x0"], Bug::Bignum.test_pack((-0x10), 1, 1, 4, BIG_ENDIAN))
+ assert_equal([-1, "\xF"], Bug::Bignum.test_pack((-0x0F), 1, 1, 4, BIG_ENDIAN))
+ assert_equal([+1, "\xF"], Bug::Bignum.test_pack((+0x0F), 1, 1, 4, BIG_ENDIAN))
+ assert_equal([+2, "\x0"], Bug::Bignum.test_pack((+0x10), 1, 1, 4, BIG_ENDIAN))
+ assert_equal([+2, "\x1"], Bug::Bignum.test_pack((+0x11), 1, 1, 4, BIG_ENDIAN))
+
+ assert_equal([-2, "\x01"], Bug::Bignum.test_pack((-0x101), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([-2, "\x00"], Bug::Bignum.test_pack((-0x100), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([-1, "\xFF"], Bug::Bignum.test_pack((-0x0FF), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([+1, "\xFF"], Bug::Bignum.test_pack((+0x0FF), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x00"], Bug::Bignum.test_pack((+0x100), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x01"], Bug::Bignum.test_pack((+0x101), 1, 1, 0, BIG_ENDIAN))
+
+ assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((-0x10000000000000001), 2, 4, 0, BIG_ENDIAN))
+ assert_equal([-2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((-0x10000000000000000), 2, 4, 0, BIG_ENDIAN))
+ assert_equal([-1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((-0x0FFFFFFFFFFFFFFFF), 2, 4, 0, BIG_ENDIAN))
+ assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((+0x0FFFFFFFFFFFFFFFF), 2, 4, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((+0x10000000000000000), 2, 4, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((+0x10000000000000001), 2, 4, 0, BIG_ENDIAN))
+
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ n = 256**w
+ assert_equal([-2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, BIG_ENDIAN))
+ assert_equal([-2, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, BIG_ENDIAN))
+ assert_equal([-1, "\xFF"*w], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, BIG_ENDIAN))
+ assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, BIG_ENDIAN))
+ assert_equal([+2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, BIG_ENDIAN))
}
- end
-
- def test_pack_sign
- assert_equal([-1, "\x01"], Bug::Bignum.test_pack((-1), 1, 1, 0, BIG_ENDIAN))
- assert_equal([-1, "\x80\x70\x60\x50\x40\x30\x20\x10"], Bug::Bignum.test_pack((-0x8070605040302010), 8, 1, 0, BIG_ENDIAN))
- end
-
- def test_pack_orders
- [MSWORD_FIRST, LSWORD_FIRST].each {|word_order|
- [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order|
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- n = 0;
- 0.upto(w) {|i|
- n |= ((i+1) % 256) << (i*8)
- }
- assert_equal(Bug::Bignum.test_pack(n, numwords, wordsize, 0, word_order|byte_order|GENERIC),
- Bug::Bignum.test_pack(n, numwords, wordsize, 0, word_order|byte_order),
- "#{'%#x' % n}.test_pack(#{numwords}, #{wordsize}, 0, #{'%#x' % (word_order|byte_order)})")
+ }
+
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ n = 256**w
+ assert_equal([-2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, LITTLE_ENDIAN))
+ assert_equal([-2, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, LITTLE_ENDIAN))
+ assert_equal([-1, "\xFF"*w], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, LITTLE_ENDIAN))
+ assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, LITTLE_ENDIAN))
+ assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, LITTLE_ENDIAN))
+ assert_equal([+2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, LITTLE_ENDIAN))
+ }
+ }
+ end
+
+ def test_pack_sign
+ assert_equal([-1, "\x01"], Bug::Bignum.test_pack((-1), 1, 1, 0, BIG_ENDIAN))
+ assert_equal([-1, "\x80\x70\x60\x50\x40\x30\x20\x10"], Bug::Bignum.test_pack((-0x8070605040302010), 8, 1, 0, BIG_ENDIAN))
+ end
+
+ def test_pack_orders
+ [MSWORD_FIRST, LSWORD_FIRST].each {|word_order|
+ [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order|
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ n = 0;
+ 0.upto(w) {|i|
+ n |= ((i+1) % 256) << (i*8)
}
+ assert_equal(Bug::Bignum.test_pack(n, numwords, wordsize, 0, word_order|byte_order|GENERIC),
+ Bug::Bignum.test_pack(n, numwords, wordsize, 0, word_order|byte_order),
+ "#{'%#x' % n}.test_pack(#{numwords}, #{wordsize}, 0, #{'%#x' % (word_order|byte_order)})")
}
}
}
- end
-
- def test_pack2comp_zero
- assert_equal([0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- end
-
- def test_pack2comp_emptybuf
- assert_equal([-2, ""], Bug::Bignum.test_pack((-3), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-2, ""], Bug::Bignum.test_pack((-2), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, ""], Bug::Bignum.test_pack((-1), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([ 0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, ""], Bug::Bignum.test_pack(1, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, ""], Bug::Bignum.test_pack(2, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
- end
-
- def test_pack2comp_nearly_zero
- assert_equal([-1, "\xFE"], Bug::Bignum.test_pack((-2), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\xFF"], Bug::Bignum.test_pack((-1), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([ 0, "\x00"], Bug::Bignum.test_pack(0, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\x02"], Bug::Bignum.test_pack(2, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- end
-
- def test_pack2comp_overflow
- assert_equal([-2, "\xF"], Bug::Bignum.test_pack((-0x11), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x0"], Bug::Bignum.test_pack((-0x10), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x1"], Bug::Bignum.test_pack((-0x0F), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\xF"], Bug::Bignum.test_pack((+0x0F), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x0"], Bug::Bignum.test_pack((+0x10), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x1"], Bug::Bignum.test_pack((+0x11), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
-
- assert_equal([-2, "\xFF"], Bug::Bignum.test_pack((-0x101), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x00"], Bug::Bignum.test_pack((-0x100), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x01"], Bug::Bignum.test_pack((-0x0FF), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\xFF"], Bug::Bignum.test_pack((+0x0FF), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x00"], Bug::Bignum.test_pack((+0x100), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x01"], Bug::Bignum.test_pack((+0x101), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
-
- assert_equal([-2, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((-0x10000000000000001), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((-0x10000000000000000), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((-0x0FFFFFFFFFFFFFFFF), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((+0x0FFFFFFFFFFFFFFFF), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((+0x10000000000000000), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((+0x10000000000000001), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
-
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- n = 256**w
- assert_equal([-2, "\xFF"*w ], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([-1, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal([+2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
- }
- }
+ }
+ end
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- n = 256**w
- assert_equal([-2, "\xFF"*w ], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- assert_equal([-1, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- assert_equal([-1, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- assert_equal([+2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
- }
- }
+ def test_pack2comp_zero
+ assert_equal([0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ end
- 2.upto(16) {|wordsize|
- w = wordsize
- b = 8*wordsize-1
- n = 2**b
- assert_equal([-2, "\x7F"+"\xFF"*(w-2)+"\xFF"], Bug::Bignum.test_pack((-n-1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n ), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x01"], Bug::Bignum.test_pack((-n+1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- assert_equal([+1, "\x7F"+"\xFF"*(w-2)+"\xFF"], Bug::Bignum.test_pack((+n-1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n ), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x01"], Bug::Bignum.test_pack((+n+1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
- }
+ def test_pack2comp_emptybuf
+ assert_equal([-2, ""], Bug::Bignum.test_pack((-3), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-2, ""], Bug::Bignum.test_pack((-2), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, ""], Bug::Bignum.test_pack((-1), 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([ 0, ""], Bug::Bignum.test_pack(0, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, ""], Bug::Bignum.test_pack(1, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, ""], Bug::Bignum.test_pack(2, 0, 1, 0, TWOCOMP|BIG_ENDIAN))
+ end
- 2.upto(16) {|wordsize|
- w = wordsize
- b = 8*wordsize-1
- n = 2**b
- assert_equal([-2, "\xFF"+"\xFF"*(w-2)+"\x7F"], Bug::Bignum.test_pack((-n-1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
- assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n ), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
- assert_equal([-1, "\x01"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n+1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
- assert_equal([+1, "\xFF"+"\xFF"*(w-2)+"\x7F"], Bug::Bignum.test_pack((+n-1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
- assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n ), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
- assert_equal([+2, "\x01"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n+1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ def test_pack2comp_nearly_zero
+ assert_equal([-1, "\xFE"], Bug::Bignum.test_pack((-2), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\xFF"], Bug::Bignum.test_pack((-1), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([ 0, "\x00"], Bug::Bignum.test_pack(0, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\x01"], Bug::Bignum.test_pack(1, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\x02"], Bug::Bignum.test_pack(2, 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ end
+
+ def test_pack2comp_overflow
+ assert_equal([-2, "\xF"], Bug::Bignum.test_pack((-0x11), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x0"], Bug::Bignum.test_pack((-0x10), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x1"], Bug::Bignum.test_pack((-0x0F), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\xF"], Bug::Bignum.test_pack((+0x0F), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x0"], Bug::Bignum.test_pack((+0x10), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x1"], Bug::Bignum.test_pack((+0x11), 1, 1, 4, TWOCOMP|BIG_ENDIAN))
+
+ assert_equal([-2, "\xFF"], Bug::Bignum.test_pack((-0x101), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x00"], Bug::Bignum.test_pack((-0x100), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x01"], Bug::Bignum.test_pack((-0x0FF), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\xFF"], Bug::Bignum.test_pack((+0x0FF), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x00"], Bug::Bignum.test_pack((+0x100), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x01"], Bug::Bignum.test_pack((+0x101), 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+
+ assert_equal([-2, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((-0x10000000000000001), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((-0x10000000000000000), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((-0x0FFFFFFFFFFFFFFFF), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], Bug::Bignum.test_pack((+0x0FFFFFFFFFFFFFFFF), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], Bug::Bignum.test_pack((+0x10000000000000000), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], Bug::Bignum.test_pack((+0x10000000000000001), 2, 4, 0, TWOCOMP|BIG_ENDIAN))
+
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ n = 256**w
+ assert_equal([-2, "\xFF"*w ], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([-1, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal([+2, "\x00"*(w-1)+"\x01"], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, TWOCOMP|BIG_ENDIAN))
}
+ }
+
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ n = 256**w
+ assert_equal([-2, "\xFF"*w ], Bug::Bignum.test_pack((-n-1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ assert_equal([-1, "\x00"*w], Bug::Bignum.test_pack((-n ), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ assert_equal([-1, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((-n+1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ assert_equal([+1, "\xFF"*w], Bug::Bignum.test_pack((+n-1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ assert_equal([+2, "\x00"*w], Bug::Bignum.test_pack((+n ), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ assert_equal([+2, "\x01"+"\x00"*(w-1)], Bug::Bignum.test_pack((+n+1), numwords, wordsize, 0, TWOCOMP|LITTLE_ENDIAN))
+ }
+ }
+
+ 2.upto(16) {|wordsize|
+ w = wordsize
+ b = 8*wordsize-1
+ n = 2**b
+ assert_equal([-2, "\x7F"+"\xFF"*(w-2)+"\xFF"], Bug::Bignum.test_pack((-n-1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n ), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x01"], Bug::Bignum.test_pack((-n+1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ assert_equal([+1, "\x7F"+"\xFF"*(w-2)+"\xFF"], Bug::Bignum.test_pack((+n-1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n ), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x01"], Bug::Bignum.test_pack((+n+1), 1, wordsize, 1, TWOCOMP|MSBYTE_FIRST))
+ }
+
+ 2.upto(16) {|wordsize|
+ w = wordsize
+ b = 8*wordsize-1
+ n = 2**b
+ assert_equal([-2, "\xFF"+"\xFF"*(w-2)+"\x7F"], Bug::Bignum.test_pack((-n-1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ assert_equal([-1, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n ), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ assert_equal([-1, "\x01"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((-n+1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ assert_equal([+1, "\xFF"+"\xFF"*(w-2)+"\x7F"], Bug::Bignum.test_pack((+n-1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ assert_equal([+2, "\x00"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n ), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ assert_equal([+2, "\x01"+"\x00"*(w-2)+"\x00"], Bug::Bignum.test_pack((+n+1), 1, wordsize, 1, TWOCOMP|LSBYTE_FIRST))
+ }
+
+ end
+
+ def test_unpack_zero
+ assert_equal(0, Bug::Bignum.test_unpack("", 0, 1, 0, BIG_ENDIAN))
+ end
+
+ def test_unpack_argument_check
+ assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 2, 1, 0, MSBYTE_FIRST) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1, 0, MSWORD_FIRST) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 0, 0, BIG_ENDIAN) }
+ assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1, 8, BIG_ENDIAN) }
+
+ # assume sizeof(ssize_t) == sizeof(intptr_t)
+ assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) }
+ end
+
+ def test_unpack_wordsize
+ assert_equal(1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN))
+ assert_equal(1, Bug::Bignum.test_unpack("\x00\x01", 1, 2, 0, BIG_ENDIAN))
+ assert_equal(1, Bug::Bignum.test_unpack("\x00\x00\x01", 1, 3, 0, BIG_ENDIAN))
+ assert_equal(1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, LITTLE_ENDIAN))
+ assert_equal(1, Bug::Bignum.test_unpack("\x01\x00", 1, 2, 0, LITTLE_ENDIAN))
+ assert_equal(1, Bug::Bignum.test_unpack("\x01\x00\x00", 1, 3, 0, LITTLE_ENDIAN))
+ end
+
+ def test_unpack_wordorder_and_endian
+ assert_equal(0x01020304, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST))
+ assert_equal(0x02010403, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST))
+ assert_equal(0x03040102, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST))
+ assert_equal(0x04030201, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST))
+ end
+
+ def test_unpack_native_endian
+ assert_equal("\x12\x34".unpack("S!")[0], Bug::Bignum.test_unpack("\x12\x34", 1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER))
+ end
+
+ def test_unpack_nail
+ assert_equal(0b100011, Bug::Bignum.test_unpack("\x01\x00\x00\x00\x01\x01", 6, 1, 7, BIG_ENDIAN))
+ assert_equal(0x12345678, Bug::Bignum.test_unpack("\x01\x02\x03\x04\x05\x06\x07\x08", 8, 1, 4, BIG_ENDIAN))
+ assert_equal(0x12345678, Bug::Bignum.test_unpack("\x00\x12\x00\x34\x00\x56\x00\x78", 4, 2, 8, BIG_ENDIAN))
+ end
+
+ def test_unpack_sign
+ assert_equal(-1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
+ assert_equal(-0x8070605040302010, Bug::Bignum.test_unpack("\x80\x70\x60\x50\x40\x30\x20\x10", 8, 1, 0, BIG_ENDIAN|NEGATIVE))
+ end
- end
-
- def test_unpack_zero
- assert_equal(0, Bug::Bignum.test_unpack("", 0, 1, 0, BIG_ENDIAN))
- end
-
- def test_unpack_argument_check
- assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 2, 1, 0, MSBYTE_FIRST) }
- assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1, 0, MSWORD_FIRST) }
- assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 0, 0, BIG_ENDIAN) }
- assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1, 8, BIG_ENDIAN) }
-
- # assume sizeof(ssize_t) == sizeof(intptr_t)
- assert_raise(ArgumentError) { Bug::Bignum.test_unpack("x", 1, 1 << ([""].pack("p").length * 8 - 1), 0, BIG_ENDIAN) }
- end
-
- def test_unpack_wordsize
- assert_equal(1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN))
- assert_equal(1, Bug::Bignum.test_unpack("\x00\x01", 1, 2, 0, BIG_ENDIAN))
- assert_equal(1, Bug::Bignum.test_unpack("\x00\x00\x01", 1, 3, 0, BIG_ENDIAN))
- assert_equal(1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, LITTLE_ENDIAN))
- assert_equal(1, Bug::Bignum.test_unpack("\x01\x00", 1, 2, 0, LITTLE_ENDIAN))
- assert_equal(1, Bug::Bignum.test_unpack("\x01\x00\x00", 1, 3, 0, LITTLE_ENDIAN))
- end
-
- def test_unpack_wordorder_and_endian
- assert_equal(0x01020304, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|MSBYTE_FIRST))
- assert_equal(0x02010403, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, MSWORD_FIRST|LSBYTE_FIRST))
- assert_equal(0x03040102, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|MSBYTE_FIRST))
- assert_equal(0x04030201, Bug::Bignum.test_unpack("\x01\x02\x03\x04", 2, 2, 0, LSWORD_FIRST|LSBYTE_FIRST))
- end
-
- def test_unpack_native_endian
- assert_equal("\x12\x34".unpack("S!")[0], Bug::Bignum.test_unpack("\x12\x34", 1, 2, 0, MSWORD_FIRST|NATIVE_BYTE_ORDER))
- end
-
- def test_unpack_nail
- assert_equal(0b100011, Bug::Bignum.test_unpack("\x01\x00\x00\x00\x01\x01", 6, 1, 7, BIG_ENDIAN))
- assert_equal(0x12345678, Bug::Bignum.test_unpack("\x01\x02\x03\x04\x05\x06\x07\x08", 8, 1, 4, BIG_ENDIAN))
- assert_equal(0x12345678, Bug::Bignum.test_unpack("\x00\x12\x00\x34\x00\x56\x00\x78", 4, 2, 8, BIG_ENDIAN))
- end
-
- def test_unpack_sign
- assert_equal(-1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
- assert_equal(-0x8070605040302010, Bug::Bignum.test_unpack("\x80\x70\x60\x50\x40\x30\x20\x10", 8, 1, 0, BIG_ENDIAN|NEGATIVE))
- end
-
- def test_unpack_orders
- [MSWORD_FIRST, LSWORD_FIRST].each {|word_order|
- [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order|
- 1.upto(16) {|wordsize|
- 1.upto(20) {|numwords|
- w = numwords*wordsize
- ary = []
- 0.upto(w) {|i|
- ary << ((i+1) % 256);
- }
- str = ary.pack("C*")
- flags = word_order|byte_order
- assert_equal(Bug::Bignum.test_unpack(str, numwords, wordsize, 0, flags|GENERIC),
- Bug::Bignum.test_unpack(str, numwords, wordsize, 0, flags),
- "Bug::Bignum.test_unpack(#{str.dump}, #{numwords}, #{wordsize}, 0, #{'%#x' % flags})")
+ def test_unpack_orders
+ [MSWORD_FIRST, LSWORD_FIRST].each {|word_order|
+ [MSBYTE_FIRST, LSBYTE_FIRST, NATIVE_BYTE_ORDER].each {|byte_order|
+ 1.upto(16) {|wordsize|
+ 1.upto(20) {|numwords|
+ w = numwords*wordsize
+ ary = []
+ 0.upto(w) {|i|
+ ary << ((i+1) % 256);
}
+ str = ary.pack("C*")
+ flags = word_order|byte_order
+ assert_equal(Bug::Bignum.test_unpack(str, numwords, wordsize, 0, flags|GENERIC),
+ Bug::Bignum.test_unpack(str, numwords, wordsize, 0, flags),
+ "Bug::Bignum.test_unpack(#{str.dump}, #{numwords}, #{wordsize}, 0, #{'%#x' % flags})")
}
}
}
- end
-
- def test_unpack2comp_single_byte
- assert_equal(-128, Bug::Bignum.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( -2, Bug::Bignum.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( -1, Bug::Bignum.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( 0, Bug::Bignum.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( 1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( 2, Bug::Bignum.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal( 127, Bug::Bignum.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
- end
-
- def test_unpack2comp_sequence_of_ff
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*2, 2, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*3, 3, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*4, 4, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*5, 5, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*6, 6, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*7, 7, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*8, 8, 1, 0, TWOCOMP|BIG_ENDIAN))
- assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*9, 9, 1, 0, TWOCOMP|BIG_ENDIAN))
- end
-
- def test_unpack2comp_negative_single_byte
- assert_equal(-256, Bug::Bignum.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal(-255, Bug::Bignum.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal(-254, Bug::Bignum.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal(-129, Bug::Bignum.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal(-128, Bug::Bignum.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal( -2, Bug::Bignum.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- assert_equal( -1, Bug::Bignum.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
- end
-
- def test_unpack2comp_negative_zero
- 0.upto(100) {|n|
- str = "\x00"*n
- flags = TWOCOMP|BIG_ENDIAN|NEGATIVE
- assert_equal(-(256**n), Bug::Bignum.test_unpack(str, n, 1, 0, flags))
- flags = TWOCOMP|LITTLE_ENDIAN|NEGATIVE
- assert_equal(-(256**n), Bug::Bignum.test_unpack(str, n, 1, 0, flags),
- "Bug::Bignum.test_unpack(#{str.dump}, #{n}, 1, 0, #{'%#x' % flags})")
- }
- end
+ }
+ end
+
+ def test_unpack2comp_single_byte
+ assert_equal(-128, Bug::Bignum.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( -2, Bug::Bignum.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( -1, Bug::Bignum.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( 0, Bug::Bignum.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( 1, Bug::Bignum.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( 2, Bug::Bignum.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal( 127, Bug::Bignum.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
+ end
+
+ def test_unpack2comp_sequence_of_ff
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*2, 2, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*3, 3, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*4, 4, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*5, 5, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*6, 6, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*7, 7, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*8, 8, 1, 0, TWOCOMP|BIG_ENDIAN))
+ assert_equal(-1, Bug::Bignum.test_unpack("\xFF"*9, 9, 1, 0, TWOCOMP|BIG_ENDIAN))
+ end
+
+ def test_unpack2comp_negative_single_byte
+ assert_equal(-256, Bug::Bignum.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal(-255, Bug::Bignum.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal(-254, Bug::Bignum.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal(-129, Bug::Bignum.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal(-128, Bug::Bignum.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal( -2, Bug::Bignum.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ assert_equal( -1, Bug::Bignum.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
+ end
+
+ def test_unpack2comp_negative_zero
+ 0.upto(100) {|n|
+ str = "\x00"*n
+ flags = TWOCOMP|BIG_ENDIAN|NEGATIVE
+ assert_equal(-(256**n), Bug::Bignum.test_unpack(str, n, 1, 0, flags))
+ flags = TWOCOMP|LITTLE_ENDIAN|NEGATIVE
+ assert_equal(-(256**n), Bug::Bignum.test_unpack(str, n, 1, 0, flags),
+ "Bug::Bignum.test_unpack(#{str.dump}, #{n}, 1, 0, #{'%#x' % flags})")
+ }
end
def test_numbits_2comp
@@ -395,5 +393,4 @@ class Test_Bignum < Test::Unit::TestCase
assert_equal(5, Bug::Bignum.test_numbytes_2comp_with_sign(0x7fffffffff))
assert_equal(6, Bug::Bignum.test_numbytes_2comp_with_sign(0x8000000000))
end
-
end
diff --git a/test/-ext-/bignum/test_str2big.rb b/test/-ext-/bignum/test_str2big.rb
index d5bd72a85b..d27e4d23f7 100644
--- a/test/-ext-/bignum/test_str2big.rb
+++ b/test/-ext-/bignum/test_str2big.rb
@@ -2,37 +2,35 @@
require 'test/unit'
require "-test-/bignum"
-class Test_Bignum < Test::Unit::TestCase
- class TestStr2big < Test::Unit::TestCase
+class TestBignum_Str2big < Test::Unit::TestCase
- SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
- BITSPERDIG = Bug::Bignum::BITSPERDIG
- BDIGMAX = (1 << BITSPERDIG) - 1
+ SIZEOF_BDIGIT = Bug::Bignum::SIZEOF_BDIGIT
+ BITSPERDIG = Bug::Bignum::BITSPERDIG
+ BDIGMAX = (1 << BITSPERDIG) - 1
- def test_str2big_poweroftwo
- s = "1" + "0" * 1000
- n = 16 ** 1000
- assert_equal(n, Bug::Bignum.str2big_poweroftwo(s, 16, true))
- end
-
- def test_str2big_normal
- s = "1" + "0" * 1000
- n = 10 ** 1000
- assert_equal(n, Bug::Bignum.str2big_normal(s, 10, true))
- end
+ def test_str2big_poweroftwo
+ s = "1" + "0" * 1000
+ n = 16 ** 1000
+ assert_equal(n, Bug::Bignum.str2big_poweroftwo(s, 16, true))
+ end
- def test_str2big_karatsuba
- s = "1" + "0" * 1000
- n = 10 ** 1000
- assert_equal(n, Bug::Bignum.str2big_karatsuba(s, 10, true))
- end
+ def test_str2big_normal
+ s = "1" + "0" * 1000
+ n = 10 ** 1000
+ assert_equal(n, Bug::Bignum.str2big_normal(s, 10, true))
+ end
- def test_str2big_gmp
- s = "1" + "0" * 1000
- n = 10 ** 1000
- assert_equal(n, Bug::Bignum.str2big_gmp(s, 10, true))
- rescue NotImplementedError
- end
+ def test_str2big_karatsuba
+ s = "1" + "0" * 1000
+ n = 10 ** 1000
+ assert_equal(n, Bug::Bignum.str2big_karatsuba(s, 10, true))
+ end
+ def test_str2big_gmp
+ s = "1" + "0" * 1000
+ n = 10 ** 1000
+ assert_equal(n, Bug::Bignum.str2big_gmp(s, 10, true))
+ rescue NotImplementedError
end
+
end
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index 6d3640eba5..990b6a2cc5 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -4,10 +4,10 @@ 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(/\+MJIT /, '') if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
description = description.sub(/\+YJIT /, '') if defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
expected_stderr = [
:*,
@@ -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 e0a76935b1..ea8d7c7fc7 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-/funcall/test_funcall.rb b/test/-ext-/funcall/test_funcall.rb
deleted file mode 100644
index 01a03bf5ef..0000000000
--- a/test/-ext-/funcall/test_funcall.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-
-class TestFuncall < Test::Unit::TestCase
- require '-test-/funcall'
-
- def test_funcall_extra_args
- assert_equal 'TestFuncall', TestFuncall.extra_args_name,
- '[ruby-core:85266] [Bug #14425]'
- end
-end
diff --git a/test/-ext-/funcall/test_passing_block.rb b/test/-ext-/funcall/test_passing_block.rb
index 71c9d905be..8964403494 100644
--- a/test/-ext-/funcall/test_passing_block.rb
+++ b/test/-ext-/funcall/test_passing_block.rb
@@ -9,6 +9,11 @@ class TestFuncall < Test::Unit::TestCase
end
require '-test-/funcall'
+ def test_funcall_extra_args
+ assert_equal 'TestFuncall', TestFuncall.extra_args_name,
+ '[ruby-core:85266] [Bug #14425]'
+ end
+
def test_with_funcall2
ok = nil
Relay.with_funcall2("feature#4504") {|arg| ok = arg || true}
diff --git a/test/-ext-/gvl/test_ubf_async_safe.rb b/test/-ext-/gvl/test_ubf_async_safe.rb
index fdaa4d418b..3261b42475 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 ffa6541c72..6e5bc8e811 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-/string/test_capacity.rb b/test/-ext-/string/test_capacity.rb
index 583c98fca4..0cb7c00761 100644
--- a/test/-ext-/string/test_capacity.rb
+++ b/test/-ext-/string/test_capacity.rb
@@ -5,13 +5,14 @@ require 'rbconfig/sizeof'
class Test_StringCapacity < Test::Unit::TestCase
def test_capacity_embedded
- assert_equal GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] - embed_header_size - 1, capa('foo')
+ assert_equal GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] - embed_header_size - 1, capa('foo')
assert_equal max_embed_len, capa('1' * max_embed_len)
assert_equal max_embed_len, capa('1' * (max_embed_len - 1))
end
def test_capacity_shared
- assert_equal 0, capa(:abcdefghijklmnopqrstuvwxyz.to_s)
+ sym = ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]).to_sym
+ assert_equal 0, capa(sym.to_s)
end
def test_capacity_normal
@@ -46,13 +47,13 @@ class Test_StringCapacity < Test::Unit::TestCase
def test_capacity_frozen
s = String.new("I am testing", capacity: 1000)
- s << "fstring capacity"
+ s << "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]
s.freeze
assert_equal(s.length, capa(s))
end
def test_capacity_fstring
- s = String.new("a" * max_embed_len, capacity: 1000)
+ s = String.new("a" * max_embed_len, capacity: max_embed_len * 3)
s << "fstring capacity"
s = -s
assert_equal(s.length, capa(s))
@@ -66,7 +67,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 9b4956ecef..5a3456c566 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 58f51012fb..67ba961194 100644
--- a/test/-ext-/string/test_set_len.rb
+++ b/test/-ext-/string/test_set_len.rb
@@ -4,23 +4,25 @@ require "-test-/string"
class Test_StrSetLen < Test::Unit::TestCase
def setup
- @s0 = [*"a".."z"].join("").freeze
+ # Make string long enough so that it is not embedded
+ @range_end = ("0".ord + GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]).chr
+ @s0 = [*"0"..@range_end].join("").freeze
@s1 = Bug::String.new(@s0)
end
def teardown
- orig = [*"a".."z"].join("")
+ orig = [*"0"..@range_end].join("")
assert_equal(orig, @s0)
end
def test_non_shared
@s1.modify!
- assert_equal("abc", @s1.set_len(3))
+ assert_equal("012", @s1.set_len(3))
end
def test_shared
assert_raise(RuntimeError) {
- assert_equal("abc", @s1.set_len(3))
+ @s1.set_len(3)
}
end
diff --git a/test/-ext-/test_abi.rb b/test/-ext-/test_abi.rb
new file mode 100644
index 0000000000..ec2050ecad
--- /dev/null
+++ b/test/-ext-/test_abi.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class TestABI < Test::Unit::TestCase
+ def test_require_lib_with_incorrect_abi_on_dev_ruby
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [], <<~RUBY
+ err = assert_raise(LoadError) { require "-test-/abi" }
+ assert_match(/ABI version of binary is incompatible with this Ruby/, err.message)
+ RUBY
+ end
+
+ def test_disable_abi_check_using_environment_variable
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [{ "RUBY_ABI_CHECK" => "0" }], <<~RUBY
+ assert_nothing_raised { require "-test-/abi" }
+ RUBY
+ end
+
+ def test_enable_abi_check_using_environment_variable
+ omit "ABI is not checked" unless abi_checking_supported?
+
+ assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY
+ err = assert_raise(LoadError) { require "-test-/abi" }
+ assert_match(/ABI version of binary is incompatible with this Ruby/, err.message)
+ RUBY
+ end
+
+ def test_require_lib_with_incorrect_abi_on_release_ruby
+ omit "ABI is enforced" if abi_checking_supported?
+
+ assert_separately [], <<~RUBY
+ assert_nothing_raised { require "-test-/abi" }
+ RUBY
+ end
+
+ private
+
+ def abi_checking_supported?
+ !(RUBY_PLATFORM =~ /mswin|mingw/)
+ end
+end
diff --git a/test/bigdecimal/helper.rb b/test/bigdecimal/helper.rb
index 22b05f09ae..46721fb9a8 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 49e6b2a70e..0cd85249ad 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 ffd4c5f679..2f27163ebf 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_util.rb b/test/cgi/test_cgi_util.rb
index 6ce8b42c20..5a2d07b328 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 bfe6ddd527..21d9f20b28 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 14903d462c..d2b74008eb 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 3564fcb3ba..c5e35209cc 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 3202963a67..968e64eae7 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 34a672b069..d8dcf6e05e 100644
--- a/test/date/test_date_parse.rb
+++ b/test/date/test_date_parse.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'test/unit'
require 'date'
-require 'timeout'
+require 'envutil'
class TestDateParse < Test::Unit::TestCase
@@ -585,6 +585,18 @@ class TestDateParse < Test::Unit::TestCase
assert_equal(5025, h[:offset])
end
+ def test__parse_too_long_year
+ str = "Jan 1" + "0" * 100_000
+ h = EnvUtil.timeout(3) {Date._parse(str, limit: 100_010)}
+ assert_equal(100_000, Math.log10(h[:year]))
+ assert_equal(1, h[:mon])
+
+ str = "Jan - 1" + "0" * 100_000
+ h = EnvUtil.timeout(3) {Date._parse(str, limit: 100_010)}
+ assert_equal(1, h[:mon])
+ assert_not_include(h, :year)
+ end
+
require 'time'
def test_parse__time
@@ -852,7 +864,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._iso8601(nil)
assert_equal({}, h)
- h = Date._iso8601('01-02-03T04:05:06Z'.to_sym)
+ h = assert_deprecated_warn {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
@@ -874,7 +886,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc3339(nil)
assert_equal({}, h)
- h = Date._rfc3339('2001-02-03T04:05:06Z'.to_sym)
+ h = assert_deprecated_warn {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
@@ -963,7 +975,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._xmlschema(nil)
assert_equal({}, h)
- h = Date._xmlschema('2001-02-03'.to_sym)
+ h = assert_deprecated_warn {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
@@ -1002,7 +1014,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc2822(nil)
assert_equal({}, h)
- h = Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT'.to_sym)
+ h = assert_deprecated_warn {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
@@ -1029,7 +1041,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._httpdate(nil)
assert_equal({}, h)
- h = Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT'.to_sym)
+ h = assert_deprecated_warn {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
@@ -1112,7 +1124,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._jisx0301(nil)
assert_equal({}, h)
- h = Date._jisx0301('H13.02.03T04:05:06.07+0100'.to_sym)
+ h = assert_deprecated_warn {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
@@ -1297,6 +1309,5 @@ class TestDateParse < Test::Unit::TestCase
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_ractor.rb b/test/date/test_date_ractor.rb
index 7b0c3f4911..7ec953d87a 100644
--- a/test/date/test_date_ractor.rb
+++ b/test/date/test_date_ractor.rb
@@ -2,7 +2,7 @@
require 'test/unit'
require 'date'
-class TestDateParse < Test::Unit::TestCase
+class TestDateParseRactor < Test::Unit::TestCase
def code(klass = Date, share: false)
<<~RUBY.gsub('Date', klass.name)
share = #{share}
diff --git a/test/date/test_date_strftime.rb b/test/date/test_date_strftime.rb
index be9354504a..dd04c0d9a4 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 9dc08dbde3..91871cda9a 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 d8aa41c3d1..7cb7b10282 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/did_you_mean/test_ractor_compatibility.rb b/test/did_you_mean/test_ractor_compatibility.rb
new file mode 100644
index 0000000000..f66a1a9d62
--- /dev/null
+++ b/test/did_you_mean/test_ractor_compatibility.rb
@@ -0,0 +1,117 @@
+require_relative './helper'
+
+return if not DidYouMean::TestHelper.ractor_compatible?
+
+class RactorCompatibilityTest < Test::Unit::TestCase
+ def test_class_name_suggestion_works_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ class ::Book; end
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ begin
+ Boook
+ rescue NameError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_correction "Book", error.corrections
+ CODE
+ end
+
+ def test_key_name_suggestion_works_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ begin
+ hash = { "foo" => 1, bar: 2 }
+
+ hash.fetch(:bax)
+ rescue KeyError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_correction ":bar", error.corrections
+ assert_match "Did you mean? :bar", error.to_s
+ CODE
+ end
+
+ def test_method_name_suggestion_works_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ begin
+ self.to__s
+ rescue NoMethodError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_correction :to_s, error.corrections
+ assert_match "Did you mean? to_s", error.to_s
+ CODE
+ end
+
+ if defined?(::NoMatchingPatternKeyError)
+ def test_pattern_key_name_suggestion_works_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ begin
+ eval(<<~RUBY, binding, __FILE__, __LINE__)
+ hash = {foo: 1, bar: 2, baz: 3}
+ hash => {fooo:}
+ fooo = 1 # suppress "unused variable: fooo" warning
+ RUBY
+ rescue NoMatchingPatternKeyError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_correction ":foo", error.corrections
+ assert_match "Did you mean? :foo", error.to_s
+ CODE
+ end
+ end
+
+ def test_can_raise_other_name_error_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ class FirstNameError < NameError; end
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ begin
+ raise FirstNameError, "Other name error"
+ rescue FirstNameError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_not_match(/Did you mean\?/, error.message)
+ CODE
+ end
+
+ def test_variable_name_suggestion_works_in_ractor
+ assert_ractor(<<~CODE, require_relative: "helper")
+ include DidYouMean::TestHelper
+ error = Ractor.new {
+ in_ractor = in_ractor = 1
+
+ begin
+ in_reactor
+ rescue NameError => e
+ e.corrections # It is important to call the #corrections method within Ractor.
+ e
+ end
+ }.take
+
+ assert_correction :in_ractor, error.corrections
+ assert_match "Did you mean? in_ractor", error.to_s
+ CODE
+ end
+end
diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb
index f3d20201bc..3c33aedb6f 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 ce730800b4..7fa16965f1 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 08036bca54..a3cc7aa149 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/excludes/TestGem.rb b/test/excludes/TestGem.rb
new file mode 100644
index 0000000000..042af26eff
--- /dev/null
+++ b/test/excludes/TestGem.rb
@@ -0,0 +1,4 @@
+if RbConfig::CONFIG["LIBRUBY_RELATIVE"] == "yes"
+ exclude(/test_looks_for_gemdeps_files_automatically_from_binstubs/,
+ "can't test before installation")
+end
diff --git a/test/excludes/TestThread.rb b/test/excludes/TestThread.rb
index ea73a4c010..cf7e88427e 100644
--- a/test/excludes/TestThread.rb
+++ b/test/excludes/TestThread.rb
@@ -1,2 +1,14 @@
# frozen_string_literal: false
exclude(/_stack_size$/, 'often too expensive')
+if /freebsd13/ =~ RUBY_PLATFORM
+ # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220216T143001Z.fail.html.gz
+ #
+ # 1) Error:
+ # TestThread#test_signal_at_join:
+ # Timeout::Error: execution of assert_separately expired timeout (120 sec)
+ # pid 30743 killed by SIGABRT (signal 6) (core dumped)
+ # |
+ #
+ # /usr/home/chkbuild/chkbuild/tmp/build/20220216T143001Z/ruby/test/ruby/test_thread.rb:1390:in `test_signal_at_join'
+ exclude(:test_signal_at_join, 'gets stuck somewhere')
+end
diff --git a/test/excludes/TestThreadQueue.rb b/test/excludes/TestThreadQueue.rb
new file mode 100644
index 0000000000..c8231e372a
--- /dev/null
+++ b/test/excludes/TestThreadQueue.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: false
+if /freebsd13/ =~ RUBY_PLATFORM
+ # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220308T023001Z.fail.html.gz
+ #
+ # 1) Failure:
+ # TestThreadQueue#test_thr_kill [/usr/home/chkbuild/chkbuild/tmp/build/20220308T023001Z/ruby/test/ruby/test_thread_queue.rb:175]:
+ # only 169/250 done in 60 seconds.
+ exclude(:test_thr_kill, 'gets stuck somewhere')
+end
diff --git a/test/fiber/autoload.rb b/test/fiber/autoload.rb
new file mode 100644
index 0000000000..dcb27164a7
--- /dev/null
+++ b/test/fiber/autoload.rb
@@ -0,0 +1,3 @@
+sleep 0.01
+module TestFiberSchedulerAutoload
+end
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index a6e1325259..96b22856d1 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -30,7 +30,7 @@ class Scheduler
@closed = false
@lock = Thread::Mutex.new
- @blocking = 0
+ @blocking = Hash.new.compare_by_identity
@ready = []
@urgent = IO.pipe
@@ -57,7 +57,7 @@ class Scheduler
def run
# $stderr.puts [__method__, Fiber.current].inspect
- while @readable.any? or @writable.any? or @waiting.any? or @blocking.positive?
+ while @readable.any? or @writable.any? or @waiting.any? or @blocking.any?
# Can only handle file descriptors up to 1024...
readable, writable = IO.select(@readable.keys + [@urgent.first], @writable.keys, [], next_timeout)
@@ -192,6 +192,9 @@ class Scheduler
end
Fiber.yield
+ ensure
+ @readable.delete(io)
+ @writable.delete(io)
end
# Used for Kernel#sleep and Thread::Mutex#sleep
@@ -208,20 +211,22 @@ class Scheduler
def block(blocker, timeout = nil)
# $stderr.puts [__method__, blocker, timeout].inspect
+ fiber = Fiber.current
+
if timeout
- @waiting[Fiber.current] = current_time + timeout
+ @waiting[fiber] = current_time + timeout
begin
Fiber.yield
ensure
# Remove from @waiting in the case #unblock was called before the timeout expired:
- @waiting.delete(Fiber.current)
+ @waiting.delete(fiber)
end
else
- @blocking += 1
+ @blocking[fiber] = true
begin
Fiber.yield
ensure
- @blocking -= 1
+ @blocking.delete(fiber)
end
end
end
@@ -257,6 +262,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 cd4ccd1de5..c635f474db 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 ce65a55f78..4252641cde 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 0000000000..48a34c31b6
--- /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 c6583cac9b..a5990be204 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 d03455a9f7..3c4ccbd8e5 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 1870ab1c33..4b1310f0a6 100644
--- a/test/fiber/test_scheduler.rb
+++ b/test/fiber/test_scheduler.rb
@@ -104,4 +104,26 @@ class TestFiberScheduler < Test::Unit::TestCase
thread.join
end
+
+ def test_autoload
+ 100.times do
+ Object.autoload(:TestFiberSchedulerAutoload, File.expand_path("autoload.rb", __dir__))
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ 10.times do
+ Fiber.schedule do
+ Object.const_get(:TestFiberSchedulerAutoload)
+ end
+ end
+ end
+
+ thread.join
+ ensure
+ $LOADED_FEATURES.delete(File.expand_path("autoload.rb", __dir__))
+ Object.send(:remove_const, :TestFiberSchedulerAutoload)
+ end
+ end
end
diff --git a/test/fileutils/clobber.rb b/test/fileutils/clobber.rb
index fdcecd5e08..ac5c8c79c0 100644
--- a/test/fileutils/clobber.rb
+++ b/test/fileutils/clobber.rb
@@ -4,10 +4,7 @@ require 'test/unit'
require 'tmpdir'
require_relative 'fileasserts'
-class TestFileUtils < Test::Unit::TestCase
-end
-
-module TestFileUtils::Clobber
+module TestFileUtilsClobber
include Test::Unit::FileAssertions
def my_rm_rf(path)
diff --git a/test/fileutils/test_dryrun.rb b/test/fileutils/test_dryrun.rb
index fd8a7805ec..a3efbb4bdf 100644
--- a/test/fileutils/test_dryrun.rb
+++ b/test/fileutils/test_dryrun.rb
@@ -8,7 +8,7 @@ require_relative 'visibility_tests'
class TestFileUtilsDryRun < Test::Unit::TestCase
include FileUtils::DryRun
- include TestFileUtilsInc::Visibility
+ include TestFileUtilsIncVisibility
def setup
super
diff --git a/test/fileutils/test_nowrite.rb b/test/fileutils/test_nowrite.rb
index 543fa39f5a..659fa20886 100644
--- a/test/fileutils/test_nowrite.rb
+++ b/test/fileutils/test_nowrite.rb
@@ -8,7 +8,7 @@ require_relative 'visibility_tests'
class TestFileUtilsNoWrite < Test::Unit::TestCase
include FileUtils::NoWrite
- include TestFileUtilsInc::Visibility
+ include TestFileUtilsIncVisibility
def setup
super
diff --git a/test/fileutils/test_verbose.rb b/test/fileutils/test_verbose.rb
index cf65be8e03..7987af2395 100644
--- a/test/fileutils/test_verbose.rb
+++ b/test/fileutils/test_verbose.rb
@@ -8,7 +8,7 @@ require_relative 'visibility_tests'
class TestFileUtilsVerbose < Test::Unit::TestCase
include FileUtils::Verbose
- include TestFileUtilsInc::Visibility
+ include TestFileUtilsIncVisibility
def setup
super
diff --git a/test/fileutils/visibility_tests.rb b/test/fileutils/visibility_tests.rb
index 4c02c9d207..9f8f8dc9e1 100644
--- a/test/fileutils/visibility_tests.rb
+++ b/test/fileutils/visibility_tests.rb
@@ -2,14 +2,11 @@
require 'test/unit'
require 'fileutils'
-class TestFileUtilsInc < Test::Unit::TestCase
-end
-
##
# These tests are reused in the FileUtils::Verbose, FileUtils::NoWrite and
# FileUtils::DryRun tests
-module TestFileUtilsInc::Visibility
+module TestFileUtilsIncVisibility
FileUtils::METHODS.each do |m|
define_method "test_singleton_visibility_#{m}" do
diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb
index 33b98990a1..f6e46fe112 100644
--- a/test/io/console/test_io_console.rb
+++ b/test/io/console/test_io_console.rb
@@ -383,7 +383,14 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("Interrupt", cc, r, w) unless /linux|solaris/ =~ RUBY_PLATFORM
end
- if cc = ctrl["dsusp"]
+ # This test fails randomly on FreeBSD 13
+ # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220304T163001Z.fail.html.gz
+ #
+ # 1) Failure:
+ # TestIO_Console#test_intr [/usr/home/chkbuild/chkbuild/tmp/build/20220304T163001Z/ruby/test/io/console/test_io_console.rb:387]:
+ # <"25"> expected but was
+ # <"-e:12:in `p': \e[1mexecution expired (\e[1;4mTimeout::Error\e[m\e[1m)\e[m">.
+ if (cc = ctrl["dsusp"]) && /freebsd/ !~ RUBY_PLATFORM
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
@@ -407,6 +414,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
@@ -483,6 +494,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 08d129de3f..447d761f18 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 75cd335802..7b92e4c758 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"
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb
index 8eee36badc..7b7ab55a64 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 d908195e6a..42f82fc37e 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_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index e02370d3f7..47435d675e 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/json/json_addition_test.rb b/test/json/json_addition_test.rb
index e95ace8375..614c735567 100644
--- a/test/json/json_addition_test.rb
+++ b/test/json/json_addition_test.rb
@@ -165,7 +165,7 @@ class JSONAdditionTest < Test::Unit::TestCase
def test_utc_datetime
now = Time.now
- d = DateTime.parse(now.to_s, :create_additions => true) # usual case
+ d = DateTime.parse(now.to_s) # usual case
assert_equal d, parse(d.to_json, :create_additions => true)
d = DateTime.parse(now.utc.to_s) # of = 0
assert_equal d, parse(d.to_json, :create_additions => true)
diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb
index dce693e548..00b254fc6a 100644
--- a/test/json/json_parser_test.rb
+++ b/test/json/json_parser_test.rb
@@ -84,6 +84,7 @@ class JSONParserTest < Test::Unit::TestCase
assert_equal({ "a" => 23 }, parse(' { "a" : 23 } '))
assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
assert_equal({ "a" => 0.23 }, parse(' { "a" : 0.23 } '))
+ assert_equal({ "" => 123 }, parse('{"":123}'))
end
def test_parse_numbers
diff --git a/test/lib/jit_support.rb b/test/lib/jit_support.rb
index 779aa8567e..c7618e03a0 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 0000000000..9465722991
--- /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 d360fa2107..8f1c15542a 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 3281d17c7b..37d0f5862a 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/mkmf/base.rb b/test/mkmf/base.rb
index 4f67478a56..e097c396d6 100644
--- a/test/mkmf/base.rb
+++ b/test/mkmf/base.rb
@@ -20,134 +20,131 @@ $INCFLAGS << " -I."
$extout_prefix = "$(extout)$(target_prefix)/"
class TestMkmf < Test::Unit::TestCase
-end
-
-module TestMkmf::Base
- MKMFLOG = proc {File.read("mkmf.log") rescue ""}
+ module Base
+ MKMFLOG = proc {File.read("mkmf.log") rescue ""}
- class Capture
- attr_accessor :origin
- def initialize
- @buffer = ""
- @filter = nil
- @out = true
- @origin = nil
- end
- def clear
- @buffer.clear
- end
- def flush
- STDOUT.print @filter ? @filter.call(@buffer) : @buffer
- clear
- end
- def reopen(io)
- case io
- when Capture
- initialize_copy(io)
- when File
- @out = false
- @origin.reopen(io) if @origin
- when IO
+ class Capture
+ attr_accessor :origin
+ def initialize
+ @buffer = ""
+ @filter = nil
@out = true
- @origin.reopen(io) if @origin
- else
- @out = false
+ @origin = nil
end
- end
- def filter(&block)
- @filter = block
- end
- def write(*s)
- if @out
- @buffer.concat(*s)
- elsif @origin
- @origin.write(*s)
+ def clear
+ @buffer.clear
+ end
+ def flush
+ STDOUT.print @filter ? @filter.call(@buffer) : @buffer
+ clear
+ end
+ def reopen(io)
+ case io
+ when Capture
+ initialize_copy(io)
+ when File
+ @out = false
+ @origin.reopen(io) if @origin
+ when IO
+ @out = true
+ @origin.reopen(io) if @origin
+ else
+ @out = false
+ end
+ end
+ def filter(&block)
+ @filter = block
+ end
+ def write(*s)
+ if @out
+ @buffer.concat(*s)
+ elsif @origin
+ @origin.write(*s)
+ end
end
end
- end
- attr_reader :stdout
+ attr_reader :stdout
- def mkmflog(msg)
- proc {MKMFLOG[] << msg}
- end
+ def mkmflog(msg)
+ proc {MKMFLOG[] << msg}
+ end
- def setup
- @rbconfig = rbconfig0 = RbConfig::CONFIG
- @mkconfig = mkconfig0 = RbConfig::MAKEFILE_CONFIG
- rbconfig = {
- "hdrdir" => $hdrdir,
- "srcdir" => $srcdir,
- "topdir" => $topdir,
- }
- mkconfig = {
- "hdrdir" => "$(top_srcdir)/include",
- "srcdir" => "$(top_srcdir)",
- "topdir" => $topdir,
- }
- rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}
- mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}
- RbConfig.module_eval {
- remove_const(:CONFIG)
- const_set(:CONFIG, rbconfig)
- remove_const(:MAKEFILE_CONFIG)
- const_set(:MAKEFILE_CONFIG, mkconfig)
- }
- MakeMakefile.class_eval {
- remove_const(:CONFIG)
- const_set(:CONFIG, mkconfig)
- }
- @tmpdir = Dir.mktmpdir
- @curdir = Dir.pwd
- @mkmfobj = Object.new
- @stdout = Capture.new
- Dir.chdir(@tmpdir)
- @quiet, Logging.quiet = Logging.quiet, true
- init_mkmf
- $INCFLAGS[0, 0] = "-I. "
- end
+ def setup
+ @rbconfig = rbconfig0 = RbConfig::CONFIG
+ @mkconfig = mkconfig0 = RbConfig::MAKEFILE_CONFIG
+ rbconfig = {
+ "hdrdir" => $hdrdir,
+ "srcdir" => $srcdir,
+ "topdir" => $topdir,
+ }
+ mkconfig = {
+ "hdrdir" => "$(top_srcdir)/include",
+ "srcdir" => "$(top_srcdir)",
+ "topdir" => $topdir,
+ }
+ rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}
+ mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}
+ RbConfig.module_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, rbconfig)
+ remove_const(:MAKEFILE_CONFIG)
+ const_set(:MAKEFILE_CONFIG, mkconfig)
+ }
+ MakeMakefile.class_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, mkconfig)
+ }
+ @tmpdir = Dir.mktmpdir
+ @curdir = Dir.pwd
+ @mkmfobj = Object.new
+ @stdout = Capture.new
+ Dir.chdir(@tmpdir)
+ @quiet, Logging.quiet = Logging.quiet, true
+ init_mkmf
+ $INCFLAGS[0, 0] = "-I. "
+ end
- def teardown
- rbconfig0 = @rbconfig
- mkconfig0 = @mkconfig
- RbConfig.module_eval {
- remove_const(:CONFIG)
- const_set(:CONFIG, rbconfig0)
- remove_const(:MAKEFILE_CONFIG)
- const_set(:MAKEFILE_CONFIG, mkconfig0)
- }
- MakeMakefile.class_eval {
- remove_const(:CONFIG)
- const_set(:CONFIG, mkconfig0)
- }
- Logging.quiet = @quiet
- Logging.log_close
- FileUtils.rm_f("mkmf.log")
- Dir.chdir(@curdir)
- FileUtils.rm_rf(@tmpdir)
- end
+ def teardown
+ rbconfig0 = @rbconfig
+ mkconfig0 = @mkconfig
+ RbConfig.module_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, rbconfig0)
+ remove_const(:MAKEFILE_CONFIG)
+ const_set(:MAKEFILE_CONFIG, mkconfig0)
+ }
+ MakeMakefile.class_eval {
+ remove_const(:CONFIG)
+ const_set(:CONFIG, mkconfig0)
+ }
+ Logging.quiet = @quiet
+ Logging.log_close
+ FileUtils.rm_f("mkmf.log")
+ Dir.chdir(@curdir)
+ FileUtils.rm_rf(@tmpdir)
+ end
- def mkmf(*args, &block)
- @stdout.clear
- stdout, @stdout.origin, $stdout = @stdout.origin, $stdout, @stdout
- verbose, $VERBOSE = $VERBOSE, false
- @mkmfobj.instance_eval(*args, &block)
- ensure
- $VERBOSE = verbose
- $stdout, @stdout.origin = @stdout.origin, stdout
- end
+ def mkmf(*args, &block)
+ @stdout.clear
+ stdout, @stdout.origin, $stdout = @stdout.origin, $stdout, @stdout
+ verbose, $VERBOSE = $VERBOSE, false
+ @mkmfobj.instance_eval(*args, &block)
+ ensure
+ $VERBOSE = verbose
+ $stdout, @stdout.origin = @stdout.origin, stdout
+ end
- def config_value(name)
- create_tmpsrc("---config-value=#{name}")
- xpopen(cpp_command('')) do |f|
- f.grep(/^---config-value=(.*)/) {return $1}
+ def config_value(name)
+ create_tmpsrc("---config-value=#{name}")
+ xpopen(cpp_command('')) do |f|
+ f.grep(/^---config-value=(.*)/) {return $1}
+ end
+ nil
end
- nil
end
-end
-class TestMkmf
- include TestMkmf::Base
+ include Base
def assert_separately(args, src, *rest, **options)
super(args + ["-r#{__FILE__}"], "extend TestMkmf::Base; setup\nEND{teardown}\n#{src}", *rest, **options)
diff --git a/test/mkmf/test_config.rb b/test/mkmf/test_config.rb
index 07ed641415..3878db1964 100644
--- a/test/mkmf/test_config.rb
+++ b/test/mkmf/test_config.rb
@@ -4,14 +4,12 @@ $extmk = true
require 'test/unit'
require 'mkmf'
-class TestMkmf < Test::Unit::TestCase
- class TestConfig < Test::Unit::TestCase
- def test_dir_config
- bug8074 = '[Bug #8074]'
- lib = RbConfig.expand(RbConfig::MAKEFILE_CONFIG["libdir"], "exec_prefix"=>"")
- assert_separately %w[-rmkmf - -- --with-foo-dir=/test/foo], %{
- assert_equal(%w[/test/foo/include /test/foo#{lib}], dir_config("foo"), #{bug8074.dump})
- }
- end
+class TestMkmfConfig < Test::Unit::TestCase
+ def test_dir_config
+ bug8074 = '[Bug #8074]'
+ lib = RbConfig.expand(RbConfig::MAKEFILE_CONFIG["libdir"], "exec_prefix"=>"")
+ assert_separately %w[-rmkmf - -- --with-foo-dir=/test/foo], %{
+ assert_equal(%w[/test/foo/include /test/foo#{lib}], dir_config("foo"), #{bug8074.dump})
+ }
end
end
diff --git a/test/mkmf/test_constant.rb b/test/mkmf/test_constant.rb
index f5a87a1caa..f6834c7f28 100644
--- a/test/mkmf/test_constant.rb
+++ b/test/mkmf/test_constant.rb
@@ -1,38 +1,36 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestTryConstant < TestMkmf
- def test_simple
- assert_equal( 0, mkmf {try_constant("0")}, MKMFLOG)
- assert_equal( 1, mkmf {try_constant("1")}, MKMFLOG)
- assert_equal(-1, mkmf {try_constant("-1")}, MKMFLOG)
- end
-
- def test_sizeof
- assert_equal(config_value("SIZEOF_INT").to_i, mkmf {try_constant("sizeof(int)")}, MKMFLOG)
- assert_equal(config_value("SIZEOF_LONG").to_i, mkmf {try_constant("sizeof(long)")}, MKMFLOG)
- assert_equal(config_value("SIZEOF_VOIDP").to_i, mkmf {try_constant("sizeof(void*)")}, MKMFLOG)
- assert_equal(config_value("SIZEOF_VALUE").to_i, mkmf {try_constant("sizeof(Qnil)")}, MKMFLOG)
- end
+class TestMkmfTryConstant < TestMkmf
+ def test_simple
+ assert_equal( 0, mkmf {try_constant("0")}, MKMFLOG)
+ assert_equal( 1, mkmf {try_constant("1")}, MKMFLOG)
+ assert_equal(-1, mkmf {try_constant("-1")}, MKMFLOG)
+ end
- def test_long
- sizeof_int = config_value("SIZEOF_INT").to_i
- sizeof_long = config_value("SIZEOF_LONG").to_i
- if sizeof_long > sizeof_int
- type = 'long'
- else
- sizeof_long_long = config_value("SIZEOF_LONG_LONG").to_i
- return if !sizeof_long_long or sizeof_long_long <= sizeof_int
- type = 'LONG_LONG'
- end
+ def test_sizeof
+ assert_equal(config_value("SIZEOF_INT").to_i, mkmf {try_constant("sizeof(int)")}, MKMFLOG)
+ assert_equal(config_value("SIZEOF_LONG").to_i, mkmf {try_constant("sizeof(long)")}, MKMFLOG)
+ assert_equal(config_value("SIZEOF_VOIDP").to_i, mkmf {try_constant("sizeof(void*)")}, MKMFLOG)
+ assert_equal(config_value("SIZEOF_VALUE").to_i, mkmf {try_constant("sizeof(Qnil)")}, MKMFLOG)
+ end
- decl = "#define CONFTEST_VALUE (unsigned #{type})(((unsigned #{type})1)<<(CHAR_BIT*sizeof(int)))"
- assert_operator(mkmf {try_constant("CONFTEST_VALUE", [[decl]])}, :>, 0, MKMFLOG)
+ def test_long
+ sizeof_int = config_value("SIZEOF_INT").to_i
+ sizeof_long = config_value("SIZEOF_LONG").to_i
+ if sizeof_long > sizeof_int
+ type = 'long'
+ else
+ sizeof_long_long = config_value("SIZEOF_LONG_LONG").to_i
+ return if !sizeof_long_long or sizeof_long_long <= sizeof_int
+ type = 'LONG_LONG'
end
- def test_large_unsigned
- assert_operator(mkmf {try_constant("1U<<(CHAR_BIT*sizeof(int)-1)")}, :>, 0, MKMFLOG)
- end
+ decl = "#define CONFTEST_VALUE (unsigned #{type})(((unsigned #{type})1)<<(CHAR_BIT*sizeof(int)))"
+ assert_operator(mkmf {try_constant("CONFTEST_VALUE", [[decl]])}, :>, 0, MKMFLOG)
+ end
+
+ def test_large_unsigned
+ assert_operator(mkmf {try_constant("1U<<(CHAR_BIT*sizeof(int)-1)")}, :>, 0, MKMFLOG)
end
end
diff --git a/test/mkmf/test_convertible.rb b/test/mkmf/test_convertible.rb
index 1baf892842..d65db4265b 100644
--- a/test/mkmf/test_convertible.rb
+++ b/test/mkmf/test_convertible.rb
@@ -1,35 +1,33 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestConvertible < TestMkmf
- def test_typeof_builtin
- ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
- %w[short int long].each do |type|
- assert_equal((prefix || signed)+type,
- mkmf {convertible_int(signed+type)}, MKMFLOG)
- end
+class TestMkmfConvertible < TestMkmf
+ def test_typeof_builtin
+ ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
+ %w[short int long].each do |type|
+ assert_equal((prefix || signed)+type,
+ mkmf {convertible_int(signed+type)}, MKMFLOG)
end
end
+ end
- def test_typeof_typedef
- ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
- %w[short int long].each do |type|
- open("confdefs.h", "w") {|f|
- f.puts "typedef #{signed}#{type} test1_t;"
- }
- $defs.clear
- assert_equal((prefix || signed)+type,
- mkmf {convertible_int("test1_t", "confdefs.h")}, MKMFLOG)
- (u = signed[/^u/]) and u.upcase!
- assert_include($defs, "-DTYPEOF_TEST1_T="+"#{prefix||signed}#{type}".quote)
- assert_include($defs, "-DPRI_TEST1T_PREFIX=PRI_#{type.upcase}_PREFIX")
- assert_include($defs, "-DTEST1T2NUM=#{u}#{type.upcase}2NUM")
- assert_include($defs, "-DNUM2TEST1T=NUM2#{u}#{type.upcase}")
- end
+ def test_typeof_typedef
+ ["", ["signed ", ""], "unsigned "].each do |signed, prefix|
+ %w[short int long].each do |type|
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef #{signed}#{type} test1_t;"
+ }
+ $defs.clear
+ assert_equal((prefix || signed)+type,
+ mkmf {convertible_int("test1_t", "confdefs.h")}, MKMFLOG)
+ (u = signed[/^u/]) and u.upcase!
+ assert_include($defs, "-DTYPEOF_TEST1_T="+"#{prefix||signed}#{type}".quote)
+ assert_include($defs, "-DPRI_TEST1T_PREFIX=PRI_#{type.upcase}_PREFIX")
+ assert_include($defs, "-DTEST1T2NUM=#{u}#{type.upcase}2NUM")
+ assert_include($defs, "-DNUM2TEST1T=NUM2#{u}#{type.upcase}")
end
- ensure
- File.unlink("confdefs.h")
end
+ ensure
+ File.unlink("confdefs.h")
end
end
diff --git a/test/mkmf/test_egrep_cpp.rb b/test/mkmf/test_egrep_cpp.rb
index ce276bef20..7ac0e60010 100644
--- a/test/mkmf/test_egrep_cpp.rb
+++ b/test/mkmf/test_egrep_cpp.rb
@@ -2,14 +2,12 @@
require_relative 'base'
require 'tempfile'
-class TestMkmf
- class TestEgrepCpp < TestMkmf
- def test_egrep_cpp
- assert_equal(true, egrep_cpp(/ruby_init/, ""), MKMFLOG)
- end
+class TestMkmfEgrepCpp < TestMkmf
+ def test_egrep_cpp
+ assert_equal(true, egrep_cpp(/ruby_init/, ""), MKMFLOG)
+ end
- def test_not_have_func
- assert_equal(false, egrep_cpp(/never match/, ""), MKMFLOG)
- end
+ def test_not_have_func
+ assert_equal(false, egrep_cpp(/never match/, ""), MKMFLOG)
end
end
diff --git a/test/mkmf/test_find_executable.rb b/test/mkmf/test_find_executable.rb
index 7ffc28ecc8..88b70c21c0 100644
--- a/test/mkmf/test_find_executable.rb
+++ b/test/mkmf/test_find_executable.rb
@@ -1,58 +1,56 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestFindExecutable < TestMkmf
- def setup
- super
- @path, ENV["PATH"] = ENV["PATH"], @tmpdir
- end
+class TestMkmfFindExecutable < TestMkmf
+ def setup
+ super
+ @path, ENV["PATH"] = ENV["PATH"], @tmpdir
+ end
- def each_exts(&block)
- name = "foobar#{$$}#{rand(1000)}"
- stdout.filter {|s| s.sub(name, "<executable>")}
- exts = mkmf {self.class::CONFIG['EXECUTABLE_EXTS']}.split
- exts[0] ||= ""
- exts.each do |ext|
- yield name+ext, name
- end
+ def each_exts(&block)
+ name = "foobar#{$$}#{rand(1000)}"
+ stdout.filter {|s| s.sub(name, "<executable>")}
+ exts = mkmf {self.class::CONFIG['EXECUTABLE_EXTS']}.split
+ exts[0] ||= ""
+ exts.each do |ext|
+ yield name+ext, name
end
+ end
- def teardown
- ENV["PATH"] = @path
- super
- end
+ def teardown
+ ENV["PATH"] = @path
+ super
+ end
- def test_find_executable
- bug2669 = '[ruby-core:27912]'
- each_exts do |full, name|
- begin
- open(full, "w") {|ff| ff.chmod(0755)}
- result = mkmf {find_executable(name)}
- ensure
- File.unlink(full)
- end
- assert_equal("#{@tmpdir}/#{full}", result, bug2669)
+ def test_find_executable
+ bug2669 = '[ruby-core:27912]'
+ each_exts do |full, name|
+ begin
+ open(full, "w") {|ff| ff.chmod(0755)}
+ result = mkmf {find_executable(name)}
+ ensure
+ File.unlink(full)
end
+ assert_equal("#{@tmpdir}/#{full}", result, bug2669)
end
+ end
- def test_find_executable_dir
- each_exts do |full, name|
- begin
- Dir.mkdir(full)
- result = mkmf {find_executable(name)}
- ensure
- Dir.rmdir(full)
- end
- assert_nil(result)
+ def test_find_executable_dir
+ each_exts do |full, name|
+ begin
+ Dir.mkdir(full)
+ result = mkmf {find_executable(name)}
+ ensure
+ Dir.rmdir(full)
end
+ assert_nil(result)
end
+ end
- if /mingw|mswin/ =~ RUBY_PLATFORM
- def test_quoted_path_on_windows
- ENV["PATH"] = %["#{@tmpdir}"]
- test_find_executable
- end
+ if /mingw|mswin/ =~ RUBY_PLATFORM
+ def test_quoted_path_on_windows
+ ENV["PATH"] = %["#{@tmpdir}"]
+ test_find_executable
end
end
end
diff --git a/test/mkmf/test_flags.rb b/test/mkmf/test_flags.rb
index a3596d8e55..aedf06b610 100644
--- a/test/mkmf/test_flags.rb
+++ b/test/mkmf/test_flags.rb
@@ -1,57 +1,55 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestFlags < TestMkmf
- def test_valid_warnflags
- val = $extmk
- warnflags = $warnflags
- makefile = mkmf do
- $extmk = false
- self.class::CONFIG['warnflags'] = %w"-Wextra
- -Wno-unused-parameter -Wno-parentheses -Wno-long-long
- -Wno-missing-field-initializers -Werror=pointer-arith
- -Werror=write-strings -Werror=declaration-after-statement
- -Werror=shorten-64-to-32
- -Werror-implicit-function-declaration
- ".join(' ')
- self.class::CONFIG['GCC'] = 'yes'
- init_mkmf(self.class::CONFIG)
- configuration '.'
- end
- generated_flags = makefile.grep(/warnflags/).first[/^warnflags = (.*)$/, 1].split
+class TestMkmfFlags < TestMkmf
+ def test_valid_warnflags
+ val = $extmk
+ warnflags = $warnflags
+ makefile = mkmf do
+ $extmk = false
+ self.class::CONFIG['warnflags'] = %w"-Wextra
+ -Wno-unused-parameter -Wno-parentheses -Wno-long-long
+ -Wno-missing-field-initializers -Werror=pointer-arith
+ -Werror=write-strings -Werror=declaration-after-statement
+ -Werror=shorten-64-to-32
+ -Werror-implicit-function-declaration
+ ".join(' ')
+ self.class::CONFIG['GCC'] = 'yes'
+ init_mkmf(self.class::CONFIG)
+ configuration '.'
+ end
+ generated_flags = makefile.grep(/warnflags/).first[/^warnflags = (.*)$/, 1].split
- assert_equal %w"
- -Wextra -Wno-unused-parameter -Wno-parentheses
- -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith
- -Wwrite-strings -Wdeclaration-after-statement
- -Wshorten-64-to-32 -Wimplicit-function-declaration
- ", generated_flags
+ assert_equal %w"
+ -Wextra -Wno-unused-parameter -Wno-parentheses
+ -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith
+ -Wwrite-strings -Wdeclaration-after-statement
+ -Wshorten-64-to-32 -Werror-implicit-function-declaration
+ ", generated_flags
- ensure
- $warnflags = warnflags
- $extmk = val
- end
+ ensure
+ $warnflags = warnflags
+ $extmk = val
+ end
- def test_try_ldflag_invalid_opt
- assert_separately([], <<-'end;') #do
- assert(!try_ldflags("nosuch.c"), TestMkmf::MKMFLOG)
- assert(have_devel?, TestMkmf::MKMFLOG)
- end;
- end
+ def test_try_ldflag_invalid_opt
+ assert_separately([], <<-'end;') #do
+ assert(!try_ldflags("nosuch.c"), TestMkmf::MKMFLOG)
+ assert(have_devel?, TestMkmf::MKMFLOG)
+ end;
+ end
- def test_try_cflag_invalid_opt
- assert_separately([], <<-'end;', timeout: 30) #do
- assert(!try_cflags("nosuch.c"), TestMkmf::MKMFLOG)
- assert(have_devel?, TestMkmf::MKMFLOG)
- end;
- end
+ def test_try_cflag_invalid_opt
+ assert_separately([], <<-'end;', timeout: 30) #do
+ assert(!try_cflags("nosuch.c"), TestMkmf::MKMFLOG)
+ assert(have_devel?, TestMkmf::MKMFLOG)
+ end;
+ end
- def test_try_cppflag_invalid_opt
- assert_separately([], <<-'end;') #do
- assert(!try_cppflags("nosuch.c"), TestMkmf::MKMFLOG)
- assert(have_devel?, TestMkmf::MKMFLOG)
- end;
- end
+ def test_try_cppflag_invalid_opt
+ assert_separately([], <<-'end;') #do
+ assert(!try_cppflags("nosuch.c"), TestMkmf::MKMFLOG)
+ assert(have_devel?, TestMkmf::MKMFLOG)
+ end;
end
end
diff --git a/test/mkmf/test_framework.rb b/test/mkmf/test_framework.rb
index ba15299ae0..3245e43c75 100644
--- a/test/mkmf/test_framework.rb
+++ b/test/mkmf/test_framework.rb
@@ -1,49 +1,47 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestHaveFramework < TestMkmf
- def create_framework(fw, hdrname = "#{fw}.h")
- Dir.mktmpdir("frameworks") do |dir|
- fwdir = "#{dir}/#{fw}.framework"
- hdrdir = "#{fwdir}/Headers"
- FileUtils.mkdir_p(hdrdir)
- File.write("#{hdrdir}/#{hdrname}", "")
- src = "#{fwdir}/main.c"
- File.write(src, "void #{fw}(void) {}\n")
- cmd = LINK_SO.dup
- RbConfig.expand(cmd, RbConfig::CONFIG.merge("OBJS"=>src))
- cmd.gsub!("$@", "#{fwdir}/#{fw}")
- cmd.gsub!(/ -bundle /, ' -dynamiclib ')
- assert(xsystem(cmd), MKMFLOG)
- $INCFLAGS << " " << "-F#{dir}".quote
- yield fw, hdrname
- end
+class TestMkmfHaveFramework < TestMkmf
+ def create_framework(fw, hdrname = "#{fw}.h")
+ Dir.mktmpdir("frameworks") do |dir|
+ fwdir = "#{dir}/#{fw}.framework"
+ hdrdir = "#{fwdir}/Headers"
+ FileUtils.mkdir_p(hdrdir)
+ File.write("#{hdrdir}/#{hdrname}", "")
+ src = "#{fwdir}/main.c"
+ File.write(src, "void #{fw}(void) {}\n")
+ cmd = LINK_SO.dup
+ RbConfig.expand(cmd, RbConfig::CONFIG.merge("OBJS"=>src))
+ cmd.gsub!("$@", "#{fwdir}/#{fw}")
+ cmd.gsub!(/ -bundle /, ' -dynamiclib ')
+ assert(xsystem(cmd), MKMFLOG)
+ $INCFLAGS << " " << "-F#{dir}".quote
+ yield fw, hdrname
end
+ end
- def test_single_framework
- assert(have_framework(%w"Ruby ruby.h"), mkmflog("try as Objective-C"))
- end
+ def test_single_framework
+ assert(have_framework(%w"Ruby ruby.h"), mkmflog("try as Objective-C"))
+ end
- def test_multi_frameworks
- assert(have_framework(%w"Ruby ruby.h"), mkmflog("try as Objective-C"))
- create_framework("MkmfTest") do |fw|
- assert(have_framework(fw), MKMFLOG)
- end
+ def test_multi_frameworks
+ assert(have_framework(%w"Ruby ruby.h"), mkmflog("try as Objective-C"))
+ create_framework("MkmfTest") do |fw|
+ assert(have_framework(fw), MKMFLOG)
end
+ end
- def test_empty_framework
- create_framework("MkmfTest") do |fw|
- assert(have_framework(fw), MKMFLOG)
- end
+ def test_empty_framework
+ create_framework("MkmfTest") do |fw|
+ assert(have_framework(fw), MKMFLOG)
end
+ end
- def test_different_name_header
- _bug8593 = '[ruby-core:55745] [Bug #8593]'
- create_framework("MkmfTest", "test_mkmf.h") do |fw, hdrname|
- assert(!have_framework(fw), MKMFLOG)
- assert(have_framework([fw, hdrname]), MKMFLOG)
- end
+ def test_different_name_header
+ _bug8593 = '[ruby-core:55745] [Bug #8593]'
+ create_framework("MkmfTest", "test_mkmf.h") do |fw, hdrname|
+ assert(!have_framework(fw), MKMFLOG)
+ assert(have_framework([fw, hdrname]), MKMFLOG)
end
end
end if /darwin/ =~ RUBY_PLATFORM
diff --git a/test/mkmf/test_have_func.rb b/test/mkmf/test_have_func.rb
index 6204ab24f0..521a0bb435 100644
--- a/test/mkmf/test_have_func.rb
+++ b/test/mkmf/test_have_func.rb
@@ -2,16 +2,14 @@
require_relative 'base'
require 'tempfile'
-class TestMkmf
- class TestHaveFunc < TestMkmf
- def test_have_func
- assert_equal(true, have_func("ruby_init"), MKMFLOG)
- assert_include($defs, '-DHAVE_RUBY_INIT')
- end
+class TestMkmfHaveFunc < TestMkmf
+ def test_have_func
+ assert_equal(true, have_func("ruby_init"), MKMFLOG)
+ assert_include($defs, '-DHAVE_RUBY_INIT')
+ end
- def test_not_have_func
- assert_equal(false, have_func("no_ruby_init"), MKMFLOG)
- assert_not_include($defs, '-DHAVE_RUBY_INIT')
- end
+ def test_not_have_func
+ assert_equal(false, have_func("no_ruby_init"), MKMFLOG)
+ assert_not_include($defs, '-DHAVE_RUBY_INIT')
end
end
diff --git a/test/mkmf/test_have_library.rb b/test/mkmf/test_have_library.rb
index bb9ce6972d..e34a9b06da 100644
--- a/test/mkmf/test_have_library.rb
+++ b/test/mkmf/test_have_library.rb
@@ -2,55 +2,53 @@
require_relative 'base'
require 'tempfile'
-class TestMkmf
- class TestHaveLibrary < TestMkmf
- LIBRARY_NAME = 'mkmftest'
- HEADER_NAME = "#{LIBRARY_NAME}.h"
- FUNC_NAME = 'ruby_mkmftest_foo'
- ARPREFIX = config_string('LIBRUBY_A') {|lib| lib[/\A\w+/]}
-
- def create_library(libname = LIBRARY_NAME)
- lib = "#{ARPREFIX}#{libname}.#{$LIBEXT}"
- open(HEADER_NAME, "w") do |hdr|
- hdr.puts "void #{FUNC_NAME}(void);"
- hdr.puts "void #{FUNC_NAME}_fake(void);"
- end
- create_tmpsrc("#include \"#{HEADER_NAME}\"\n""void #{FUNC_NAME}(void) {}")
- assert(xsystem(cc_command), "compile failed: #{cc_command}")
- command = "#{CONFIG['AR']} #{config_string('ARFLAGS') || 'cru '}#{lib} #{CONFTEST}.#{$OBJEXT}"
- assert(xsystem(command), "making library failed: #{command}")
- File.unlink("#{CONFTEST}.#{$OBJEXT}")
- config_string('RANLIB') do |ranlib|
- command = "#{ranlib} #{lib}"
- assert(xsystem(command), "ranlib failed: #{command}")
- end
+class TestMkmfHaveLibrary < TestMkmf
+ LIBRARY_NAME = 'mkmftest'
+ HEADER_NAME = "#{LIBRARY_NAME}.h"
+ FUNC_NAME = 'ruby_mkmftest_foo'
+ ARPREFIX = config_string('LIBRUBY_A') {|lib| lib[/\A\w+/]}
+
+ def create_library(libname = LIBRARY_NAME)
+ lib = "#{ARPREFIX}#{libname}.#{$LIBEXT}"
+ open(HEADER_NAME, "w") do |hdr|
+ hdr.puts "void #{FUNC_NAME}(void);"
+ hdr.puts "void #{FUNC_NAME}_fake(void);"
end
-
- def assert_have_library(*args)
- assert_equal(true, have_library(LIBRARY_NAME, *args), MKMFLOG)
+ create_tmpsrc("#include \"#{HEADER_NAME}\"\n""void #{FUNC_NAME}(void) {}")
+ assert(xsystem(cc_command), "compile failed: #{cc_command}")
+ command = "#{CONFIG['AR']} #{config_string('ARFLAGS') || 'cru '}#{lib} #{CONFTEST}.#{$OBJEXT}"
+ assert(xsystem(command), "making library failed: #{command}")
+ File.unlink("#{CONFTEST}.#{$OBJEXT}")
+ config_string('RANLIB') do |ranlib|
+ command = "#{ranlib} #{lib}"
+ assert(xsystem(command), "ranlib failed: #{command}")
end
+ end
- def assert_not_have_library(*args)
- assert_equal(false, have_library(LIBRARY_NAME, *args), MKMFLOG)
- end
+ def assert_have_library(*args)
+ assert_equal(true, have_library(LIBRARY_NAME, *args), MKMFLOG)
+ end
- def test_have_library
- create_library
- assert_have_library
- end
+ def assert_not_have_library(*args)
+ assert_equal(false, have_library(LIBRARY_NAME, *args), MKMFLOG)
+ end
- def test_have_library_with_name
- create_library
- assert_have_library(FUNC_NAME, HEADER_NAME)
- end
+ def test_have_library
+ create_library
+ assert_have_library
+ end
- def test_not_have_library
- assert_not_have_library
- end
+ def test_have_library_with_name
+ create_library
+ assert_have_library(FUNC_NAME, HEADER_NAME)
+ end
- def test_not_have_library_with_name
- create_library
- assert_not_have_library("#{FUNC_NAME}_fake", HEADER_NAME)
- end
+ def test_not_have_library
+ assert_not_have_library
+ end
+
+ def test_not_have_library_with_name
+ create_library
+ assert_not_have_library("#{FUNC_NAME}_fake", HEADER_NAME)
end
end
diff --git a/test/mkmf/test_have_macro.rb b/test/mkmf/test_have_macro.rb
index ebc5648097..3178bfea0b 100644
--- a/test/mkmf/test_have_macro.rb
+++ b/test/mkmf/test_have_macro.rb
@@ -2,35 +2,33 @@
require_relative 'base'
require 'tempfile'
-class TestMkmf
- class TestHaveMacro < TestMkmf
- MACRO_NAME = "RUBY_MKMFTEST_FOOBAR"
+class TestMkmfHaveMacro < TestMkmf
+ MACRO_NAME = "RUBY_MKMFTEST_FOOBAR"
- def test_have_macro_opt
- assert_equal(true, have_macro(MACRO_NAME, nil, "-D#{MACRO_NAME}"), MKMFLOG)
- end
+ def test_have_macro_opt
+ assert_equal(true, have_macro(MACRO_NAME, nil, "-D#{MACRO_NAME}"), MKMFLOG)
+ end
- def test_have_macro_header
- Tempfile.create(%w"test_mkmf .h", ".") do |tmp|
- tmp.puts("#undef #{MACRO_NAME}")
- tmp.puts("#define #{MACRO_NAME} 1")
- tmp.close
- base = File.basename(tmp.path)
- assert_equal(true, have_macro(MACRO_NAME, base, "-I."), MKMFLOG)
- end
+ def test_have_macro_header
+ Tempfile.create(%w"test_mkmf .h", ".") do |tmp|
+ tmp.puts("#undef #{MACRO_NAME}")
+ tmp.puts("#define #{MACRO_NAME} 1")
+ tmp.close
+ base = File.basename(tmp.path)
+ assert_equal(true, have_macro(MACRO_NAME, base, "-I."), MKMFLOG)
end
+ end
- def test_not_have_macro_opt
- assert_equal(false, have_macro(MACRO_NAME, nil, "-U#{MACRO_NAME}"), MKMFLOG)
- end
+ def test_not_have_macro_opt
+ assert_equal(false, have_macro(MACRO_NAME, nil, "-U#{MACRO_NAME}"), MKMFLOG)
+ end
- def test_not_have_macro_header
- Tempfile.create(%w"test_mkmf .h", ".") do |tmp|
- tmp.puts("#undef #{MACRO_NAME}")
- tmp.close
- base = File.basename(tmp.path)
- assert_equal(false, have_macro(MACRO_NAME, base, "-I."), MKMFLOG)
- end
+ def test_not_have_macro_header
+ Tempfile.create(%w"test_mkmf .h", ".") do |tmp|
+ tmp.puts("#undef #{MACRO_NAME}")
+ tmp.close
+ base = File.basename(tmp.path)
+ assert_equal(false, have_macro(MACRO_NAME, base, "-I."), MKMFLOG)
end
end
end
diff --git a/test/mkmf/test_install.rb b/test/mkmf/test_install.rb
index 7f8c603d42..009d55f72d 100644
--- a/test/mkmf/test_install.rb
+++ b/test/mkmf/test_install.rb
@@ -1,27 +1,25 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestInstall < TestMkmf
- def test_install_dirs
- Dir.mktmpdir do |dir|
- File.write(dir+"/extconf.rb", "require 'mkmf'; create_makefile('test')")
- all_assertions do |a|
+class TestMkmfInstall < TestMkmf
+ def test_install_dirs
+ Dir.mktmpdir do |dir|
+ File.write(dir+"/extconf.rb", "require 'mkmf'; create_makefile('test')")
+ all_assertions do |a|
+ a.foreach(
+ ["site"],
+ ["vendor", "--vendor"],
+ ) do |dest, *options|
+ assert_ruby_status(["-C", dir, "extconf.rb", *options])
+ mf = File.read(dir+"/Makefile")
a.foreach(
- ["site"],
- ["vendor", "--vendor"],
- ) do |dest, *options|
- assert_ruby_status(["-C", dir, "extconf.rb", *options])
- mf = File.read(dir+"/Makefile")
- a.foreach(
- ["RUBYCOMMONDIR", "$(#{dest}dir)$(target_prefix)"],
- ["RUBYLIBDIR", "$(#{dest}libdir)$(target_prefix)"],
- ["RUBYARCHDIR", "$(#{dest}archdir)$(target_prefix)"],
- ["HDRDIR", "$(#{dest}hdrdir)$(target_prefix)"],
- ["ARCHHDRDIR", "$(#{dest}archhdrdir)$(target_prefix)"],
- ) do |(var, path)|
- assert_equal path, mf[/^#{var}\s*=\s*(.*)$/, 1]
- end
+ ["RUBYCOMMONDIR", "$(#{dest}dir)$(target_prefix)"],
+ ["RUBYLIBDIR", "$(#{dest}libdir)$(target_prefix)"],
+ ["RUBYARCHDIR", "$(#{dest}archdir)$(target_prefix)"],
+ ["HDRDIR", "$(#{dest}hdrdir)$(target_prefix)"],
+ ["ARCHHDRDIR", "$(#{dest}archhdrdir)$(target_prefix)"],
+ ) do |(var, path)|
+ assert_equal path, mf[/^#{var}\s*=\s*(.*)$/, 1]
end
end
end
diff --git a/test/mkmf/test_libs.rb b/test/mkmf/test_libs.rb
index 9c5e1d29fb..2f84d024e2 100644
--- a/test/mkmf/test_libs.rb
+++ b/test/mkmf/test_libs.rb
@@ -1,94 +1,92 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestLibs < TestMkmf
- def test_split_libs
- assert_equal(%w[-lfoo -lbar], split_libs("-lfoo -lbar"))
- end
+class TestMkmfLibs < TestMkmf
+ def test_split_libs
+ assert_equal(%w[-lfoo -lbar], split_libs("-lfoo -lbar"))
+ end
- def test_split_libs_macos
- assert_equal(%w[-ObjC -framework\ Ruby], split_libs("-ObjC -framework Ruby"), 'Bug #6987')
- end if /darwin/ =~ RUBY_PLATFORM
+ def test_split_libs_macos
+ assert_equal(%w[-ObjC -framework\ Ruby], split_libs("-ObjC -framework Ruby"), 'Bug #6987')
+ end if /darwin/ =~ RUBY_PLATFORM
- def test_split_libs_windows
- assert_equal(%w[zdll.lib libffi.lib], split_libs("zdll.lib libffi.lib"))
- end if /mswin/ =~ RUBY_PLATFORM
+ def test_split_libs_windows
+ assert_equal(%w[zdll.lib libffi.lib], split_libs("zdll.lib libffi.lib"))
+ end if /mswin/ =~ RUBY_PLATFORM
- def assert_in_order(array, x, y, mesg = nil)
- mesg = "#{x} must proceed to #{y}#{': ' if mesg}#{mesg}"
- assert_operator(array.index(x), :<, array.rindex(y), mesg)
- end
+ def assert_in_order(array, x, y, mesg = nil)
+ mesg = "#{x} must proceed to #{y}#{': ' if mesg}#{mesg}"
+ assert_operator(array.index(x), :<, array.rindex(y), mesg)
+ end
- def test_merge_simple
- bug = '[ruby-dev:21765]'
- assert_equal([], merge_libs(%w[]))
- assert_equal(%w[a b], merge_libs(%w[a], %w[b]))
- array = merge_libs(%w[a c], %w[b])
- assert_in_order(array, "a", "c", bug)
- end
+ def test_merge_simple
+ bug = '[ruby-dev:21765]'
+ assert_equal([], merge_libs(%w[]))
+ assert_equal(%w[a b], merge_libs(%w[a], %w[b]))
+ array = merge_libs(%w[a c], %w[b])
+ assert_in_order(array, "a", "c", bug)
+ end
- def test_merge_seq
- bug = '[ruby-dev:21765]'
- array = merge_libs(%w[a c d], %w[c b e])
- assert_in_order(array, "a", "c", bug)
- assert_in_order(array, "c", "d", bug)
- assert_in_order(array, "c", "b", bug)
- assert_in_order(array, "b", "e", bug)
- end
+ def test_merge_seq
+ bug = '[ruby-dev:21765]'
+ array = merge_libs(%w[a c d], %w[c b e])
+ assert_in_order(array, "a", "c", bug)
+ assert_in_order(array, "c", "d", bug)
+ assert_in_order(array, "c", "b", bug)
+ assert_in_order(array, "b", "e", bug)
+ end
- def test_merge_seq_pre
- bug = '[ruby-dev:21765]'
- array = merge_libs(%w[a c d], %w[b c d e])
- assert_in_order(array, "a", "c", bug)
- assert_in_order(array, "c", "d", bug)
- assert_in_order(array, "b", "c", bug)
- assert_in_order(array, "d", "e", bug)
- end
+ def test_merge_seq_pre
+ bug = '[ruby-dev:21765]'
+ array = merge_libs(%w[a c d], %w[b c d e])
+ assert_in_order(array, "a", "c", bug)
+ assert_in_order(array, "c", "d", bug)
+ assert_in_order(array, "b", "c", bug)
+ assert_in_order(array, "d", "e", bug)
+ end
- def test_merge_cyclic
- bug = '[ruby-dev:21765]'
- array = merge_libs(%w[a c d], %w[b c b])
- assert_in_order(array, "a", "c", bug)
- assert_in_order(array, "c", "d", bug)
- assert_in_order(array, "b", "c", bug)
- assert_in_order(array, "c", "b", bug)
- end
+ def test_merge_cyclic
+ bug = '[ruby-dev:21765]'
+ array = merge_libs(%w[a c d], %w[b c b])
+ assert_in_order(array, "a", "c", bug)
+ assert_in_order(array, "c", "d", bug)
+ assert_in_order(array, "b", "c", bug)
+ assert_in_order(array, "c", "b", bug)
+ end
- def test_merge_cyclic_2
- bug = '[ruby-dev:21765]'
- array = merge_libs(%w[a c a d], %w[b c b])
- assert_in_order(array, "a", "c", bug)
- assert_in_order(array, "c", "a", bug)
- assert_in_order(array, "c", "d", bug)
- assert_in_order(array, "a", "d", bug)
- assert_in_order(array, "b", "c", bug)
- assert_in_order(array, "c", "b", bug)
- end
+ def test_merge_cyclic_2
+ bug = '[ruby-dev:21765]'
+ array = merge_libs(%w[a c a d], %w[b c b])
+ assert_in_order(array, "a", "c", bug)
+ assert_in_order(array, "c", "a", bug)
+ assert_in_order(array, "c", "d", bug)
+ assert_in_order(array, "a", "d", bug)
+ assert_in_order(array, "b", "c", bug)
+ assert_in_order(array, "c", "b", bug)
+ end
- def test_merge_reversal
- bug = '[ruby-dev:22440]'
- array = merge_libs(%w[a b c], %w[c d a])
- assert_in_order(array, "a", "b" , bug)
- assert_in_order(array, "c", "d" , bug)
- ## assume that a and c have no dependency
- end
+ def test_merge_reversal
+ bug = '[ruby-dev:22440]'
+ array = merge_libs(%w[a b c], %w[c d a])
+ assert_in_order(array, "a", "b" , bug)
+ assert_in_order(array, "c", "d" , bug)
+ ## assume that a and c have no dependency
+ end
- def test_merge_reversal_followed
- bug7467 = '[ruby-core:50314] [Bug #7467]'
- array = nil
- assert_nothing_raised(bug7467) {
- array = merge_libs(%w[a b c d e f g h], %w[d c d e], [])
- }
- assert_in_order(array, "a", "b", bug7467)
- assert_in_order(array, "b", "c", bug7467)
- assert_in_order(array, "c", "d", bug7467)
- assert_in_order(array, "d", "e", bug7467)
- assert_in_order(array, "e", "f", bug7467)
- assert_in_order(array, "f", "g", bug7467)
- assert_in_order(array, "g", "h", bug7467)
- assert_in_order(array, "d", "c", bug7467)
- assert_in_order(array, "c", "e", bug7467)
- end
+ def test_merge_reversal_followed
+ bug7467 = '[ruby-core:50314] [Bug #7467]'
+ array = nil
+ assert_nothing_raised(bug7467) {
+ array = merge_libs(%w[a b c d e f g h], %w[d c d e], [])
+ }
+ assert_in_order(array, "a", "b", bug7467)
+ assert_in_order(array, "b", "c", bug7467)
+ assert_in_order(array, "c", "d", bug7467)
+ assert_in_order(array, "d", "e", bug7467)
+ assert_in_order(array, "e", "f", bug7467)
+ assert_in_order(array, "f", "g", bug7467)
+ assert_in_order(array, "g", "h", bug7467)
+ assert_in_order(array, "d", "c", bug7467)
+ assert_in_order(array, "c", "e", bug7467)
end
end if RUBY_ENGINE == "ruby"
diff --git a/test/mkmf/test_mkmf.rb b/test/mkmf/test_mkmf.rb
index adb86eca8d..55f9aa3b88 100644
--- a/test/mkmf/test_mkmf.rb
+++ b/test/mkmf/test_mkmf.rb
@@ -2,14 +2,12 @@
require 'test/unit'
require 'mkmf'
-class TestMkmf < Test::Unit::TestCase
- class TestGlobal < TestMkmf
- main = TOPLEVEL_BINDING.receiver
- MakeMakefile.public_instance_methods(false).each do |m|
- define_method(:"test_global_#{m}") do
- assert_respond_to(main, [m, true])
- assert_not_respond_to(main, [m, false])
- end
+class TestMkmfGlobal < Test::Unit::TestCase
+ main = TOPLEVEL_BINDING.receiver
+ MakeMakefile.public_instance_methods(false).each do |m|
+ define_method(:"test_global_#{m}") do
+ assert_respond_to(main, [m, true])
+ assert_not_respond_to(main, [m, false])
end
end
end
diff --git a/test/mkmf/test_pkg_config.rb b/test/mkmf/test_pkg_config.rb
new file mode 100644
index 0000000000..72efb4ba81
--- /dev/null
+++ b/test/mkmf/test_pkg_config.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: false
+require_relative 'base'
+require 'shellwords'
+
+class TestMkmfPkgConfig < TestMkmf
+ PKG_CONFIG = find_executable0("pkg-config")
+
+ def setup
+ super
+
+ if PKG_CONFIG
+ @fixtures_dir = File.join(Dir.pwd, "fixtures")
+ @fixtures_lib_dir = File.join(@fixtures_dir, "lib")
+ @fixtures_inc_dir = File.join(@fixtures_dir, "include")
+
+ FileUtils.mkdir(@fixtures_dir)
+ File.write("fixtures/test1.pc", <<~EOF)
+ libdir=#{@fixtures_lib_dir}
+ includedir=#{@fixtures_inc_dir}
+
+ Name: test1
+ Description: Test for mkmf pkg-config method
+ Version: 1.2.3
+ Libs: -L${libdir} -ltest1-public
+ Libs.private: -ltest1-private
+ Cflags: -I${includedir}/cflags-I --cflags-other
+ EOF
+
+ @pkg_config_path, ENV["PKG_CONFIG_PATH"] = ENV["PKG_CONFIG_PATH"], File.join(Dir.pwd, "fixtures")
+ end
+ end
+
+ def teardown
+ if PKG_CONFIG
+ ENV["PKG_CONFIG_PATH"] = @pkg_config_path
+ end
+
+ super
+ end
+
+ def test_pkgconfig_with_option_returns_nil_on_error
+ pend("skipping because pkg-config is not installed") unless PKG_CONFIG
+ assert_nil(pkg_config("package-does-not-exist", "exists"), MKMFLOG)
+ end
+
+ def test_pkgconfig_with_libs_option_returns_output
+ pend("skipping because pkg-config is not installed") unless PKG_CONFIG
+ expected = ["-L#{@fixtures_lib_dir}", "-ltest1-public"].sort
+ actual = pkg_config("test1", "libs").shellsplit.sort
+ assert_equal(expected, actual, MKMFLOG)
+ end
+
+ def test_pkgconfig_with_cflags_option_returns_output
+ pend("skipping because pkg-config is not installed") unless PKG_CONFIG
+ expected = ["--cflags-other", "-I#{@fixtures_inc_dir}/cflags-I"].sort
+ actual = pkg_config("test1", "cflags").shellsplit.sort
+ assert_equal(expected, actual, MKMFLOG)
+ end
+
+ def test_pkgconfig_with_multiple_options
+ pend("skipping because pkg-config is not installed") unless PKG_CONFIG
+ expected = ["-L#{@fixtures_lib_dir}", "-ltest1-public", "-ltest1-private"].sort
+ actual = pkg_config("test1", "libs", "static").shellsplit.sort
+ assert_equal(expected, actual, MKMFLOG)
+ end
+end
diff --git a/test/mkmf/test_signedness.rb b/test/mkmf/test_signedness.rb
index 589dcb56e8..a59e3548a2 100644
--- a/test/mkmf/test_signedness.rb
+++ b/test/mkmf/test_signedness.rb
@@ -1,30 +1,28 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestSignedness < TestMkmf
- def test_typeof_builtin
- bug4144 = '[ruby-dev:42731]'
- [["", "-1"], ["signed ", "-1"], ["unsigned ", "+1"]].each do |signed, expect|
- %w[short int long].each do |type|
- assert_equal(expect.to_i, mkmf {check_signedness(signed+type)}, mkmflog(bug4144))
- end
+class TestMkmfSignedness < TestMkmf
+ def test_typeof_builtin
+ bug4144 = '[ruby-dev:42731]'
+ [["", "-1"], ["signed ", "-1"], ["unsigned ", "+1"]].each do |signed, expect|
+ %w[short int long].each do |type|
+ assert_equal(expect.to_i, mkmf {check_signedness(signed+type)}, mkmflog(bug4144))
end
end
+ end
- def test_typeof_typedef
- [["", "-1"], ["signed ", "-1"], ["unsigned ", "+1"]].each do |signed, expect|
- %w[short int long].each do |type|
- open("confdefs.h", "w") {|f|
- f.puts "typedef #{signed}#{type} test1_t;"
- }
- $defs.clear
- assert_equal(expect.to_i, mkmf {check_signedness("test1_t", "confdefs.h")}, MKMFLOG)
- assert_include($defs, "-DSIGNEDNESS_OF_TEST1_T=#{expect}")
- end
+ def test_typeof_typedef
+ [["", "-1"], ["signed ", "-1"], ["unsigned ", "+1"]].each do |signed, expect|
+ %w[short int long].each do |type|
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef #{signed}#{type} test1_t;"
+ }
+ $defs.clear
+ assert_equal(expect.to_i, mkmf {check_signedness("test1_t", "confdefs.h")}, MKMFLOG)
+ assert_include($defs, "-DSIGNEDNESS_OF_TEST1_T=#{expect}")
end
- ensure
- File.unlink("confdefs.h")
end
+ ensure
+ File.unlink("confdefs.h")
end
end
diff --git a/test/mkmf/test_sizeof.rb b/test/mkmf/test_sizeof.rb
index 742c3d6454..6fb0a6a8f6 100644
--- a/test/mkmf/test_sizeof.rb
+++ b/test/mkmf/test_sizeof.rb
@@ -1,48 +1,46 @@
# frozen_string_literal: false
require_relative 'base'
-class TestMkmf
- class TestSizeof < TestMkmf
- def setup
- super
- @sizeof_short = config_value("SIZEOF_SHORT").to_i
- @sizeof_int = config_value("SIZEOF_INT").to_i
- @sizeof_long = config_value("SIZEOF_LONG").to_i
- @sizeof_long_long = config_value("SIZEOF_LONG_LONG").to_i
- @sizeof___int64 = config_value("SIZEOF___INT64").to_i
- end
+class TestMkmfSizeof < TestMkmf
+ def setup
+ super
+ @sizeof_short = config_value("SIZEOF_SHORT").to_i
+ @sizeof_int = config_value("SIZEOF_INT").to_i
+ @sizeof_long = config_value("SIZEOF_LONG").to_i
+ @sizeof_long_long = config_value("SIZEOF_LONG_LONG").to_i
+ @sizeof___int64 = config_value("SIZEOF___INT64").to_i
+ end
- def test_sizeof_builtin
- %w[char short int long float double void*].each do |type|
- assert_kind_of(Integer, mkmf {check_sizeof(type)}, MKMFLOG)
- end
- assert_operator(@sizeof_short, :<=, @sizeof_int)
- assert_operator(@sizeof_int, :<=, @sizeof_long)
- assert_operator(@sizeof_long, :<=, @sizeof_long_long) unless @sizeof_long_long.zero?
- assert_equal(8, @sizeof___int64) unless @sizeof___int64.zero?
+ def test_sizeof_builtin
+ %w[char short int long float double void*].each do |type|
+ assert_kind_of(Integer, mkmf {check_sizeof(type)}, MKMFLOG)
end
+ assert_operator(@sizeof_short, :<=, @sizeof_int)
+ assert_operator(@sizeof_int, :<=, @sizeof_long)
+ assert_operator(@sizeof_long, :<=, @sizeof_long_long) unless @sizeof_long_long.zero?
+ assert_equal(8, @sizeof___int64) unless @sizeof___int64.zero?
+ end
- def test_sizeof_struct
- open("confdefs.h", "w") {|f|
- f.puts "typedef struct {char x;} test1_t;"
- }
- assert_equal(1, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
+ def test_sizeof_struct
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef struct {char x;} test1_t;"
+ }
+ assert_equal(1, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
- open("confdefs.h", "w") {|f|
- f.puts "typedef struct {char x, y;} test1_t;"
- }
- assert_equal(2, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef struct {char x, y;} test1_t;"
+ }
+ assert_equal(2, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
- open("confdefs.h", "w") {|f|
- f.puts "typedef struct {int x;} test1_t;"
- }
- assert_equal(@sizeof_int, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
- open("confdefs.h", "w") {|f|
- f.puts "typedef struct {int x, y;} test1_t;"
- }
- assert_equal(2 * @sizeof_int, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
- ensure
- File.unlink("confdefs.h")
- end
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef struct {int x;} test1_t;"
+ }
+ assert_equal(@sizeof_int, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
+ open("confdefs.h", "w") {|f|
+ f.puts "typedef struct {int x, y;} test1_t;"
+ }
+ assert_equal(2 * @sizeof_int, mkmf {check_sizeof("test1_t", "confdefs.h")}, MKMFLOG)
+ ensure
+ File.unlink("confdefs.h")
end
end
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb
index b5156078a4..e9471273f4 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -1294,3 +1294,87 @@ class TestNetHTTPLocalBind < Test::Unit::TestCase
end
end
+class TestNetHTTPForceEncoding < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => 'localhost',
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ }
+
+ include TestNetHTTPUtils
+
+ def fe_request(force_enc, content_type=nil)
+ @server.mount_proc('/fe') do |req, res|
+ res['Content-Type'] = content_type if content_type
+ res.body = "hello\u1234"
+ end
+
+ http = Net::HTTP.new(config('host'), config('port'))
+ http.local_host = Addrinfo.tcp(config('host'), config('port')).ip_address
+ assert_not_nil(http.local_host)
+ assert_nil(http.local_port)
+
+ http.response_body_encoding = force_enc
+ http.get('/fe')
+ end
+
+ def test_response_body_encoding_false
+ res = fe_request(false)
+ assert_equal("hello\u1234".b, res.body)
+ assert_equal(Encoding::ASCII_8BIT, res.body.encoding)
+ end
+
+ def test_response_body_encoding_true_without_content_type
+ res = fe_request(true)
+ assert_equal("hello\u1234".b, res.body)
+ assert_equal(Encoding::ASCII_8BIT, res.body.encoding)
+ end
+
+ def test_response_body_encoding_true_with_content_type
+ res = fe_request(true, 'text/html; charset=utf-8')
+ assert_equal("hello\u1234", res.body)
+ assert_equal(Encoding::UTF_8, res.body.encoding)
+ end
+
+ def test_response_body_encoding_string_without_content_type
+ res = fe_request('utf-8')
+ assert_equal("hello\u1234", res.body)
+ assert_equal(Encoding::UTF_8, res.body.encoding)
+ end
+
+ def test_response_body_encoding_encoding_without_content_type
+ res = fe_request(Encoding::UTF_8)
+ assert_equal("hello\u1234", res.body)
+ assert_equal(Encoding::UTF_8, res.body.encoding)
+ end
+end
+
+class TestNetHTTPPartialResponse < Test::Unit::TestCase
+ CONFIG = {
+ 'host' => '127.0.0.1',
+ 'proxy_host' => nil,
+ 'proxy_port' => nil,
+ }
+
+ include TestNetHTTPUtils
+
+ def test_partial_response
+ str = "0123456789"
+ @server.mount_proc('/') do |req, res|
+ res.status = 200
+ res['Content-Type'] = 'text/plain'
+
+ res.body = str
+ res['Content-Length'] = str.length + 1
+ end
+ @server.mount_proc('/show_ip') { |req, res| res.body = req.remote_ip }
+
+ http = Net::HTTP.new(config('host'), config('port'))
+ res = http.get('/')
+ assert_equal(str, res.body)
+
+ http = Net::HTTP.new(config('host'), config('port'))
+ http.ignore_eof = false
+ assert_raise(EOFError) {http.get('/')}
+ end
+end
diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb
index 00b0072e70..394b4c5bfa 100644
--- a/test/net/http/test_httpresponse.rb
+++ b/test/net/http/test_httpresponse.rb
@@ -54,6 +54,241 @@ EOS
assert_equal 'hello', body
end
+ def test_read_body_body_encoding_false
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234".b, body
+ assert_equal Encoding::ASCII_8BIT, body.encoding
+ end
+
+ def test_read_body_body_encoding_encoding
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = Encoding.find('utf-8')
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234", body
+ assert_equal Encoding::UTF_8, body.encoding
+ end
+
+ def test_read_body_body_encoding_string
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = 'utf-8'
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234", body
+ assert_equal Encoding::UTF_8, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_without_content_type_header
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234".b, body
+ assert_equal Encoding::ASCII_8BIT, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_utf8_content_type_header
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+Content-Type: text/plain; charset=utf-8
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234", body
+ assert_equal Encoding::UTF_8, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_iso_8859_1_content_type_header
+ body = "hello\u1234"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{body.bytesize}
+Content-Type: text/plain; charset=iso-8859-1
+
+#{body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal "hello\u1234".force_encoding("ISO-8859-1"), body
+ assert_equal Encoding::ISO_8859_1, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_utf8_meta_charset
+ res_body = "<html><meta charset=\"utf-8\">hello\u1234</html>"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{res_body.bytesize}
+Content-Type: text/html
+
+#{res_body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal res_body, body
+ assert_equal Encoding::UTF_8, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_iso8859_1_meta_charset
+ res_body = "<html><meta charset=\"iso-8859-1\">hello\u1234</html>"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{res_body.bytesize}
+Content-Type: text/html
+
+#{res_body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal res_body.force_encoding("ISO-8859-1"), body
+ assert_equal Encoding::ISO_8859_1, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_utf8_meta_content_charset
+ res_body = "<meta http-equiv='content-type' content='text/html; charset=UTF-8'>hello\u1234</html>"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{res_body.bytesize}
+Content-Type: text/html
+
+#{res_body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal res_body, body
+ assert_equal Encoding::UTF_8, body.encoding
+ end
+
+ def test_read_body_body_encoding_true_with_iso8859_1_meta_content_charset
+ res_body = "<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>hello\u1234</html>"
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: #{res_body.bytesize}
+Content-Type: text/html
+
+#{res_body}
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = true
+
+ body = nil
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal res_body.force_encoding("ISO-8859-1"), body
+ assert_equal Encoding::ISO_8859_1, body.encoding
+ end
+
def test_read_body_block
io = dummy_io(<<EOS)
HTTP/1.1 200 OK
@@ -78,7 +313,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|
@@ -127,9 +362,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal '5', res['content-length']
assert_equal 'hello', body
else
assert_equal 'deflate', res['content-encoding']
+ assert_equal '13', res['content-length']
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body
end
end
@@ -155,9 +392,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal '5', res['content-length']
assert_equal 'hello', body
else
assert_equal 'DEFLATE', res['content-encoding']
+ assert_equal '13', res['content-length']
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body
end
end
@@ -188,9 +427,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal 'hello', body
else
assert_equal 'deflate', res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body
end
end
@@ -215,6 +456,7 @@ EOS
end
assert_equal 'deflate', res['content-encoding'], 'Bug #7831'
+ assert_equal '13', res['content-length']
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body, 'Bug #7381'
end
@@ -238,9 +480,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal 'hello', body
else
assert_equal 'deflate', res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15\r\n", body
end
end
@@ -288,9 +532,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal '0', res['content-length']
assert_equal '', body
else
assert_equal 'deflate', res['content-encoding']
+ assert_equal '0', res['content-length']
assert_equal '', body
end
end
@@ -314,9 +560,11 @@ EOS
if Net::HTTP::HAVE_ZLIB
assert_equal nil, res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal '', body
else
assert_equal 'deflate', res['content-encoding']
+ assert_equal nil, res['content-length']
assert_equal '', body
end
end
diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
index 4dc9f1b026..72a69af1a5 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
@@ -152,19 +152,21 @@ class TestNetHTTPS < Test::Unit::TestCase
end
http.start
- assert_equal false, http.instance_variable_get(:@socket).io.session_reused?
+ session_reused = http.instance_variable_get(:@socket).io.session_reused?
+ assert_false session_reused unless session_reused.nil? # can not detect re-use under JRuby
http.get("/")
http.finish
http.start
- assert_equal true, http.instance_variable_get(:@socket).io.session_reused?
+ session_reused = http.instance_variable_get(:@socket).io.session_reused?
+ assert_true session_reused unless session_reused.nil? # can not detect re-use under JRuby
assert_equal $test_net_http_data, http.get("/").body
http.finish
end
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
@@ -301,7 +303,7 @@ class TestNetHTTPS < Test::Unit::TestCase
ex = assert_raise(OpenSSL::SSL::SSLError){
http.request_get("/") {|res| }
}
- re_msg = /\ASSL_connect returned=1 errno=0 |SSL_CTX_set_max_proto_version/
+ re_msg = /\ASSL_connect returned=1 errno=0 |SSL_CTX_set_max_proto_version|No appropriate protocol/
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 f833f1a1e3..4c2a92ccd6 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/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index a1954d56a9..ed9c998597 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -33,7 +33,7 @@ class TestObjSpace < Test::Unit::TestCase
b = a.dup
c = nil
ObjectSpace.each_object(String) {|x| break c = x if x == a and x.frozen?}
- rv_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
+ rv_size = GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]
assert_equal([rv_size, rv_size, a.length + 1 + rv_size], [a, b, c].map {|x| ObjectSpace.memsize_of(x)})
end
@@ -140,6 +140,18 @@ class TestObjSpace < Test::Unit::TestCase
end;
end
+ def test_reachable_objects_during_iteration
+ opts = %w[--disable-gem --disable=frozen-string-literal -robjspace]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+ begin;
+ ObjectSpace.each_object{|o|
+ o.inspect
+ ObjectSpace.reachable_objects_from(Class)
+ }
+ end;
+ end
+
+
def test_reachable_objects_from_root
root_objects = ObjectSpace.reachable_objects_from_root
@@ -295,6 +307,28 @@ class TestObjSpace < Test::Unit::TestCase
JSON.parse(info) if defined?(JSON)
end
+ def test_dump_array
+ # Empty array
+ info = ObjectSpace.dump([])
+ assert_include(info, '"length":0, "embedded":true')
+ assert_not_include(info, '"shared":true')
+
+ # Non-embed array
+ arr = (1..10).to_a
+ info = ObjectSpace.dump(arr)
+ assert_include(info, '"length":10')
+ assert_not_include(info, '"embedded":true')
+ assert_not_include(info, '"shared":true')
+
+ # Shared array
+ arr1 = (1..10).to_a
+ arr = []
+ arr.replace(arr1)
+ info = ObjectSpace.dump(arr)
+ assert_include(info, '"length":10, "shared":true')
+ assert_not_include(info, '"embedded":true')
+ end
+
def test_dump_control_char
assert_include(ObjectSpace.dump("\x0f"), '"value":"\u000f"')
assert_include(ObjectSpace.dump("\C-?"), '"value":"\u007f"')
@@ -431,6 +465,27 @@ class TestObjSpace < Test::Unit::TestCase
end
end
+ def test_dump_objects_dumps_page_slot_sizes
+ assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error|
+ begin;
+ def dump_my_heap_please
+ ObjectSpace.dump_all(output: $stdout)
+ end
+
+ p $stdout == dump_my_heap_please
+ end;
+ assert_equal 'true', output.pop
+ assert(output.count > 1)
+ output.each { |l|
+ obj = JSON.parse(l)
+ next if obj["type"] == "ROOT"
+
+ assert(obj["slot_size"] != nil)
+ assert(obj["slot_size"] % GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] == 0)
+ }
+ end
+ end
+
def test_dump_escapes_method_name
method_name = "foo\"bar"
klass = Class.new do
@@ -449,6 +504,13 @@ class TestObjSpace < Test::Unit::TestCase
ObjectSpace.trace_object_allocations_stop
end
+ def test_dump_includes_slot_size
+ str = "TEST"
+ dump = ObjectSpace.dump(str)
+
+ assert_includes dump, "\"slot_size\":#{GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]}"
+ end
+
def test_dump_reference_addresses_match_dump_all_addresses
assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error|
begin;
@@ -470,8 +532,28 @@ class TestObjSpace < Test::Unit::TestCase
end
end
+ def assert_test_string_entry_correct_in_dump_all(output)
+ # `TEST STRING` appears twice in the output of `ObjectSpace.dump_all`
+ # 1. To create the T_STRING object for the literal string "TEST STRING"
+ # 2. When it is assigned to the `str` variable with a new encoding
+ #
+ # This test makes assertions on the assignment to `str`, so we look for
+ # the second appearance of /TEST STRING/ in the output
+ test_string_in_dump_all = output.grep(/TEST STRING/)
+ assert_equal(test_string_in_dump_all.size, 2)
+
+ entry_hash = JSON.parse(test_string_in_dump_all[1])
+
+ assert_equal(entry_hash["bytesize"], 11)
+ assert_equal(entry_hash["value"], "TEST STRING")
+ assert_equal(entry_hash["encoding"], "UTF-8")
+ assert_equal(entry_hash["file"], "-")
+ assert_equal(entry_hash["line"], 4)
+ assert_equal(entry_hash["method"], "dump_my_heap_please")
+ assert_not_nil(entry_hash["generation"])
+ end
+
def test_dump_all
- entry = /"bytesize":11, "value":"TEST STRING", "encoding":"UTF-8", "file":"-", "line":4, "method":"dump_my_heap_please", "generation":/
opts = %w[--disable-gem --disable=frozen-string-literal -robjspace]
assert_in_out_err(opts, "#{<<-"begin;"}#{<<-'end;'}") do |output, error|
@@ -485,8 +567,8 @@ class TestObjSpace < Test::Unit::TestCase
p dump_my_heap_please
end;
- assert_equal 'nil', output.pop
- assert_match(entry, output.grep(/TEST STRING/).join("\n"))
+
+ assert_test_string_entry_correct_in_dump_all(output)
end
assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}#{<<-'end;'}") do |(output), (error)|
@@ -503,7 +585,8 @@ class TestObjSpace < Test::Unit::TestCase
assert_nil(error)
dump = File.readlines(output)
File.unlink(output)
- assert_match(entry, dump.grep(/TEST STRING/).join("\n"))
+
+ assert_test_string_entry_correct_in_dump_all(dump)
end
if defined?(JSON)
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 3f0622f94f..346602dada 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 6d18c0c85c..b5fdf0b3d1 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 2f53a813e1..47cb3718df 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 757704caf6..161af1897b 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 0994607f21..726b7dbf7e 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 3f5958af50..ffe5a94e5b 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 dbe87ba4c1..4bb39ed4a6 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 ef9958aee5..a7607da073 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -893,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
@@ -1211,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_acceptable.rb b/test/optparse/test_acceptable.rb
index 12f7886538..12f5322726 100644
--- a/test/optparse/test_acceptable.rb
+++ b/test/optparse/test_acceptable.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-class TestOptionParser::Acceptable < TestOptionParser
+class TestOptionParserAcceptable < TestOptionParser
def setup
super
diff --git a/test/optparse/test_autoconf.rb b/test/optparse/test_autoconf.rb
index 45f2ba09b2..ec87744633 100644
--- a/test/optparse/test_autoconf.rb
+++ b/test/optparse/test_autoconf.rb
@@ -2,9 +2,7 @@
require 'test/unit'
require 'optparse/ac'
-class TestOptionParser < Test::Unit::TestCase; end
-
-class TestOptionParser::AutoConf < Test::Unit::TestCase
+class TestOptionParserAutoConf < Test::Unit::TestCase
def setup
@opt = OptionParser::AC.new
@foo = @bar = self.class
diff --git a/test/optparse/test_bash_completion.rb b/test/optparse/test_bash_completion.rb
index 513e986f66..60c82f7136 100644
--- a/test/optparse/test_bash_completion.rb
+++ b/test/optparse/test_bash_completion.rb
@@ -2,9 +2,7 @@
require 'test/unit'
require 'optparse'
-class TestOptionParser < Test::Unit::TestCase
-end
-class TestOptionParser::BashCompletion < Test::Unit::TestCase
+class TestOptionParserBashCompletion < Test::Unit::TestCase
def setup
@opt = OptionParser.new
@opt.define("-z", "zzz") {}
diff --git a/test/optparse/test_cclass.rb b/test/optparse/test_cclass.rb
index ac46f46bb2..0ded61f60e 100644
--- a/test/optparse/test_cclass.rb
+++ b/test/optparse/test_cclass.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-class TestOptionParser::CClass < TestOptionParser
+class TestOptionParserCClass < TestOptionParser
def test_no_argument
flags = []
@opt.def_option("-[a-z]") {|x| flags << x}
diff --git a/test/optparse/test_did_you_mean.rb b/test/optparse/test_did_you_mean.rb
index aa866f4072..3c923922ec 100644
--- a/test/optparse/test_did_you_mean.rb
+++ b/test/optparse/test_did_you_mean.rb
@@ -6,17 +6,21 @@ rescue LoadError
return
end
-class TestOptionParser::DidYouMean < TestOptionParser
+class TestOptionParserDidYouMean < TestOptionParser
def setup
super
@opt.def_option("--foo", Integer) { |v| @foo = v }
@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
diff --git a/test/optparse/test_getopts.rb b/test/optparse/test_getopts.rb
index 3711e6f269..7d9160f7af 100644
--- a/test/optparse/test_getopts.rb
+++ b/test/optparse/test_getopts.rb
@@ -2,9 +2,7 @@
require 'test/unit'
require 'optparse'
-class TestOptionParser < Test::Unit::TestCase
-end
-class TestOptionParser::Getopts < Test::Unit::TestCase
+class TestOptionParserGetopts < Test::Unit::TestCase
def setup
@opt = OptionParser.new
end
diff --git a/test/optparse/test_kwargs.rb b/test/optparse/test_kwargs.rb
index 78d7e2ee9c..2e826bfd12 100644
--- a/test/optparse/test_kwargs.rb
+++ b/test/optparse/test_kwargs.rb
@@ -3,9 +3,7 @@ require 'test/unit'
require 'optparse'
require 'optparse/kwargs'
-class TestOptionParser < Test::Unit::TestCase
-end
-class TestOptionParser::KwArg < Test::Unit::TestCase
+class TestOptionParserKwArg < Test::Unit::TestCase
class K
def initialize(host:, port: 8080)
@host = host
diff --git a/test/optparse/test_noarg.rb b/test/optparse/test_noarg.rb
index 8f20519408..a53399afc2 100644
--- a/test/optparse/test_noarg.rb
+++ b/test/optparse/test_noarg.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-module TestOptionParser::NoArg
+module TestOptionParserNoArg
def setup
super
@opt.def_option "--with_underscore" do |x| @flag = x end
@@ -9,7 +9,7 @@ module TestOptionParser::NoArg
end
class Def1 < TestOptionParser
- include NoArg
+ include TestOptionParserNoArg
def setup
super
@opt.def_option("-x") {|x| @flag = x}
@@ -17,7 +17,7 @@ module TestOptionParser::NoArg
end
end
class Def2 < TestOptionParser
- include NoArg
+ include TestOptionParserNoArg
def setup
super
@opt.def_option("-x", "--option") {|x| @flag = x}
diff --git a/test/optparse/test_optarg.rb b/test/optparse/test_optarg.rb
index 14584f7e89..81127a8a37 100644
--- a/test/optparse/test_optarg.rb
+++ b/test/optparse/test_optarg.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-class TestOptionParser::OptArg < TestOptionParser
+class TestOptionParserOptArg < TestOptionParser
def setup
super
@opt.def_option("-x[VAL]") {|x| @flag = x}
diff --git a/test/optparse/test_placearg.rb b/test/optparse/test_placearg.rb
index 8acfdb2161..94cfb0e819 100644
--- a/test/optparse/test_placearg.rb
+++ b/test/optparse/test_placearg.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-class TestOptionParser::PlaceArg < TestOptionParser
+class TestOptionParserPlaceArg < TestOptionParser
def setup
super
@opt.def_option("-x [VAL]") {|x| @flag = x}
diff --git a/test/optparse/test_reqarg.rb b/test/optparse/test_reqarg.rb
index b2e4755f80..d5686d13aa 100644
--- a/test/optparse/test_reqarg.rb
+++ b/test/optparse/test_reqarg.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-module TestOptionParser::ReqArg
+module TestOptionParserReqArg
def setup
super
@opt.def_option "--with_underscore=VAL" do |x| @flag = x end
@@ -9,7 +9,7 @@ module TestOptionParser::ReqArg
end
class Def1 < TestOptionParser
- include ReqArg
+ include TestOptionParserReqArg
def setup
super
@opt.def_option("-xVAL") {|x| @flag = x}
@@ -19,21 +19,21 @@ module TestOptionParser::ReqArg
end
end
class Def2 < TestOptionParser
- include ReqArg
+ include TestOptionParserReqArg
def setup
super
@opt.def_option("-x", "--option=VAL") {|x| @flag = x}
end
end
class Def3 < TestOptionParser
- include ReqArg
+ include TestOptionParserReqArg
def setup
super
@opt.def_option("--option=VAL", "-x") {|x| @flag = x}
end
end
class Def4 < TestOptionParser
- include ReqArg
+ include TestOptionParserReqArg
def setup
super
@opt.def_option("-xVAL", "--option=VAL") {|x| @flag = x}
diff --git a/test/optparse/test_summary.rb b/test/optparse/test_summary.rb
index 67b05672d4..6b36ce3c76 100644
--- a/test/optparse/test_summary.rb
+++ b/test/optparse/test_summary.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'test_optparse'
-class TestOptionParser::SummaryTest < TestOptionParser
+class TestOptionParserSummaryTest < TestOptionParser
def test_short_clash
r = nil
o = OptionParser.new do |opts|
diff --git a/test/optparse/test_zsh_completion.rb b/test/optparse/test_zsh_completion.rb
index c548d4af8a..76f0a73f32 100644
--- a/test/optparse/test_zsh_completion.rb
+++ b/test/optparse/test_zsh_completion.rb
@@ -2,9 +2,7 @@
require 'test/unit'
require 'optparse'
-class TestOptionParser < Test::Unit::TestCase
-end
-class TestOptionParser::ZshCompletion < Test::Unit::TestCase
+class TestOptionParserZshCompletion < Test::Unit::TestCase
def setup
@opt = OptionParser.new
@opt.define("-z", "zzz") {}
diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb
index 4ec4d43084..256db7a0c7 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
@@ -405,4 +406,10 @@ class TC_OpenStruct < Test::Unit::TestCase
o2 = Marshal.load(Marshal.dump(o))
assert_equal o, o2
end
+
+ def test_class
+ os = OpenStruct.new(class: 'my-class', method: 'post')
+ assert_equal('my-class', os.class)
+ assert_equal(OpenStruct, os.class!)
+ end
end
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 9e14668c99..a23dc21ae3 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -1043,6 +1043,25 @@ class TestPathname < Test::Unit::TestCase
}
end
+ def test_lutime
+ return if !has_symlink?
+ with_tmpchdir('rubytest-pathname') {|dir|
+ open("a", "w") {|f| f.write "abc" }
+ atime = File.atime("a")
+ mtime = File.mtime("a")
+ latime = Time.utc(2000)
+ lmtime = Time.utc(1999)
+ File.symlink("a", "l")
+ Pathname("l").utime(latime, lmtime)
+ s = File.lstat("a")
+ ls = File.lstat("l")
+ assert_equal(atime, s.atime)
+ assert_equal(mtime, s.mtime)
+ assert_equal(latime, ls.atime)
+ assert_equal(lmtime, ls.mtime)
+ }
+ end
+
def test_basename
assert_equal(Pathname("basename"), Pathname("dirname/basename").basename)
assert_equal(Pathname("bar"), Pathname("foo/bar.x").basename(".x"))
@@ -1355,6 +1374,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 8c3dcd173c..9c75c016cd 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 ebc9fbdcd2..145db58fd9 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/racc/case.rb b/test/racc/case.rb
index f4240bfd21..d917f3a4e4 100644
--- a/test/racc/case.rb
+++ b/test/racc/case.rb
@@ -90,8 +90,7 @@ module Racc
actual = File.read("#{@TAB_DIR}/#{file}")
result = (strip_version(expected) == strip_version(actual))
- assert(result, "Output of test/assets/#{file}.y differed from " \
- "expectation. Try compiling it and diff with test/regress/#{file}.")
+ assert(result, proc {`diff -u #{REGRESS_DIR}/#{file} #{@TAB_DIR}/#{file}`})
end
def racc(*arg, **opt)
diff --git a/test/rdoc/helper.rb b/test/rdoc/helper.rb
index 2ba26c296b..7985433060 100644
--- a/test/rdoc/helper.rb
+++ b/test/rdoc/helper.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require_relative './support/test_case'
-require_relative './support/formatter_test_case'
-require_relative './support/text_formatter_test_case'
+require_relative 'support/test_case'
+require_relative 'support/formatter_test_case'
+require_relative 'support/text_formatter_test_case'
diff --git a/test/rdoc/support/test_case.rb b/test/rdoc/support/test_case.rb
index 7617fc8471..36009111e2 100644
--- a/test/rdoc/support/test_case.rb
+++ b/test/rdoc/support/test_case.rb
@@ -13,7 +13,7 @@ require 'tempfile'
require 'tmpdir'
require 'stringio'
-require 'rdoc'
+require_relative '../../../lib/rdoc'
##
# RDoc::TestCase is an abstract TestCase to provide common setup and teardown
diff --git a/test/rdoc/test_rdoc_alias.rb b/test/rdoc/test_rdoc_alias.rb
index 89ae2d5a56..3c096a49b4 100644
--- a/test/rdoc/test_rdoc_alias.rb
+++ b/test/rdoc/test_rdoc_alias.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocAlias < XrefTestCase
@@ -11,4 +11,3 @@ class TestRDocAlias < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_any_method.rb b/test/rdoc/test_rdoc_any_method.rb
index caff86b059..826ef1c8d8 100644
--- a/test/rdoc/test_rdoc_any_method.rb
+++ b/test/rdoc/test_rdoc_any_method.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocAnyMethod < XrefTestCase
diff --git a/test/rdoc/test_rdoc_class_module.rb b/test/rdoc/test_rdoc_class_module.rb
index ad185671cf..27d37cb7dd 100644
--- a/test/rdoc/test_rdoc_class_module.rb
+++ b/test/rdoc/test_rdoc_class_module.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocClassModule < XrefTestCase
@@ -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
@@ -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
@@ -1501,4 +1501,3 @@ class TestRDocClassModule < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_code_object.rb b/test/rdoc/test_rdoc_code_object.rb
index fad182722a..24e228cce1 100644
--- a/test/rdoc/test_rdoc_code_object.rb
+++ b/test/rdoc/test_rdoc_code_object.rb
@@ -1,7 +1,7 @@
# coding: US-ASCII
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocCodeObject < XrefTestCase
diff --git a/test/rdoc/test_rdoc_constant.rb b/test/rdoc/test_rdoc_constant.rb
index 79dcdad57e..32ffe3f84d 100644
--- a/test/rdoc/test_rdoc_constant.rb
+++ b/test/rdoc/test_rdoc_constant.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocConstant < XrefTestCase
diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb
index ecdb3cbd67..85665599fb 100644
--- a/test/rdoc/test_rdoc_context.rb
+++ b/test/rdoc/test_rdoc_context.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocContext < XrefTestCase
@@ -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 94ddc1e1e4..cbda77a798 100644
--- a/test/rdoc/test_rdoc_cross_reference.rb
+++ b/test/rdoc/test_rdoc_cross_reference.rb
@@ -1,7 +1,10 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocCrossReference < XrefTestCase
+ EXAMPLE_METHODS = %w'== === != =~ !~ < > <= >= <=> [] []= << >>
+ -@ +@ ! - + * / % ** !@ ` | & ^ ~ __id__
+ '
def setup
super
@@ -18,9 +21,9 @@ class TestRDocCrossReference < XrefTestCase
end
def test_METHOD_REGEXP_STR
- re = /#{RDoc::CrossReference::METHOD_REGEXP_STR}/
+ re = /\A(?:#{RDoc::CrossReference::METHOD_REGEXP_STR})\z/
- %w'== === [] []= << >>'.each do |x|
+ EXAMPLE_METHODS.each do |x|
re =~ x
assert_equal x, $&
end
@@ -88,6 +91,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'
@@ -154,34 +166,35 @@ class TestRDocCrossReference < XrefTestCase
assert_ref @c9_a_c_bar, 'C9::B.bar'
end
- def test_resolve_method_equals3
- m = RDoc::AnyMethod.new '', '==='
- @c1.add_method m
-
- assert_ref m, '==='
- end
-
def test_resolve_page
page = @store.add_file 'README.txt', parser: RDoc::Parser::Simple
assert_ref page, 'README'
end
- def test_resolve_percent
- i_percent = RDoc::AnyMethod.new nil, '%'
- i_percent.singleton = false
- @c1.add_method i_percent
+ def assert_resolve_method(x)
+ @c1.methods_hash.clear
- c_percent = RDoc::AnyMethod.new nil, '%'
- c_percent.singleton = true
- @c1.add_method c_percent
+ i_op = RDoc::AnyMethod.new nil, x
+ i_op.singleton = false
+ @c1.add_method i_op
- assert_ref i_percent, '%'
- assert_ref i_percent, '#%'
- assert_ref c_percent, '::%'
+ c_op = RDoc::AnyMethod.new nil, x
+ c_op.singleton = true
+ @c1.add_method c_op
- assert_ref i_percent, 'C1#%'
- assert_ref c_percent, 'C1::%'
+ assert_ref i_op, x
+ assert_ref i_op, "##{x}"
+ assert_ref c_op, "::#{x}"
+
+ assert_ref i_op, "C1##{x}"
+ assert_ref c_op, "C1::#{x}"
+ end
+
+ EXAMPLE_METHODS.each do |x|
+ define_method("test_resolve_method:#{x}") do
+ assert_resolve_method(x)
+ end
end
def test_resolve_no_ref
@@ -204,4 +217,3 @@ class TestRDocCrossReference < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_extend.rb b/test/rdoc/test_rdoc_extend.rb
index f4c8425864..cc5038cc51 100644
--- a/test/rdoc/test_rdoc_extend.rb
+++ b/test/rdoc/test_rdoc_extend.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocExtend < XrefTestCase
@@ -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,8 +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_generator_darkfish.rb b/test/rdoc/test_rdoc_generator_darkfish.rb
index b78a3fb45f..ae3a4c5ebf 100644
--- a/test/rdoc/test_rdoc_generator_darkfish.rb
+++ b/test/rdoc/test_rdoc_generator_darkfish.rb
@@ -72,11 +72,14 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
def test_generate
top_level = @store.add_file 'file.rb'
top_level.add_class @klass.class, @klass.name
+ @klass.add_class RDoc::NormalClass, 'Inner'
@g.generate
assert_file 'index.html'
assert_file 'Object.html'
+ assert_file 'Klass.html'
+ assert_file 'Klass/Inner.html'
assert_file 'table_of_contents.html'
assert_file 'js/search_index.js'
@@ -92,6 +95,25 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
assert_match %r%<meta charset="#{encoding}">%, File.read('Object.html')
refute_match(/Ignored/, File.read('index.html'))
+ summary = File.read('index.html')[%r[<summary.*Klass\.html.*</summary>.*</details>]m]
+ assert_match(%r[Klass/Inner\.html".*>Inner<], summary)
+ end
+
+ def test_generate_page
+ @store.add_file 'outer.rdoc', parser: RDoc::Parser::Simple
+ @store.add_file 'outer/inner.rdoc', parser: RDoc::Parser::Simple
+ @g.generate
+ assert_file 'outer_rdoc.html'
+ assert_file 'outer/inner_rdoc.html'
+ index = File.read('index.html')
+ re = %r[<summary><a href="\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
+ assert_match(re, index)
+ summary = index[re]
+ assert_match %r[<a href="\./outer/inner_rdoc.html">inner</a>], summary
+ re = %r[<details open><summary><a href="\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
+ assert_match(re, File.read('outer_rdoc.html'))
+ re = %r[<details open><summary><a href="\.\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
+ assert_match(re, File.read('outer/inner_rdoc.html'))
end
def test_generate_dry_run
diff --git a/test/rdoc/test_rdoc_include.rb b/test/rdoc/test_rdoc_include.rb
index 67d3dfd88e..380464f6cc 100644
--- a/test/rdoc/test_rdoc_include.rb
+++ b/test/rdoc/test_rdoc_include.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocInclude < XrefTestCase
@@ -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
@@ -106,4 +107,3 @@ class TestRDocInclude < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markdown.rb b/test/rdoc/test_rdoc_markdown.rb
index ad53e9473c..c223c44c12 100644
--- a/test/rdoc/test_rdoc_markdown.rb
+++ b/test/rdoc/test_rdoc_markdown.rb
@@ -2,8 +2,8 @@
# frozen_string_literal: true
require_relative 'helper'
-require 'rdoc/markup/block_quote'
-require 'rdoc/markdown'
+require_relative '../../lib/rdoc/markup/block_quote'
+require_relative '../../lib/rdoc/markdown'
class TestRDocMarkdown < RDoc::TestCase
@@ -1068,4 +1068,3 @@ and an extra note.[^2]
end
end
-
diff --git a/test/rdoc/test_rdoc_markdown_test.rb b/test/rdoc/test_rdoc_markdown_test.rb
index 0ecd000136..d4f894c924 100644
--- a/test/rdoc/test_rdoc_markdown_test.rb
+++ b/test/rdoc/test_rdoc_markdown_test.rb
@@ -2,8 +2,8 @@
require_relative 'helper'
require 'pp'
-require 'rdoc'
-require 'rdoc/markdown'
+require_relative '../../lib/rdoc'
+require_relative '../../lib/rdoc/markdown'
class TestRDocMarkdownTest < RDoc::TestCase
diff --git a/test/rdoc/test_rdoc_markup_attribute_manager.rb b/test/rdoc/test_rdoc_markup_attribute_manager.rb
index 944364ba89..e8ff602f96 100644
--- a/test/rdoc/test_rdoc_markup_attribute_manager.rb
+++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb
@@ -145,6 +145,8 @@ class TestRDocMarkupAttributeManager < RDoc::TestCase
assert_equal(["cat and ", @em_on, "5", @em_off, " dogs"],
@am.flow("cat and _5_ dogs"))
+
+ assert_equal([@tt_on, "__id__", @tt_off], @am.flow("+__id__+"))
end
def test_bold
diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb
index b2b21de806..e5d7a35710 100644
--- a/test/rdoc/test_rdoc_markup_to_html.rb
+++ b/test/rdoc/test_rdoc_markup_to_html.rb
@@ -707,6 +707,7 @@ EXPECTED
def test_convert_with_exclude_tag
assert_equal "\n<p><code>aaa</code>[:symbol]</p>\n", @to.convert('+aaa+[:symbol]')
assert_equal "\n<p><code>aaa[:symbol]</code></p>\n", @to.convert('+aaa[:symbol]+')
+ assert_equal "\n<p><code>https:</code>-foobar</p>\n", @to.convert('<tt>https:</tt>-foobar')
assert_equal "\n<p><a href=\":symbol\">aaa</a></p>\n", @to.convert('aaa[:symbol]')
end
diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
index f6fabfb7db..4b87dd5da5 100644
--- a/test/rdoc/test_rdoc_markup_to_html_crossref.rb
+++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocMarkupToHtmlCrossref < XrefTestCase
@@ -17,6 +17,12 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
assert_equal para("<a href=\"C1.html\"><code>C1</code></a>"), result
end
+ def test_convert_CROSSREF_method
+ result = @to.convert 'C1#m(foo, bar, baz)'
+
+ assert_equal para("<a href=\"C1.html#method-i-m\"><code>C1#m(foo, bar, baz)</code></a>"), result
+ end
+
def test_convert_CROSSREF_label
result = @to.convert 'C1@foo'
assert_equal para("<a href=\"C1.html#class-C1-label-foo\">foo at <code>C1</code></a>"), result
@@ -260,4 +266,3 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_method_attr.rb b/test/rdoc/test_rdoc_method_attr.rb
index 68a9d6cc21..d607619a60 100644
--- a/test/rdoc/test_rdoc_method_attr.rb
+++ b/test/rdoc/test_rdoc_method_attr.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocMethodAttr < XrefTestCase
@@ -191,4 +191,3 @@ class TestRDocMethodAttr < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_normal_class.rb b/test/rdoc/test_rdoc_normal_class.rb
index 874eaaa88c..3d097ebb52 100644
--- a/test/rdoc/test_rdoc_normal_class.rb
+++ b/test/rdoc/test_rdoc_normal_class.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocNormalClass < XrefTestCase
@@ -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
@@ -45,4 +45,3 @@ class TestRDocNormalClass < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_normal_module.rb b/test/rdoc/test_rdoc_normal_module.rb
index 68e776c41f..cccee5c44c 100644
--- a/test/rdoc/test_rdoc_normal_module.rb
+++ b/test/rdoc/test_rdoc_normal_module.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocNormalModule < XrefTestCase
@@ -40,4 +40,3 @@ class TestRDocNormalModule < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 7c264c5e86..009dcdd998 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -55,11 +55,10 @@ class TestRDocOptions < RDoc::TestCase
refute @options.dry_run
end
- def test_encode_with
- coder = {}
- class << coder; alias add []=; end
+ def test_to_yaml
+ RDoc.load_yaml
- @options.encode_with coder
+ coder = YAML.load(@options.to_yaml)
encoding = 'UTF-8'
@@ -89,10 +88,11 @@ class TestRDocOptions < RDoc::TestCase
assert_equal expected, coder
end
- def test_encode_with_trim_paths
+ def test_to_yaml_trim_paths
+ RDoc.load_yaml
+
subdir = nil
- coder = {}
- class << coder; alias add []=; end
+ coder = nil
temp_dir do |dir|
FileUtils.mkdir 'project'
@@ -113,7 +113,7 @@ class TestRDocOptions < RDoc::TestCase
--include /
]
- @options.encode_with coder
+ coder = YAML.load(@options.to_yaml)
end
end
@@ -145,7 +145,9 @@ class TestRDocOptions < RDoc::TestCase
@options.encoding = Encoding::IBM437
- options = YAML.safe_load(YAML.dump(@options), permitted_classes: [RDoc::Options, Symbol])
+ options = @options.to_yaml
+ options = YAML.safe_load(options, permitted_classes: [Symbol])
+ options = RDoc::Options.new(options)
assert_equal Encoding::IBM437, options.encoding
end
@@ -154,14 +156,15 @@ class TestRDocOptions < RDoc::TestCase
RDoc.load_yaml
yaml = <<-YAML
---- !ruby/object:RDoc::Options
+---
static_path:
- /etc
rdoc_include:
- /etc
YAML
- options = YAML.safe_load(yaml, permitted_classes: [RDoc::Options, Symbol])
+ options = YAML.safe_load(yaml, permitted_classes: [Symbol])
+ options = RDoc::Options.new(options)
assert_empty options.rdoc_include
assert_empty options.static_path
@@ -243,6 +246,7 @@ rdoc_include:
def test_parse_default
@options.parse []
+ @options.finish
assert_equal RDoc::Generator::Darkfish, @options.generator
assert_equal 'darkfish', @options.template
@@ -502,6 +506,7 @@ rdoc_include:
out, err = capture_output do
@options.parse %W[--page-dir #{Dir.tmpdir}]
+ @options.finish
end
assert_empty out
@@ -530,6 +535,7 @@ rdoc_include:
out, err = capture_output do
@options.parse %W[--page-dir #{abs_page_dir} --root #{abs_root}]
+ @options.finish
end
assert_empty out
@@ -558,6 +564,8 @@ rdoc_include:
assert_empty err
assert_equal Pathname(Dir.tmpdir), @options.root
+
+ @options.finish
assert_includes @options.rdoc_include, @options.root.to_s
end
@@ -602,6 +610,7 @@ rdoc_include:
assert_empty out
assert_equal "could not find template NONEXISTENT\n", err
+ @options.finish
assert_equal 'darkfish', @options.template
assert_match %r%rdoc/generator/template/darkfish$%, @options.template_dir
end
@@ -668,6 +677,7 @@ rdoc_include:
Dir.chdir tmpdir do
e = assert_raise SystemExit do
@options.parse %w[--write-options]
+ @options.finish
end
assert_equal 0, e.status
@@ -764,7 +774,9 @@ rdoc_include:
assert File.exist? '.rdoc_options'
- assert_equal @options, YAML.safe_load(File.read('.rdoc_options'), permitted_classes: [RDoc::Options, Symbol])
+ options = File.read('.rdoc_options')
+ options = YAML.safe_load(options, permitted_classes: [Symbol])
+ assert_equal @options, RDoc::Options.new(options)
end
end
@@ -834,20 +846,34 @@ rdoc_include:
def test_load_options_partial_override
temp_dir do
File.open '.rdoc_options', 'w' do |io|
- io.write "markup: Markdown"
+ io.puts "markup: Markdown"
+ io.puts "encoding: iso-8859-1"
+ io.puts "static_path: [static]"
+ io.puts "rdoc_include: [.]"
+ io.puts "page_dir: pages"
end
options = RDoc::Options.load_options
assert_equal 'Markdown', options.markup
+ assert_equal Encoding::ISO_8859_1, options.encoding
+ assert_equal ["static"], options.static_path
+ assert_equal ["."], options.rdoc_include
+ assert_equal "pages", options.page_dir
end
end
- def load_options_no_file
+ def test_load_options_no_file
temp_dir do
options = RDoc::Options.load_options
assert_kind_of RDoc::Options, options
end
end
+
+ class DummyCoder < Hash
+ alias add :[]=
+ def tag=(tag)
+ end
+ end
end
diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb
index 8f51f32f26..d3138d23aa 100644
--- a/test/rdoc/test_rdoc_parser_c.rb
+++ b/test/rdoc/test_rdoc_parser_c.rb
@@ -355,6 +355,35 @@ VALUE cFoo = rb_define_class("Foo", rb_cObject);
/* Document-class: Foo
* this is the Foo class
*/
+VALUE cFoo = rb_struct_define(
+ "Foo",
+ "some", "various", "fields", NULL);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo class", klass.comment.text
+ end
+
+ def test_do_classes_struct_under
+ content = <<-EOF
+/* Document-class: Kernel::Foo
+ * this is the Foo class under Kernel
+ */
+VALUE cFoo = rb_struct_define_under(
+ rb_mKernel, "Foo",
+ "some", "various", "fields", NULL);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal 'Kernel::Foo', klass.full_name
+ assert_equal "this is the Foo class under Kernel", klass.comment.text
+ end
+
+ def test_do_classes_struct_without_accessor
+ content = <<-EOF
+/* Document-class: Foo
+ * this is the Foo class
+ */
VALUE cFoo = rb_struct_define_without_accessor(
"Foo", rb_cObject, foo_alloc,
"some", "various", "fields", NULL);
@@ -364,6 +393,21 @@ VALUE cFoo = rb_struct_define_without_accessor(
assert_equal "this is the Foo class", klass.comment.text
end
+ def test_do_classes_struct_without_accessor_under
+ content = <<-EOF
+/* Document-class: Kernel::Foo
+ * this is the Foo class under Kernel
+ */
+VALUE cFoo = rb_struct_define_without_accessor_under(
+ rb_mKernel, "Foo", rb_cObject, foo_alloc,
+ "some", "various", "fields", NULL);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal 'Kernel::Foo', klass.full_name
+ assert_equal "this is the Foo class under Kernel", klass.comment.text
+ end
+
def test_do_classes_class_under
content = <<-EOF
/* Document-class: Kernel::Foo
@@ -594,6 +638,17 @@ void Init_File(void) {
assert_equal 'LOCK_SH', constant.name
assert_equal 'INT2FIX(LOCK_SH)', constant.value
assert_equal 'Shared lock', constant.comment.text
+
+ @parser = util_parser <<-EOF
+void Init_File(void) {
+ rb_cFile = rb_define_class("File", rb_cIO);
+ rb_mFConst = rb_define_module_under(rb_cFile, "Constants");
+}
+ EOF
+ @parser.do_classes_and_modules
+ @parser.do_constants
+
+ assert_equal 'File::Constants', klass.full_name
end
def test_do_includes
diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb
index 337cf9ea1a..ef8ad91668 100644
--- a/test/rdoc/test_rdoc_parser_ruby.rb
+++ b/test/rdoc/test_rdoc_parser_ruby.rb
@@ -921,7 +921,7 @@ end
@parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
end
err = stds[1]
- assert_match(/Expected class name or '<<'\. Got/, err)
+ assert_match(/Expected class name or '<<\'\. Got/, err)
end
def test_parse_syntax_error_code
@@ -4345,4 +4345,17 @@ end
assert_equal 'Hello', meth.comment.text
end
+ def test_parenthesized_cdecl
+ util_parser <<-RUBY
+module DidYouMean
+ class << (NameErrorCheckers = Object.new)
+ end
+end
+ RUBY
+
+ @parser.scan
+
+ refute_predicate @store.find_class_or_module('DidYouMean'), :nil?
+ refute_predicate @store.find_class_or_module('DidYouMean::NameErrorCheckers'), :nil?
+ end
end
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index eaf92c8a9f..e958e5f2f6 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -254,6 +254,7 @@ class TestRDocRDoc < RDoc::TestCase
top_level = nil
temp_dir do |dir|
@rdoc.options.parse %W[--root #{test_path}]
+ @rdoc.options.finish
File.open 'include.txt', 'w' do |io|
io.puts ':include: test.txt'
diff --git a/test/rdoc/test_rdoc_require.rb b/test/rdoc/test_rdoc_require.rb
index 46c225299a..4cc53e6c6c 100644
--- a/test/rdoc/test_rdoc_require.rb
+++ b/test/rdoc/test_rdoc_require.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocRequire < XrefTestCase
@@ -23,4 +23,3 @@ class TestRDocRequire < XrefTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb
index 87e4ebd2b1..5f3468c368 100644
--- a/test/rdoc/test_rdoc_ri_driver.rb
+++ b/test/rdoc/test_rdoc_ri_driver.rb
@@ -32,8 +32,8 @@ class TestRDocRIDriver < RDoc::TestCase
end
def teardown
- ENV['RI'] = @orig_ri
- FileUtils.rm_rf @tmpdir
+ defined?(@orig_ri) and ENV['RI'] = @orig_ri
+ defined?(@tmpdir) and FileUtils.rm_rf @tmpdir
super
end
diff --git a/test/rdoc/test_rdoc_rubygems_hook.rb b/test/rdoc/test_rdoc_rubygems_hook.rb
index 04f84d4bcc..59a7ed0f89 100644
--- a/test/rdoc/test_rdoc_rubygems_hook.rb
+++ b/test/rdoc/test_rdoc_rubygems_hook.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require "rubygems"
-require "fileutils"
-require "tmpdir"
-require 'rdoc/rubygems_hook'
-require "test/unit"
+require 'rubygems'
+require 'fileutils'
+require 'tmpdir'
+require_relative '../../lib/rdoc/rubygems_hook'
+require 'test/unit'
class TestRDocRubygemsHook < Test::Unit::TestCase
def setup
diff --git a/test/rdoc/test_rdoc_store.rb b/test/rdoc/test_rdoc_store.rb
index 82340e6b7a..aa4db4c65e 100644
--- a/test/rdoc/test_rdoc_store.rb
+++ b/test/rdoc/test_rdoc_store.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocStore < XrefTestCase
@@ -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_task.rb b/test/rdoc/test_rdoc_task.rb
index 77f2af33a3..23add7d5fe 100644
--- a/test/rdoc/test_rdoc_task.rb
+++ b/test/rdoc/test_rdoc_task.rb
@@ -171,4 +171,3 @@ class TestRDocTask < RDoc::TestCase
end
end if defined?(Rake::Task)
-
diff --git a/test/rdoc/test_rdoc_top_level.rb b/test/rdoc/test_rdoc_top_level.rb
index a954fde981..3cfaa9b763 100644
--- a/test/rdoc/test_rdoc_top_level.rb
+++ b/test/rdoc/test_rdoc_top_level.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require File.expand_path '../xref_test_case', __FILE__
+require_relative 'xref_test_case'
class TestRDocTopLevel < XrefTestCase
@@ -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
@@ -288,4 +288,3 @@ class TestRDocTopLevel < XrefTestCase
end
end
-
diff --git a/test/rdoc/xref_data.rb b/test/rdoc/xref_data.rb
index aa9faaecd9..de76a90602 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 729e4a70b7..22b00d04bc 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 f59e9ee900..be338c6c0d 100644
--- a/test/readline/test_readline.rb
+++ b/test/readline/test_readline.rb
@@ -494,18 +494,17 @@ module BasetestReadline
# 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
@@ -535,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
@@ -568,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 cd3783ddb8..e8b8e3a6e1 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 aa549a392d..99d190d246 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
@@ -256,6 +274,28 @@ class Reline::Config::Test < Reline::TestCase
assert_equal expected, @config.key_bindings
end
+ def test_additional_key_bindings_for_auxiliary_emacs_keymaps
+ @config.read_lines(<<~'LINES'.lines)
+ set keymap emacs
+ "ab": "AB"
+ set keymap emacs-standard
+ "cd": "CD"
+ set keymap emacs-ctlx
+ "ef": "EF"
+ set keymap emacs-meta
+ "gh": "GH"
+ set editing-mode emacs # keymap changes to be emacs
+ LINES
+
+ expected = {
+ 'ab'.bytes => 'AB'.bytes,
+ 'cd'.bytes => 'CD'.bytes,
+ "\C-xef".bytes => 'EF'.bytes,
+ "\egh".bytes => 'GH'.bytes,
+ }
+ assert_equal expected, @config.key_bindings
+ end
+
def test_history_size
@config.read_lines(<<~LINES.lines)
set history-size 5000
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 8053225d24..40b26e5058 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 722cdc0b75..b3d49c9bbb 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 dd049ac127..0d45c5da54 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 f1bf197931..dda9b32495 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 ff2d68bb82..43a66f45f4 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 1f2a023724..d27d216652 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
}
diff --git a/test/reline/yamatanooroti/termination_checker.rb b/test/reline/yamatanooroti/termination_checker.rb
index 9c2c3ae740..24fb24c4b1 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 f68b614327..c383112131 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')
@@ -1187,6 +1199,140 @@ begin
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 62092676ba..f701c31d3e 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 5171604a82..9d243bbf50 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 f155e88de1..d937cd0f45 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 cef584c157..13bd44e83d 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 bde47017a2..bc57d57ee4 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 cdde4da9bf..c96d6088f5 100644
--- a/test/ruby/enc/test_emoji_breaks.rb
+++ b/test/ruby/enc/test_emoji_breaks.rb
@@ -4,50 +4,47 @@
require "test/unit"
class TestEmojiBreaks < Test::Unit::TestCase
-end
-
-class TestEmojiBreaks::BreakTest
- attr_reader :string, :comment, :filename, :line_number, :type, :shortname
-
- def initialize(filename, line_number, data, comment='')
- @filename = filename
- @line_number = line_number
- @comment = comment.gsub(/\s+/, ' ').strip
- if filename=='emoji-test' or filename=='emoji-variation-sequences'
- codes, @type = data.split(/\s*;\s*/)
- @shortname = ''
- else
- codes, @type, @shortname = data.split(/\s*;\s*/)
+ class BreakTest
+ attr_reader :string, :comment, :filename, :line_number, :type, :shortname
+
+ def initialize(filename, line_number, data, comment='')
+ @filename = filename
+ @line_number = line_number
+ @comment = comment.gsub(/\s+/, ' ').strip
+ if filename=='emoji-test' or filename=='emoji-variation-sequences'
+ codes, @type = data.split(/\s*;\s*/)
+ @shortname = ''
+ else
+ codes, @type, @shortname = data.split(/\s*;\s*/)
+ end
+ @type = @type.gsub(/\s+/, ' ').strip
+ @shortname = @shortname.gsub(/\s+/, ' ').strip
+ @string = codes.split(/\s+/)
+ .map do |ch|
+ c = ch.to_i(16)
+ # eliminate cases with surrogates
+ # raise ArgumentError if 0xD800 <= c and c <= 0xDFFF
+ c.chr('UTF-8')
+ end.join
end
- @type = @type.gsub(/\s+/, ' ').strip
- @shortname = @shortname.gsub(/\s+/, ' ').strip
- @string = codes.split(/\s+/)
- .map do |ch|
- c = ch.to_i(16)
- # eliminate cases with surrogates
- # raise ArgumentError if 0xD800 <= c and c <= 0xDFFF
- c.chr('UTF-8')
- end.join
end
-end
-class TestEmojiBreaks::BreakFile
- attr_reader :basename, :fullname, :version
- FILES = []
+ class BreakFile
+ attr_reader :basename, :fullname, :version
+ FILES = []
- def initialize(basename, path, version)
- @basename = basename
- @fullname = "#{path}/#{basename}.txt" # File.expand_path(path + version, __dir__)
- @version = version
- FILES << self
- end
+ def initialize(basename, path, version)
+ @basename = basename
+ @fullname = "#{path}/#{basename}.txt" # File.expand_path(path + version, __dir__)
+ @version = version
+ FILES << self
+ end
- def self.files
- FILES
+ def self.files
+ FILES
+ end
end
-end
-class TestEmojiBreaks < Test::Unit::TestCase
UNICODE_VERSION = RbConfig::CONFIG['UNICODE_VERSION']
UNICODE_DATA_PATH = File.expand_path("../../../enc/unicode/data/#{UNICODE_VERSION}/ucd/emoji", __dir__)
EMOJI_VERSION = RbConfig::CONFIG['UNICODE_EMOJI_VERSION']
@@ -56,7 +53,7 @@ class TestEmojiBreaks < Test::Unit::TestCase
EMOJI_DATA_FILES = %w[emoji-sequences emoji-test emoji-zwj-sequences].map do |basename|
BreakFile.new(basename, EMOJI_DATA_PATH, EMOJI_VERSION)
end
- UNICODE_DATA_FILE = BreakFile.new('emoji-variation-sequences', UNICODE_DATA_PATH, UNICODE_VERSION[0..-3]) # [0..-3] deals with a versioning mismatch problem in Unicode
+ UNICODE_DATA_FILE = BreakFile.new('emoji-variation-sequences', UNICODE_DATA_PATH, UNICODE_VERSION)
EMOJI_DATA_FILES << UNICODE_DATA_FILE
def self.data_files_available?
@@ -68,83 +65,89 @@ 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
-TestEmojiBreaks.data_files_available? and class TestEmojiBreaks
- def read_data
- tests = []
- EMOJI_DATA_FILES.each do |file|
- version_mismatch = true
- file_tests = []
- IO.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
- line.chomp!
- raise "File Name Mismatch: line: #{line}, expected filename: #{file.basename}.txt" if $.==1 and not line=="# #{file.basename}.txt"
- version_mismatch = false if line =~ /^# Version: #{file.version}/
- next if line.match?(/\A(#|\z)/)
- if line =~ /^(\h{4,6})\.\.(\h{4,6}) *(;.+)/ # deal with Unicode ranges in emoji-sequences.txt (Bug #18028)
- range_start = $1.to_i(16)
- range_end = $2.to_i(16)
- rest = $3
- (range_start..range_end).each do |code_point|
- file_tests << BreakTest.new(file.basename, $., *(code_point.to_s(16)+rest).split('#', 2))
+ if data_files_available?
+ def read_data
+ tests = []
+ EMOJI_DATA_FILES.each do |file|
+ version_mismatch = true
+ file_tests = []
+ IO.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
+ line.chomp!
+ if $.==1
+ if line=="# #{file.basename}-#{file.version}.txt"
+ version_mismatch = false
+ elsif line!="# #{file.basename}.txt"
+ raise "File Name Mismatch: line: #{line}, expected filename: #{file.basename}.txt"
+ end
+ end
+ version_mismatch = false if line =~ /^# Version: #{file.version}/
+ next if line.match?(/\A(#|\z)/)
+ if line =~ /^(\h{4,6})\.\.(\h{4,6}) *(;.+)/ # deal with Unicode ranges in emoji-sequences.txt (Bug #18028)
+ range_start = $1.to_i(16)
+ range_end = $2.to_i(16)
+ rest = $3
+ (range_start..range_end).each do |code_point|
+ file_tests << BreakTest.new(file.basename, $., *(code_point.to_s(16)+rest).split('#', 2))
+ end
+ else
+ file_tests << BreakTest.new(file.basename, $., *line.split('#', 2))
end
- else
- file_tests << BreakTest.new(file.basename, $., *line.split('#', 2))
end
+ raise "File Version Mismatch: file: #{file.fullname}, version: #{file.version}" if version_mismatch
+ tests += file_tests
end
- raise "File Version Mismatch: file: #{file.fullname}, version: #{file.version}" if version_mismatch
- tests += file_tests
+ tests
end
- tests
- end
-
- def all_tests
- @@tests ||= read_data
- rescue Errno::ENOENT
- @@tests ||= []
- end
- def test_single_emoji
- all_tests.each do |test|
- expected = [test.string]
- actual = test.string.each_grapheme_cluster.to_a
- assert_equal expected, actual,
- "file: #{test.filename}, line #{test.line_number}, " +
- "type: #{test.type}, shortname: #{test.shortname}, comment: #{test.comment}"
+ def all_tests
+ @@tests ||= read_data
+ rescue Errno::ENOENT
+ @@tests ||= []
end
- end
- def test_embedded_emoji
- all_tests.each do |test|
- expected = ["\t", test.string, "\t"]
- actual = "\t#{test.string}\t".each_grapheme_cluster.to_a
- assert_equal expected, actual,
- "file: #{test.filename}, line #{test.line_number}, " +
- "type: #{test.type}, shortname: #{test.shortname}, comment: #{test.comment}"
+ def test_single_emoji
+ all_tests.each do |test|
+ expected = [test.string]
+ actual = test.string.each_grapheme_cluster.to_a
+ assert_equal expected, actual,
+ "file: #{test.filename}, line #{test.line_number}, " +
+ "type: #{test.type}, shortname: #{test.shortname}, comment: #{test.comment}"
+ end
end
- end
- # test some pseodorandom combinations of emoji
- def test_mixed_emoji
- srand 0
- length = all_tests.length
- step = 503 # use a prime number
- all_tests.each do |test1|
- start = rand step
- start.step(by: step, to: length-1) do |t2|
- test2 = all_tests[t2]
- # exclude skin tones, because they glue to previous grapheme clusters
- next if (0x1F3FB..0x1F3FF).include? test2.string.ord
- expected = [test1.string, test2.string]
- actual = (test1.string+test2.string).each_grapheme_cluster.to_a
+ def test_embedded_emoji
+ all_tests.each do |test|
+ expected = ["\t", test.string, "\t"]
+ actual = "\t#{test.string}\t".each_grapheme_cluster.to_a
assert_equal expected, actual,
- "file1: #{test1.filename}, line1 #{test1.line_number}, " +
- "file2: #{test2.filename}, line2 #{test2.line_number},\n" +
- "type1: #{test1.type}, shortname1: #{test1.shortname}, comment1: #{test1.comment},\n" +
- "type2: #{test2.type}, shortname2: #{test2.shortname}, comment2: #{test2.comment}"
+ "file: #{test.filename}, line #{test.line_number}, " +
+ "type: #{test.type}, shortname: #{test.shortname}, comment: #{test.comment}"
+ end
+ end
+
+ # test some pseodorandom combinations of emoji
+ def test_mixed_emoji
+ srand 0
+ length = all_tests.length
+ step = 503 # use a prime number
+ all_tests.each do |test1|
+ start = rand step
+ start.step(by: step, to: length-1) do |t2|
+ test2 = all_tests[t2]
+ # exclude skin tones, because they glue to previous grapheme clusters
+ next if (0x1F3FB..0x1F3FF).include? test2.string.ord
+ expected = [test1.string, test2.string]
+ actual = (test1.string+test2.string).each_grapheme_cluster.to_a
+ assert_equal expected, actual,
+ "file1: #{test1.filename}, line1 #{test1.line_number}, " +
+ "file2: #{test2.filename}, line2 #{test2.line_number},\n" +
+ "type1: #{test1.type}, shortname1: #{test1.shortname}, comment1: #{test1.comment},\n" +
+ "type2: #{test2.type}, shortname2: #{test2.shortname}, comment2: #{test2.comment}"
+ end
end
end
end
diff --git a/test/ruby/enc/test_grapheme_breaks.rb b/test/ruby/enc/test_grapheme_breaks.rb
index 2d210946a9..f4e3c93b47 100644
--- a/test/ruby/enc/test_grapheme_breaks.rb
+++ b/test/ruby/enc/test_grapheme_breaks.rb
@@ -4,31 +4,28 @@
require "test/unit"
class TestGraphemeBreaksFromFile < Test::Unit::TestCase
-end
-
-class TestGraphemeBreaksFromFile::BreakTest
- attr_reader :clusters, :string, :comment, :line_number
+ class BreakTest
+ attr_reader :clusters, :string, :comment, :line_number
- def initialize(line_number, data, comment)
- @line_number = line_number
- @comment = comment
- @clusters = data.sub(/\A\s*÷\s*/, '')
- .sub(/\s*÷\s*\z/, '')
- .split(/\s*÷\s*/)
- .map do |cl|
- cl.split(/\s*×\s*/)
- .map do |ch|
- c = ch.to_i(16)
- # eliminate cases with surrogates
- raise ArgumentError if 0xD800 <= c and c <= 0xDFFF
- c.chr('UTF-8')
- end.join
- end
- @string = @clusters.join
+ def initialize(line_number, data, comment)
+ @line_number = line_number
+ @comment = comment
+ @clusters = data.sub(/\A\s*÷\s*/, '')
+ .sub(/\s*÷\s*\z/, '')
+ .split(/\s*÷\s*/)
+ .map do |cl|
+ cl.split(/\s*×\s*/)
+ .map do |ch|
+ c = ch.to_i(16)
+ # eliminate cases with surrogates
+ raise ArgumentError if 0xD800 <= c and c <= 0xDFFF
+ c.chr('UTF-8')
+ end.join
+ end
+ @string = @clusters.join
+ end
end
-end
-class TestGraphemeBreaksFromFile < Test::Unit::TestCase
UNICODE_VERSION = RbConfig::CONFIG['UNICODE_VERSION']
path = File.expand_path("../../../enc/unicode/data/#{UNICODE_VERSION}", __dir__)
UNICODE_DATA_PATH = File.directory?("#{path}/ucd/auxiliary") ? "#{path}/ucd/auxiliary" : path
@@ -40,56 +37,56 @@ 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
-TestGraphemeBreaksFromFile.file_available? and class TestGraphemeBreaksFromFile
- def read_data
- tests = []
- IO.foreach(GRAPHEME_BREAK_TEST_FILE, encoding: Encoding::UTF_8) do |line|
- if $. == 1 and not line.start_with?("# GraphemeBreakTest-#{UNICODE_VERSION}.txt")
- raise "File Version Mismatch"
+ if file_available?
+ def read_data
+ tests = []
+ IO.foreach(GRAPHEME_BREAK_TEST_FILE, encoding: Encoding::UTF_8) do |line|
+ if $. == 1 and not line.start_with?("# GraphemeBreakTest-#{UNICODE_VERSION}.txt")
+ raise "File Version Mismatch"
+ end
+ next if /\A#/.match? line
+ tests << BreakTest.new($., *line.chomp.split('#')) rescue 'whatever'
end
- next if /\A#/.match? line
- tests << BreakTest.new($., *line.chomp.split('#')) rescue 'whatever'
+ tests
end
- tests
- end
- def all_tests
- @@tests ||= read_data
- rescue Errno::ENOENT
- @@tests ||= []
- end
+ def all_tests
+ @@tests ||= read_data
+ rescue Errno::ENOENT
+ @@tests ||= []
+ end
- def test_each_grapheme_cluster
- all_tests.each do |test|
- expected = test.clusters
- actual = test.string.each_grapheme_cluster.to_a
- assert_equal expected, actual,
- "line #{test.line_number}, expected '#{expected}', " +
- "but got '#{actual}', comment: #{test.comment}"
+ def test_each_grapheme_cluster
+ all_tests.each do |test|
+ expected = test.clusters
+ actual = test.string.each_grapheme_cluster.to_a
+ assert_equal expected, actual,
+ "line #{test.line_number}, expected '#{expected}', " +
+ "but got '#{actual}', comment: #{test.comment}"
+ end
end
- end
- def test_backslash_X
- all_tests.each do |test|
- clusters = test.clusters.dup
- string = test.string.dup
- removals = 0
- while string.sub!(/\A\X/, '')
- removals += 1
- clusters.shift
- expected = clusters.join
+ def test_backslash_X
+ all_tests.each do |test|
+ clusters = test.clusters.dup
+ string = test.string.dup
+ removals = 0
+ while string.sub!(/\A\X/, '')
+ removals += 1
+ clusters.shift
+ expected = clusters.join
+ assert_equal expected, string,
+ "line #{test.line_number}, removals: #{removals}, expected '#{expected}', " +
+ "but got '#{string}', comment: #{test.comment}"
+ end
assert_equal expected, string,
- "line #{test.line_number}, removals: #{removals}, expected '#{expected}', " +
+ "line #{test.line_number}, after last removal, expected '#{expected}', " +
"but got '#{string}', comment: #{test.comment}"
end
- assert_equal expected, string,
- "line #{test.line_number}, after last removal, expected '#{expected}', " +
- "but got '#{string}', comment: #{test.comment}"
end
end
end
diff --git a/test/ruby/enc/test_regex_casefold.rb b/test/ruby/enc/test_regex_casefold.rb
index ec5dc7f220..eaabbc58a2 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 271d552bf5..0d33cb993c 100644
--- a/test/ruby/test_alias.rb
+++ b/test/ruby/test_alias.rb
@@ -253,4 +253,43 @@ 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
+
+ class C2
+ public :system
+ alias_method :bar, :system
+ alias_method :system, :bar
+ end
+
+ def test_zsuper_alias_visibility
+ assert(C2.new.respond_to?(:system))
+ 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 e3bd1cd075..dbffd24370 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_arity.rb b/test/ruby/test_arity.rb
index b98248f603..d26338e0aa 100644
--- a/test/ruby/test_arity.rb
+++ b/test/ruby/test_arity.rb
@@ -2,7 +2,7 @@
require 'test/unit'
class TestArity < Test::Unit::TestCase
- def err_mess(method_proc = nil, argc = 0)
+ def assert_arity(expected, method_proc = nil, argc = 0)
args = (1..argc).to_a
assert_raise_with_message(ArgumentError, /wrong number of arguments \(.*\b(\d+)\b.* (\d\S*?)\)/) do
case method_proc
@@ -14,7 +14,7 @@ class TestArity < Test::Unit::TestCase
method_proc.call(*args)
end
end
- [$1, $2]
+ assert_equal expected, [$1, $2]
end
def a
@@ -36,22 +36,22 @@ class TestArity < Test::Unit::TestCase
end
def test_method_err_mess
- assert_equal %w[1 0], err_mess(:a, 1)
- assert_equal %w[10 7..9], err_mess(:b, 10)
- assert_equal %w[2 3+], err_mess(:c, 2)
- assert_equal %w[2 1], err_mess(:d, 2)
- assert_equal %w[0 1], err_mess(:d, 0)
- assert_equal %w[2 1], err_mess(:e, 2)
- assert_equal %w[0 1], err_mess(:e, 0)
- assert_equal %w[1 2+], err_mess(:f, 1)
+ assert_arity(%w[1 0], :a, 1)
+ assert_arity(%w[10 7..9], :b, 10)
+ assert_arity(%w[2 3+], :c, 2)
+ assert_arity(%w[2 1], :d, 2)
+ assert_arity(%w[0 1], :d, 0)
+ assert_arity(%w[2 1], :e, 2)
+ assert_arity(%w[0 1], :e, 0)
+ assert_arity(%w[1 2+], :f, 1)
end
def test_proc_err_mess
- assert_equal %w[0 1..2], err_mess(->(b, c=42){}, 0)
- assert_equal %w[1 2+], err_mess(->(a, b, c=42, *d){}, 1)
- assert_equal %w[3 4+], err_mess(->(a, b, *c, d, e){}, 3)
- assert_equal %w[3 1..2], err_mess(->(b, c=42){}, 3)
- assert_equal %w[1 0], err_mess(->(&block){}, 1)
+ assert_arity(%w[0 1..2], ->(b, c=42){}, 0)
+ assert_arity(%w[1 2+], ->(a, b, c=42, *d){}, 1)
+ assert_arity(%w[3 4+], ->(a, b, *c, d, e){}, 3)
+ assert_arity(%w[3 1..2], ->(b, c=42){}, 3)
+ assert_arity(%w[1 0], ->(&block){}, 1)
# Double checking:
p = Proc.new{|b, c=42| :ok}
assert_equal :ok, p.call(1, 2, 3)
@@ -59,12 +59,12 @@ class TestArity < Test::Unit::TestCase
end
def test_message_change_issue_6085
- assert_equal %w[3 1..2], err_mess{ SignalException.new(1, "", nil) }
- assert_equal %w[1 0], err_mess{ Hash.new(1){} }
- assert_equal %w[3 1..2], err_mess{ Module.send :define_method, 1, 2, 3 }
- assert_equal %w[1 2], err_mess{ "".sub!(//) }
- assert_equal %w[0 1..2], err_mess{ "".sub!{} }
- assert_equal %w[0 1+], err_mess{ exec }
- assert_equal %w[0 1+], err_mess{ Struct.new }
+ assert_arity(%w[3 1..2]) { SignalException.new(1, "", nil) }
+ assert_arity(%w[1 0]) { Hash.new(1){} }
+ assert_arity(%w[3 1..2]) { Module.send :define_method, 1, 2, 3 }
+ assert_arity(%w[1 2]) { "".sub!(//) }
+ assert_arity(%w[0 1..2]) { "".sub!{} }
+ assert_arity(%w[0 1+]) { exec }
+ assert_arity(%w[0 1+]) { Struct.new }
end
end
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index a97a9c2558..e376d76a16 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -1439,6 +1439,14 @@ class TestArray < Test::Unit::TestCase
assert_raise(FrozenError) { fa.replace(42) }
end
+ def test_replace_wb_variable_width_alloc
+ small_embed = []
+ 4.times { GC.start } # age small_embed
+ large_embed = [1, 2, 3, 4, 5, Array.new] # new young object
+ small_embed.replace(large_embed) # adds old to young reference
+ GC.verify_internal_consistency
+ end
+
def test_reverse
a = @cls[*%w( dog cat bee ant )]
assert_equal(@cls[*%w(ant bee cat dog)], a.reverse)
@@ -3270,7 +3278,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 41e8bffe82..3a8dafb7f0 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 953c8435c3..cd96027654 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,83 @@ 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
+ pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
+
+ 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
+ pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
+
+ 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 +541,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_autoload.rb b/test/ruby/test_autoload.rb
index 7709760d19..bac6337eb9 100644
--- a/test/ruby/test_autoload.rb
+++ b/test/ruby/test_autoload.rb
@@ -491,4 +491,53 @@ p Foo::Bar
::Object.class_eval {remove_const(:AutoloadTest)} if defined? Object::AutoloadTest
TestAutoload.class_eval {remove_const(:AutoloadTest)} if defined? TestAutoload::AutoloadTest
end
+
+ def test_autoload_module_gc
+ Dir.mktmpdir('autoload') do |tmpdir|
+ autoload_path = File.join(tmpdir, "autoload_module_gc.rb")
+ File.write(autoload_path, "X = 1; Y = 2;")
+
+ x = Module.new
+ x.autoload :X, "./feature.rb"
+
+ 1000.times do
+ y = Module.new
+ y.autoload :Y, "./feature.rb"
+ end
+
+ x = y = nil
+
+ # Ensure the internal data structures are cleaned up correctly / don't crash:
+ GC.start
+ end
+ end
+
+ def test_autoload_parallel_race
+ Dir.mktmpdir('autoload') do |tmpdir|
+ autoload_path = File.join(tmpdir, "autoload_parallel_race.rb")
+ File.write(autoload_path, 'module Foo; end; module Bar; end')
+
+ assert_separately([], <<-RUBY, timeout: 100)
+ autoload_path = #{File.realpath(autoload_path).inspect}
+
+ # This should work with no errors or failures.
+ 1000.times do
+ autoload :Foo, autoload_path
+ autoload :Bar, autoload_path
+
+ t1 = Thread.new {Foo}
+ t2 = Thread.new {Bar}
+
+ t1.join
+ GC.start # force GC.
+ t2.join
+
+ Object.send(:remove_const, :Foo)
+ Object.send(:remove_const, :Bar)
+
+ $LOADED_FEATURES.delete(autoload_path)
+ end
+ RUBY
+ end
+ end
end
diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb
index aa79db24cb..bb0562c0bb 100644
--- a/test/ruby/test_backtrace.rb
+++ b/test/ruby/test_backtrace.rb
@@ -154,6 +154,35 @@ class TestBacktrace < Test::Unit::TestCase
assert_equal caller(0), caller(0, nil)
end
+ def test_each_backtrace_location
+ i = 0
+ cl = caller_locations(1, 1)[0]; ecl = Thread.each_caller_location{|x| i+=1; break x if i == 1}
+ assert_equal(cl.to_s, ecl.to_s)
+ assert_kind_of(Thread::Backtrace::Location, ecl)
+
+ i = 0
+ ary = []
+ cllr = caller_locations(1, 2); last = Thread.each_caller_location{|x| ary << x; i+=1; break x if i == 2}
+ assert_equal(cllr.map(&:to_s), ary.map(&:to_s))
+ assert_kind_of(Thread::Backtrace::Location, last)
+
+ i = 0
+ ary = []
+ ->{->{
+ cllr = caller_locations(1, 2); last = Thread.each_caller_location{|x| ary << x; i+=1; break x if i == 2}
+ }.()}.()
+ assert_equal(cllr.map(&:to_s), ary.map(&:to_s))
+ assert_kind_of(Thread::Backtrace::Location, last)
+
+ cllr = caller_locations(1, 2); ary = Thread.to_enum(:each_caller_location).to_a[2..3]
+ assert_equal(cllr.map(&:to_s), ary.map(&:to_s))
+
+ ecl = Thread.to_enum(:each_caller_location)
+ assert_raise(StopIteration) {
+ ecl.next
+ }
+ end
+
def test_caller_locations_first_label
def self.label
caller_locations.first.label
diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb
index 3ffe7114b5..53a2b20cc8 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 0ceb36bb1d..07c34ce9d5 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -738,38 +738,6 @@ class TestClass < Test::Unit::TestCase
assert_same(c, Module.new.const_set(:Foo, c))
end
- def test_descendants
- c = Class.new
- sc = Class.new(c)
- ssc = Class.new(sc)
- [c, sc, ssc].each do |k|
- 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)
-
- object_descendants = Object.descendants
- assert_include(object_descendants, c)
- assert_include(object_descendants, sc)
- assert_include(object_descendants, ssc)
- end
-
- def test_descendants_gc
- c = Class.new
- 100000.times { Class.new(c) }
- assert(c.descendants.size <= 100000)
- end
-
- def test_descendants_gc_stress
- 10000.times do
- c = Class.new
- 100.times { Class.new(c) }
- assert(c.descendants.size <= 100)
- end
- end
-
def test_subclasses
c = Class.new
sc = Class.new(c)
@@ -793,11 +761,11 @@ class TestClass < Test::Unit::TestCase
def test_subclass_gc
c = Class.new
- 100000.times do
+ 10_000.times do
cc = Class.new(c)
100.times { Class.new(cc) }
end
- assert(c.subclasses.size <= 100000)
+ assert(c.subclasses.size <= 10_000)
end
def test_subclass_gc_stress
diff --git a/test/ruby/test_complex2.rb b/test/ruby/test_complex2.rb
index 594fc3f45a..b89e83efb2 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 bf4e2b1809..31d11fe317 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 3c4aea1561..467e5ecf83 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 9474c6e927..514c6e5921 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
@@ -490,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 f6375a4ffc..cc217b05cc 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -234,6 +234,8 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal(24, @obj.inject(2) {|z, x| z * x })
assert_equal(24, assert_warning(/given block not used/) {@obj.inject(2, :*) {|z, x| z * x }})
assert_equal(nil, @empty.inject() {9})
+
+ assert_raise(ArgumentError) {@obj.inject}
end
FIXNUM_MIN = RbConfig::LIMITS['FIXNUM_MIN']
@@ -461,6 +463,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
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index ea0f367334..87ccd5102b 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 bf551c6845..d55977c986 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 67f38c2e91..0b05ff7c51 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -252,6 +252,27 @@ class TestException < Test::Unit::TestCase
}
end
+ def test_catch_throw_in_require_cant_be_rescued
+ bug18562 = '[ruby-core:107403]'
+ Tempfile.create(["dep", ".rb"]) {|t|
+ t.puts("throw :extdep, 42")
+ t.close
+
+ rescue_all = Class.new(Exception)
+ def rescue_all.===(_)
+ raise "should not reach here"
+ end
+
+ v = assert_throw(:extdep, bug18562) do
+ require t.path
+ rescue rescue_all
+ assert(false, "should not reach here")
+ end
+
+ assert_equal(42, v, bug18562)
+ }
+ end
+
def test_throw_false
bug12743 = '[ruby-core:77229] [Bug #12743]'
Thread.start {
@@ -423,7 +444,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 +582,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
@@ -786,6 +807,7 @@ end.join
cause = ArgumentError.new("foobar")
e = assert_raise(RuntimeError) {raise msg, cause: cause}
assert_same(cause, e.cause)
+ assert_raise(TypeError) {raise msg, {cause: cause}}
end
def test_cause_with_no_arguments
@@ -970,11 +992,12 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
assert_not_nil(e)
assert_include(e.message, "\0")
- assert_in_out_err([], src, [], [], *args, **opts) do |_, err,|
- err.each do |e|
- assert_not_include(e, "\0")
- end
- end
+ # Disabled by [Feature #18367]
+ #assert_in_out_err([], src, [], [], *args, **opts) do |_, err,|
+ # err.each do |e|
+ # assert_not_include(e, "\0")
+ # end
+ #end
e
end
@@ -1064,25 +1087,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 +1215,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;
@@ -1399,4 +1422,33 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
end;
end
+
+ def test_detailed_message
+ e = RuntimeError.new("message")
+ assert_equal("message (RuntimeError)", e.detailed_message)
+ assert_equal("\e[1mmessage (\e[1;4mRuntimeError\e[m\e[1m)\e[m", e.detailed_message(highlight: true))
+
+ e = RuntimeError.new("foo\nbar\nbaz")
+ assert_equal("foo (RuntimeError)\nbar\nbaz", e.detailed_message)
+ assert_equal("\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n\e[1mbar\e[m\n\e[1mbaz\e[m", e.detailed_message(highlight: true))
+
+ e = RuntimeError.new("")
+ assert_equal("unhandled exception", e.detailed_message)
+ assert_equal("\e[1;4munhandled exception\e[m", e.detailed_message(highlight: true))
+
+ e = RuntimeError.new
+ assert_equal("RuntimeError (RuntimeError)", e.detailed_message)
+ assert_equal("\e[1mRuntimeError (\e[1;4mRuntimeError\e[m\e[1m)\e[m", e.detailed_message(highlight: true))
+ end
+
+ def test_full_message_with_custom_detailed_message
+ e = RuntimeError.new("message")
+ opt_ = nil
+ e.define_singleton_method(:detailed_message) do |**opt|
+ opt_ = opt
+ "BOO!"
+ end
+ assert_match("BOO!", e.full_message.lines.first)
+ assert_equal({ highlight: Exception.to_tty? }, opt_)
+ end
end
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index a0fd4a7491..5825aaf6cc 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{}
@@ -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 d570b6f6fb..905416911a 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 03675eaebc..579e4d77a9 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -173,9 +173,7 @@ class TestFileExhaustive < Test::Unit::TestCase
end
def chardev
- return @chardev if defined? @chardev
- @chardev = File::NULL == "/dev/null" ? "/dev/null" : nil
- @chardev
+ File::NULL
end
def blockdev
@@ -332,7 +330,7 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_file.not_chardev?(regular_file)
assert_file.not_chardev?(utf8_file)
assert_file.not_chardev?(nofile)
- assert_file.chardev?(chardev) if chardev
+ assert_file.chardev?(chardev)
end
def test_exist_p
@@ -640,7 +638,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 +771,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
@@ -872,9 +870,10 @@ class TestFileExhaustive < Test::Unit::TestCase
bug9934 = '[ruby-core:63114] [Bug #9934]'
require "objspace"
path = File.expand_path("/foo")
- assert_operator(ObjectSpace.memsize_of(path), :<=, path.bytesize + GC::INTERNAL_CONSTANTS[:RVALUE_SIZE], bug9934)
+ assert_operator(ObjectSpace.memsize_of(path), :<=, path.bytesize + GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE], bug9934)
path = File.expand_path("/a"*25)
- assert_equal(path.bytesize+1 + GC::INTERNAL_CONSTANTS[:RVALUE_SIZE], ObjectSpace.memsize_of(path), bug9934)
+ assert_operator(ObjectSpace.memsize_of(path), :<=,
+ (path.bytesize + 1) * 2 + GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE], bug9934)
end
def test_expand_path_encoding
@@ -1119,7 +1118,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
@@ -1512,6 +1511,31 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_equal(File.executable?(f), test(?x, f), f)
assert_equal(File.executable_real?(f), test(?X, f), f)
assert_equal(File.zero?(f), test(?z, f), f)
+
+ stat = File.stat(f)
+ assert_equal(stat.atime, File.atime(f), f)
+ assert_equal(stat.ctime, File.ctime(f), f)
+ assert_equal(stat.mtime, File.mtime(f), f)
+ assert_bool_equal(stat.blockdev?, File.blockdev?(f), f)
+ assert_bool_equal(stat.chardev?, File.chardev?(f), f)
+ assert_bool_equal(stat.directory?, File.directory?(f), f)
+ assert_bool_equal(stat.file?, File.file?(f), f)
+ assert_bool_equal(stat.setgid?, File.setgid?(f), f)
+ assert_bool_equal(stat.grpowned?, File.grpowned?(f), f)
+ assert_bool_equal(stat.sticky?, File.sticky?(f), f)
+ assert_bool_equal(File.lstat(f).symlink?, File.symlink?(f), f)
+ assert_bool_equal(stat.owned?, File.owned?(f), f)
+ assert_bool_equal(stat.pipe?, File.pipe?(f), f)
+ assert_bool_equal(stat.readable?, File.readable?(f), f)
+ assert_bool_equal(stat.readable_real?, File.readable_real?(f), f)
+ assert_equal(stat.size?, File.size?(f), f)
+ assert_bool_equal(stat.socket?, File.socket?(f), f)
+ assert_bool_equal(stat.setuid?, File.setuid?(f), f)
+ assert_bool_equal(stat.writable?, File.writable?(f), f)
+ assert_bool_equal(stat.writable_real?, File.writable_real?(f), f)
+ assert_bool_equal(stat.executable?, File.executable?(f), f)
+ assert_bool_equal(stat.executable_real?, File.executable_real?(f), f)
+ assert_bool_equal(stat.zero?, File.zero?(f), f)
end
assert_equal(false, test(?-, @dir, fn1))
assert_equal(true, test(?-, fn1, fn1))
@@ -1621,7 +1645,7 @@ class TestFileExhaustive < Test::Unit::TestCase
def test_stat_chardev_p
assert_not_predicate(File::Stat.new(@dir), :chardev?)
assert_not_predicate(File::Stat.new(regular_file), :chardev?)
- assert_predicate(File::Stat.new(chardev), :chardev?) if chardev
+ assert_predicate(File::Stat.new(chardev), :chardev?)
end
def test_stat_readable_p
@@ -1764,4 +1788,8 @@ class TestFileExhaustive < Test::Unit::TestCase
dir = File.expand_path("/bar")
assert_equal(File.join(dir, "~foo"), File.absolute_path("~foo", dir))
end
+
+ def assert_bool_equal(expected, result, *messages)
+ assert_equal(expected, true & result, *messages)
+ end
end
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
index 4be2cfeeda..57a46fce92 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -171,6 +171,24 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError, n += z + "A") {Float(n)}
assert_raise(ArgumentError, n += z + ".0") {Float(n)}
end
+
+ x = nil
+ 2000.times do
+ x = Float("0x"+"0"*30)
+ break unless x == 0.0
+ end
+ assert_equal(0.0, x, ->{"%a" % x})
+ x = nil
+ 2000.times do
+ begin
+ x = Float("0x1."+"0"*270)
+ rescue ArgumentError => e
+ raise unless /"0x1\.0{270}"/ =~ e.message
+ else
+ break
+ end
+ end
+ assert_nil(x, ->{"%a" % x})
end
def test_divmod
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index baf9971c48..b081e9fa78 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,78 @@ 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[:BASE_SLOT_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
+ assert_operator stat_heap[:total_allocated_pages], :>=, 0
+ assert_operator stat_heap[:total_freed_pages], :>=, 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]
+ assert_equal stat[:total_allocated_pages], stat_heap_sum[:total_allocated_pages]
+ assert_equal stat[:total_freed_pages], stat_heap_sum[:total_freed_pages]
+ 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 +350,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 c591b1d74e..da0023e6f3 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -4,20 +4,14 @@ require 'fiddle'
require 'etc'
if RUBY_PLATFORM =~ /s390x/
- puts "Currently, it is known that the compaction does not work well on s390x; contribution is welcome https://github.com/ruby/ruby/pull/5077"
+ 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?
- super
- end
-
- private
-
+ module CompactionSupportInspector
def supports_auto_compact?
+ return false if /wasm/ =~ RUBY_PLATFORM
return true unless defined?(Etc::SC_PAGE_SIZE)
begin
@@ -30,10 +24,19 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- include SupportsCompact
+ module OmitUnlessCompactSupported
+ include CompactionSupportInspector
+
+ def setup
+ omit "autocompact not supported on this platform" unless supports_auto_compact?
+ super
+ end
+ end
+
+ include OmitUnlessCompactSupported
class AutoCompact < Test::Unit::TestCase
- include SupportsCompact
+ include OmitUnlessCompactSupported
def test_enable_autocompact
before = GC.auto_compact
@@ -78,7 +81,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,13 +90,39 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- def os_page_size
- return true unless defined?(Etc::SC_PAGE_SIZE)
+ class CompactMethodsNotImplemented < Test::Unit::TestCase
+ include CompactionSupportInspector
+
+ def assert_not_implemented(method, *args)
+ omit "autocompact is supported on this platform" if supports_auto_compact?
+
+ assert_raise(NotImplementedError) { GC.send(method, *args) }
+ refute(GC.respond_to?(method), "GC.#{method} should be defined as rb_f_notimplement")
+ end
+
+ def test_gc_compact_not_implemented
+ assert_not_implemented(:compact)
+ end
+
+ def test_gc_auto_compact_get_not_implemented
+ assert_not_implemented(:auto_compact)
+ end
+
+ def test_gc_auto_compact_set_not_implemented
+ assert_not_implemented(:auto_compact=, true)
+ end
+
+ def test_gc_latest_compact_info_not_implemented
+ assert_not_implemented(:latest_compact_info)
+ end
+
+ def test_gc_verify_compaction_references_not_implemented
+ assert_not_implemented(:verify_compaction_references)
+ end
end
- def setup
- skip "autocompact not supported on this platform" unless supports_auto_compact?
- super
+ def os_page_size
+ return true unless defined?(Etc::SC_PAGE_SIZE)
end
def test_gc_compact_stats
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index f79879c20a..073a0dabe8 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,20 @@ 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_shift_for_empty_hash
+ # [ruby-dev:51159]
+ h = @cls[]
+ 100.times{|n|
+ while h.size < n
+ k = Random.rand 0..1<<30
+ h[k] = 1
+ end
+ 0 while h.shift
+ assert_equal({}, h)
+ }
end
def test_reject_bang2
diff --git a/test/ruby/test_inlinecache.rb b/test/ruby/test_inlinecache.rb
index 6c2d86aefd..d48d95d74e 100644
--- a/test/ruby/test_inlinecache.rb
+++ b/test/ruby/test_inlinecache.rb
@@ -3,7 +3,7 @@
require 'test/unit'
-class TestMethod < Test::Unit::TestCase
+class TestMethodInlineCache < Test::Unit::TestCase
def test_alias
m0 = Module.new do
def foo; :M0 end
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index 9354514df0..a2b181c642 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 96e572b98d..ed0198321d 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
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index f7c175b589..0f8a9c5e80 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: false
+require 'tempfile'
+
class TestIOBuffer < Test::Unit::TestCase
experimental = Warning[:experimental]
begin
@@ -18,14 +20,14 @@ class TestIOBuffer < Test::Unit::TestCase
end
def test_flags
- assert_equal 0, IO::Buffer::EXTERNAL
- assert_equal 1, IO::Buffer::INTERNAL
- assert_equal 2, IO::Buffer::MAPPED
+ assert_equal 1, IO::Buffer::EXTERNAL
+ assert_equal 2, IO::Buffer::INTERNAL
+ assert_equal 4, IO::Buffer::MAPPED
- assert_equal 16, IO::Buffer::LOCKED
- assert_equal 32, IO::Buffer::PRIVATE
+ assert_equal 32, IO::Buffer::LOCKED
+ assert_equal 64, IO::Buffer::PRIVATE
- assert_equal 64, IO::Buffer::IMMUTABLE
+ assert_equal 128, IO::Buffer::READONLY
end
def test_endian
@@ -36,6 +38,10 @@ class TestIOBuffer < Test::Unit::TestCase
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
@@ -52,41 +58,62 @@ class TestIOBuffer < Test::Unit::TestCase
assert buffer.mapped?
end
- def test_new_immutable
- buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::IMMUTABLE)
- assert buffer.immutable?
+ def test_new_readonly
+ buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::READONLY)
+ assert buffer.readonly?
- assert_raise RuntimeError do
- buffer.copy("", 0)
+ assert_raise IO::Buffer::AccessError do
+ buffer.set_string("")
end
- assert_raise RuntimeError do
- buffer.copy("!", 1)
+ 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)}
- assert_include buffer.to_str, "Hello World"
+ 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)
+ assert buffer.readonly?
+ end
- # Cannot modify string as it's locked by the buffer:
- assert_raise RuntimeError do
- string[0] = "h"
- end
+ def test_string_mapped_frozen
+ string = "Hello World".freeze
+ buffer = IO::Buffer.for(string)
+ assert buffer.readonly?
+ end
- buffer.set(:U8, 0, "h".ord)
+ def test_string_mapped_mutable
+ string = "Hello World"
+ IO::Buffer.for(string) do |buffer|
+ refute buffer.readonly?
- # Buffer releases it's ownership of the string:
- buffer.free
+ # Cannot modify string as it's locked by the buffer:
+ assert_raise RuntimeError do
+ string[0] = "h"
+ end
- assert_equal "hello World", string
- string[0] = "H"
- assert_equal "Hello World", string
+ buffer.set_value(:U8, 0, "h".ord)
+
+ # Buffer releases it's ownership of the string:
+ buffer.free
+
+ assert_equal "hello World", string
+ end
end
def test_non_string
@@ -97,18 +124,22 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
- def test_resize
- buffer = IO::Buffer.new(1024, IO::Buffer::MAPPED)
- buffer.resize(2048, 0)
+ 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, IO::Buffer::MAPPED)
- buffer.copy(message, 0)
- buffer.resize(2048, 1024)
- assert_equal message, buffer.to_str(0, message.bytesize)
+ 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
@@ -116,8 +147,8 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal buffer1, buffer1
buffer2 = IO::Buffer.new(1)
- buffer1.set(:U8, 0, 0x10)
- buffer2.set(:U8, 0, 0x20)
+ buffer1.set_value(:U8, 0, 0x10)
+ buffer2.set_value(:U8, 0, 0x20)
assert_negative buffer1 <=> buffer2
assert_positive buffer2 <=> buffer1
@@ -134,15 +165,14 @@ class TestIOBuffer < Test::Unit::TestCase
def test_slice
buffer = IO::Buffer.new(128)
slice = buffer.slice(8, 32)
- slice.copy("Hello World", 0)
- assert_equal("Hello World", buffer.to_str(8, 11))
+ slice.set_string("Hello World")
+ assert_equal("Hello World", buffer.get_string(8, 11))
end
def test_slice_bounds
buffer = IO::Buffer.new(128)
- # What is best exception class?
- assert_raise RuntimeError do
+ assert_raise ArgumentError do
buffer.slice(128, 10)
end
@@ -154,19 +184,73 @@ class TestIOBuffer < Test::Unit::TestCase
def test_locked
buffer = IO::Buffer.new(128, IO::Buffer::INTERNAL|IO::Buffer::LOCKED)
- assert_raise RuntimeError do
- buffer.resize(256, 0)
+ assert_raise IO::Buffer::LockedError do
+ buffer.resize(256)
end
assert_equal 128, buffer.size
- assert_raise RuntimeError do
+ 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
@@ -181,7 +265,7 @@ class TestIOBuffer < Test::Unit::TestCase
# (4) scheduler returns
# (5) rb_write_internal invalidate the buffer object
- assert_raise RuntimeError do
+ assert_raise IO::Buffer::LockedError do
buffer.free
end
@@ -192,4 +276,79 @@ class TestIOBuffer < Test::Unit::TestCase
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
+
+ def test_operators
+ source = IO::Buffer.for("1234123412")
+ mask = IO::Buffer.for("133\x00")
+
+ assert_equal IO::Buffer.for("123\x00123\x0012"), (source & mask)
+ assert_equal IO::Buffer.for("1334133413"), (source | mask)
+ assert_equal IO::Buffer.for("\x00\x01\x004\x00\x01\x004\x00\x01"), (source ^ mask)
+ assert_equal IO::Buffer.for("\xce\xcd\xcc\xcb\xce\xcd\xcc\xcb\xce\xcd"), ~source
+ end
+
+ def test_inplace_operators
+ source = IO::Buffer.for("1234123412")
+ mask = IO::Buffer.for("133\x00")
+
+ assert_equal IO::Buffer.for("123\x00123\x0012"), source.dup.and!(mask)
+ assert_equal IO::Buffer.for("1334133413"), source.dup.or!(mask)
+ assert_equal IO::Buffer.for("\x00\x01\x004\x00\x01\x004\x00\x01"), source.dup.xor!(mask)
+ assert_equal IO::Buffer.for("\xce\xcd\xcc\xcb\xce\xcd\xcc\xcb\xce\xcd"), source.dup.not!
+ end
end
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index ac191531de..2a18ff02e1 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -129,7 +129,7 @@ class TestISeq < Test::Unit::TestCase
def test_lambda_with_ractor_roundtrip
iseq = compile(<<~EOF, __LINE__+1)
x = 42
- y = lambda { x }
+ y = nil.instance_eval{ lambda { x } }
Ractor.make_shareable(y)
y.call
EOF
@@ -148,17 +148,21 @@ class TestISeq < Test::Unit::TestCase
def test_ractor_unshareable_outer_variable
name = "\u{2603 26a1}"
- y = eval("proc {#{name} = nil; proc {|x| #{name} = x}}").call
+ 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 = eval("proc {#{name} = []; proc {|x| #{name}}}").call
+ 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(*) ->{super} end
- assert_raise_with_message(Ractor::IsolationError, /hidden variable/) do
+ 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
@@ -388,10 +392,18 @@ class TestISeq < Test::Unit::TestCase
def anon_star(*); end
- def test_anon_param_in_disasm
+ 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 [2], param_names
+ 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
@@ -527,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
@@ -721,4 +733,21 @@ class TestISeq < Test::Unit::TestCase
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_debug.rb b/test/ruby/test_jit_debug.rb
deleted file mode 100644
index 50e52b4c2e..0000000000
--- a/test/ruby/test_jit_debug.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require_relative 'test_jit'
-
-return unless defined?(TestJIT)
-return if ENV.key?('APPVEYOR')
-return if ENV.key?('RUBYCI_NICKNAME')
-return if ENV['RUBY_DEBUG']&.include?('ci') # ci.rvm.jp
-return if /mswin/ =~ RUBY_PLATFORM
-
-class TestJITDebug < TestJIT
- @@test_suites.delete TestJIT if self.respond_to? :on_parallel_worker?
-
- def setup
- super
- # let `#eval_with_jit` use --jit-debug
- @jit_debug = true
- end
-end
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 9094259bc2..9978072744 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -190,6 +190,53 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal(["bar", 111111], f[str: "bar", num: 111111])
end
+ def test_unset_hash_flag
+ bug18625 = "[ruby-core: 107847]"
+ singleton_class.class_eval do
+ ruby2_keywords def foo(*args)
+ args
+ end
+
+ def single(arg)
+ arg
+ end
+
+ def splat(*args)
+ args.last
+ end
+
+ def kwargs(**kw)
+ kw
+ end
+ end
+
+ h = { a: 1 }
+ args = foo(**h)
+ marked = args.last
+ assert_equal(true, Hash.ruby2_keywords_hash?(marked))
+
+ after_usage = single(*args)
+ assert_equal(h, after_usage)
+ assert_same(marked, args.last)
+ assert_not_same(marked, after_usage)
+ assert_equal(false, Hash.ruby2_keywords_hash?(after_usage))
+
+ after_usage = splat(*args)
+ assert_equal(h, after_usage)
+ assert_same(marked, args.last)
+ assert_not_same(marked, after_usage, bug18625)
+ assert_equal(false, Hash.ruby2_keywords_hash?(after_usage), bug18625)
+
+ after_usage = kwargs(*args)
+ assert_equal(h, after_usage)
+ assert_same(marked, args.last)
+ assert_not_same(marked, after_usage, bug18625)
+ assert_not_same(marked, after_usage)
+ assert_equal(false, Hash.ruby2_keywords_hash?(after_usage))
+
+ assert_equal(true, Hash.ruby2_keywords_hash?(marked))
+ end
+
def test_keyword_splat_new
kw = {}
h = {a: 1}
@@ -3538,7 +3585,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal(splat_expect, pr.call(a), bug8463)
pr = proc {|a, **opt| next a, opt}
- assert_equal(splat_expect.values_at(0, -1), pr.call(splat_expect), bug8463)
+ assert_equal([splat_expect, {}], pr.call(splat_expect), bug8463)
end
def req_plus_keyword(x, **h)
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index 8c3256c034..99dd3a0c56 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 c793520ac4..c00bf59e18 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -300,7 +300,7 @@ class TestM17N < Test::Unit::TestCase
orig_int, Encoding.default_internal = Encoding.default_internal, nil
orig_ext = Encoding.default_external
- skip "https://bugs.ruby-lang.org/issues/18338"
+ omit "https://bugs.ruby-lang.org/issues/18338"
o = Object.new
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index daf0ec73ca..83e499913a 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
@@ -318,6 +323,17 @@ class TestMethod < Test::Unit::TestCase
assert_equal(:foo, o.foo)
end
+ PUBLIC_SINGLETON_TEST = Object.new
+ class << PUBLIC_SINGLETON_TEST
+ private
+ PUBLIC_SINGLETON_TEST.define_singleton_method(:dsm){}
+ def PUBLIC_SINGLETON_TEST.def; end
+ end
+ def test_define_singleton_method_public
+ assert_equal(true, PUBLIC_SINGLETON_TEST.method(:dsm).public?)
+ assert_equal(true, PUBLIC_SINGLETON_TEST.method(:def).public?)
+ end
+
def test_define_singleton_method_no_proc
o = Object.new
assert_raise(ArgumentError) {
@@ -566,9 +582,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 +608,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 +635,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 +659,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 +1197,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 +1248,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 +1450,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_jit.rb b/test/ruby/test_mjit.rb
index dcbe694d7a..30c5659c14 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_mjit.rb
@@ -3,8 +3,8 @@ require 'test/unit'
require 'tmpdir'
require_relative '../lib/jit_support'
-# Test for --jit option
-class TestJIT < Test::Unit::TestCase
+# Test for --mjit option
+class TestMJIT < Test::Unit::TestCase
include JITSupport
IGNORABLE_PATTERNS = [
@@ -31,7 +31,7 @@ class TestJIT < Test::Unit::TestCase
:opt_invokebuiltin_delegate,
].each do |insn|
if !RubyVM::INSTRUCTION_NAMES.include?(insn.to_s)
- warn "instruction #{insn.inspect} is not defined but included in TestJIT::TEST_PENDING_INSNS"
+ warn "instruction #{insn.inspect} is not defined but included in TestMJIT::TEST_PENDING_INSNS"
end
end
@@ -46,17 +46,17 @@ class TestJIT < Test::Unit::TestCase
# ci.rvm.jp caches its build environment. Clean up temporary files left by SEGV.
if ENV['RUBY_DEBUG']&.include?('ci')
Dir.glob("#{ENV.fetch('TMPDIR', '/tmp')}/_ruby_mjit_p*u*.*").each do |file|
- puts "test/ruby/test_jit.rb: removing #{file}"
+ puts "test/ruby/test_mjit.rb: removing #{file}"
File.unlink(file)
end
end
- # ruby -w -Itest/lib test/ruby/test_jit.rb
+ # ruby -w -Itest/lib test/ruby/test_mjit.rb
if $VERBOSE
pid = $$
at_exit do
- if pid == $$ && !TestJIT.untested_insns.empty?
- warn "you may want to add tests for following insns, when you have a chance: #{TestJIT.untested_insns.join(' ')}"
+ if pid == $$ && !TestMJIT.untested_insns.empty?
+ warn "you may want to add tests for following insns, when you have a chance: #{TestMJIT.untested_insns.join(' ')}"
end
end
end
@@ -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
@@ -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
@@ -620,7 +620,7 @@ class TestJIT < Test::Unit::TestCase
end;
end
- def test_jit_output
+ def test_mjit_output
out, err = eval_with_jit('5.times { puts "MJIT" }', verbose: 1, min_calls: 5)
assert_equal("MJIT\n" * 5, out)
assert_match(/^#{JIT_SUCCESS_PREFIX}: block in <main>@-e:1 -> .+_ruby_mjit_p\d+u\d+\.c$/, err)
@@ -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
@@ -1237,7 +1237,7 @@ class TestJIT < Test::Unit::TestCase
$stderr.puts
warn "'#{insn}' insn is not included in the script. Actual insns are: #{used_insns.join(' ')}\n", uplevel: uplevel
end
- TestJIT.untested_insns.delete(insn)
+ TestMJIT.untested_insns.delete(insn)
end
# Collect block's insns or defined method's insns, which are expected to be JIT-ed.
diff --git a/test/ruby/test_mjit_debug.rb b/test/ruby/test_mjit_debug.rb
new file mode 100644
index 0000000000..0b50acc68d
--- /dev/null
+++ b/test/ruby/test_mjit_debug.rb
@@ -0,0 +1,17 @@
+require_relative 'test_mjit'
+
+return unless defined?(TestMJIT)
+return if ENV.key?('APPVEYOR')
+return if ENV.key?('RUBYCI_NICKNAME')
+return if ENV['RUBY_DEBUG']&.include?('ci') # ci.rvm.jp
+return if /mswin/ =~ RUBY_PLATFORM
+
+class TestMJITDebug < TestMJIT
+ @@test_suites.delete TestMJIT if self.respond_to? :on_parallel_worker?
+
+ def setup
+ super
+ # let `#eval_with_jit` use --mjit-debug
+ @mjit_debug = true
+ end
+end
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index e1524a5d81..c7245ab2db 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)
@@ -553,6 +572,26 @@ class TestModule < Test::Unit::TestCase
assert_equal(2, a2.b)
end
+ def test_ancestry_of_duped_classes
+ m = Module.new
+ sc = Class.new
+ a = Class.new(sc) do
+ def b; 2 end
+ prepend m
+ end
+
+ a2 = a.dup.new
+
+ assert_kind_of Object, a2
+ assert_kind_of sc, a2
+ refute_kind_of a, a2
+ assert_kind_of m, a2
+
+ assert_kind_of Class, a2.class
+ assert_kind_of sc.singleton_class, a2.class
+ assert_same sc, a2.class.superclass
+ end
+
def test_gc_prepend_chain
assert_separately([], <<-EOS)
10000.times { |i|
@@ -737,6 +776,25 @@ class TestModule < Test::Unit::TestCase
assert_equal([:m1, :m0, :m, :sc, :m1, :m0, :c], sc.new.m)
end
+ def test_protected_include_into_included_module
+ m1 = Module.new do
+ def other_foo(other)
+ other.foo
+ end
+
+ protected
+ def foo
+ :ok
+ end
+ end
+ m2 = Module.new
+ c1 = Class.new { include m2 }
+ c2 = Class.new { include m2 }
+ m2.include(m1)
+
+ assert_equal :ok, c1.new.other_foo(c2.new)
+ end
+
def test_instance_methods
assert_equal([:user, :user2], User.instance_methods(false).sort)
assert_equal([:user, :user2, :mixin].sort, User.instance_methods(true).sort)
@@ -1665,6 +1723,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_optimization.rb b/test/ruby/test_optimization.rb
index a834996788..80c3c3860b 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;"}")
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index d697a29c1c..2841e20f6d 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -930,6 +930,10 @@ x = __ENCODING__
assert_no_warning(/shadowing outer local variable/) {eval("a=1; tap {|a|}")}
end
+ def test_shadowing_private_local_variable
+ assert_equal 1, eval("_ = 1; [[2]].each{ |(_)| }; _")
+ end
+
def test_unused_variable
o = Object.new
assert_warning(/assigned but unused variable/) {o.instance_eval("def foo; a=1; nil; end")}
diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb
index 35c41eb8b6..7531466f91 100644
--- a/test/ruby/test_pattern_matching.rb
+++ b/test/ruby/test_pattern_matching.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
require 'test/unit'
-experimental, Warning[:experimental] = Warning[:experimental], false # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!"
-eval "\n#{<<~'END_of_GUARD'}", binding, __FILE__, __LINE__
class TestPatternMatching < Test::Unit::TestCase
class NullFormatter
def message_for(corrections)
@@ -1550,22 +1548,6 @@ END
assert_equal false, (1 in 2)
end
- def assert_experimental_warning(code)
- w = Warning[:experimental]
-
- Warning[:experimental] = false
- assert_warn('') {eval(code)}
-
- Warning[:experimental] = true
- assert_warn(/is experimental/) {eval(code)}
- ensure
- Warning[:experimental] = w
- end
-
- def test_experimental_warning
- assert_experimental_warning("case [0]; in [*, 0, *]; end")
- end
-
################################################################
def test_single_pattern_error_value_pattern
@@ -1693,5 +1675,3 @@ END
end
end
end
-END_of_GUARD
-Warning[:experimental] = experimental
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 51872e49be..05c6e03aac 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
@@ -440,6 +445,11 @@ class TestProc < Test::Unit::TestCase
assert_equal(@@line_of_source_location_test, lineno, 'Bug #2427')
end
+ def test_binding_error_unless_ruby_frame
+ define_singleton_method :binding_from_c!, method(:binding).to_proc >> ->(bndg) {bndg}
+ assert_raise(RuntimeError) { binding_from_c! }
+ end
+
def test_proc_lambda
assert_raise(ArgumentError) { proc }
assert_raise(ArgumentError) { assert_warn(/deprecated/) {lambda} }
@@ -847,6 +857,88 @@ class TestProc < Test::Unit::TestCase
assert_equal [[1, 2], Proc, :x], (pr.call(1, 2){|x| x})
end
+ def test_proc_args_single_kw_no_autosplat
+ pr = proc {|c, a: 1| [c, a] }
+ assert_equal [nil, 1], pr.call()
+ assert_equal [1, 1], pr.call(1)
+ assert_equal [[1], 1], pr.call([1])
+ assert_equal [1, 1], pr.call(1,2)
+ assert_equal [[1, 2], 1], pr.call([1,2])
+
+ assert_equal [nil, 3], pr.call(a: 3)
+ assert_equal [1, 3], pr.call(1, a: 3)
+ assert_equal [[1], 3], pr.call([1], a: 3)
+ assert_equal [1, 3], pr.call(1,2, a: 3)
+ assert_equal [[1, 2], 3], pr.call([1,2], a: 3)
+ end
+
+ def test_proc_args_single_kwsplat_no_autosplat
+ pr = proc {|c, **kw| [c, kw] }
+ assert_equal [nil, {}], pr.call()
+ assert_equal [1, {}], pr.call(1)
+ assert_equal [[1], {}], pr.call([1])
+ assert_equal [1, {}], pr.call(1,2)
+ assert_equal [[1, 2], {}], pr.call([1,2])
+
+ assert_equal [nil, {a: 3}], pr.call(a: 3)
+ assert_equal [1, {a: 3}], pr.call(1, a: 3)
+ assert_equal [[1], {a: 3}], pr.call([1], a: 3)
+ assert_equal [1, {a: 3}], pr.call(1,2, a: 3)
+ assert_equal [[1, 2], {a: 3}], pr.call([1,2], a: 3)
+ end
+
+ def test_proc_args_multiple_kw_autosplat
+ pr = proc {|c, b, a: 1| [c, b, a] }
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c=nil, b=nil, a: 1| [c, b, a] }
+ assert_equal [nil, nil, 1], pr.call([])
+ assert_equal [1, nil, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c, b=nil, a: 1| [c, b, a] }
+ assert_equal [1, nil, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c=nil, b, a: 1| [c, b, a] }
+ assert_equal [nil, 1, 1], pr.call([1])
+ assert_equal [1, 2, 1], pr.call([1,2])
+
+ pr = proc {|c, *b, a: 1| [c, b, a] }
+ assert_equal [1, [], 1], pr.call([1])
+ assert_equal [1, [2], 1], pr.call([1,2])
+
+ pr = proc {|*c, b, a: 1| [c, b, a] }
+ assert_equal [[], 1, 1], pr.call([1])
+ assert_equal [[1], 2, 1], pr.call([1,2])
+ end
+
+ def test_proc_args_multiple_kwsplat_autosplat
+ pr = proc {|c, b, **kw| [c, b, kw] }
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c=nil, b=nil, **kw| [c, b, kw] }
+ assert_equal [nil, nil, {}], pr.call([])
+ assert_equal [1, nil, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c, b=nil, **kw| [c, b, kw] }
+ assert_equal [1, nil, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c=nil, b, **kw| [c, b, kw] }
+ assert_equal [nil, 1, {}], pr.call([1])
+ assert_equal [1, 2, {}], pr.call([1,2])
+
+ pr = proc {|c, *b, **kw| [c, b, kw] }
+ assert_equal [1, [], {}], pr.call([1])
+ assert_equal [1, [2], {}], pr.call([1,2])
+
+ pr = proc {|*c, b, **kw| [c, b, kw] }
+ assert_equal [[], 1, {}], pr.call([1])
+ assert_equal [[1], 2, {}], pr.call([1,2])
+ end
+
def test_proc_args_only_rest
pr = proc {|*c| c }
assert_equal [], pr.call()
@@ -1229,6 +1321,28 @@ class TestProc < Test::Unit::TestCase
assert_empty(pr.parameters.map{|_,n|n}.compact)
end
+ def test_parameters_lambda
+ assert_equal([], proc {}.parameters(lambda: true))
+ assert_equal([], proc {||}.parameters(lambda: true))
+ assert_equal([[:req, :a]], proc {|a|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:req, :b]], proc {|a, b|}.parameters(lambda: true))
+ assert_equal([[:opt, :a], [:block, :b]], proc {|a=:a, &b|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:opt, :b]], proc {|a, b=:b|}.parameters(lambda: true))
+ assert_equal([[:rest, :a]], proc {|*a|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:rest, :b], [:block, :c]], proc {|a, *b, &c|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c]], proc {|a, *b, c|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], proc {|a, *b, c, &d|}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], proc {|a, b=:b, *c, d, &e|}.parameters(lambda: true))
+ assert_equal([[:req], [:block, :b]], proc {|(a), &b|a}.parameters(lambda: true))
+ assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], proc {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters(lambda: true))
+
+ pr = eval("proc{|"+"(_),"*30+"|}")
+ assert_empty(pr.parameters(lambda: true).map{|_,n|n}.compact)
+
+ assert_equal([[:opt, :a]], lambda {|a|}.parameters(lambda: false))
+ assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters(lambda: false))
+ end
+
def pm0() end
def pm1(a) end
def pm2(a, b) end
@@ -1261,7 +1375,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)
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index 636871f822..c4888598a8 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 13b7329269..f066433f6a 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 0000000000..a5072099e1
--- /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_range.rb b/test/ruby/test_range.rb
index 8ac1930be6..8789eca749 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -604,6 +604,10 @@ class TestRange < Test::Unit::TestCase
assert_include(0...10, 5)
assert_include(5..., 10)
assert_not_include(5..., 0)
+ assert_include(.."z", "z")
+ assert_not_include(..."z", "z")
+ assert_include(..10, 10)
+ assert_not_include(...10, 10)
end
def test_cover
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 19857b035c..c0754d8cf0 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_regexp.rb b/test/ruby/test_regexp.rb
index 2bf4649f14..84687c5380 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -424,6 +424,27 @@ class TestRegexp < Test::Unit::TestCase
assert_equal([2, 3], m.offset(3))
end
+ def test_match_byteoffset_begin_end
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal([3, 6], m.byteoffset("x"))
+ assert_equal(3, m.begin("x"))
+ assert_equal(6, m.end("x"))
+ assert_raise(IndexError) { m.byteoffset("y") }
+ assert_raise(IndexError) { m.byteoffset(2) }
+ assert_raise(IndexError) { m.begin(2) }
+ assert_raise(IndexError) { m.end(2) }
+
+ m = /(?<x>q..)?/.match("foobarbaz")
+ assert_equal([nil, nil], m.byteoffset("x"))
+ assert_equal(nil, m.begin("x"))
+ assert_equal(nil, m.end("x"))
+
+ m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
+ assert_equal([3, 6], m.byteoffset(1))
+ assert_equal([nil, nil], m.byteoffset(2))
+ assert_equal([6, 9], m.byteoffset(3))
+ end
+
def test_match_to_s
m = /(?<x>b..)/.match("foobarbaz")
assert_equal("bar", m.to_s)
@@ -467,6 +488,7 @@ class TestRegexp < Test::Unit::TestCase
assert_nil(m[5])
assert_raise(IndexError) { m[:foo] }
assert_raise(TypeError) { m[nil] }
+ assert_equal(["baz", nil], m[-2, 3])
end
def test_match_values_at
@@ -536,6 +558,8 @@ class TestRegexp < Test::Unit::TestCase
def test_initialize
assert_raise(ArgumentError) { Regexp.new }
assert_equal(/foo/, assert_warning(/ignored/) {Regexp.new(/foo/, Regexp::IGNORECASE)})
+ assert_equal(/foo/, assert_no_warning(/ignored/) {Regexp.new(/foo/)})
+ assert_equal(/foo/, assert_no_warning(/ignored/) {Regexp.new(/foo/, timeout: nil)})
assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n").encoding)
assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
@@ -1184,6 +1208,11 @@ class TestRegexp < Test::Unit::TestCase
assert_no_match(/^\p{age=12.0}$/u, "\u32FF")
assert_match(/^\p{age=12.1}$/u, "\u32FF")
+ assert_no_match(/^\p{age=13.0}$/u, "\u{10570}")
+ assert_match(/^\p{age=14.0}$/u, "\u{10570}")
+ assert_match(/^\p{age=14.0}$/u, "\u9FFF")
+ assert_match(/^\p{age=14.0}$/u, "\u{2A6DF}")
+ assert_match(/^\p{age=14.0}$/u, "\u{2B738}")
end
MatchData_A = eval("class MatchData_\u{3042} < MatchData; self; end")
@@ -1396,6 +1425,21 @@ class TestRegexp < Test::Unit::TestCase
end
end
+ def test_bug18631
+ assert_kind_of MatchData, /(?<x>a)(?<x>aa)\k<x>/.match("aaaaa")
+ assert_kind_of MatchData, /(?<x>a)(?<x>aa)\k<x>/.match("aaaa")
+ assert_kind_of MatchData, /(?<x>a)(?<x>aa)\k<x>/.match("aaaab")
+ end
+
+ def test_invalid_group
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ assert_raise_with_message(RegexpError, /invalid conditional pattern/) do
+ Regexp.new("((?(1)x|x|)x)+")
+ end
+ end;
+ end
+
# This assertion is for porting x2() tests in testpy.py of Onigmo.
def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp)
@@ -1425,4 +1469,43 @@ class TestRegexp < Test::Unit::TestCase
}
assert_empty(errs, msg)
end
+
+ def test_s_timeout
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ timeout = EnvUtil.apply_timeout_scale(0.2)
+
+ Regexp.timeout = timeout
+ assert_equal(timeout, Regexp.timeout)
+
+ t = Time.now
+ assert_raise_with_message(Regexp::TimeoutError, "regexp match timeout") do
+ # A typical ReDoS case
+ /^(a*)*$/ =~ "a" * 1000000 + "x"
+ end
+ t = Time.now - t
+
+ assert_in_delta(timeout, t, timeout / 2)
+ end;
+ end
+
+ def test_timeout
+ assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ begin;
+ dummy_timeout = EnvUtil.apply_timeout_scale(10)
+ timeout = EnvUtil.apply_timeout_scale(0.2)
+
+ Regexp.timeout = dummy_timeout # This should be ignored
+
+ re = Regexp.new("^a*b?a*$", timeout: timeout)
+
+ t = Time.now
+ assert_raise_with_message(Regexp::TimeoutError, "regexp match timeout") do
+ re =~ "a" * 1000000 + "x"
+ end
+ t = Time.now - t
+
+ assert_in_delta(timeout, t, timeout / 2)
+ end;
+ end
end
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 77cdae64d9..5a24cb1ba5 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
@@ -460,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
}
}
@@ -486,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
}
}
@@ -850,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
@@ -911,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 6b2846c8fd..95fa3f29e1 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 b4080010e2..ab15006e4c 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -10,8 +10,8 @@ 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 /, '')
+ 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
@@ -121,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)
@@ -137,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
@@ -146,7 +148,7 @@ 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 self.class.yjit_enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
assert_equal(NO_JIT_DESCRIPTION, r[0])
@@ -214,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? || self.class.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])
@@ -226,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])
@@ -239,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
@@ -345,9 +357,9 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%W(-\r -e) + [""], "", [], [])
- assert_in_out_err(%W(-\rx), "", [], /invalid option -\\r \(-h will show valid options\) \(RuntimeError\)/)
+ assert_in_out_err(%W(-\rx), "", [], /invalid option -[\r\n] \(-h will show valid options\) \(RuntimeError\)/)
- assert_in_out_err(%W(-\x01), "", [], /invalid option -\\x01 \(-h will show valid options\) \(RuntimeError\)/)
+ assert_in_out_err(%W(-\x01), "", [], /invalid option -\x01 \(-h will show valid options\) \(RuntimeError\)/)
assert_in_out_err(%w(-Z), "", [], /invalid option -Z \(-h will show valid options\) \(RuntimeError\)/)
end
@@ -664,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")
@@ -687,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#{<<-'};'}")
{#
@@ -750,6 +762,7 @@ class TestRubyOptions < Test::Unit::TestCase
%r(
(?:
--\sC\slevel\sbacktrace\sinformation\s-------------------------------------------\n
+ (?:Un(?:expected|supported|known)\s.*\n)*
(?:(?:.*\s)?\[0x\h+\].*\n|.*:\d+\n)*\n
)?
)x,
@@ -762,7 +775,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
@@ -847,7 +860,7 @@ class TestRubyOptions < Test::Unit::TestCase
Process.wait pid
}
rescue RuntimeError
- skip $!
+ omit $!
end
}
assert_equal("", result, '[ruby-dev:37798]')
@@ -897,7 +910,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"
@@ -1105,15 +1118,15 @@ 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
- def test_jit_debug
+ def test_mjit_debug
# 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.rb b/test/ruby/test_rubyvm.rb
index 7d4588a165..d0b7cba341 100644
--- a/test/ruby/test_rubyvm.rb
+++ b/test/ruby/test_rubyvm.rb
@@ -4,11 +4,11 @@ require 'test/unit'
class TestRubyVM < Test::Unit::TestCase
def test_stat
assert_kind_of Hash, RubyVM.stat
- assert_kind_of Integer, RubyVM.stat[:global_constant_state]
+ assert_kind_of Integer, RubyVM.stat[:class_serial]
RubyVM.stat(stat = {})
assert_not_empty stat
- assert_equal stat[:global_constant_state], RubyVM.stat(:global_constant_state)
+ assert_equal stat[:class_serial], RubyVM.stat(:class_serial)
end
def test_stat_unknown
@@ -34,6 +34,8 @@ class TestRubyVM < Test::Unit::TestCase
end
def test_keep_script_lines
+ pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
+
prev_conf = RubyVM.keep_script_lines
# keep
diff --git a/test/ruby/test_rubyvm_jit.rb b/test/ruby/test_rubyvm_mjit.rb
index 2104ce3d18..94b773c4e6 100644
--- a/test/ruby/test_rubyvm_jit.rb
+++ b/test/ruby/test_rubyvm_mjit.rb
@@ -4,12 +4,12 @@ require_relative '../lib/jit_support'
return if RbConfig::CONFIG["MJIT_SUPPORT"] == 'no'
-class TestRubyVMJIT < Test::Unit::TestCase
+class TestRubyVMMJIT < Test::Unit::TestCase
include JITSupport
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 4a37426531..b43f9c114d 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],
@@ -586,7 +594,7 @@ CODE
eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy'
1: set_trace_func(lambda{|event, file, line, id, binding, klass|
- 2: events << [event, line, file, klass, id, binding.eval('self'), binding.eval("_local_var")] if file == 'xyzzy'
+ 2: events << [event, line, file, klass, id, binding&.eval('self'), binding&.eval("_local_var")] if file == 'xyzzy'
3: })
4: 1.times{|;_local_var| _local_var = :inner
5: tap{}
@@ -611,29 +619,31 @@ CODE
answer_events = [
#
- [:c_return, 1, "xyzzy", TracePoint, :trace, TracePoint, :outer, trace],
+ [:c_return, 1, "xyzzy", TracePoint, :trace, TracePoint, nil, nil],
[:line, 4, 'xyzzy', self.class, method, self, :outer, :nothing],
- [:c_call, 4, 'xyzzy', Integer, :times, 1, :outer, :nothing],
+ [:c_call, 4, 'xyzzy', Integer, :times, 1, nil, nil],
[:line, 4, 'xyzzy', self.class, method, self, nil, :nothing],
[:line, 5, 'xyzzy', self.class, method, self, :inner, :nothing],
- [:c_return, 4, "xyzzy", Integer, :times, 1, :outer, 1],
+ [:c_return, 4, "xyzzy", Integer, :times, 1, nil, nil],
[: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, :inherited, Object, nil, nil],
+ [:c_return, 7, "xyzzy", Class, :inherited, Object, nil, nil],
+ [:c_call, 7, "xyzzy", Class, :const_added, Object, nil, nil],
+ [:c_return, 7, "xyzzy", Class, :const_added, Object, nil, 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],
- [:c_call, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_return, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, nil],
+ [:c_call, 9, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
+ [:c_return, 9, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
[:line, 13, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_call, 13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_return,13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, nil],
+ [:c_call, 13, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
+ [:c_return,13, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
[:end, 17, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
[:line, 18, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
- [:c_call, 18, "xyzzy", Class, :new, xyzzy.class, :outer, :nothing],
- [:c_call, 18, "xyzzy", BasicObject, :initialize, xyzzy, :outer, :nothing],
- [:c_return,18, "xyzzy", BasicObject, :initialize, xyzzy, :outer, nil],
- [:c_return,18, "xyzzy", Class, :new, xyzzy.class, :outer, xyzzy],
+ [:c_call, 18, "xyzzy", Class, :new, xyzzy.class, nil, nil],
+ [:c_call, 18, "xyzzy", BasicObject, :initialize, xyzzy, nil, nil],
+ [:c_return,18, "xyzzy", BasicObject, :initialize, xyzzy, nil, nil],
+ [:c_return,18, "xyzzy", Class, :new, xyzzy.class, nil, nil],
[:line, 19, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
[:call, 9, "xyzzy", xyzzy.class, :foo, xyzzy, nil, :nothing],
[:line, 10, "xyzzy", xyzzy.class, :foo, xyzzy, nil, :nothing],
@@ -644,23 +654,29 @@ CODE
[:return, 16, "xyzzy", xyzzy.class, :bar, xyzzy, :XYZZY_bar, xyzzy],
[:return, 12, "xyzzy", xyzzy.class, :foo, xyzzy, :XYZZY_foo, xyzzy],
[:line, 20, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
- [:c_call, 20, "xyzzy", Kernel, :raise, self, :outer, :nothing],
- [:c_call, 20, "xyzzy", Exception, :exception, RuntimeError, :outer, :nothing],
- [:c_call, 20, "xyzzy", Exception, :initialize, raised_exc, :outer, :nothing],
- [:c_return,20, "xyzzy", Exception, :initialize, raised_exc, :outer, raised_exc],
- [:c_return,20, "xyzzy", Exception, :exception, RuntimeError, :outer, raised_exc],
- [:c_return,20, "xyzzy", Kernel, :raise, self, :outer, nil],
- [:c_call, 20, "xyzzy", Exception, :backtrace, raised_exc, :outer, :nothing],
- [:c_return,20, "xyzzy", Exception, :backtrace, raised_exc, :outer, nil],
+ [:c_call, 20, "xyzzy", Kernel, :raise, self, nil, nil],
+ [:c_call, 20, "xyzzy", Exception, :exception, RuntimeError, nil, nil],
+ [:c_call, 20, "xyzzy", Exception, :initialize, raised_exc, nil, nil],
+ [:c_return,20, "xyzzy", Exception, :initialize, raised_exc, nil, nil],
+ [:c_return,20, "xyzzy", Exception, :exception, RuntimeError, nil, nil],
+ [:c_return,20, "xyzzy", Kernel, :raise, self, nil, nil],
+ [:c_call, 20, "xyzzy", Exception, :backtrace, raised_exc, nil, nil],
+ [:c_return,20, "xyzzy", Exception, :backtrace, raised_exc, nil, nil],
[:raise, 20, "xyzzy", TestSetTraceFunc, :trace_by_tracepoint, self, :outer, raised_exc],
- [:c_call, 20, "xyzzy", Module, :===, RuntimeError,:outer, :nothing],
- [:c_return,20, "xyzzy", Module, :===, RuntimeError,:outer, true],
+ [:c_call, 20, "xyzzy", Module, :===, RuntimeError, nil, nil],
+ [:c_return,20, "xyzzy", Module, :===, RuntimeError, nil, nil],
[:line, 21, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
- [:c_call, 21, "xyzzy", TracePoint, :disable, trace, :outer, :nothing],
+ [:c_call, 21, "xyzzy", TracePoint, :disable, trace, nil, nil],
]
return events, answer_events
end
+ def test_set_trace_func_curry_argument_error
+ b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }.curry[1, 2]
+ set_trace_func(proc {})
+ assert_raise(ArgumentError) {b[3, 4]}
+ end
+
def test_set_trace_func
actual_events, expected_events = trace_by_set_trace_func
expected_events.zip(actual_events){|e, a|
@@ -717,25 +733,30 @@ CODE
def test_tracepoint_enable
ary = []
args = nil
- trace = TracePoint.new(:call){|tp|
- next if !target_thread?
- ary << tp.method_id
- }
- foo
- trace.enable{|*a|
- args = a
+ begin
+ trace = TracePoint.new(:call){|tp|
+ next if !target_thread?
+ ary << tp.method_id
+ }
foo
- }
- foo
- assert_equal([:foo], ary)
- assert_equal([], args)
+ trace.enable(target_thread: nil){|*a|
+ args = a
+ foo
+ }
+ foo
+ assert_equal([:foo], ary)
+ assert_equal([], args)
+ ensure
+ trace&.disable
+ end
trace = TracePoint.new{}
begin
assert_equal(false, trace.enable)
assert_equal(true, trace.enable)
- trace.enable{}
- assert_equal(true, trace.enable)
+ trace.enable(target_thread: nil){}
+ trace.disable
+ assert_equal(false, trace.enable)
ensure
trace.disable
end
@@ -967,7 +988,7 @@ CODE
tp.defined_class, #=> nil,
tp.self.class # tp.self return creating/ending thread
]
- }.enable{
+ }.enable(target_thread: nil){
created_thread = Thread.new{thread_self = self}
created_thread.join
}
@@ -1951,7 +1972,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 +1993,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 +2127,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__
@@ -2212,7 +2250,7 @@ CODE
# global TP and targeted TP
ex = assert_raise(ArgumentError) do
tp = TracePoint.new(:line){}
- tp.enable{
+ tp.enable(target_thread: nil){
tp.enable(target: code2){}
}
end
@@ -2354,7 +2392,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 +2441,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 +2596,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 a62537d59d..c5043eea59 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_string.rb b/test/ruby/test_string.rb
index 3f7c06e075..d96e8dff22 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,13 +1333,22 @@ 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/))
+
+ assert_equal(0, S("こんにちは").index(?こ))
+ assert_equal(1, S("こんにちは").index(S("んにち")))
+ assert_equal(2, S("こんにちは").index(/にち./))
+
+ assert_equal(0, S("にんにちは").index(?に, 0))
+ assert_equal(2, S("にんにちは").index(?に, 1))
+ assert_equal(2, S("にんにちは").index(?に, 2))
+ assert_nil(S("にんにちは").index(?に, 3))
end
def test_insert
@@ -1442,16 +1455,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() }
@@ -1498,18 +1511,41 @@ CODE
assert_nil(S("hello").rindex(S("z")))
assert_nil(S("hello").rindex(/z./))
+ assert_equal(5, S("hello").rindex(S("")))
+ assert_equal(5, S("hello").rindex(S(""), 5))
+ assert_equal(4, S("hello").rindex(S(""), 4))
+ assert_equal(0, S("hello").rindex(S(""), 0))
+
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/))
+
+ assert_equal(2, S("こんにちは").rindex(?に))
+ assert_equal(6, S("にちは、こんにちは").rindex(S("にちは")))
+ assert_equal(6, S("にちは、こんにちは").rindex(/にち./))
+
+ assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), 7))
+ assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), -2))
+ assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), 6))
+ assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), -3))
+ assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 5))
+ assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), -4))
+ assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 1))
+ assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 0))
+
+ assert_equal(0, S("こんにちは").rindex(S("こんにちは")))
+ assert_nil(S("こんにち").rindex(S("こんにちは")))
+ assert_nil(S("こ").rindex(S("こんにちは")))
+ assert_nil(S("").rindex(S("こんにちは")))
end
def test_rjust
@@ -1689,7 +1725,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 +1751,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 +1790,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 +1895,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 +1907,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 +1974,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 +1993,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 +2040,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 +2103,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 +2126,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 +2174,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 +2238,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 +2275,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 +2283,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!
@@ -2345,6 +2384,7 @@ CODE
assert_equal(S("HELLO"), S("HELLO").upcase)
assert_equal(S("ABC HELLO 123"), S("abc HELLO 123").upcase)
assert_equal(S("H\0""ELLO"), S("H\0""ello").upcase)
+ assert_equal(S("\u{10574}"), S("\u{1059B}").upcase)
end
def test_upcase!
@@ -2418,6 +2458,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 +2468,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 +2486,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 +2514,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 +2527,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 +2569,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 +2603,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 +2624,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 +2652,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 +2662,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 +2701,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 +2722,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 +2794,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 +2827,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 +2873,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 +2926,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 +2977,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 +3068,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 +3083,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 +3103,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 +3115,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 +3129,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 +3171,8 @@ CODE
end
def test_eq_tilde_can_be_overridden
+ return unless @cls == String
+
assert_separately([], <<-RUBY)
class String
undef =~
@@ -3140,7 +3190,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 +3200,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 +3212,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 +3235,8 @@ CODE
end
def test_uminus_frozen
+ return unless @cls == String
+
# embedded
str1 = ("foobar" * 3).freeze
str2 = ("foobar" * 3).freeze
@@ -3198,40 +3253,192 @@ CODE
end
def test_uminus_no_freeze_not_bare
- str = @cls.new("foo")