diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/minitest/metametameta.rb | 22 | ||||
-rw-r--r-- | test/minitest/test_minitest_benchmark.rb | 1 | ||||
-rw-r--r-- | test/minitest/test_minitest_mock.rb | 116 | ||||
-rw-r--r-- | test/minitest/test_minitest_spec.rb | 68 | ||||
-rw-r--r-- | test/minitest/test_minitest_unit.rb | 292 |
5 files changed, 383 insertions, 116 deletions
diff --git a/test/minitest/metametameta.rb b/test/minitest/metametameta.rb index a4f7dfa1e6..65eece07ca 100644 --- a/test/minitest/metametameta.rb +++ b/test/minitest/metametameta.rb @@ -24,7 +24,9 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase EOM - @tu.run flags + with_output do + @tu.run flags + end output = @output.string.dup output.sub!(/Finished tests in .*/, "Finished tests in 0.00") @@ -49,14 +51,24 @@ class MetaMetaMetaTestCase < MiniTest::Unit::TestCase srand 42 MiniTest::Unit::TestCase.reset @tu = MiniTest::Unit.new - @output = StringIO.new("") + MiniTest::Unit.runner = nil # protect the outer runner from the inner tests - MiniTest::Unit.output = @output end def teardown super - MiniTest::Unit.output = $stdout - Object.send :remove_const, :ATestCase if defined? ATestCase + end + + def with_output + synchronize do + begin + @output = StringIO.new("") + MiniTest::Unit.output = @output + + yield + ensure + MiniTest::Unit.output = STDOUT + end + end end end diff --git a/test/minitest/test_minitest_benchmark.rb b/test/minitest/test_minitest_benchmark.rb index fc1301e63b..708589b3fa 100644 --- a/test/minitest/test_minitest_benchmark.rb +++ b/test/minitest/test_minitest_benchmark.rb @@ -117,4 +117,3 @@ class TestMiniTestBenchmark < MiniTest::Unit::TestCase assert_in_delta exp_b, b end end - diff --git a/test/minitest/test_minitest_mock.rb b/test/minitest/test_minitest_mock.rb index cd235d60da..cfd97e4002 100644 --- a/test/minitest/test_minitest_mock.rb +++ b/test/minitest/test_minitest_mock.rb @@ -11,6 +11,8 @@ require 'minitest/unit' MiniTest::Unit.autorun class TestMiniTestMock < MiniTest::Unit::TestCase + parallelize_me! if ENV["PARALLEL"] + def setup @mock = MiniTest::Mock.new.expect(:foo, nil) @mock.expect(:meaning_of_life, 42) @@ -103,6 +105,7 @@ class TestMiniTestMock < MiniTest::Unit::TestCase 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 @@ -202,6 +205,68 @@ class TestMiniTestMock < MiniTest::Unit::TestCase 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 @@ -214,6 +279,8 @@ end require "minitest/metametameta" class TestMiniTestStub < MiniTest::Unit::TestCase + parallelize_me! if ENV["PARALLEL"] + def setup super MiniTest::Unit::TestCase.reset @@ -230,13 +297,15 @@ class TestMiniTestStub < MiniTest::Unit::TestCase def assert_stub val_or_callable @assertion_count += 1 - t = Time.now.to_i + synchronize do + t = Time.now.to_i - Time.stub :now, val_or_callable do - @tc.assert_equal 42, Time.now - end + Time.stub :now, val_or_callable do + @tc.assert_equal 42, Time.now + end - @tc.assert_operator Time.now.to_i, :>=, t + @tc.assert_operator Time.now.to_i, :>=, t + end end def test_stub_value @@ -250,13 +319,15 @@ class TestMiniTestStub < MiniTest::Unit::TestCase def test_stub_block_args @assertion_count += 1 - t = Time.now.to_i + synchronize do + t = Time.now.to_i - Time.stub :now, lambda { |n| n * 2 } do - @tc.assert_equal 42, Time.now(21) - end + Time.stub :now, lambda { |n| n * 2 } do + @tc.assert_equal 42, Time.now(21) + end - @tc.assert_operator Time.now.to_i, :>=, t + @tc.assert_operator Time.now.to_i, :>=, t + end end def test_stub_callable @@ -278,4 +349,29 @@ class TestMiniTestStub < MiniTest::Unit::TestCase @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/test/minitest/test_minitest_spec.rb b/test/minitest/test_minitest_spec.rb index 56aa78d620..85cb95f42b 100644 --- a/test/minitest/test_minitest_spec.rb +++ b/test/minitest/test_minitest_spec.rb @@ -15,6 +15,8 @@ class ExampleA; end class ExampleB < ExampleA; end describe MiniTest::Spec do + # do not parallelize this suite... it just can't handle it. + def assert_triggered expected = "blah", klass = MiniTest::Assertion @assertion_count += 2 @@ -567,11 +569,28 @@ describe MiniTest::Spec, :subject do end end -class TestMeta < MiniTest::Unit::TestCase - def test_setup - srand 42 - MiniTest::Unit::TestCase.reset +class TestMetaStatic < MiniTest::Unit::TestCase + def test_children + MiniTest::Spec.children.clear # prevents parallel run + + x = y = z = nil + x = describe "top-level thingy" do + y = describe "first thingy" do end + + it "top-level-it" do end + + z = describe "second thingy" do end + end + + assert_equal [x], MiniTest::Spec.children + assert_equal [y, z], x.children + assert_equal [], y.children + assert_equal [], z.children end +end + +class TestMeta < MiniTest::Unit::TestCase + parallelize_me! if ENV["PARALLEL"] def util_structure x = y = z = nil @@ -659,35 +678,15 @@ class TestMeta < MiniTest::Unit::TestCase _, _, z, before_list, after_list = util_structure @tu = MiniTest::Unit.new - @output = StringIO.new("") MiniTest::Unit.runner = nil # protect the outer runner from the inner tests - MiniTest::Unit.output = @output - tc = z.new :test_0002_anonymous - tc.run @tu + with_output do + tc = z.new :test_0002_anonymous + tc.run @tu + end assert_equal [1, 2, 3], before_list assert_equal [3, 2, 1], after_list - ensure - MiniTest::Unit.output = $stdout - end - - def test_children - MiniTest::Spec.children.clear - - x = y = z = nil - x = describe "top-level thingy" do - y = describe "first thingy" do end - - it "top-level-it" do end - - z = describe "second thingy" do end - end - - assert_equal [x], MiniTest::Spec.children - assert_equal [y, z], x.children - assert_equal [], y.children - assert_equal [], z.children end def test_describe_first_structure @@ -723,4 +722,17 @@ class TestMeta < MiniTest::Unit::TestCase assert_respond_to y.new(nil), "xyz" assert_respond_to z.new(nil), "xyz" end + + def with_output # REFACTOR: dupe from metametameta + synchronize do + begin + @output = StringIO.new("") + MiniTest::Unit.output = @output + + yield + ensure + MiniTest::Unit.output = STDOUT + end + end + end end diff --git a/test/minitest/test_minitest_unit.rb b/test/minitest/test_minitest_unit.rb index eadf59ee70..45bd96fcd4 100644 --- a/test/minitest/test_minitest_unit.rb +++ b/test/minitest/test_minitest_unit.rb @@ -13,6 +13,8 @@ class AnError < StandardError; include MyModule; end class ImmutableString < String; def inspect; super.freeze; end; end class TestMiniTestUnit < MetaMetaMetaTestCase + parallelize_me! if ENV["PARALLEL"] + pwd = Pathname.new File.expand_path Dir.pwd basedir = Pathname.new(File.expand_path "lib/minitest") + 'mini' basedir = basedir.relative_path_from(pwd).to_s @@ -22,6 +24,23 @@ class TestMiniTestUnit < MetaMetaMetaTestCase "#{MINITEST_BASE_DIR}/test.rb:139:in `run'", "#{MINITEST_BASE_DIR}/test.rb:106:in `run'"] + def test_wtf + $hook_value = nil + + capture_io do # don't care about deprecation + MiniTest::Unit::TestCase.add_setup_hook do + $hook_value = 42 + end + end + + run_setup_hooks + + assert_equal 42, $hook_value + assert_equal [Proc], MiniTest::Unit::TestCase.setup_hooks.map(&:class) + MiniTest::Unit::TestCase.reset_setup_teardown_hooks + assert_equal [], MiniTest::Unit::TestCase.setup_hooks.map(&:class) + end + def test_class_puke_with_assertion_failed exception = MiniTest::Assertion.new "Oh no!" exception.set_backtrace ["unhappy"] @@ -156,6 +175,85 @@ class TestMiniTestUnit < MetaMetaMetaTestCase assert_equal ex, fu end + def test_default_runner_is_minitest_unit + assert_instance_of MiniTest::Unit, MiniTest::Unit.runner + end + + def with_overridden_include + Class.class_eval do + def inherited_with_hacks klass + throw :inherited_hook + end + + alias inherited_without_hacks inherited + alias inherited inherited_with_hacks + alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros + end + + yield + ensure + Class.class_eval do + alias inherited inherited_without_hacks + + undef_method :inherited_with_hacks + undef_method :inherited_without_hacks + end + + refute_respond_to Class, :inherited_with_hacks + refute_respond_to Class, :inherited_without_hacks + end + + def test_inherited_hook_plays_nice_with_others + with_overridden_include do + assert_throws :inherited_hook do + Class.new MiniTest::Unit::TestCase + end + end + end + + def test_passed_eh_teardown_good + test_class = Class.new MiniTest::Unit::TestCase do + def teardown; assert true; end + def test_omg; assert true; end + end + + test = test_class.new :test_omg + test.run @tu + assert test.passed? + end + + def test_passed_eh_teardown_flunked + test_class = Class.new MiniTest::Unit::TestCase do + def teardown; flunk; end + def test_omg; assert true; end + end + + test = test_class.new :test_omg + test.run @tu + refute test.passed? + end + + def util_expand_bt bt + if RUBY_VERSION >= '1.9.0' then + bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f } + else + bt + end + end +end + +class TestMiniTestRunner < MetaMetaMetaTestCase + # do not parallelize this suite... it just can't handle it. + + def test_class_test_suites + @assertion_count = 0 + + tc = Class.new(MiniTest::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 @@ -352,10 +450,6 @@ class TestMiniTestUnit < MetaMetaMetaTestCase assert_report expected, %w[--seed 42 --verbose] end - def test_default_runner_is_minitest_unit - assert_instance_of MiniTest::Unit, MiniTest::Unit.runner - end - def test_run_with_other_runner MiniTest::Unit.runner = Class.new MiniTest::Unit do def _run_suite suite, type @@ -393,37 +487,74 @@ class TestMiniTestUnit < MetaMetaMetaTestCase assert_report expected end - def with_overridden_include - Class.class_eval do - def inherited_with_hacks klass - throw :inherited_hook - end + require 'monitor' - alias inherited_without_hacks inherited - alias inherited inherited_with_hacks - alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros + class Latch + def initialize count = 1 + @count = count + @lock = Monitor.new + @cv = @lock.new_cond end - yield - ensure - Class.class_eval do - alias inherited inherited_without_hacks - - undef_method :inherited_with_hacks - undef_method :inherited_without_hacks + def release + @lock.synchronize do + @count -= 1 if @count > 0 + @cv.broadcast if @count == 0 + end end - refute_respond_to Class, :inherited_with_hacks - refute_respond_to Class, :inherited_without_hacks + def await + @lock.synchronize { @cv.wait_while { @count > 0 } } + end end - def test_inherited_hook_plays_nice_with_others - with_overridden_include do - assert_throws :inherited_hook do - Class.new MiniTest::Unit::TestCase + def test_run_parallel + test_count = 2 + test_latch = Latch.new test_count + main_latch = Latch.new + + thread = Thread.new { + Thread.current.abort_on_exception = true + + # This latch waits until both test latches have been released. Both + # latches can't be released unless done in separate threads because + # `main_latch` keeps the test method from finishing. + test_latch.await + main_latch.release + } + + Class.new MiniTest::Unit::TestCase do + parallelize_me! + + test_count.times do |i| + define_method :"test_wait_on_main_thread_#{i}" do + test_latch.release + + # This latch blocks until the "main thread" releases it. The main + # thread can't release this latch until both test latches have + # been released. This forces the latches to be released in separate + # threads. + main_latch.await + assert true + end end end + + expected = clean <<-EOM + .. + + Finished tests in 0.00 + + 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected + assert thread.join end +end + +class TestMiniTestUnitOrder < MetaMetaMetaTestCase + # do not parallelize this suite... it just can't handle it. def test_before_setup call_order = [] @@ -440,34 +571,14 @@ class TestMiniTestUnit < MetaMetaMetaTestCase def test_omg; assert true; end end - @tu.run %w[--seed 42] + with_output do + @tu.run %w[--seed 42] + end expected = [:before_setup, :setup] assert_equal expected, call_order end - def test_passed_eh_teardown_good - test_class = Class.new MiniTest::Unit::TestCase do - def teardown; assert true; end - def test_omg; assert true; end - end - - test = test_class.new :test_omg - test.run @tu - assert test.passed? - end - - def test_passed_eh_teardown_flunked - test_class = Class.new MiniTest::Unit::TestCase do - def teardown; flunk; end - def test_omg; assert true; end - end - - test = test_class.new :test_omg - test.run @tu - refute test.passed? - end - def test_after_teardown call_order = [] Class.new MiniTest::Unit::TestCase do @@ -483,7 +594,9 @@ class TestMiniTestUnit < MetaMetaMetaTestCase def test_omg; assert true; end end - @tu.run %w[--seed 42] + with_output do + @tu.run %w[--seed 42] + end expected = [:teardown, :after_teardown] assert_equal expected, call_order @@ -513,7 +626,9 @@ class TestMiniTestUnit < MetaMetaMetaTestCase def test_omg; assert true; end end - @tu.run %w[--seed 42] + with_output do + @tu.run %w[--seed 42] + end expected = [:before_teardown, :teardown, :after_teardown] assert_equal expected, call_order @@ -538,24 +653,20 @@ class TestMiniTestUnit < MetaMetaMetaTestCase _ = Class.new parent - @tu.run %w[--seed 42] + with_output do + @tu.run %w[--seed 42] + end # Once for the parent class, once for the child expected = [:setup_method, :test, :teardown_method] * 2 assert_equal expected, call_order end - - def util_expand_bt bt - if RUBY_VERSION >= '1.9.0' then - bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f } - else - bt - end - end end class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase + parallelize_me! if ENV["PARALLEL"] + RUBY18 = ! defined? Encoding def setup @@ -633,6 +744,30 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase @tc.assert_equal 1, 1 end + 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(/^ +/, "") + util_assert_triggered msg do + @tc.assert_equal [object1], [object2] + end + end + + def test_assert_equal_different_collection_hash_hex_invisible + 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(/^ +/, "") + + util_assert_triggered msg do + @tc.assert_equal h1, h2 + end + end + def test_assert_equal_different_diff_deactivated without_diff do util_assert_triggered util_msg("haha" * 10, "blah" * 10) do @@ -667,8 +802,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase o1 = Object.new o2 = Object.new - msg = "No visible difference. - You should look at your implementation of Object#==. + msg = "No visible difference in the Object#inspect output. + You should look at the implementation of #== on Object or its members. #<Object:0xXXXXXX>".gsub(/^ +/, "") util_assert_triggered msg do @@ -693,8 +828,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase end def test_assert_equal_different_long_invisible - msg = "No visible difference. - You should look at your implementation of String#==. + msg = "No visible difference in the String#inspect output. + You should look at the implementation of #== on String or its members. \"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "") util_assert_triggered msg do @@ -1181,6 +1316,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase orig_verbose = $VERBOSE $VERBOSE = false + out, err = capture_io do puts 'hi' warn 'bye!' @@ -1192,6 +1328,24 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase $VERBOSE = orig_verbose end + def test_capture_subprocess_io + @assertion_count = 0 + skip "Dunno why but the parallel run of this fails" + + orig_verbose = $VERBOSE + $VERBOSE = false + + out, err = capture_subprocess_io do + system("echo 'hi'") + system("echo 'bye!' 1>&2") + end + + assert_equal "hi\n", out + assert_equal "bye!\n", err + ensure + $VERBOSE = orig_verbose + end + def test_class_asserts_match_refutes @assertion_count = 0 @@ -1215,15 +1369,6 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase assert_empty asserts.map { |n| n.sub(/^assert/, 'refute') } - refutes end - def test_class_test_suites - @assertion_count = 0 - - tc = Class.new(MiniTest::Unit::TestCase) - - assert_equal 1, MiniTest::Unit::TestCase.test_suites.size - assert_equal [tc], MiniTest::Unit::TestCase.test_suites - end - def test_expectation @assertion_count = 2 @@ -1458,6 +1603,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase @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 @@ -1532,6 +1678,8 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase end class TestMiniTestGuard < MiniTest::Unit::TestCase + parallelize_me! if ENV["PARALLEL"] + def test_mri_eh assert self.class.mri? "ruby blah" assert self.mri? "ruby blah" |