summaryrefslogtreecommitdiff
path: root/tool/test
diff options
context:
space:
mode:
Diffstat (limited to 'tool/test')
-rw-r--r--tool/test/init.rb26
-rw-r--r--tool/test/minitest/test_minitest_benchmark.rb131
-rw-r--r--tool/test/minitest/test_minitest_mock.rb404
-rw-r--r--tool/test/runner.rb45
-rw-r--r--tool/test/test_commit_email.rb102
-rwxr-xr-xtool/test/test_sync_default_gems.rb373
-rw-r--r--tool/test/testunit/metametameta.rb (renamed from tool/test/minitest/metametameta.rb)17
-rw-r--r--tool/test/testunit/test4test_hideskip.rb8
-rw-r--r--tool/test/testunit/test4test_load_failure.rb1
-rw-r--r--tool/test/testunit/test4test_sorting.rb2
-rw-r--r--tool/test/testunit/test4test_timeout.rb15
-rw-r--r--tool/test/testunit/test_assertion.rb201
-rw-r--r--tool/test/testunit/test_hideskip.rb7
-rw-r--r--tool/test/testunit/test_launchable.rb70
-rw-r--r--tool/test/testunit/test_load_failure.rb23
-rw-r--r--tool/test/testunit/test_minitest_unit.rb (renamed from tool/test/minitest/test_minitest_unit.rb)562
-rw-r--r--tool/test/testunit/test_parallel.rb112
-rw-r--r--tool/test/testunit/test_redefinition.rb13
-rw-r--r--tool/test/testunit/test_sorting.rb59
-rw-r--r--tool/test/testunit/test_timeout.rb10
-rw-r--r--tool/test/testunit/tests_for_parallel/ptest_forth.rb8
-rw-r--r--tool/test/testunit/tests_for_parallel/slow_helper.rb8
-rw-r--r--tool/test/testunit/tests_for_parallel/test4test_hungup.rb15
23 files changed, 1133 insertions, 1079 deletions
diff --git a/tool/test/init.rb b/tool/test/init.rb
new file mode 100644
index 0000000000..3fd1419a9c
--- /dev/null
+++ b/tool/test/init.rb
@@ -0,0 +1,26 @@
+# This file includes the settings for "make test-all" and "make test-tool".
+# Note that this file is loaded not only by test/runner.rb but also by tool/lib/test/unit/parallel.rb.
+
+# Prevent test-all from using bundled gems
+["GEM_HOME", "GEM_PATH"].each do |gem_env|
+ # Preserve the gem environment prepared by tool/runruby.rb for test-tool, which uses bundled gems.
+ ENV["BUNDLED_#{gem_env}"] = ENV[gem_env]
+
+ ENV[gem_env] = "".freeze
+end
+ENV["GEM_SKIP"] = "".freeze
+
+ENV.delete("RUBY_CODESIGN")
+
+Warning[:experimental] = false
+
+$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
+
+require 'test/unit'
+
+require "profile_test_all" if ENV.key?('RUBY_TEST_ALL_PROFILE')
+require "tracepointchecker"
+require "zombie_hunter"
+require "iseq_loader_checker"
+require "gc_checker"
+require_relative "../test-coverage.rb" if ENV.key?('COVERAGE')
diff --git a/tool/test/minitest/test_minitest_benchmark.rb b/tool/test/minitest/test_minitest_benchmark.rb
deleted file mode 100644
index a783e684c2..0000000000
--- a/tool/test/minitest/test_minitest_benchmark.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: false
-
-require 'minitest/autorun'
-require 'minitest/benchmark'
-
-##
-# Used to verify data:
-# http://www.wolframalpha.com/examples/RegressionAnalysis.html
-
-class TestMiniTestBenchmark < MiniTest::Unit::TestCase
- def test_cls_bench_exp
- assert_equal [2, 4, 8, 16, 32], self.class.bench_exp(2, 32, 2)
- end
-
- def test_cls_bench_linear
- assert_equal [2, 4, 6, 8, 10], self.class.bench_linear(2, 10, 2)
- end
-
- def test_cls_benchmark_methods
- assert_equal [], self.class.benchmark_methods
-
- c = Class.new(MiniTest::Unit::TestCase) do
- def bench_blah
- end
- end
-
- assert_equal ["bench_blah"], c.benchmark_methods
- end
-
- def test_cls_bench_range
- assert_equal [1, 10, 100, 1_000, 10_000], self.class.bench_range
- end
-
- def test_fit_exponential_clean
- x = [1.0, 2.0, 3.0, 4.0, 5.0]
- y = x.map { |n| 1.1 * Math.exp(2.1 * n) }
-
- assert_fit :exponential, x, y, 1.0, 1.1, 2.1
- end
-
- def test_fit_exponential_noisy
- x = [1.0, 1.9, 2.6, 3.4, 5.0]
- y = [12, 10, 8.2, 6.9, 5.9]
-
- # verified with Numbers and R
- assert_fit :exponential, x, y, 0.95, 13.81148, -0.1820
- end
-
- def test_fit_logarithmic_clean
- x = [1.0, 2.0, 3.0, 4.0, 5.0]
- y = x.map { |n| 1.1 + 2.1 * Math.log(n) }
-
- assert_fit :logarithmic, x, y, 1.0, 1.1, 2.1
- end
-
- def test_fit_logarithmic_noisy
- x = [1.0, 2.0, 3.0, 4.0, 5.0]
- # Generated with
- # y = x.map { |n| jitter = 0.999 + 0.002 * rand; (Math.log(n) ) * jitter }
- y = [0.0, 0.6935, 1.0995, 1.3873, 1.6097]
-
- assert_fit :logarithmic, x, y, 0.95, 0, 1
- end
-
- def test_fit_constant_clean
- x = (1..5).to_a
- y = [5.0, 5.0, 5.0, 5.0, 5.0]
-
- assert_fit :linear, x, y, nil, 5.0, 0
- end
-
- def test_fit_constant_noisy
- x = (1..5).to_a
- y = [1.0, 1.2, 1.0, 0.8, 1.0]
-
- # verified in numbers and R
- assert_fit :linear, x, y, nil, 1.12, -0.04
- end
-
- def test_fit_linear_clean
- # y = m * x + b where m = 2.2, b = 3.1
- x = (1..5).to_a
- y = x.map { |n| 2.2 * n + 3.1 }
-
- assert_fit :linear, x, y, 1.0, 3.1, 2.2
- end
-
- def test_fit_linear_noisy
- x = [ 60, 61, 62, 63, 65]
- y = [3.1, 3.6, 3.8, 4.0, 4.1]
-
- # verified in numbers and R
- assert_fit :linear, x, y, 0.8315, -7.9635, 0.1878
- end
-
- def test_fit_power_clean
- # y = A x ** B, where B = b and A = e ** a
- # if, A = 1, B = 2, then
-
- x = [1.0, 2.0, 3.0, 4.0, 5.0]
- y = [1.0, 4.0, 9.0, 16.0, 25.0]
-
- assert_fit :power, x, y, 1.0, 1.0, 2.0
- end
-
- def test_fit_power_noisy
- # from www.engr.uidaho.edu/thompson/courses/ME330/lecture/least_squares.html
- x = [10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35]
- y = [95, 105, 125, 141, 173, 200, 253, 298, 385, 459, 602]
-
- # verified in numbers
- assert_fit :power, x, y, 0.90, 2.6217, 1.4556
-
- # income to % of households below income amount
- # http://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
- x = [15000, 25000, 35000, 50000, 75000, 100000]
- y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
-
- # verified in numbers
- assert_fit :power, x, y, 0.96, 3.119e-5, 0.8959
- end
-
- def assert_fit msg, x, y, fit, exp_a, exp_b
- a, b, rr = send "fit_#{msg}", x, y
-
- assert_operator rr, :>=, fit if fit
- assert_in_delta exp_a, a
- assert_in_delta exp_b, b
- end
-end
diff --git a/tool/test/minitest/test_minitest_mock.rb b/tool/test/minitest/test_minitest_mock.rb
deleted file mode 100644
index da222c5aa8..0000000000
--- a/tool/test/minitest/test_minitest_mock.rb
+++ /dev/null
@@ -1,404 +0,0 @@
-# encoding: utf-8
-# frozen_string_literal: false
-
-require 'minitest/autorun'
-
-class TestMiniTestMock < MiniTest::Unit::TestCase
- def setup
- @mock = MiniTest::Mock.new.expect(:foo, nil)
- @mock.expect(:meaning_of_life, 42)
- end
-
- def test_create_stub_method
- assert_nil @mock.foo
- end
-
- def test_allow_return_value_specification
- assert_equal 42, @mock.meaning_of_life
- end
-
- def test_blow_up_if_not_called
- @mock.foo
-
- util_verify_bad "expected meaning_of_life() => 42, got []"
- end
-
- def test_not_blow_up_if_everything_called
- @mock.foo
- @mock.meaning_of_life
-
- assert @mock.verify
- end
-
- def test_allow_expectations_to_be_added_after_creation
- @mock.expect(:bar, true)
- assert @mock.bar
- end
-
- def test_not_verify_if_new_expected_method_is_not_called
- @mock.foo
- @mock.meaning_of_life
- @mock.expect(:bar, true)
-
- util_verify_bad "expected bar() => true, got []"
- end
-
- def test_blow_up_on_wrong_number_of_arguments
- @mock.foo
- @mock.meaning_of_life
- @mock.expect(:sum, 3, [1, 2])
-
- e = assert_raises ArgumentError do
- @mock.sum
- end
-
- assert_equal "mocked method :sum expects 2 arguments, got 0", e.message
- end
-
- def test_return_mock_does_not_raise
- retval = MiniTest::Mock.new
- mock = MiniTest::Mock.new
- mock.expect(:foo, retval)
- mock.foo
-
- assert mock.verify
- end
-
- def test_mock_args_does_not_raise
- skip "non-opaque use of ==" if maglev?
-
- arg = MiniTest::Mock.new
- mock = MiniTest::Mock.new
- mock.expect(:foo, nil, [arg])
- mock.foo(arg)
-
- assert mock.verify
- end
-
- def test_blow_up_on_wrong_arguments
- @mock.foo
- @mock.meaning_of_life
- @mock.expect(:sum, 3, [1, 2])
-
- e = assert_raises MockExpectationError do
- @mock.sum(2, 4)
- end
-
- exp = "mocked method :sum called with unexpected arguments [2, 4]"
- assert_equal exp, e.message
- end
-
- def test_expect_with_non_array_args
- e = assert_raises ArgumentError do
- @mock.expect :blah, 3, false
- end
-
- assert_equal "args must be an array", e.message
- end
-
- def test_respond_appropriately
- assert @mock.respond_to?(:foo)
- assert @mock.respond_to?(:foo, true)
- assert @mock.respond_to?('foo')
- assert !@mock.respond_to?(:bar)
- end
-
- def test_no_method_error_on_unexpected_methods
- e = assert_raises NoMethodError do
- @mock.bar
- end
-
- expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]"
-
- assert_equal expected, e.message
- end
-
- def test_assign_per_mock_return_values
- a = MiniTest::Mock.new
- b = MiniTest::Mock.new
-
- a.expect(:foo, :a)
- b.expect(:foo, :b)
-
- assert_equal :a, a.foo
- assert_equal :b, b.foo
- end
-
- def test_do_not_create_stub_method_on_new_mocks
- a = MiniTest::Mock.new
- a.expect(:foo, :a)
-
- assert !MiniTest::Mock.new.respond_to?(:foo)
- end
-
- def test_mock_is_a_blank_slate
- @mock.expect :kind_of?, true, [Integer]
- @mock.expect :==, true, [1]
-
- assert @mock.kind_of?(Integer), "didn't mock :kind_of\?"
- assert @mock == 1, "didn't mock :=="
- end
-
- def test_verify_allows_called_args_to_be_loosely_specified
- mock = MiniTest::Mock.new
- mock.expect :loose_expectation, true, [Integer]
- mock.loose_expectation 1
-
- assert mock.verify
- end
-
- def test_verify_raises_with_strict_args
- mock = MiniTest::Mock.new
- mock.expect :strict_expectation, true, [2]
-
- e = assert_raises MockExpectationError do
- mock.strict_expectation 1
- end
-
- exp = "mocked method :strict_expectation called with unexpected arguments [1]"
- assert_equal exp, e.message
- end
-
- def test_method_missing_empty
- mock = MiniTest::Mock.new
-
- mock.expect :a, nil
-
- mock.a
-
- e = assert_raises MockExpectationError do
- mock.a
- end
-
- assert_equal "No more expects available for :a: []", e.message
- end
-
- def test_same_method_expects_are_verified_when_all_called
- mock = MiniTest::Mock.new
- mock.expect :foo, nil, [:bar]
- mock.expect :foo, nil, [:baz]
-
- mock.foo :bar
- mock.foo :baz
-
- assert mock.verify
- end
-
- def test_same_method_expects_blow_up_when_not_all_called
- mock = MiniTest::Mock.new
- mock.expect :foo, nil, [:bar]
- mock.expect :foo, nil, [:baz]
-
- mock.foo :bar
-
- e = assert_raises(MockExpectationError) { mock.verify }
-
- exp = "expected foo(:baz) => nil, got [foo(:bar) => nil]"
-
- assert_equal exp, e.message
- end
-
- def test_verify_passes_when_mock_block_returns_true
- mock = MiniTest::Mock.new
- mock.expect :foo, nil do
- true
- end
-
- mock.foo
-
- assert mock.verify
- end
-
- def test_mock_block_is_passed_function_params
- arg1, arg2, arg3 = :bar, [1,2,3], {:a => 'a'}
- mock = MiniTest::Mock.new
- mock.expect :foo, nil do |a1, a2, a3|
- a1 == arg1 &&
- a2 == arg2 &&
- a3 == arg3
- end
-
- mock.foo arg1, arg2, arg3
-
- assert mock.verify
- end
-
- def test_verify_fails_when_mock_block_returns_false
- mock = MiniTest::Mock.new
- mock.expect :foo, nil do
- false
- end
-
- e = assert_raises(MockExpectationError) { mock.foo }
- exp = "mocked method :foo failed block w/ []"
-
- assert_equal exp, e.message
- end
-
- def test_mock_block_throws_if_args_passed
- mock = MiniTest::Mock.new
-
- e = assert_raises(ArgumentError) do
- mock.expect :foo, nil, [:a, :b, :c] do
- true
- end
- end
-
- exp = "args ignored when block given"
-
- assert_equal exp, e.message
- end
-
- def test_mock_returns_retval_when_called_with_block
- mock = MiniTest::Mock.new
- mock.expect(:foo, 32) do
- true
- end
-
- rs = mock.foo
-
- assert_equal rs, 32
- end
-
- def util_verify_bad exp
- e = assert_raises MockExpectationError do
- @mock.verify
- end
-
- assert_equal exp, e.message
- end
-end
-
-require_relative "metametameta"
-
-class TestMiniTestStub < MiniTest::Unit::TestCase
- def setup
- super
- MiniTest::Unit::TestCase.reset
-
- @tc = MiniTest::Unit::TestCase.new 'fake tc'
- @assertion_count = 1
- end
-
- def teardown
- super
- assert_equal @assertion_count, @tc._assertions
- end
-
- class Time
- def self.now
- 24
- end
- end
-
- def assert_stub val_or_callable
- @assertion_count += 1
-
- t = Time.now.to_i
-
- Time.stub :now, val_or_callable do
- @tc.assert_equal 42, Time.now
- end
-
- @tc.assert_operator Time.now.to_i, :>=, t
- end
-
- def test_stub_private_module_method
- @assertion_count += 1
-
- t0 = Time.now
-
- self.stub :sleep, nil do
- @tc.assert_nil sleep(10)
- end
-
- @tc.assert_operator Time.now - t0, :<=, 1
- end
-
- def test_stub_private_module_method_indirect
- @assertion_count += 1
-
- slow_clapper = Class.new do
- def slow_clap
- sleep 3
- :clap
- end
- end.new
-
- slow_clapper.stub :sleep, nil do |fast_clapper|
- @tc.assert_equal :clap, fast_clapper.slow_clap # either form works
- @tc.assert_equal :clap, slow_clapper.slow_clap # yay closures
- end
- end
-
- def test_stub_public_module_method
- Math.stub(:log10, 42.0) do
- @tc.assert_in_delta 42.0, Math.log10(1000)
- end
- end
-
- def test_stub_value
- assert_stub 42
- end
-
- def test_stub_block
- assert_stub lambda { 42 }
- end
-
- def test_stub_block_args
- @assertion_count += 1
-
- t = Time.now.to_i
-
- Time.stub :now, lambda { |n| n * 2 } do
- @tc.assert_equal 42, Time.now(21)
- end
-
- @tc.assert_operator Time.now.to_i, :>=, t
- end
-
- def test_stub_callable
- obj = Object.new
-
- def obj.call
- 42
- end
-
- assert_stub obj
- end
-
- def test_stub_yield_self
- obj = "foo"
-
- val = obj.stub :to_s, "bar" do |s|
- s.to_s
- end
-
- @tc.assert_equal "bar", val
- end
-
- def test_dynamic_method
- @assertion_count = 2
-
- dynamic = Class.new do
- def self.respond_to?(meth)
- meth == :found
- end
-
- def self.method_missing(meth, *args, &block)
- if meth == :found
- false
- else
- super
- end
- end
- end
-
- val = dynamic.stub(:found, true) do |s|
- s.found
- end
-
- @tc.assert_equal true, val
- @tc.assert_equal false, dynamic.found
- end
-end
diff --git a/tool/test/runner.rb b/tool/test/runner.rb
index 64f6df167e..9001fc2d06 100644
--- a/tool/test/runner.rb
+++ b/tool/test/runner.rb
@@ -1,39 +1,14 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'rbconfig'
-src_testdir = File.dirname(File.realpath(__FILE__))
-$LOAD_PATH << src_testdir
-tool_dir = File.join src_testdir, ".."
-$LOAD_PATH.unshift "#{tool_dir}/lib"
+require_relative "init"
-# Get bundled gems on load path
-Dir.glob("#{src_testdir}/../gems/*/*.gemspec")
- .reject {|f| f =~ /minitest|test-unit|power_assert/ }
- .map {|f| $LOAD_PATH.unshift File.join(File.dirname(f), "lib") }
-
-require 'test/unit'
-
-module Gem
-end
-class Gem::TestCase < MiniTest::Unit::TestCase
- @@project_dir = File.dirname($LOAD_PATH.last)
-end
-
-ENV["GEM_SKIP"] = ENV["GEM_HOME"] = ENV["GEM_PATH"] = "".freeze
-
-require_relative "#{tool_dir}/lib/profile_test_all" if ENV.has_key?('RUBY_TEST_ALL_PROFILE')
-require_relative "#{tool_dir}/lib/tracepointchecker"
-require_relative "#{tool_dir}/lib/zombie_hunter"
-require_relative "#{tool_dir}/lib/iseq_loader_checker"
-
-if ENV['COVERAGE']
- require_relative "#{tool_dir}/test-coverage.rb"
-end
-
-begin
- exit Test::Unit::AutoRunner.run(true, src_testdir)
-rescue NoMemoryError
- system("cat /proc/meminfo") if File.exist?("/proc/meminfo")
- system("ps x -opid,args,%cpu,%mem,nlwp,rss,vsz,wchan,stat,start,time,etime,blocked,caught,ignored,pending,f") if File.exist?("/bin/ps")
- raise
+case $0
+when __FILE__
+ dir = __dir__
+when "-e"
+ # No default directory
+else
+ dir = File.realdirpath("..", $0)
end
+exit Test::Unit::AutoRunner.run(true, dir)
diff --git a/tool/test/test_commit_email.rb b/tool/test/test_commit_email.rb
new file mode 100644
index 0000000000..db441584fd
--- /dev/null
+++ b/tool/test/test_commit_email.rb
@@ -0,0 +1,102 @@
+require 'test/unit'
+require 'shellwords'
+require 'tmpdir'
+require 'fileutils'
+require 'open3'
+
+class TestCommitEmail < Test::Unit::TestCase
+ STDIN_DELIMITER = "---\n"
+
+ def setup
+ omit 'git command is not available' unless system('git', '--version', out: File::NULL, err: File::NULL)
+
+ @ruby = Dir.mktmpdir
+ Dir.chdir(@ruby) do
+ git('init', '--initial-branch=master')
+ git('config', 'user.name', 'Jóhän Grübél')
+ git('config', 'user.email', 'johan@example.com')
+ env = {
+ 'GIT_AUTHOR_DATE' => '2025-10-08T12:00:00Z',
+ 'GIT_CONFIG_GLOBAL' => @ruby + "/gitconfig",
+ 'TZ' => 'UTC',
+ }
+ git('commit', '--allow-empty', '-m', 'New repository initialized by cvs2svn.', env:)
+ git('commit', '--allow-empty', '-m', 'Initial revision', env:)
+ git('commit', '--allow-empty', '-m', 'version 1.0.0', env:)
+ end
+
+ @sendmail = File.join(Dir.mktmpdir, 'sendmail')
+ File.write(@sendmail, <<~SENDMAIL, mode: "wx", perm: 0755)
+ #!/bin/sh
+ echo #{STDIN_DELIMITER.chomp.dump}
+ exec cat
+ SENDMAIL
+
+ @commit_email = File.expand_path('../../tool/commit-email.rb', __dir__)
+ end
+
+ def teardown
+ # Clean up temporary files if #setup was not omitted
+ if @sendmail
+ File.unlink(@sendmail)
+ Dir.rmdir(File.dirname(@sendmail))
+ end
+ if @ruby
+ FileUtils.rm_rf(@ruby)
+ end
+ end
+
+ def test_sendmail_encoding
+ omit 'the sendmail script does not work on windows' if windows?
+
+ Dir.chdir(@ruby) do
+ before_rev = git('rev-parse', 'HEAD^').chomp
+ after_rev = git('rev-parse', 'HEAD').chomp
+ short_rev = after_rev[0...10]
+
+ out, _, status = EnvUtil.invoke_ruby([
+ { 'SENDMAIL' => @sendmail, 'TZ' => 'UTC' }.merge!(gem_env),
+ @commit_email, './', 'cvs-admin@ruby-lang.org',
+ before_rev, after_rev, 'refs/heads/master',
+ '--viewer-uri', 'https://github.com/ruby/ruby/commit/',
+ '--error-to', 'cvs-admin@ruby-lang.org',
+ ], '', true)
+ stdin = out.b.split(STDIN_DELIMITER.b, 2).last.force_encoding('UTF-8')
+
+ assert_true(status.success?)
+ assert_equal(stdin, <<~EOS)
+ Mime-Version: 1.0
+ Content-Type: text/plain; charset=utf-8
+ Content-Transfer-Encoding: quoted-printable
+ From: =?UTF-8?B?SsOzaMOkbiBHcsO8YsOpbA==?= <noreply@ruby-lang.org>
+ To: cvs-admin@ruby-lang.org
+ Subject: #{short_rev} (master): =?UTF-8?B?dmVyc2lvbuOAgDEuMC4w?=
+ J=C3=B3h=C3=A4n Gr=C3=BCb=C3=A9l\t2025-10-08 12:00:00 +0000 (Wed, 08 Oct 2=
+ 025)
+
+ New Revision: #{short_rev}
+
+ https://github.com/ruby/ruby/commit/#{short_rev}
+
+ Log:
+ version=E3=80=801.0.0=
+ EOS
+ end
+ end
+
+ private
+
+ # Resurrect the gem environment preserved by tool/test/init.rb.
+ # This should work as long as you have run `make up` or `make install`.
+ def gem_env
+ { 'GEM_PATH' => ENV['BUNDLED_GEM_PATH'], 'GEM_HOME' => ENV['BUNDLED_GEM_HOME'] }
+ end
+
+ def git(*cmd, env: {})
+ out, status = Open3.capture2(env, 'git', *cmd)
+ unless status.success?
+ raise "git #{cmd.shelljoin}\n#{out}"
+ end
+ out
+ end
+end
diff --git a/tool/test/test_sync_default_gems.rb b/tool/test/test_sync_default_gems.rb
new file mode 100755
index 0000000000..252687f3f3
--- /dev/null
+++ b/tool/test/test_sync_default_gems.rb
@@ -0,0 +1,373 @@
+#!/usr/bin/ruby
+require 'test/unit'
+require 'stringio'
+require 'tmpdir'
+require 'rubygems/version'
+require_relative '../sync_default_gems'
+
+module Test_SyncDefaultGems
+ class TestMessageFilter < Test::Unit::TestCase
+ def assert_message_filter(expected, trailers, input, repo = "ruby/test", sha = "0123456789")
+ subject, *expected = expected
+ expected = [
+ "[#{repo}] #{subject}\n",
+ *expected.map {_1+"\n"},
+ "\n",
+ "https://github.com/#{repo}/commit/#{sha[0, 10]}\n",
+ ]
+ if trailers
+ expected << "\n"
+ expected.concat(trailers.map {_1+"\n"})
+ end
+
+ out = SyncDefaultGems.message_filter(repo, sha, input)
+ assert_pattern_list(expected, out)
+ end
+
+ def test_subject_only
+ expected = [
+ "initial commit",
+ ]
+ assert_message_filter(expected, nil, "initial commit")
+ end
+
+ def test_link_in_parenthesis
+ expected = [
+ "fix (https://github.com/ruby/test/pull/1)",
+ ]
+ assert_message_filter(expected, nil, "fix (#1)")
+ end
+
+ def test_co_authored_by
+ expected = [
+ "commit something",
+ ]
+ trailers = [
+ "Co-Authored-By: git <git@ruby-lang.org>",
+ ]
+ assert_message_filter(expected, trailers, [expected, "", trailers, ""].join("\n"))
+ end
+
+ def test_multiple_co_authored_by
+ expected = [
+ "many commits",
+ ]
+ trailers = [
+ "Co-authored-by: git <git@ruby-lang.org>",
+ "Co-authored-by: svn <svn@ruby-lang.org>",
+ ]
+ assert_message_filter(expected, trailers, [expected, "", trailers, ""].join("\n"))
+ end
+
+ def test_co_authored_by_no_newline
+ expected = [
+ "commit something",
+ ]
+ trailers = [
+ "Co-Authored-By: git <git@ruby-lang.org>",
+ ]
+ assert_message_filter(expected, trailers, [expected, "", trailers].join("\n"))
+ end
+
+ def test_dot_ending_subject
+ expected = [
+ "subject with a dot.",
+ "",
+ "- next body line",
+ ]
+ assert_message_filter(expected, nil, [expected[0], expected[2], ""].join("\n"))
+ end
+ end
+
+ class TestSyncWithCommits < Test::Unit::TestCase
+ def setup
+ super
+ @target = nil
+ pend "No git" unless system("git --version", out: IO::NULL)
+ @testdir = Dir.mktmpdir("sync")
+ user, email = "Ruby", "test@ruby-lang.org"
+ @git_config = %W"HOME USER GIT_CONFIG_GLOBAL GNUPGHOME".each_with_object({}) {|k, c| c[k] = ENV[k]}
+ ENV["HOME"] = @testdir
+ ENV["USER"] = user
+ ENV["GNUPGHOME"] = @testdir + '/.gnupg'
+ expire = EnvUtil.apply_timeout_scale(30).to_i
+ # Generate a new unprotected key with default parameters that
+ # expires after 30 seconds.
+ if @gpgsign = system(*%w"gpg --quiet --batch --passphrase", "",
+ "--quick-generate-key", email, *%W"default default seconds=#{expire}",
+ err: IO::NULL)
+ # Fetch the generated public key.
+ signingkey = IO.popen(%W"gpg --quiet --list-public-key #{email}", &:read)[/^pub .*\n +\K\h+/]
+ end
+ ENV["GIT_CONFIG_GLOBAL"] = @testdir + "/gitconfig"
+ git(*%W"config --global user.email", email)
+ git(*%W"config --global user.name", user)
+ git(*%W"config --global init.defaultBranch default")
+ if signingkey
+ git(*%W"config --global user.signingkey", signingkey)
+ git(*%W"config --global commit.gpgsign true")
+ git(*%W"config --global gpg.program gpg")
+ git(*%W"config --global log.showSignature true")
+ end
+ @target = "sync-test"
+ SyncDefaultGems::REPOSITORIES[@target] = SyncDefaultGems.repo(
+ ["ruby/#{@target}", "default"],
+ [
+ ["lib", "lib"],
+ ["test", "test"],
+ ],
+ exclude: [
+ "test/fixtures/*",
+ ],
+ )
+ @sha = {}
+ @origdir = Dir.pwd
+ Dir.chdir(@testdir)
+ ["src", @target].each do |dir|
+ git(*%W"init -q #{dir}")
+ File.write("#{dir}/.gitignore", "*~\n")
+ Dir.mkdir("#{dir}/lib")
+ File.write("#{dir}/lib/common.rb", ":ok\n")
+ Dir.mkdir("#{dir}/.github")
+ Dir.mkdir("#{dir}/.github/workflows")
+ File.write("#{dir}/.github/workflows/default.yml", "default:\n")
+ git(*%W"add .gitignore lib/common.rb .github", chdir: dir)
+ git(*%W"commit -q -m", "Initialize", chdir: dir)
+ if dir == "src"
+ File.write("#{dir}/lib/fine.rb", "return\n")
+ Dir.mkdir("#{dir}/test")
+ File.write("#{dir}/test/test_fine.rb", "return\n")
+ git(*%W"add lib/fine.rb test/test_fine.rb", chdir: dir)
+ git(*%W"commit -q -m", "Looks fine", chdir: dir)
+ end
+ Dir.mkdir("#{dir}/tool")
+ File.write("#{dir}/tool/ok", "#!/bin/sh\n""echo ok\n")
+ git(*%W"add tool/ok", chdir: dir)
+ git(*%W"commit -q -m", "Add tool #{dir}", chdir: dir)
+ @sha[dir] = top_commit(dir)
+ end
+ git(*%W"remote add #{@target} ../#{@target}", chdir: "src")
+ end
+
+ def teardown
+ if @target
+ if @gpgsign
+ system(*%W"gpgconf --kill all")
+ end
+ Dir.chdir(@origdir)
+ SyncDefaultGems::REPOSITORIES.delete(@target)
+ ENV.update(@git_config)
+ FileUtils.rm_rf(@testdir)
+ end
+ super
+ end
+
+ def capture_process_output_to(outputs)
+ return yield unless outputs&.empty? == false
+ IO.pipe do |r, w|
+ orig = outputs.map {|out| out.dup}
+ outputs.each {|out| out.reopen(w)}
+ w.close
+ reader = Thread.start {r.read}
+ yield
+ ensure
+ outputs.each {|out| o = orig.shift; out.reopen(o); o.close}
+ return reader.value
+ end
+ end
+
+ def capture_process_outputs
+ out = err = nil
+ synchronize do
+ out = capture_process_output_to(STDOUT) do
+ err = capture_process_output_to(STDERR) do
+ yield
+ end
+ end
+ end
+ return out, err
+ end
+
+ def git(*commands, **opts)
+ system("git", *commands, exception: true, **opts)
+ end
+
+ def top_commit(dir, format: "%H")
+ IO.popen(%W[git log --no-show-signature --format=#{format} -1], chdir: dir, &:read)&.chomp
+ end
+
+ def assert_sync(commits = true, success: true, editor: nil)
+ result = nil
+ out = capture_process_output_to([STDOUT, STDERR]) do
+ Dir.chdir("src") do
+ orig_editor = ENV["GIT_EDITOR"]
+ ENV["GIT_EDITOR"] = editor || 'false'
+ edit = true if editor
+
+ result = SyncDefaultGems.sync_default_gems_with_commits(@target, commits, edit: edit)
+ ensure
+ ENV["GIT_EDITOR"] = orig_editor
+ end
+ end
+ assert_equal(success, result, out)
+ out
+ end
+
+ def test_sync
+ File.write("#@target/lib/common.rb", "# OK!\n")
+ git(*%W"commit -q -m", "OK", "lib/common.rb", chdir: @target)
+ out = assert_sync()
+ assert_not_equal(@sha["src"], top_commit("src"), out)
+ assert_equal("# OK!\n", File.read("src/lib/common.rb"))
+ log = top_commit("src", format: "%B").lines
+ assert_equal("[ruby/#@target] OK\n", log.first, out)
+ assert_match(%r[/ruby/#{@target}/commit/\h+$], log.last, out)
+ assert_operator(top_commit(@target), :start_with?, log.last[/\h+$/], out)
+ end
+
+ def test_skip_tool
+ git(*%W"rm -q tool/ok", chdir: @target)
+ git(*%W"commit -q -m", "Remove tool", chdir: @target)
+ out = assert_sync()
+ assert_equal(@sha["src"], top_commit("src"), out)
+ end
+
+ def test_skip_test_fixtures
+ Dir.mkdir("#@target/test")
+ Dir.mkdir("#@target/test/fixtures")
+ File.write("#@target/test/fixtures/fixme.rb", "")
+ git(*%W"add test/fixtures/fixme.rb", chdir: @target)
+ git(*%W"commit -q -m", "Add fixtures", chdir: @target)
+ out = assert_sync(["#{@sha[@target]}..#{@target}/default"])
+ assert_equal(@sha["src"], top_commit("src"), out)
+ end
+
+ def test_skip_toplevel
+ Dir.mkdir("#@target/docs")
+ File.write("#@target/docs/NEWS.md", "= NEWS!!!\n")
+ git(*%W"add --", "docs/NEWS.md", chdir: @target)
+ File.write("#@target/docs/hello.md", "Hello\n")
+ git(*%W"add --", "docs/hello.md", chdir: @target)
+ git(*%W"commit -q -m", "It's a news", chdir: @target)
+ out = assert_sync()
+ assert_equal(@sha["src"], top_commit("src"), out)
+ end
+
+ def test_adding_toplevel
+ Dir.mkdir("#@target/docs")
+ File.write("#@target/docs/NEWS.md", "= New library\n")
+ File.write("#@target/lib/news.rb", "return\n")
+ git(*%W"add --", "docs/NEWS.md", "lib/news.rb", chdir: @target)
+ git(*%W"commit -q -m", "New lib", chdir: @target)
+ out = assert_sync()
+ assert_not_equal(@sha["src"], top_commit("src"), out)
+ assert_equal "return\n", File.read("src/lib/news.rb")
+ assert_include top_commit("src", format: "oneline"), "[ruby/#{@target}] New lib"
+ assert_not_operator File, :exist?, "src/docs"
+ end
+
+ def test_gitignore
+ File.write("#@target/.gitignore", "*.bak\n", mode: "a")
+ File.write("#@target/lib/common.rb", "Should.be_merged\n", mode: "a")
+ File.write("#@target/.github/workflows/main.yml", "# Should not merge\n", mode: "a")
+ git(*%W"add .github", chdir: @target)
+ git(*%W"commit -q -m", "Should be common.rb only",
+ *%W".gitignore lib/common.rb .github", chdir: @target)
+ out = assert_sync()
+ assert_not_equal(@sha["src"], top_commit("src"), out)
+ assert_equal("*~\n", File.read("src/.gitignore"), out)
+ assert_equal("#!/bin/sh\n""echo ok\n", File.read("src/tool/ok"), out)
+ assert_equal(":ok\n""Should.be_merged\n", File.read("src/lib/common.rb"), out)
+ assert_not_operator(File, :exist?, "src/.github/workflows/main.yml", out)
+ end
+
+ def test_gitignore_after_conflict
+ File.write("src/Gemfile", "# main\n")
+ git(*%W"add Gemfile", chdir: "src")
+ git(*%W"commit -q -m", "Add Gemfile", chdir: "src")
+ File.write("#@target/Gemfile", "# conflict\n", mode: "a")
+ File.write("#@target/lib/common.rb", "Should.be_merged\n", mode: "a")
+ File.write("#@target/.github/workflows/main.yml", "# Should not merge\n", mode: "a")
+ git(*%W"add Gemfile .github lib/common.rb", chdir: @target)
+ git(*%W"commit -q -m", "Should be common.rb only", chdir: @target)
+ out = assert_sync()
+ assert_not_equal(@sha["src"], top_commit("src"), out)
+ assert_equal("# main\n", File.read("src/Gemfile"), out)
+ assert_equal(":ok\n""Should.be_merged\n", File.read("src/lib/common.rb"), out)
+ assert_not_operator(File, :exist?, "src/.github/workflows/main.yml", out)
+ end
+
+ def test_delete_after_conflict
+ File.write("#@target/lib/bad.rb", "raise\n")
+ git(*%W"add lib/bad.rb", chdir: @target)
+ git(*%W"commit -q -m", "Add bad.rb", chdir: @target)
+ out = assert_sync
+ assert_equal("raise\n", File.read("src/lib/bad.rb"))
+
+ git(*%W"rm lib/bad.rb", chdir: "src", out: IO::NULL)
+ git(*%W"commit -q -m", "Remove bad.rb", chdir: "src")
+
+ File.write("#@target/lib/bad.rb", "raise 'bar'\n")
+ File.write("#@target/lib/common.rb", "Should.be_merged\n", mode: "a")
+ git(*%W"add lib/bad.rb lib/common.rb", chdir: @target)
+ git(*%W"commit -q -m", "Add conflict", chdir: @target)
+
+ head = top_commit("src")
+ out = assert_sync(editor: "git rm -f lib/bad.rb")
+ assert_not_equal(head, top_commit("src"))
+ assert_equal(":ok\n""Should.be_merged\n", File.read("src/lib/common.rb"), out)
+ assert_not_operator(File, :exist?, "src/lib/bad.rb", out)
+ end
+
+ def test_squash_merge
+ # This test is known to fail with git 2.43.0, which is used by Ubuntu 24.04.
+ # We don't know which exact version fixed it, but we know git 2.52.0 works.
+ stdout, status = Open3.capture2('git', '--version', err: File::NULL)
+ omit 'git version check failed' unless status.success?
+ git_version = stdout[/\Agit version \K\S+/]
+ omit "git #{git_version} is too old" if Gem::Version.new(git_version) < Gem::Version.new('2.44.0')
+
+ # 2---. <- branch
+ # / \
+ # 1---3---3'<- merge commit with conflict resolution
+ File.write("#@target/lib/conflict.rb", "# 1\n")
+ git(*%W"add lib/conflict.rb", chdir: @target)
+ git(*%W"commit -q -m", "Add conflict.rb", chdir: @target)
+
+ git(*%W"checkout -q -b branch", chdir: @target)
+ File.write("#@target/lib/conflict.rb", "# 2\n")
+ File.write("#@target/lib/new.rb", "# new\n")
+ git(*%W"add lib/conflict.rb lib/new.rb", chdir: @target)
+ git(*%W"commit -q -m", "Commit in branch", chdir: @target)
+
+ git(*%W"checkout -q default", chdir: @target)
+ File.write("#@target/lib/conflict.rb", "# 3\n")
+ git(*%W"add lib/conflict.rb", chdir: @target)
+ git(*%W"commit -q -m", "Commit in default", chdir: @target)
+
+ # How can I suppress "Auto-merging ..." message from git merge?
+ git(*%W"merge -X ours -m", "Merge commit", "branch", chdir: @target, out: IO::NULL)
+
+ out = assert_sync()
+ assert_equal("# 3\n", File.read("src/lib/conflict.rb"), out)
+ subject, body = top_commit("src", format: "%B").split("\n\n", 2)
+ assert_equal("[ruby/#@target] Merge commit", subject, out)
+ assert_includes(body, "Commit in branch", out)
+ end
+
+ def test_no_upstream_file
+ group = SyncDefaultGems::Repository.group(%w[
+ lib/un.rb
+ lib/unicode_normalize/normalize.rb
+ lib/unicode_normalize/tables.rb
+ lib/net/https.rb
+ ])
+ expected = {
+ "un" => %w[lib/un.rb],
+ "net-http" => %w[lib/net/https.rb],
+ nil => %w[lib/unicode_normalize/normalize.rb lib/unicode_normalize/tables.rb],
+ }
+ assert_equal(expected, group)
+ end
+ end if /darwin|linux/ =~ RUBY_PLATFORM
+end
diff --git a/tool/test/minitest/metametameta.rb b/tool/test/testunit/metametameta.rb
index a12717c8b1..e494038939 100644
--- a/tool/test/minitest/metametameta.rb
+++ b/tool/test/testunit/metametameta.rb
@@ -3,15 +3,14 @@
require 'tempfile'
require 'stringio'
-require 'minitest/autorun'
-class MiniTest::Unit::TestCase
+class Test::Unit::TestCase
def clean s
s.gsub(/^ {6}/, '')
end
end
-class MetaMetaMetaTestCase < MiniTest::Unit::TestCase
+class MetaMetaMetaTestCase < Test::Unit::TestCase
def assert_report expected, flags = %w[--seed 42]
header = clean <<-EOM
Run options: #{flags.map { |s| s =~ /\|/ ? s.inspect : s }.join " "}
@@ -45,10 +44,10 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase
def setup
super
srand 42
- MiniTest::Unit::TestCase.reset
- @tu = MiniTest::Unit.new
+ Test::Unit::TestCase.reset
+ @tu = Test::Unit::Runner.new
- MiniTest::Unit.runner = nil # protect the outer runner from the inner tests
+ Test::Unit::Runner.runner = nil # protect the outer runner from the inner tests
end
def teardown
@@ -58,13 +57,13 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase
def with_output
synchronize do
begin
- save = MiniTest::Unit.output
+ save = Test::Unit::Runner.output
@output = StringIO.new("")
- MiniTest::Unit.output = @output
+ Test::Unit::Runner.output = @output
yield
ensure
- MiniTest::Unit.output = save
+ Test::Unit::Runner.output = save
end
end
end
diff --git a/tool/test/testunit/test4test_hideskip.rb b/tool/test/testunit/test4test_hideskip.rb
index 410bffc13c..14f79a5743 100644
--- a/tool/test/testunit/test4test_hideskip.rb
+++ b/tool/test/testunit/test4test_hideskip.rb
@@ -4,7 +4,11 @@ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
require 'test/unit'
class TestForTestHideSkip < Test::Unit::TestCase
- def test_skip
- skip "do nothing"
+ def test_omit
+ omit "do nothing"
+ end
+
+ def test_pend
+ pend "do nothing"
end
end
diff --git a/tool/test/testunit/test4test_load_failure.rb b/tool/test/testunit/test4test_load_failure.rb
new file mode 100644
index 0000000000..e1570c2542
--- /dev/null
+++ b/tool/test/testunit/test4test_load_failure.rb
@@ -0,0 +1 @@
+raise LoadError, "no-such-library"
diff --git a/tool/test/testunit/test4test_sorting.rb b/tool/test/testunit/test4test_sorting.rb
index 698c875b79..f5a6866425 100644
--- a/tool/test/testunit/test4test_sorting.rb
+++ b/tool/test/testunit/test4test_sorting.rb
@@ -5,7 +5,7 @@ require 'test/unit'
class TestForTestHideSkip < Test::Unit::TestCase
def test_c
- skip "do nothing"
+ omit "do nothing"
end
def test_b
diff --git a/tool/test/testunit/test4test_timeout.rb b/tool/test/testunit/test4test_timeout.rb
new file mode 100644
index 0000000000..3225f66398
--- /dev/null
+++ b/tool/test/testunit/test4test_timeout.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
+
+require 'test/unit'
+require 'timeout'
+
+class TestForTestTimeout < Test::Unit::TestCase
+ 10.times do |i|
+ define_method("test_timeout_#{i}") do
+ Timeout.timeout(0.001) do
+ sleep
+ end
+ end
+ end
+end
diff --git a/tool/test/testunit/test_assertion.rb b/tool/test/testunit/test_assertion.rb
index 0c7c4882b8..d9bdc8f3c5 100644
--- a/tool/test/testunit/test_assertion.rb
+++ b/tool/test/testunit/test_assertion.rb
@@ -8,6 +8,8 @@ class TestAssertion < Test::Unit::TestCase
end
def test_timeout_separately
+ pend "hang-up" if /mswin|mingw/ =~ RUBY_PLATFORM
+
assert_raise(Timeout::Error) do
assert_separately([], <<~"end;", timeout: 0.1)
sleep
@@ -15,6 +17,29 @@ class TestAssertion < Test::Unit::TestCase
end
end
+ def test_assertion_count_separately
+ beginning = self._assertions
+
+ assert_separately([], "")
+ assertions_at_nothing = self._assertions - beginning
+
+ prev_assertions = self._assertions + assertions_at_nothing
+ assert_separately([], "assert true")
+ assert_equal(1, self._assertions - prev_assertions)
+
+ omit unless Process.respond_to?(:fork)
+ prev_assertions = self._assertions + assertions_at_nothing
+ assert_separately([], "Process.fork {assert true}; assert true")
+ assert_equal(2, self._assertions - prev_assertions)
+
+ prev_assertions = self._assertions + assertions_at_nothing
+ # TODO: assertions before `fork` are counted twice; it is possible
+ # to reset `_assertions` at `Process._fork`, but the hook can
+ # interfere in other tests.
+ assert_separately([], "assert true; Process.fork {assert true}")
+ assert_equal(3, self._assertions - prev_assertions)
+ end
+
def return_in_assert_raise
assert_raise(RuntimeError) do
return
@@ -22,8 +47,182 @@ class TestAssertion < Test::Unit::TestCase
end
def test_assert_raise
- assert_raise(MiniTest::Assertion) do
+ assert_raise(Test::Unit::AssertionFailedError) do
return_in_assert_raise
end
end
+
+ def test_assert_raise_with_message
+ my_error = Class.new(StandardError)
+
+ assert_raise_with_message(my_error, "with message") do
+ raise my_error, "with message"
+ end
+
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_raise_with_message(RuntimeError, "with message") do
+ raise my_error, "with message"
+ end
+ end
+
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_raise_with_message(my_error, "without message") do
+ raise my_error, "with message"
+ end
+ end
+ end
+
+ def test_assert_raise_kind_of
+ my_error = Class.new(StandardError)
+
+ assert_raise_kind_of(my_error) do
+ raise my_error
+ end
+
+ assert_raise_kind_of(StandardError) do
+ raise my_error
+ end
+ end
+
+ def test_assert_pattern_list
+ assert_pattern_list([/foo?/], "foo")
+ assert_not_pattern_list([/foo?/], "afoo")
+ assert_not_pattern_list([/foo?/], "foo?")
+ assert_pattern_list([:*, /foo?/, :*], "foo")
+ assert_pattern_list([:*, /foo?/], "afoo")
+ assert_not_pattern_list([:*, /foo?/], "afoo?")
+ assert_pattern_list([/foo?/, :*], "foo?")
+
+ assert_not_pattern_list(["foo?"], "foo")
+ assert_not_pattern_list(["foo?"], "afoo")
+ assert_pattern_list(["foo?"], "foo?")
+ assert_not_pattern_list([:*, "foo?", :*], "foo")
+ assert_not_pattern_list([:*, "foo?"], "afoo")
+ assert_pattern_list([:*, "foo?"], "afoo?")
+ assert_pattern_list(["foo?", :*], "foo?")
+ end
+
+ def assert_not_pattern_list(pattern_list, actual, message=nil)
+ assert_raise(Test::Unit::AssertionFailedError) do
+ assert_pattern_list(pattern_list, actual, message)
+ end
+ end
+
+ def test_caller_bactrace_location
+ begin
+ line = __LINE__; assert_fail_for_backtrace_location
+ rescue Test::Unit::AssertionFailedError => e
+ end
+ location = Test::Unit::Runner.new.location(e)
+ assert_equal "#{__FILE__}:#{line}", location
+ end
+
+ def assert_fail_for_backtrace_location
+ assert false
+ end
+
+ VersionClass = Struct.new(:version) do
+ def version?(*ver)
+ Test::Unit::CoreAssertions.version_match?(ver, self.version)
+ end
+ end
+
+ V14_6_0 = VersionClass.new([14, 6, 0])
+ V15_0_0 = VersionClass.new([15, 0, 0])
+
+ def test_version_match_integer
+ assert_not_operator(V14_6_0, :version?, 13)
+ assert_operator(V14_6_0, :version?, 14)
+ assert_not_operator(V14_6_0, :version?, 15)
+ assert_not_operator(V15_0_0, :version?, 14)
+ assert_operator(V15_0_0, :version?, 15)
+ end
+
+ def test_version_match_integer_range
+ assert_operator(V14_6_0, :version?, 13..14)
+ assert_not_operator(V15_0_0, :version?, 13..14)
+ assert_not_operator(V14_6_0, :version?, 13...14)
+ assert_not_operator(V15_0_0, :version?, 13...14)
+ end
+
+ def test_version_match_array_range
+ assert_operator(V14_6_0, :version?, [14, 0]..[14, 6])
+ assert_not_operator(V15_0_0, :version?, [14, 0]..[14, 6])
+ assert_not_operator(V14_6_0, :version?, [14, 0]...[14, 6])
+ assert_not_operator(V15_0_0, :version?, [14, 0]...[14, 6])
+ assert_operator(V14_6_0, :version?, [14, 0]..[15])
+ assert_operator(V15_0_0, :version?, [14, 0]..[15])
+ assert_operator(V14_6_0, :version?, [14, 0]...[15])
+ assert_not_operator(V15_0_0, :version?, [14, 0]...[15])
+ end
+
+ def test_version_match_integer_endless_range
+ assert_operator(V14_6_0, :version?, 14..)
+ assert_operator(V15_0_0, :version?, 14..)
+ assert_not_operator(V14_6_0, :version?, 15..)
+ assert_operator(V15_0_0, :version?, 15..)
+ end
+
+ def test_version_match_integer_endless_range_exclusive
+ assert_operator(V14_6_0, :version?, 14...)
+ assert_operator(V15_0_0, :version?, 14...)
+ assert_not_operator(V14_6_0, :version?, 15...)
+ assert_operator(V15_0_0, :version?, 15...)
+ end
+
+ def test_version_match_array_endless_range
+ assert_operator(V14_6_0, :version?, [14, 5]..)
+ assert_operator(V15_0_0, :version?, [14, 5]..)
+ assert_not_operator(V14_6_0, :version?, [14, 7]..)
+ assert_operator(V15_0_0, :version?, [14, 7]..)
+ assert_not_operator(V14_6_0, :version?, [15]..)
+ assert_operator(V15_0_0, :version?, [15]..)
+ assert_not_operator(V14_6_0, :version?, [15, 0]..)
+ assert_operator(V15_0_0, :version?, [15, 0]..)
+ end
+
+ def test_version_match_array_endless_range_exclude_end
+ assert_operator(V14_6_0, :version?, [14, 5]...)
+ assert_operator(V15_0_0, :version?, [14, 5]...)
+ assert_not_operator(V14_6_0, :version?, [14, 7]...)
+ assert_operator(V15_0_0, :version?, [14, 7]...)
+ assert_not_operator(V14_6_0, :version?, [15]...)
+ assert_operator(V15_0_0, :version?, [15]...)
+ assert_not_operator(V14_6_0, :version?, [15, 0]...)
+ assert_operator(V15_0_0, :version?, [15, 0]...)
+ end
+
+ def test_version_match_integer_beginless_range
+ assert_operator(V14_6_0, :version?, ..14)
+ assert_not_operator(V15_0_0, :version?, ..14)
+ assert_operator(V14_6_0, :version?, ..15)
+ assert_operator(V15_0_0, :version?, ..15)
+
+ assert_not_operator(V14_6_0, :version?, ...14)
+ assert_not_operator(V15_0_0, :version?, ...14)
+ assert_operator(V14_6_0, :version?, ...15)
+ assert_not_operator(V15_0_0, :version?, ...15)
+ end
+
+ def test_version_match_array_beginless_range
+ assert_not_operator(V14_6_0, :version?, ..[14, 5])
+ assert_not_operator(V15_0_0, :version?, ..[14, 5])
+ assert_operator(V14_6_0, :version?, ..[14, 6])
+ assert_not_operator(V15_0_0, :version?, ..[14, 6])
+ assert_operator(V14_6_0, :version?, ..[15])
+ assert_operator(V15_0_0, :version?, ..[15])
+ assert_operator(V14_6_0, :version?, ..[15, 0])
+ assert_operator(V15_0_0, :version?, ..[15, 0])
+ end
+
+ def test_version_match_array_beginless_range_exclude_end
+ assert_not_operator(V14_6_0, :version?, ...[14, 5])
+ assert_not_operator(V15_0_0, :version?, ...[14, 5])
+ assert_not_operator(V14_6_0, :version?, ...[14, 6])
+ assert_not_operator(V15_0_0, :version?, ...[14, 6])
+ assert_operator(V14_6_0, :version?, ...[15])
+ assert_not_operator(V15_0_0, :version?, ...[15])
+ assert_operator(V14_6_0, :version?, ...[15, 0])
+ assert_not_operator(V15_0_0, :version?, ...[15, 0])
+ end
end
diff --git a/tool/test/testunit/test_hideskip.rb b/tool/test/testunit/test_hideskip.rb
index 0188316a2c..a470368bca 100644
--- a/tool/test/testunit/test_hideskip.rb
+++ b/tool/test/testunit/test_hideskip.rb
@@ -4,16 +4,15 @@ require 'test/unit'
class TestHideSkip < Test::Unit::TestCase
def test_hideskip
assert_not_match(/^ *1\) Skipped/, hideskip)
- assert_match(/^ *1\) Skipped/, hideskip("--show-skip"))
+ assert_match(/^ *1\) Skipped.*^ *2\) Skipped/m, hideskip("--show-skip"))
output = hideskip("--hide-skip")
- output.gsub!(/Successful MJIT finish\n/, '') if RubyVM::MJIT.enabled?
- assert_match(/assertions\/s.\n+1 tests, 0 assertions, 0 failures, 0 errors, 1 skips/, output)
+ assert_match(/assertions\/s.\n+2 tests, 0 assertions, 0 failures, 0 errors, 2 skips/, output)
end
private
def hideskip(*args)
- IO.popen([*@options[:ruby], "#{File.dirname(__FILE__)}/test4test_hideskip.rb",
+ IO.popen([*@__runner_options__[:ruby], "#{File.dirname(__FILE__)}/test4test_hideskip.rb",
"--verbose", *args], err: [:child, :out]) {|f|
f.read
}
diff --git a/tool/test/testunit/test_launchable.rb b/tool/test/testunit/test_launchable.rb
new file mode 100644
index 0000000000..76be876456
--- /dev/null
+++ b/tool/test/testunit/test_launchable.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'tempfile'
+require 'json'
+require_relative '../../lib/launchable'
+
+class TestLaunchable < Test::Unit::TestCase
+ def test_json_stream_writer
+ Tempfile.create(['launchable-test-', '.json']) do |f|
+ json_stream_writer = Launchable::JsonStreamWriter.new(f.path)
+ json_stream_writer.write_array('testCases')
+ json_stream_writer.write_object(
+ {
+ testPath: "file=test/test_a.rb#class=class1#testcase=testcase899",
+ duration: 42,
+ status: "TEST_FAILED",
+ stdout: nil,
+ stderr: nil,
+ createdAt: "2021-10-05T12:34:00",
+ data: {
+ lineNumber: 1
+ }
+ }
+ )
+ json_stream_writer.write_object(
+ {
+ testPath: "file=test/test_a.rb#class=class1#testcase=testcase899",
+ duration: 45,
+ status: "TEST_PASSED",
+ stdout: "This is stdout",
+ stderr: "This is stderr",
+ createdAt: "2021-10-05T12:36:00",
+ data: {
+ lineNumber: 10
+ }
+ }
+ )
+ json_stream_writer.close()
+ expected = <<JSON
+{
+ "testCases": [
+ {
+ "testPath": "file=test/test_a.rb#class=class1#testcase=testcase899",
+ "duration": 42,
+ "status": "TEST_FAILED",
+ "stdout": null,
+ "stderr": null,
+ "createdAt": "2021-10-05T12:34:00",
+ "data": {
+ "lineNumber": 1
+ }
+ },
+ {
+ "testPath": "file=test/test_a.rb#class=class1#testcase=testcase899",
+ "duration": 45,
+ "status": "TEST_PASSED",
+ "stdout": "This is stdout",
+ "stderr": "This is stderr",
+ "createdAt": "2021-10-05T12:36:00",
+ "data": {
+ "lineNumber": 10
+ }
+ }
+ ]
+}
+JSON
+ assert_equal(expected, f.read)
+ end
+ end
+end
diff --git a/tool/test/testunit/test_load_failure.rb b/tool/test/testunit/test_load_failure.rb
new file mode 100644
index 0000000000..8defa9e39a
--- /dev/null
+++ b/tool/test/testunit/test_load_failure.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+require 'test/unit'
+
+class TestLoadFailure < Test::Unit::TestCase
+ def test_load_failure
+ assert_not_predicate(load_failure, :success?)
+ end
+
+ def test_load_failure_parallel
+ assert_not_predicate(load_failure("-j2"), :success?)
+ end
+
+ private
+
+ def load_failure(*args)
+ IO.popen([*@__runner_options__[:ruby], "#{__dir__}/../runner.rb",
+ "#{__dir__}/test4test_load_failure.rb",
+ "--verbose", *args], err: [:child, :out]) {|f|
+ assert_include(f.read, "test4test_load_failure.rb")
+ }
+ $?
+ end
+end
diff --git a/tool/test/minitest/test_minitest_unit.rb b/tool/test/testunit/test_minitest_unit.rb
index 1286b15372..84b6cf688c 100644
--- a/tool/test/minitest/test_minitest_unit.rb
+++ b/tool/test/testunit/test_minitest_unit.rb
@@ -10,7 +10,7 @@ class ImmutableString < String; def inspect; super.freeze; end; end
class TestMiniTestUnit < MetaMetaMetaTestCase
pwd = Pathname.new File.expand_path Dir.pwd
- basedir = Pathname.new(File.expand_path "lib/minitest") + 'mini'
+ basedir = Pathname.new(File.expand_path "lib/test")
basedir = basedir.relative_path_from(pwd).to_s
MINITEST_BASE_DIR = basedir[/\A\./] ? basedir : "./#{basedir}"
BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:161:in `each'",
@@ -19,7 +19,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
"#{MINITEST_BASE_DIR}/test.rb:106:in `run'"]
def test_class_puke_with_assertion_failed
- exception = MiniTest::Assertion.new "Oh no!"
+ exception = Test::Unit::AssertionFailedError.new "Oh no!"
exception.set_backtrace ["unhappy"]
assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
assert_equal 1, @tu.failures
@@ -29,7 +29,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
def test_class_puke_with_assertion_failed_and_long_backtrace
bt = (["test/test_some_class.rb:615:in `method_name'",
- "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raise'",
"test/test_some_class.rb:615:in `each'",
"test/test_some_class.rb:614:in `test_method_name'",
"#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
@@ -39,7 +39,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
- exception = MiniTest::Assertion.new "Oh no!"
+ exception = Test::Unit::AssertionFailedError.new "Oh no!"
exception.set_backtrace bt
assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
assert_equal 1, @tu.failures
@@ -49,7 +49,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
def test_class_puke_with_assertion_failed_and_user_defined_assertions
bt = (["lib/test/my/util.rb:16:in `another_method_name'",
- "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raise'",
"lib/test/my/util.rb:15:in `block in assert_something'",
"lib/test/my/util.rb:14:in `each'",
"lib/test/my/util.rb:14:in `assert_something'",
@@ -62,7 +62,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
- exception = MiniTest::Assertion.new "Oh no!"
+ exception = Test::Unit::AssertionFailedError.new "Oh no!"
exception.set_backtrace bt
assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
assert_equal 1, @tu.failures
@@ -72,8 +72,8 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
def test_class_puke_with_failure_and_flunk_in_backtrace
exception = begin
- MiniTest::Unit::TestCase.new('fake tc').flunk
- rescue MiniTest::Assertion => failure
+ Test::Unit::TestCase.new('fake tc').flunk
+ rescue Test::Unit::AssertionFailedError => failure
failure
end
assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
@@ -82,7 +82,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
def test_class_puke_with_flunk_and_user_defined_assertions
bt = (["lib/test/my/util.rb:16:in `flunk'",
- "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
+ "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raise'",
"lib/test/my/util.rb:15:in `block in assert_something'",
"lib/test/my/util.rb:14:in `each'",
"lib/test/my/util.rb:14:in `assert_something'",
@@ -95,7 +95,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
- exception = MiniTest::Assertion.new "Oh no!"
+ exception = Test::Unit::AssertionFailedError.new "Oh no!"
exception.set_backtrace bt
assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
assert_equal 1, @tu.failures
@@ -125,7 +125,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
"test/test_autotest.rb:62:in `test_add_exception'"]
ex = util_expand_bt ex
- fu = MiniTest::filter_backtrace(bt)
+ fu = Test::filter_backtrace(bt)
assert_equal ex, fu
end
@@ -135,7 +135,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
BT_MIDDLE +
["#{MINITEST_BASE_DIR}/test.rb:29"])
ex = bt.clone
- fu = MiniTest::filter_backtrace(bt)
+ fu = Test::filter_backtrace(bt)
assert_equal ex, fu
end
@@ -148,17 +148,17 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
bt = util_expand_bt bt
ex = ["-e:1"]
- fu = MiniTest::filter_backtrace bt
+ fu = Test::filter_backtrace bt
assert_equal ex, fu
end
def test_default_runner_is_minitest_unit
- assert_instance_of MiniTest::Unit, MiniTest::Unit.runner
+ assert_instance_of Test::Unit::Runner, Test::Unit::Runner.runner
end
def test_passed_eh_teardown_good
- test_class = Class.new MiniTest::Unit::TestCase do
+ test_class = Class.new Test::Unit::TestCase do
def teardown; assert true; end
def test_omg; assert true; end
end
@@ -169,9 +169,9 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
end
def test_passed_eh_teardown_skipped
- test_class = Class.new MiniTest::Unit::TestCase do
+ test_class = Class.new Test::Unit::TestCase do
def teardown; assert true; end
- def test_omg; skip "bork"; end
+ def test_omg; omit "bork"; end
end
test = test_class.new :test_omg
@@ -180,7 +180,7 @@ class TestMiniTestUnit < MetaMetaMetaTestCase
end
def test_passed_eh_teardown_flunked
- test_class = Class.new MiniTest::Unit::TestCase do
+ test_class = Class.new Test::Unit::TestCase do
def teardown; flunk; end
def test_omg; assert true; end
end
@@ -223,7 +223,7 @@ class TestMiniTestUnitInherited < MetaMetaMetaTestCase
def test_inherited_hook_plays_nice_with_others
with_overridden_include do
assert_throws :inherited_hook do
- Class.new MiniTest::Unit::TestCase
+ Class.new Test::Unit::TestCase
end
end
end
@@ -235,151 +235,23 @@ class TestMiniTestRunner < MetaMetaMetaTestCase
def test_class_test_suites
@assertion_count = 0
- tc = Class.new(MiniTest::Unit::TestCase)
+ tc = Class.new(Test::Unit::TestCase)
- assert_equal 1, MiniTest::Unit::TestCase.test_suites.size
- assert_equal [tc], MiniTest::Unit::TestCase.test_suites
- end
-
- def test_run_test
- Class.new MiniTest::Unit::TestCase do
- attr_reader :foo
-
- def run_test name
- @foo = "hi mom!"
- super
- @foo = "okay"
- end
-
- def test_something
- assert_equal "hi mom!", foo
- end
- end
-
- expected = clean <<-EOM
- .
-
- Finished tests in 0.00
-
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_error
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def test_error
- raise "unhandled exception"
- end
- end
-
- expected = clean <<-EOM
- E.
-
- Finished tests in 0.00
-
- 1) Error:
- #<Class:0xXXX>#test_error:
- RuntimeError: unhandled exception
- FILE:LINE:in \`test_error\'
-
- 2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_error_teardown
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def teardown
- raise "unhandled exception"
- end
- end
-
- expected = clean <<-EOM
- E
-
- Finished tests in 0.00
-
- 1) Error:
- #<Class:0xXXX>#test_something:
- RuntimeError: unhandled exception
- FILE:LINE:in \`teardown\'
-
- 1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_failing
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def test_failure
- assert false
- end
- end
-
- expected = clean <<-EOM
- F.
-
- Finished tests in 0.00
-
- 1) Failure:
- #<Class:0xXXX>#test_failure [FILE:LINE]:
- Failed assertion, no message given.
-
- 2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_failing_filtered
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def test_failure
- assert false
- end
- end
-
- expected = clean <<-EOM
- .
-
- Finished tests in 0.00
-
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_report expected, %w[--name /some|thing/ --seed 42]
+ assert_equal 2, Test::Unit::TestCase.test_suites.size
+ assert_equal [tc, Test::Unit::TestCase], Test::Unit::TestCase.test_suites.sort_by {|ts| ts.name.to_s}
end
def assert_filtering name, expected, a = false
args = %W[--name #{name} --seed 42]
- alpha = Class.new MiniTest::Unit::TestCase do
+ alpha = Class.new Test::Unit::TestCase do
define_method :test_something do
assert a
end
end
Object.const_set(:Alpha, alpha)
- beta = Class.new MiniTest::Unit::TestCase do
+ beta = Class.new Test::Unit::TestCase do
define_method :test_something do
assert true
end
@@ -392,123 +264,20 @@ class TestMiniTestRunner < MetaMetaMetaTestCase
Object.send :remove_const, :Beta
end
- def test_run_filtered_including_suite_name
- expected = clean <<-EOM
- .
-
- Finished tests in 0.00
-
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_filtering "/Beta#test_something/", expected
- end
-
- def test_run_filtered_including_suite_name_string
- expected = clean <<-EOM
- .
-
- Finished tests in 0.00
-
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_filtering "Beta#test_something", expected
- end
-
- def test_run_filtered_string_method_only
- expected = clean <<-EOM
- ..
-
- Finished tests in 0.00
-
- 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_filtering "test_something", expected, :pass
- end
-
- def test_run_passing
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
- end
-
- expected = clean <<-EOM
- .
-
- Finished tests in 0.00
-
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_skip
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def test_skip
- skip "not yet"
- end
- end
-
- expected = clean <<-EOM
- S.
-
- Finished tests in 0.00
-
- 2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
- EOM
-
- assert_report expected
- end
-
- def test_run_skip_verbose
- Class.new MiniTest::Unit::TestCase do
- def test_something
- assert true
- end
-
- def test_skip
- skip "not yet"
- end
- end
-
- expected = clean <<-EOM
- #<Class:0xXXX>#test_skip = 0.00 s = S
- #<Class:0xXXX>#test_something = 0.00 s = .
-
-
- Finished tests in 0.00
-
- 1) Skipped:
- #<Class:0xXXX>#test_skip [FILE:LINE]:
- not yet
-
- 2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
- EOM
-
- assert_report expected, %w[--seed 42 --verbose]
- end
-
def test_run_with_other_runner
- MiniTest::Unit.runner = Class.new MiniTest::Unit do
+ pend "We don't imagine to replace the default runner with ruby/ruby test suite."
+ Test::Unit::Runner.runner = Class.new Test::Unit::Runner do
def _run_suite suite, type
suite.before_suite # Run once before each suite
super suite, type
end
end.new
- Class.new MiniTest::Unit::TestCase do
+ Class.new Test::Unit::TestCase do
def self.name; "wacky!" end
def self.before_suite
- MiniTest::Unit.output.puts "Running #{self.name} tests"
+ Test::Unit::Runner.output.puts "Running #{self.name} tests"
@@foo = 1
end
@@ -559,8 +328,10 @@ class TestMiniTestUnitOrder < MetaMetaMetaTestCase
# do not parallelize this suite... it just can't handle it.
def test_before_setup
+ pend "Surpressing the raise message when running with tests"
+
call_order = []
- Class.new MiniTest::Unit::TestCase do
+ Class.new Test::Unit::TestCase do
define_method :setup do
super()
call_order << :setup
@@ -582,8 +353,10 @@ class TestMiniTestUnitOrder < MetaMetaMetaTestCase
end
def test_after_teardown
+ pend "Surpressing the result message of this tests"
+
call_order = []
- Class.new MiniTest::Unit::TestCase do
+ Class.new Test::Unit::TestCase do
define_method :teardown do
super()
call_order << :teardown
@@ -605,8 +378,10 @@ class TestMiniTestUnitOrder < MetaMetaMetaTestCase
end
def test_all_teardowns_are_guaranteed_to_run
+ pend "Surpressing the raise message when running with tests"
+
call_order = []
- Class.new MiniTest::Unit::TestCase do
+ Class.new Test::Unit::TestCase do
define_method :after_teardown do
super()
call_order << :after_teardown
@@ -637,9 +412,11 @@ class TestMiniTestUnitOrder < MetaMetaMetaTestCase
end
def test_setup_and_teardown_survive_inheritance
+ pend "Surpressing the result message of this tests"
+
call_order = []
- parent = Class.new MiniTest::Unit::TestCase do
+ parent = Class.new Test::Unit::TestCase do
define_method :setup do
call_order << :setup_method
end
@@ -666,19 +443,17 @@ class TestMiniTestUnitOrder < MetaMetaMetaTestCase
end
end
-class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
+class TestMiniTestUnitTestCase < Test::Unit::TestCase
# do not call parallelize_me! - teardown accesses @tc._assertions
# which is not threadsafe. Nearly every method in here is an
# assertion test so it isn't worth splitting it out further.
- RUBY18 = ! defined? Encoding
-
def setup
super
- MiniTest::Unit::TestCase.reset
+ Test::Unit::TestCase.reset
- @tc = MiniTest::Unit::TestCase.new 'fake tc'
+ @tc = Test::Unit::TestCase.new 'fake tc'
@zomg = "zomg ponies!"
@assertion_count = 1
end
@@ -736,9 +511,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
def test_assert_equal_different_collection_array_hex_invisible
object1 = Object.new
object2 = Object.new
- msg = "No visible difference in the Array#inspect output.
- You should look at the implementation of #== on Array or its members.
- [#<Object:0xXXXXXX>]".gsub(/^ +/, "")
+ msg = "<[#{object1.inspect}]> expected but was
+ <[#{object2.inspect}]>.".gsub(/^ +/, "")
util_assert_triggered msg do
@tc.assert_equal [object1], [object2]
end
@@ -748,9 +522,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
h1, h2 = {}, {}
h1[1] = Object.new
h2[1] = Object.new
- msg = "No visible difference in the Hash#inspect output.
- You should look at the implementation of #== on Hash or its members.
- {1=>#<Object:0xXXXXXX>}".gsub(/^ +/, "")
+ msg = "<#{h1.inspect}> expected but was
+ <#{h2.inspect}>.".gsub(/^ +/, "")
util_assert_triggered msg do
@tc.assert_equal h1, h2
@@ -758,8 +531,6 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_equal_different_diff_deactivated
- skip "https://github.com/MagLev/maglev/issues/209" if maglev?
-
without_diff do
util_assert_triggered util_msg("haha" * 10, "blah" * 10) do
o1 = "haha" * 10
@@ -777,12 +548,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
o1 = c.new "a"
o2 = c.new "b"
- msg = "--- expected
- +++ actual
- @@ -1 +1 @@
- -#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"a\">
- +#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"b\">
- ".gsub(/^ +/, "")
+ msg = "<#{o1.inspect}> expected but was
+ <#{o2.inspect}>.".gsub(/^ +/, "")
util_assert_triggered msg do
@tc.assert_equal o1, o2
@@ -793,9 +560,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
o1 = Object.new
o2 = Object.new
- msg = "No visible difference in the Object#inspect output.
- You should look at the implementation of #== on Object or its members.
- #<Object:0xXXXXXX>".gsub(/^ +/, "")
+ msg = "<#{o1.inspect}> expected but was
+ <#{o2.inspect}>.".gsub(/^ +/, "")
util_assert_triggered msg do
@tc.assert_equal o1, o2
@@ -803,12 +569,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_equal_different_long
- msg = "--- expected
- +++ actual
- @@ -1 +1 @@
- -\"hahahahahahahahahahahahahahahahahahahaha\"
- +\"blahblahblahblahblahblahblahblahblahblah\"
- ".gsub(/^ +/, "")
+ msg = "<\"hahahahahahahahahahahahahahahahahahahaha\"> expected but was
+ <\"blahblahblahblahblahblahblahblahblahblah\">.".gsub(/^ +/, "")
util_assert_triggered msg do
o1 = "haha" * 10
@@ -819,9 +581,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_equal_different_long_invisible
- msg = "No visible difference in the String#inspect output.
- You should look at the implementation of #== on String or its members.
- \"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
+ msg = "<\"blahblahblahblahblahblahblahblahblahblah\"> (UTF-8) expected but was
+ <\"blahblahblahblahblahblahblahblahblahblah\"> (UTF-8).".gsub(/^ +/, "")
util_assert_triggered msg do
o1 = "blah" * 10
@@ -835,12 +596,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
def test_assert_equal_different_long_msg
msg = "message.
- --- expected
- +++ actual
- @@ -1 +1 @@
- -\"hahahahahahahahahahahahahahahahahahahaha\"
- +\"blahblahblahblahblahblahblahblahblahblah\"
- ".gsub(/^ +/, "")
+ <\"hahahahahahahahahahahahahahahahahahahaha\"> expected but was
+ <\"blahblahblahblahblahblahblahblahblahblah\">.".gsub(/^ +/, "")
util_assert_triggered msg do
o1 = "haha" * 10
@@ -862,14 +619,14 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_equal_different_short_multiline
- msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n"
+ msg = "<\"a\\n\" + \"b\"> expected but was\n<\"a\\n\" + \"c\">."
util_assert_triggered msg do
@tc.assert_equal "a\nb", "a\nc"
end
end
def test_assert_equal_different_escaped_newline
- msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"xxx\n-a\\\\nb\"\n+a\\\\nc\"\n"
+ msg = "<\"xxx\\n\" + \"a\\\\nb\"> expected but was\n<\"xxx\\n\" + \"a\\\\nc\">."
util_assert_triggered msg do
@tc.assert_equal "xxx\na\\nb", "xxx\na\\nc"
end
@@ -888,7 +645,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_in_delta_triggered
- x = maglev? ? "9.999999xxxe-07" : "1.0e-06"
+ x = "1.0e-06"
util_assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
@tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001
end
@@ -927,8 +684,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_in_epsilon_triggered_negative_case
- x = (RUBY18 and not maglev?) ? "0.1" : "0.100000xxx"
- y = maglev? ? "0.100000xxx" : "0.1"
+ x = "0.100000xxx"
+ y = "0.1"
util_assert_triggered "Expected |-1.1 - -1| (#{x}) to be <= #{y}." do
@tc.assert_in_epsilon(-1.1, -1, 0.1)
end
@@ -943,7 +700,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
def test_assert_includes_triggered
@assertion_count = 3
- e = @tc.assert_raises MiniTest::Assertion do
+ e = @tc.assert_raise Test::Unit::AssertionFailedError do
@tc.assert_includes [true], false
end
@@ -1113,14 +870,14 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
end
- def test_assert_raises
- @tc.assert_raises RuntimeError do
+ def test_assert_raise
+ @tc.assert_raise RuntimeError do
raise "blah"
end
end
- def test_assert_raises_module
- @tc.assert_raises MyModule do
+ def test_assert_raise_module
+ @tc.assert_raise MyModule do
raise AnError
end
end
@@ -1131,34 +888,29 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
#
# https://github.com/ruby/ruby/commit/6bab4ea9917dc05cd2c94aead2e96eb7df7d4be1
- def test_assert_raises_skip
+ def test_assert_raise_skip
@assertion_count = 0
- util_assert_triggered "skipped", MiniTest::Skip do
- @tc.assert_raises ArgumentError do
+ util_assert_triggered "skipped", Test::Unit::PendedError do
+ @tc.assert_raise ArgumentError do
begin
raise "blah"
rescue
- skip "skipped"
+ omit "skipped"
end
end
end
end
- def test_assert_raises_triggered_different
- e = assert_raises MiniTest::Assertion do
- @tc.assert_raises RuntimeError do
+ def test_assert_raise_triggered_different
+ e = assert_raise Test::Unit::AssertionFailedError do
+ @tc.assert_raise RuntimeError do
raise SyntaxError, "icky"
end
end
expected = clean <<-EOM.chomp
- [RuntimeError] exception expected, not
- Class: <SyntaxError>
- Message: <\"icky\">
- ---Backtrace---
- FILE:LINE:in \`test_assert_raises_triggered_different\'
- ---------------
+ [RuntimeError] exception expected, not #<SyntaxError: icky>.
EOM
actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
@@ -1167,21 +919,16 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
assert_equal expected, actual
end
- def test_assert_raises_triggered_different_msg
- e = assert_raises MiniTest::Assertion do
- @tc.assert_raises RuntimeError, "XXX" do
+ def test_assert_raise_triggered_different_msg
+ e = assert_raise Test::Unit::AssertionFailedError do
+ @tc.assert_raise RuntimeError, "XXX" do
raise SyntaxError, "icky"
end
end
expected = clean <<-EOM
XXX.
- [RuntimeError] exception expected, not
- Class: <SyntaxError>
- Message: <\"icky\">
- ---Backtrace---
- FILE:LINE:in \`test_assert_raises_triggered_different_msg\'
- ---------------
+ [RuntimeError] exception expected, not #<SyntaxError: icky>.
EOM
actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
@@ -1190,44 +937,39 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
assert_equal expected.chomp, actual
end
- def test_assert_raises_triggered_none
- e = assert_raises MiniTest::Assertion do
- @tc.assert_raises MiniTest::Assertion do
+ def test_assert_raise_triggered_none
+ e = assert_raise Test::Unit::AssertionFailedError do
+ @tc.assert_raise Test::Unit::AssertionFailedError do
# do nothing
end
end
- expected = "MiniTest::Assertion expected but nothing was raised."
+ expected = "Test::Unit::AssertionFailedError expected but nothing was raised."
assert_equal expected, e.message
end
- def test_assert_raises_triggered_none_msg
- e = assert_raises MiniTest::Assertion do
- @tc.assert_raises MiniTest::Assertion, "XXX" do
+ def test_assert_raise_triggered_none_msg
+ e = assert_raise Test::Unit::AssertionFailedError do
+ @tc.assert_raise Test::Unit::AssertionFailedError, "XXX" do
# do nothing
end
end
- expected = "XXX.\nMiniTest::Assertion expected but nothing was raised."
+ expected = "XXX.\nTest::Unit::AssertionFailedError expected but nothing was raised."
assert_equal expected, e.message
end
- def test_assert_raises_triggered_subclass
- e = assert_raises MiniTest::Assertion do
- @tc.assert_raises StandardError do
+ def test_assert_raise_triggered_subclass
+ e = assert_raise Test::Unit::AssertionFailedError do
+ @tc.assert_raise StandardError do
raise AnError
end
end
expected = clean <<-EOM.chomp
- [StandardError] exception expected, not
- Class: <AnError>
- Message: <\"AnError\">
- ---Backtrace---
- FILE:LINE:in \`test_assert_raises_triggered_subclass\'
- ---------------
+ [StandardError] exception expected, not #<AnError: AnError>.
EOM
actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
@@ -1275,7 +1017,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_assert_send_bad
- util_assert_triggered "Expected 1.>(*[2]) to return true." do
+ util_assert_triggered "Expected 1.>(2) to return true." do
@tc.assert_send [1, :>, 2]
end
end
@@ -1328,11 +1070,11 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
end
- def test_capture_io
+ def test_capture_output
@assertion_count = 0
non_verbose do
- out, err = capture_io do
+ out, err = capture_output do
puts 'hi'
$stderr.puts 'bye!'
end
@@ -1342,43 +1084,6 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
end
- def test_capture_subprocess_io
- @assertion_count = 0
-
- non_verbose do
- out, err = capture_subprocess_io do
- system("echo", "hi")
- system("echo", "bye!", out: :err)
- end
-
- assert_equal "hi\n", out
- assert_equal "bye!\n", err
- end
- end
-
- def test_class_asserts_match_refutes
- @assertion_count = 0
-
- methods = MiniTest::Assertions.public_instance_methods
- methods.map! { |m| m.to_s } if Symbol === methods.first
-
- # These don't have corresponding refutes _on purpose_. They're
- # useless and will never be added, so don't bother.
- ignores = %w[assert_output assert_raises assert_send
- assert_silent assert_throws]
-
- # These are test/unit methods. I'm not actually sure why they're still here
- ignores += %w[assert_no_match assert_not_equal assert_not_nil
- assert_not_same assert_nothing_raised
- assert_nothing_thrown assert_raise]
-
- asserts = methods.grep(/^assert/).sort - ignores
- refutes = methods.grep(/^refute/).sort - ignores
-
- assert_empty refutes.map { |n| n.sub(/^refute/, 'assert') } - asserts
- assert_empty asserts.map { |n| n.sub(/^assert/, 'refute') } - refutes
- end
-
def test_flunk
util_assert_triggered 'Epic Fail!' do
@tc.flunk
@@ -1407,13 +1112,13 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_message_message
- util_assert_triggered "whoops.\nExpected: 1\n Actual: 2" do
+ util_assert_triggered "whoops.\n<1> expected but was\n<2>." do
@tc.assert_equal 1, 2, message { "whoops" }
end
end
def test_message_lambda
- util_assert_triggered "whoops.\nExpected: 1\n Actual: 2" do
+ util_assert_triggered "whoops.\n<1> expected but was\n<2>." do
@tc.assert_equal 1, 2, lambda { "whoops" }
end
end
@@ -1435,7 +1140,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_prints
- printer = Class.new { extend MiniTest::Assertions }
+ printer = Class.new { extend Test::Unit::CoreAssertions }
@tc.assert_equal '"test"', printer.mu_pp(ImmutableString.new 'test')
end
@@ -1474,7 +1179,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
def test_refute_in_delta_triggered
- x = maglev? ? "0.100000xxx" : "0.1"
+ x = "0.1"
util_assert_triggered "Expected |0.0 - 0.001| (0.001) to not be <= #{x}." do
@tc.refute_in_delta 0.0, 1.0 / 1000, 0.1
end
@@ -1500,7 +1205,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
def test_refute_includes_triggered
@assertion_count = 3
- e = @tc.assert_raises MiniTest::Assertion do
+ e = @tc.assert_raise Test::Unit::AssertionFailedError do
@tc.refute_includes [true], true
end
@@ -1618,46 +1323,37 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
end
end
- def test_skip
+ def test_omit
@assertion_count = 0
- util_assert_triggered "haha!", MiniTest::Skip do
- @tc.skip "haha!"
+ util_assert_triggered "haha!", Test::Unit::PendedError do
+ @tc.omit "haha!"
end
end
- def test_test_methods_random
+ def test_pend
@assertion_count = 0
- sample_test_case = Class.new MiniTest::Unit::TestCase do
- def self.test_order; :random; end
- def test_test1; assert "does not matter" end
- def test_test2; assert "does not matter" end
- def test_test3; assert "does not matter" end
- @test_order = [1, 0, 2]
- def self.rand(n) @test_order.shift; end
+ util_assert_triggered "haha!", Test::Unit::PendedError do
+ @tc.pend "haha!"
end
-
- expected = %w(test_test2 test_test1 test_test3)
- assert_equal expected, sample_test_case.test_methods
end
- def test_test_methods_sorted
+ def test_test_methods
@assertion_count = 0
- sample_test_case = Class.new MiniTest::Unit::TestCase do
- def self.test_order; :sorted end
- def test_test3; assert "does not matter" end
- def test_test2; assert "does not matter" end
+ sample_test_case = Class.new Test::Unit::TestCase do
def test_test1; assert "does not matter" end
+ def test_test2; assert "does not matter" end
+ def test_test3; assert "does not matter" end
end
- expected = %w(test_test1 test_test2 test_test3)
- assert_equal expected, sample_test_case.test_methods
+ expected = %i(test_test1 test_test2 test_test3)
+ assert_equal expected, sample_test_case.test_methods.sort
end
- def assert_triggered expected, klass = MiniTest::Assertion
- e = assert_raises klass do
+ def assert_triggered expected, klass = Test::Unit::AssertionFailedError
+ e = assert_raise klass do
yield
end
@@ -1670,22 +1366,22 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
alias util_assert_triggered assert_triggered
def util_msg exp, act, msg = nil
- s = "Expected: #{exp.inspect}\n Actual: #{act.inspect}"
+ s = "<#{exp.inspect}> expected but was\n<#{act.inspect}>."
s = "#{msg}.\n#{s}" if msg
s
end
def without_diff
- old_diff = MiniTest::Assertions.diff
- MiniTest::Assertions.diff = nil
+ old_diff = Test::Unit::Assertions.diff
+ Test::Unit::Assertions.diff = nil
yield
ensure
- MiniTest::Assertions.diff = old_diff
+ Test::Unit::Assertions.diff = old_diff
end
end
-class TestMiniTestGuard < MiniTest::Unit::TestCase
+class TestMiniTestGuard < Test::Unit::TestCase
def test_mri_eh
assert self.class.mri? "ruby blah"
assert self.mri? "ruby blah"
@@ -1696,11 +1392,6 @@ class TestMiniTestGuard < MiniTest::Unit::TestCase
assert self.jruby? "java"
end
- def test_rubinius_eh
- assert self.class.rubinius? "rbx"
- assert self.rubinius? "rbx"
- end
-
def test_windows_eh
assert self.class.windows? "mswin"
assert self.windows? "mswin"
@@ -1711,6 +1402,7 @@ class TestMiniTestUnitRecording < MetaMetaMetaTestCase
# do not parallelize this suite... it just can't handle it.
def assert_run_record(*expected, &block)
+ pend "Test::Unit::Runner#run was changed about recoding feature. We should fix it."
def @tu.record suite, method, assertions, time, error
recording[method] << error
end
@@ -1719,9 +1411,9 @@ class TestMiniTestUnitRecording < MetaMetaMetaTestCase
@recording ||= Hash.new { |h,k| h[k] = [] }
end
- MiniTest::Unit.runner = @tu
+ Test::Unit::Runner.runner = @tu
- Class.new MiniTest::Unit::TestCase, &block
+ Class.new Test::Unit::TestCase, &block
with_output do
@tu.run
@@ -1741,7 +1433,7 @@ class TestMiniTestUnitRecording < MetaMetaMetaTestCase
end
def test_record_failing
- assert_run_record MiniTest::Assertion do
+ assert_run_record Test::Unit::AssertionFailedError do
def test_method
assert false
end
@@ -1781,9 +1473,15 @@ class TestMiniTestUnitRecording < MetaMetaMetaTestCase
end
def test_record_skip
- assert_run_record MiniTest::Skip do
+ assert_run_record Test::Unit::PendedError do
+ def test_method
+ omit "not yet"
+ end
+ end
+
+ assert_run_record Test::Unit::PendedError do
def test_method
- skip "not yet"
+ pend "not yet"
end
end
end
diff --git a/tool/test/testunit/test_parallel.rb b/tool/test/testunit/test_parallel.rb
index 2cb85ad3e0..adf7d62ecd 100644
--- a/tool/test/testunit/test_parallel.rb
+++ b/tool/test/testunit/test_parallel.rb
@@ -3,17 +3,25 @@ require 'test/unit'
require 'timeout'
module TestParallel
- PARALLEL_RB = "#{File.dirname(__FILE__)}/../../lib/test/unit/parallel.rb"
- TESTS = "#{File.dirname(__FILE__)}/tests_for_parallel"
+ PARALLEL_RB = "#{__dir__}/../../lib/test/unit/parallel.rb"
+ TESTS = "#{__dir__}/tests_for_parallel"
# use large timeout for --jit-wait
- TIMEOUT = EnvUtil.apply_timeout_scale(RubyVM::MJIT.enabled? ? 100 : 30)
+ TIMEOUT = EnvUtil.apply_timeout_scale(100)
+
+ def self.timeout(n, &blk)
+ start_time = Time.now
+ Timeout.timeout(n, &blk)
+ rescue Timeout::Error
+ end_time = Time.now
+ raise Timeout::Error, "execution expired (start: #{ start_time }, end: #{ end_time })"
+ end
class TestParallelWorker < Test::Unit::TestCase
def setup
i, @worker_in = IO.pipe
@worker_out, o = IO.pipe
- @worker_pid = spawn(*@options[:ruby], PARALLEL_RB,
- "--ruby", @options[:ruby].join(" "),
+ @worker_pid = spawn(*@__runner_options__[:ruby], PARALLEL_RB,
+ "--ruby", @__runner_options__[:ruby].join(" "),
"-j", "t1", "-v", out: o, in: i)
[i,o].each(&:close)
end
@@ -22,10 +30,10 @@ module TestParallel
if @worker_pid && @worker_in
begin
begin
- @worker_in.puts "quit"
+ @worker_in.puts "quit normal"
rescue IOError, Errno::EPIPE
end
- Timeout.timeout(2) do
+ ::TestParallel.timeout(2) do
Process.waitpid(@worker_pid)
end
rescue Timeout::Error
@@ -45,10 +53,11 @@ module TestParallel
end
def test_run
- Timeout.timeout(TIMEOUT) do
+ ::TestParallel.timeout(TIMEOUT) do
assert_match(/^ready/,@worker_out.gets)
@worker_in.puts "run #{TESTS}/ptest_first.rb test"
assert_match(/^okay/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
@@ -57,13 +66,15 @@ module TestParallel
end
def test_run_multiple_testcase_in_one_file
- Timeout.timeout(TIMEOUT) do
+ ::TestParallel.timeout(TIMEOUT) do
assert_match(/^ready/,@worker_out.gets)
@worker_in.puts "run #{TESTS}/ptest_second.rb test"
assert_match(/^okay/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
@@ -72,19 +83,22 @@ module TestParallel
end
def test_accept_run_command_multiple_times
- Timeout.timeout(TIMEOUT) do
+ ::TestParallel.timeout(TIMEOUT) do
assert_match(/^ready/,@worker_out.gets)
@worker_in.puts "run #{TESTS}/ptest_first.rb test"
assert_match(/^okay/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
assert_match(/^ready/,@worker_out.gets)
@worker_in.puts "run #{TESTS}/ptest_second.rb test"
assert_match(/^okay/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
+ assert_match(/^start/,@worker_out.gets)
assert_match(/^record/,@worker_out.gets)
assert_match(/^p/,@worker_out.gets)
assert_match(/^done/,@worker_out.gets)
@@ -93,59 +107,62 @@ module TestParallel
end
def test_p
- Timeout.timeout(TIMEOUT) do
+ ::TestParallel.timeout(TIMEOUT) do
@worker_in.puts "run #{TESTS}/ptest_first.rb test"
while buf = @worker_out.gets
break if /^p (.+?)$/ =~ buf
end
- assert_match(/TestA#test_nothing_test = \d+\.\d+ s = \.\n/, $1.chomp.unpack("m")[0])
+ assert_not_nil($1, "'p' was not found")
+ assert_match(/TestA#test_nothing_test = \d+\.\d+ s = \.\n/, $1.chomp.unpack1("m"))
end
end
def test_done
- Timeout.timeout(TIMEOUT) do
+ ::TestParallel.timeout(TIMEOUT) do
@worker_in.puts "run #{TESTS}/ptest_forth.rb test"
while buf = @worker_out.gets
break if /^done (.+?)$/ =~ buf
end
-
- result = Marshal.load($1.chomp.unpack("m")[0])
-
- assert_equal(5, result[0])
- assert_equal(2, result[1])
- assert_kind_of(Array,result[2])
- assert_kind_of(Array,result[3])
- assert_kind_of(Array,result[4])
- assert_kind_of(Array,result[2][1])
- assert_kind_of(MiniTest::Assertion,result[2][0][2])
- assert_kind_of(MiniTest::Skip,result[2][1][2])
- assert_kind_of(MiniTest::Skip,result[2][2][2])
- assert_kind_of(Exception, result[2][3][2])
- assert_equal(result[5], "TestE")
+ assert_not_nil($1, "'done' was not found")
+
+ result = Marshal.load($1.chomp.unpack1("m"))
+ tests, asserts, reports, failures, loadpaths, suite = result
+ assert_equal(5, tests)
+ assert_equal(12, asserts)
+ assert_kind_of(Array, reports)
+ assert_kind_of(Array, failures)
+ assert_kind_of(Array, loadpaths)
+ reports.sort_by! {|_, t| t}
+ assert_kind_of(Array, reports[1])
+ assert_kind_of(Test::Unit::AssertionFailedError, reports[0][2])
+ assert_kind_of(Test::Unit::PendedError, reports[1][2])
+ assert_kind_of(Test::Unit::PendedError, reports[2][2])
+ assert_kind_of(Exception, reports[3][2])
+ assert_equal("TestE", suite)
end
end
def test_quit
- Timeout.timeout(TIMEOUT) do
- @worker_in.puts "quit"
+ ::TestParallel.timeout(TIMEOUT) do
+ @worker_in.puts "quit normal"
assert_match(/^bye$/m,@worker_out.read)
end
end
end
class TestParallel < Test::Unit::TestCase
- def spawn_runner(*opt_args)
+ def spawn_runner(*opt_args, jobs: "t1", env: {})
@test_out, o = IO.pipe
- @test_pid = spawn(*@options[:ruby], TESTS+"/runner.rb",
- "--ruby", @options[:ruby].join(" "),
- "-j","t1",*opt_args, out: o, err: o)
+ @test_pid = spawn(env, *@__runner_options__[:ruby], TESTS+"/runner.rb",
+ "--ruby", @__runner_options__[:ruby].join(" "),
+ "-j", jobs, *opt_args, out: o, err: o)
o.close
end
def teardown
begin
if @test_pid
- Timeout.timeout(2) do
+ ::TestParallel.timeout(2) do
Process.waitpid(@test_pid)
end
end
@@ -157,47 +174,50 @@ module TestParallel
end
def test_ignore_jzero
- @test_out, o = IO.pipe
- @test_pid = spawn(*@options[:ruby], TESTS+"/runner.rb",
- "--ruby", @options[:ruby].join(" "),
- "-j","0", out: File::NULL, err: o)
- o.close
- Timeout.timeout(TIMEOUT) {
+ spawn_runner(jobs: "0")
+ ::TestParallel.timeout(TIMEOUT) {
assert_match(/Error: parameter of -j option should be greater than 0/,@test_out.read)
}
end
def test_should_run_all_without_any_leaks
spawn_runner
- buf = Timeout.timeout(TIMEOUT) {@test_out.read}
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
assert_match(/^9 tests/,buf)
end
def test_should_retry_failed_on_workers
- spawn_runner
- buf = Timeout.timeout(TIMEOUT) {@test_out.read}
+ spawn_runner "--retry"
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
assert_match(/^Retrying\.+$/,buf)
end
def test_no_retry_option
spawn_runner "--no-retry"
- buf = Timeout.timeout(TIMEOUT) {@test_out.read}
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
refute_match(/^Retrying\.+$/,buf)
assert_match(/^ +\d+\) Failure:\nTestD#test_fail_at_worker/,buf)
end
def test_jobs_status
spawn_runner "--jobs-status"
- buf = Timeout.timeout(TIMEOUT) {@test_out.read}
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
assert_match(/\d+=ptest_(first|second|third|forth) */,buf)
end
def test_separate
# this test depends to --jobs-status
spawn_runner "--jobs-status", "--separate"
- buf = Timeout.timeout(TIMEOUT) {@test_out.read}
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
assert(buf.scan(/^\[\s*\d+\/\d+\]\s*(\d+?)=/).flatten.uniq.size > 1,
message("retried tests should run in different processes") {buf})
end
+
+ def test_hungup
+ spawn_runner("--worker-timeout=1", "--retry", "test4test_hungup.rb", env: {"RUBY_CRASH_REPORT"=>nil})
+ buf = ::TestParallel.timeout(TIMEOUT) {@test_out.read}
+ assert_match(/^Retrying hung up testcases\.+$/, buf)
+ assert_match(/^2 tests,.* 0 failures,/, buf)
+ end
end
end
diff --git a/tool/test/testunit/test_redefinition.rb b/tool/test/testunit/test_redefinition.rb
index 9129e55489..b4f5cabd4f 100644
--- a/tool/test/testunit/test_redefinition.rb
+++ b/tool/test/testunit/test_redefinition.rb
@@ -3,14 +3,9 @@ require 'test/unit'
class TestRedefinition < Test::Unit::TestCase
def test_redefinition
- assert_match(/^test\/unit warning: method TestForTestRedefinition#test_redefinition is redefined$/,
- redefinition)
- end
-
- def redefinition(*args)
- IO.popen([*@options[:ruby], "#{File.dirname(__FILE__)}/test4test_redefinition.rb", *args],
- err: [:child, :out]) {|f|
- f.read
- }
+ message = %r[test/unit: method TestForTestRedefinition#test_redefinition is redefined$]
+ assert_raise_with_message(Test::Unit::AssertionFailedError, message) do
+ require_relative("test4test_redefinition.rb")
+ end
end
end
diff --git a/tool/test/testunit/test_sorting.rb b/tool/test/testunit/test_sorting.rb
index f9de3ec154..3e5d7bfdcc 100644
--- a/tool/test/testunit/test_sorting.rb
+++ b/tool/test/testunit/test_sorting.rb
@@ -10,9 +10,66 @@ class TestTestUnitSorting < Test::Unit::TestCase
end
def sorting(*args)
- IO.popen([*@options[:ruby], "#{File.dirname(__FILE__)}/test4test_sorting.rb",
+ IO.popen([*@__runner_options__[:ruby], "#{File.dirname(__FILE__)}/test4test_sorting.rb",
"--verbose", *args], err: [:child, :out]) {|f|
f.read
}
end
+
+ Item = Struct.new(:name)
+ SEED = 0x50975eed
+
+ def make_test_list
+ (1..16).map {"test_%.3x" % rand(0x1000)}.freeze
+ end
+
+ def test_sort_alpha
+ sorter = Test::Unit::Order::Types[:alpha].new(SEED)
+ assert_kind_of(Test::Unit::Order::Types[:sorted], sorter)
+
+ list = make_test_list
+ sorted = list.sort
+ 16.times do
+ assert_equal(sorted, sorter.sort_by_string(list))
+ end
+
+ list = list.map {|s| Item.new(s)}.freeze
+ sorted = list.sort_by(&:name)
+ 16.times do
+ assert_equal(sorted, sorter.sort_by_name(list))
+ end
+ end
+
+ def test_sort_nosort
+ sorter = Test::Unit::Order::Types[:nosort].new(SEED)
+
+ list = make_test_list
+ 16.times do
+ assert_equal(list, sorter.sort_by_string(list))
+ end
+
+ list = list.map {|s| Item.new(s)}.freeze
+ 16.times do
+ assert_equal(list, sorter.sort_by_name(list))
+ end
+ end
+
+ def test_sort_random
+ type = Test::Unit::Order::Types[:random]
+ sorter = type.new(SEED)
+
+ list = make_test_list
+ sorted = type.new(SEED).sort_by_string(list).freeze
+ 16.times do
+ assert_equal(sorted, sorter.sort_by_string(list))
+ end
+ assert_not_equal(sorted, type.new(SEED+1).sort_by_string(list))
+
+ list = list.map {|s| Item.new(s)}.freeze
+ sorted = sorted.map {|s| Item.new(s)}.freeze
+ 16.times do
+ assert_equal(sorted, sorter.sort_by_name(list))
+ end
+ assert_not_equal(sorted, type.new(SEED+1).sort_by_name(list))
+ end
end
diff --git a/tool/test/testunit/test_timeout.rb b/tool/test/testunit/test_timeout.rb
new file mode 100644
index 0000000000..452f5e1a7e
--- /dev/null
+++ b/tool/test/testunit/test_timeout.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: false
+require 'test/unit'
+
+class TestTiemout < Test::Unit::TestCase
+ def test_timeout
+ cmd = [*@__runner_options__[:ruby], "#{File.dirname(__FILE__)}/test4test_timeout.rb"]
+ result = IO.popen(cmd, err: [:child, :out], &:read)
+ assert_not_match(/^T{10}$/, result)
+ end
+end
diff --git a/tool/test/testunit/tests_for_parallel/ptest_forth.rb b/tool/test/testunit/tests_for_parallel/ptest_forth.rb
index 8831676e19..54474c828d 100644
--- a/tool/test/testunit/tests_for_parallel/ptest_forth.rb
+++ b/tool/test/testunit/tests_for_parallel/ptest_forth.rb
@@ -8,19 +8,19 @@ class TestE < Test::Unit::TestCase
assert_equal(1,1)
end
- def test_always_skip
- skip "always"
+ def test_always_omit
+ omit "always"
end
def test_always_fail
assert_equal(0,1)
end
- def test_skip_after_unknown_error
+ def test_pend_after_unknown_error
begin
raise UnknownError, "unknown error"
rescue
- skip "after raise"
+ pend "after raise"
end
end
diff --git a/tool/test/testunit/tests_for_parallel/slow_helper.rb b/tool/test/testunit/tests_for_parallel/slow_helper.rb
new file mode 100644
index 0000000000..38067c1f47
--- /dev/null
+++ b/tool/test/testunit/tests_for_parallel/slow_helper.rb
@@ -0,0 +1,8 @@
+require 'test/unit'
+
+module TestSlowTimeout
+ def test_slow
+ sleep_for = EnvUtil.apply_timeout_scale((ENV['sec'] || 3).to_i)
+ sleep sleep_for if on_parallel_worker?
+ end
+end
diff --git a/tool/test/testunit/tests_for_parallel/test4test_hungup.rb b/tool/test/testunit/tests_for_parallel/test4test_hungup.rb
new file mode 100644
index 0000000000..49f503ba9e
--- /dev/null
+++ b/tool/test/testunit/tests_for_parallel/test4test_hungup.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+require_relative '../../../lib/test/unit'
+
+class TestHung < Test::Unit::TestCase
+ def test_success_at_worker
+ assert true
+ end
+
+ def test_hungup_at_worker
+ if on_parallel_worker?
+ sleep EnvUtil.apply_timeout_scale(10)
+ end
+ assert true
+ end
+end