1# encoding: utf-8
2# frozen_string_literal: false
3
4require 'pathname'
5require 'minitest/metametameta'
6
7module MyModule; end
8class AnError < StandardError; include MyModule; end
9class ImmutableString < String; def inspect; super.freeze; end; end
10
11class TestMiniTestUnit < MetaMetaMetaTestCase
12  pwd = Pathname.new File.expand_path Dir.pwd
13  basedir = Pathname.new(File.expand_path "lib/minitest") + 'mini'
14  basedir = basedir.relative_path_from(pwd).to_s
15  MINITEST_BASE_DIR = basedir[/\A\./] ? basedir : "./#{basedir}"
16  BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:161:in `each'",
17               "#{MINITEST_BASE_DIR}/test.rb:158:in `each'",
18               "#{MINITEST_BASE_DIR}/test.rb:139:in `run'",
19               "#{MINITEST_BASE_DIR}/test.rb:106:in `run'"]
20
21  def test_class_puke_with_assertion_failed
22    exception = MiniTest::Assertion.new "Oh no!"
23    exception.set_backtrace ["unhappy"]
24    assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
25    assert_equal 1, @tu.failures
26    assert_match(/^Failure.*Oh no!/m, @tu.report.first)
27    assert_match("SomeClass#method_name [unhappy]", @tu.report.first)
28  end
29
30  def test_class_puke_with_assertion_failed_and_long_backtrace
31    bt = (["test/test_some_class.rb:615:in `method_name'",
32           "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
33           "test/test_some_class.rb:615:in `each'",
34           "test/test_some_class.rb:614:in `test_method_name'",
35           "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
36          BT_MIDDLE +
37          ["#{MINITEST_BASE_DIR}/test.rb:29"])
38    bt = util_expand_bt bt
39
40    ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
41
42    exception = MiniTest::Assertion.new "Oh no!"
43    exception.set_backtrace bt
44    assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
45    assert_equal 1, @tu.failures
46    assert_match(/^Failure.*Oh no!/m, @tu.report.first)
47    assert_match("TestSomeClass#test_method_name [#{ex_location}]", @tu.report.first)
48  end
49
50  def test_class_puke_with_assertion_failed_and_user_defined_assertions
51    bt = (["lib/test/my/util.rb:16:in `another_method_name'",
52           "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
53           "lib/test/my/util.rb:15:in `block in assert_something'",
54           "lib/test/my/util.rb:14:in `each'",
55           "lib/test/my/util.rb:14:in `assert_something'",
56           "test/test_some_class.rb:615:in `each'",
57           "test/test_some_class.rb:614:in `test_method_name'",
58           "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
59          BT_MIDDLE +
60          ["#{MINITEST_BASE_DIR}/test.rb:29"])
61    bt = util_expand_bt bt
62
63    ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
64
65    exception = MiniTest::Assertion.new "Oh no!"
66    exception.set_backtrace bt
67    assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
68    assert_equal 1, @tu.failures
69    assert_match(/^Failure.*Oh no!/m, @tu.report.first)
70    assert_match("TestSomeClass#test_method_name [#{ex_location}]", @tu.report.first)
71  end
72
73  def test_class_puke_with_failure_and_flunk_in_backtrace
74    exception = begin
75                  MiniTest::Unit::TestCase.new('fake tc').flunk
76                rescue MiniTest::Assertion => failure
77                  failure
78                end
79    assert_equal 'F', @tu.puke('SomeClass', 'method_name', exception)
80    refute @tu.report.any?{|line| line =~ /in .flunk/}
81  end
82
83  def test_class_puke_with_flunk_and_user_defined_assertions
84    bt = (["lib/test/my/util.rb:16:in `flunk'",
85           "#{MINITEST_BASE_DIR}/unit.rb:140:in `assert_raises'",
86           "lib/test/my/util.rb:15:in `block in assert_something'",
87           "lib/test/my/util.rb:14:in `each'",
88           "lib/test/my/util.rb:14:in `assert_something'",
89           "test/test_some_class.rb:615:in `each'",
90           "test/test_some_class.rb:614:in `test_method_name'",
91           "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
92          BT_MIDDLE +
93          ["#{MINITEST_BASE_DIR}/test.rb:29"])
94    bt = util_expand_bt bt
95
96    ex_location = util_expand_bt(["test/test_some_class.rb:615"]).first
97
98    exception = MiniTest::Assertion.new "Oh no!"
99    exception.set_backtrace bt
100    assert_equal 'F', @tu.puke('TestSomeClass', 'test_method_name', exception)
101    assert_equal 1, @tu.failures
102    assert_match(/^Failure.*Oh no!/m, @tu.report.first)
103    assert_match("TestSomeClass#test_method_name [#{ex_location}]", @tu.report.first)
104  end
105
106  def test_class_puke_with_non_failure_exception
107    exception = Exception.new("Oh no again!")
108    assert_equal 'E', @tu.puke('SomeClass', 'method_name', exception)
109    assert_equal 1, @tu.errors
110    assert_match(/^Exception.*Oh no again!/m, @tu.report.first)
111  end
112
113  def test_filter_backtrace
114    # this is a semi-lame mix of relative paths.
115    # I cheated by making the autotest parts not have ./
116    bt = (["lib/autotest.rb:571:in `add_exception'",
117           "test/test_autotest.rb:62:in `test_add_exception'",
118           "#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
119          BT_MIDDLE +
120          ["#{MINITEST_BASE_DIR}/test.rb:29",
121           "test/test_autotest.rb:422"])
122    bt = util_expand_bt bt
123
124    ex = ["lib/autotest.rb:571:in `add_exception'",
125          "test/test_autotest.rb:62:in `test_add_exception'"]
126    ex = util_expand_bt ex
127
128    fu = MiniTest::filter_backtrace(bt)
129
130    assert_equal ex, fu
131  end
132
133  def test_filter_backtrace_all_unit
134    bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
135          BT_MIDDLE +
136          ["#{MINITEST_BASE_DIR}/test.rb:29"])
137    ex = bt.clone
138    fu = MiniTest::filter_backtrace(bt)
139    assert_equal ex, fu
140  end
141
142  def test_filter_backtrace_unit_starts
143    bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in `__send__'"] +
144          BT_MIDDLE +
145          ["#{MINITEST_BASE_DIR}/mini/test.rb:29",
146           "-e:1"])
147
148    bt = util_expand_bt bt
149
150    ex = ["-e:1"]
151    fu = MiniTest::filter_backtrace bt
152    assert_equal ex, fu
153  end
154
155  def test_default_runner_is_minitest_unit
156    assert_instance_of MiniTest::Unit, MiniTest::Unit.runner
157  end
158
159
160  def test_passed_eh_teardown_good
161    test_class = Class.new MiniTest::Unit::TestCase do
162      def teardown; assert true; end
163      def test_omg; assert true; end
164    end
165
166    test = test_class.new :test_omg
167    test.run @tu
168    assert test.passed?
169  end
170
171  def test_passed_eh_teardown_skipped
172    test_class = Class.new MiniTest::Unit::TestCase do
173      def teardown; assert true; end
174      def test_omg; skip "bork"; end
175    end
176
177    test = test_class.new :test_omg
178    test.run @tu
179    assert test.passed?
180  end
181
182  def test_passed_eh_teardown_flunked
183    test_class = Class.new MiniTest::Unit::TestCase do
184      def teardown; flunk;       end
185      def test_omg; assert true; end
186    end
187
188    test = test_class.new :test_omg
189    test.run @tu
190    refute test.passed?
191  end
192
193  def util_expand_bt bt
194    bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
195  end
196end
197
198class TestMiniTestUnitInherited < MetaMetaMetaTestCase
199  def with_overridden_include
200    Class.class_eval do
201      def inherited_with_hacks klass
202        throw :inherited_hook
203      end
204
205      alias inherited_without_hacks inherited
206      alias inherited               inherited_with_hacks
207      alias IGNORE_ME!              inherited # 1.8 bug. god I love venture bros
208    end
209
210    yield
211  ensure
212    Class.class_eval do
213      alias inherited inherited_without_hacks
214
215      undef_method :inherited_with_hacks
216      undef_method :inherited_without_hacks
217    end
218
219    refute_respond_to Class, :inherited_with_hacks
220    refute_respond_to Class, :inherited_without_hacks
221  end
222
223  def test_inherited_hook_plays_nice_with_others
224    with_overridden_include do
225      assert_throws :inherited_hook do
226        Class.new MiniTest::Unit::TestCase
227      end
228    end
229  end
230end
231
232class TestMiniTestRunner < MetaMetaMetaTestCase
233  # do not parallelize this suite... it just can't handle it.
234
235  def test_class_test_suites
236    @assertion_count = 0
237
238    tc = Class.new(MiniTest::Unit::TestCase)
239
240    assert_equal 1, MiniTest::Unit::TestCase.test_suites.size
241    assert_equal [tc], MiniTest::Unit::TestCase.test_suites
242  end
243
244  def test_run_test
245    Class.new MiniTest::Unit::TestCase do
246      attr_reader :foo
247
248      def run_test name
249        @foo = "hi mom!"
250        super
251        @foo = "okay"
252      end
253
254      def test_something
255        assert_equal "hi mom!", foo
256      end
257    end
258
259    expected = clean <<-EOM
260      .
261
262      Finished tests in 0.00
263
264      1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
265    EOM
266
267    assert_report expected
268  end
269
270  def test_run_error
271    Class.new MiniTest::Unit::TestCase do
272      def test_something
273        assert true
274      end
275
276      def test_error
277        raise "unhandled exception"
278      end
279    end
280
281    expected = clean <<-EOM
282      E.
283
284      Finished tests in 0.00
285
286        1) Error:
287      #<Class:0xXXX>#test_error:
288      RuntimeError: unhandled exception
289          FILE:LINE:in \`test_error\'
290
291      2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
292    EOM
293
294    assert_report expected
295  end
296
297  def test_run_error_teardown
298    Class.new MiniTest::Unit::TestCase do
299      def test_something
300        assert true
301      end
302
303      def teardown
304        raise "unhandled exception"
305      end
306    end
307
308    expected = clean <<-EOM
309      E
310
311      Finished tests in 0.00
312
313        1) Error:
314      #<Class:0xXXX>#test_something:
315      RuntimeError: unhandled exception
316          FILE:LINE:in \`teardown\'
317
318      1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
319    EOM
320
321    assert_report expected
322  end
323
324  def test_run_failing
325    Class.new MiniTest::Unit::TestCase do
326      def test_something
327        assert true
328      end
329
330      def test_failure
331        assert false
332      end
333    end
334
335    expected = clean <<-EOM
336      F.
337
338      Finished tests in 0.00
339
340        1) Failure:
341      #<Class:0xXXX>#test_failure [FILE:LINE]:
342      Failed assertion, no message given.
343
344      2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
345    EOM
346
347    assert_report expected
348  end
349
350  def test_run_failing_filtered
351    Class.new MiniTest::Unit::TestCase do
352      def test_something
353        assert true
354      end
355
356      def test_failure
357        assert false
358      end
359    end
360
361    expected = clean <<-EOM
362      .
363
364      Finished tests in 0.00
365
366      1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
367    EOM
368
369    assert_report expected, %w[--name /some|thing/ --seed 42]
370  end
371
372  def assert_filtering name, expected, a = false
373    args = %W[--name #{name} --seed 42]
374
375    alpha = Class.new MiniTest::Unit::TestCase do
376      define_method :test_something do
377        assert a
378      end
379    end
380    Object.const_set(:Alpha, alpha)
381
382    beta = Class.new MiniTest::Unit::TestCase do
383      define_method :test_something do
384        assert true
385      end
386    end
387    Object.const_set(:Beta, beta)
388
389    assert_report expected, args
390  ensure
391    Object.send :remove_const, :Alpha
392    Object.send :remove_const, :Beta
393  end
394
395  def test_run_filtered_including_suite_name
396    expected = clean <<-EOM
397      .
398
399      Finished tests in 0.00
400
401      1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
402    EOM
403
404    assert_filtering "/Beta#test_something/", expected
405  end
406
407  def test_run_filtered_including_suite_name_string
408    expected = clean <<-EOM
409      .
410
411      Finished tests in 0.00
412
413      1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
414    EOM
415
416    assert_filtering "Beta#test_something", expected
417  end
418
419  def test_run_filtered_string_method_only
420    expected = clean <<-EOM
421      ..
422
423      Finished tests in 0.00
424
425      2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
426    EOM
427
428    assert_filtering "test_something", expected, :pass
429  end
430
431  def test_run_passing
432    Class.new MiniTest::Unit::TestCase do
433      def test_something
434        assert true
435      end
436    end
437
438    expected = clean <<-EOM
439      .
440
441      Finished tests in 0.00
442
443      1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
444    EOM
445
446    assert_report expected
447  end
448
449  def test_run_skip
450    Class.new MiniTest::Unit::TestCase do
451      def test_something
452        assert true
453      end
454
455      def test_skip
456        skip "not yet"
457      end
458    end
459
460    expected = clean <<-EOM
461      S.
462
463      Finished tests in 0.00
464
465      2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
466    EOM
467
468    assert_report expected
469  end
470
471  def test_run_skip_verbose
472    Class.new MiniTest::Unit::TestCase do
473      def test_something
474        assert true
475      end
476
477      def test_skip
478        skip "not yet"
479      end
480    end
481
482    expected = clean <<-EOM
483      #<Class:0xXXX>#test_skip = 0.00 s = S
484      #<Class:0xXXX>#test_something = 0.00 s = .
485
486
487      Finished tests in 0.00
488
489        1) Skipped:
490      #<Class:0xXXX>#test_skip [FILE:LINE]:
491      not yet
492
493      2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
494    EOM
495
496    assert_report expected, %w[--seed 42 --verbose]
497  end
498
499  def test_run_with_other_runner
500    MiniTest::Unit.runner = Class.new MiniTest::Unit do
501      def _run_suite suite, type
502        suite.before_suite # Run once before each suite
503        super suite, type
504      end
505    end.new
506
507    Class.new MiniTest::Unit::TestCase do
508      def self.name; "wacky!" end
509
510      def self.before_suite
511        MiniTest::Unit.output.puts "Running #{self.name} tests"
512        @@foo = 1
513      end
514
515      def test_something
516        assert_equal 1, @@foo
517      end
518
519      def test_something_else
520        assert_equal 1, @@foo
521      end
522    end
523
524    expected = clean <<-EOM
525      Running wacky! tests
526      ..
527
528      Finished tests in 0.00
529
530      2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
531    EOM
532
533    assert_report expected
534  end
535
536  require 'monitor'
537
538  class Latch
539    def initialize count = 1
540      @count = count
541      @lock  = Monitor.new
542      @cv    = @lock.new_cond
543    end
544
545    def release
546      @lock.synchronize do
547        @count -= 1 if @count > 0
548        @cv.broadcast if @count == 0
549      end
550    end
551
552    def await
553      @lock.synchronize { @cv.wait_while { @count > 0 } }
554    end
555  end
556end
557
558class TestMiniTestUnitOrder < MetaMetaMetaTestCase
559  # do not parallelize this suite... it just can't handle it.
560
561  def test_before_setup
562    call_order = []
563    Class.new MiniTest::Unit::TestCase do
564      define_method :setup do
565        super()
566        call_order << :setup
567      end
568
569      define_method :before_setup do
570        call_order << :before_setup
571      end
572
573      def test_omg; assert true; end
574    end
575
576    with_output do
577      @tu.run %w[--seed 42]
578    end
579
580    expected = [:before_setup, :setup]
581    assert_equal expected, call_order
582  end
583
584  def test_after_teardown
585    call_order = []
586    Class.new MiniTest::Unit::TestCase do
587      define_method :teardown do
588        super()
589        call_order << :teardown
590      end
591
592      define_method :after_teardown do
593        call_order << :after_teardown
594      end
595
596      def test_omg; assert true; end
597    end
598
599    with_output do
600      @tu.run %w[--seed 42]
601    end
602
603    expected = [:teardown, :after_teardown]
604    assert_equal expected, call_order
605  end
606
607  def test_all_teardowns_are_guaranteed_to_run
608    call_order = []
609    Class.new MiniTest::Unit::TestCase do
610      define_method :after_teardown do
611        super()
612        call_order << :after_teardown
613        raise
614      end
615
616      define_method :teardown do
617        super()
618        call_order << :teardown
619        raise
620      end
621
622      define_method :before_teardown do
623        super()
624        call_order << :before_teardown
625        raise
626      end
627
628      def test_omg; assert true; end
629    end
630
631    with_output do
632      @tu.run %w[--seed 42]
633    end
634
635    expected = [:before_teardown, :teardown, :after_teardown]
636    assert_equal expected, call_order
637  end
638
639  def test_setup_and_teardown_survive_inheritance
640    call_order = []
641
642    parent = Class.new MiniTest::Unit::TestCase do
643      define_method :setup do
644        call_order << :setup_method
645      end
646
647      define_method :teardown do
648        call_order << :teardown_method
649      end
650
651      define_method :test_something do
652        call_order << :test
653      end
654    end
655
656    _ = Class.new parent
657
658    with_output do
659      @tu.run %w[--seed 42]
660    end
661
662    # Once for the parent class, once for the child
663    expected = [:setup_method, :test, :teardown_method] * 2
664
665    assert_equal expected, call_order
666  end
667end
668
669class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
670  # do not call parallelize_me! - teardown accesses @tc._assertions
671  # which is not threadsafe. Nearly every method in here is an
672  # assertion test so it isn't worth splitting it out further.
673
674  RUBY18 = ! defined? Encoding
675
676  def setup
677    super
678
679    MiniTest::Unit::TestCase.reset
680
681    @tc = MiniTest::Unit::TestCase.new 'fake tc'
682    @zomg = "zomg ponies!"
683    @assertion_count = 1
684  end
685
686  def teardown
687    assert_equal(@assertion_count, @tc._assertions,
688                 "expected #{@assertion_count} assertions to be fired during the test, not #{@tc._assertions}") if @tc.passed?
689  end
690
691  def non_verbose
692    orig_verbose = $VERBOSE
693    $VERBOSE = false
694
695    yield
696  ensure
697    $VERBOSE = orig_verbose
698  end
699
700  def test_assert
701    @assertion_count = 2
702
703    @tc.assert_equal true, @tc.assert(true), "returns true on success"
704  end
705
706  def test_assert__triggered
707    util_assert_triggered "Failed assertion, no message given." do
708      @tc.assert false
709    end
710  end
711
712  def test_assert__triggered_message
713    util_assert_triggered @zomg do
714      @tc.assert false, @zomg
715    end
716  end
717
718  def test_assert_empty
719    @assertion_count = 2
720
721    @tc.assert_empty []
722  end
723
724  def test_assert_empty_triggered
725    @assertion_count = 2
726
727    util_assert_triggered "Expected [1] to be empty." do
728      @tc.assert_empty [1]
729    end
730  end
731
732  def test_assert_equal
733    @tc.assert_equal 1, 1
734  end
735
736  def test_assert_equal_different_collection_array_hex_invisible
737    object1 = Object.new
738    object2 = Object.new
739    msg = "No visible difference in the Array#inspect output.
740           You should look at the implementation of #== on Array or its members.
741           [#<Object:0xXXXXXX>]".gsub(/^ +/, "")
742    util_assert_triggered msg do
743      @tc.assert_equal [object1], [object2]
744    end
745  end
746
747  def test_assert_equal_different_collection_hash_hex_invisible
748    h1, h2 = {}, {}
749    h1[1] = Object.new
750    h2[1] = Object.new
751    msg = "No visible difference in the Hash#inspect output.
752           You should look at the implementation of #== on Hash or its members.
753           {1=>#<Object:0xXXXXXX>}".gsub(/^ +/, "")
754
755    util_assert_triggered msg do
756      @tc.assert_equal h1, h2
757    end
758  end
759
760  def test_assert_equal_different_diff_deactivated
761    skip "https://github.com/MagLev/maglev/issues/209" if maglev?
762
763    without_diff do
764      util_assert_triggered util_msg("haha" * 10, "blah" * 10) do
765        o1 = "haha" * 10
766        o2 = "blah" * 10
767
768        @tc.assert_equal o1, o2
769      end
770    end
771  end
772
773  def test_assert_equal_different_hex
774    c = Class.new do
775      def initialize s; @name = s; end
776    end
777
778    o1 = c.new "a"
779    o2 = c.new "b"
780    msg = "--- expected
781           +++ actual
782           @@ -1 +1 @@
783           -#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"a\">
784           +#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"b\">
785           ".gsub(/^ +/, "")
786
787    util_assert_triggered msg do
788      @tc.assert_equal o1, o2
789    end
790  end
791
792  def test_assert_equal_different_hex_invisible
793    o1 = Object.new
794    o2 = Object.new
795
796    msg = "No visible difference in the Object#inspect output.
797           You should look at the implementation of #== on Object or its members.
798           #<Object:0xXXXXXX>".gsub(/^ +/, "")
799
800    util_assert_triggered msg do
801      @tc.assert_equal o1, o2
802    end
803  end
804
805  def test_assert_equal_different_long
806    msg = "--- expected
807           +++ actual
808           @@ -1 +1 @@
809           -\"hahahahahahahahahahahahahahahahahahahaha\"
810           +\"blahblahblahblahblahblahblahblahblahblah\"
811           ".gsub(/^ +/, "")
812
813    util_assert_triggered msg do
814      o1 = "haha" * 10
815      o2 = "blah" * 10
816
817      @tc.assert_equal o1, o2
818    end
819  end
820
821  def test_assert_equal_different_long_invisible
822    msg = "No visible difference in the String#inspect output.
823           You should look at the implementation of #== on String or its members.
824           \"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
825
826    util_assert_triggered msg do
827      o1 = "blah" * 10
828      o2 = "blah" * 10
829      def o1.== o
830        false
831      end
832      @tc.assert_equal o1, o2
833    end
834  end
835
836  def test_assert_equal_different_long_msg
837    msg = "message.
838           --- expected
839           +++ actual
840           @@ -1 +1 @@
841           -\"hahahahahahahahahahahahahahahahahahahaha\"
842           +\"blahblahblahblahblahblahblahblahblahblah\"
843           ".gsub(/^ +/, "")
844
845    util_assert_triggered msg do
846      o1 = "haha" * 10
847      o2 = "blah" * 10
848      @tc.assert_equal o1, o2, "message"
849    end
850  end
851
852  def test_assert_equal_different_short
853    util_assert_triggered util_msg(1, 2) do
854      @tc.assert_equal 1, 2
855    end
856  end
857
858  def test_assert_equal_different_short_msg
859    util_assert_triggered util_msg(1, 2, "message") do
860      @tc.assert_equal 1, 2, "message"
861    end
862  end
863
864  def test_assert_equal_different_short_multiline
865    msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n"
866    util_assert_triggered msg do
867      @tc.assert_equal "a\nb", "a\nc"
868    end
869  end
870
871  def test_assert_in_delta
872    @tc.assert_in_delta 0.0, 1.0 / 1000, 0.1
873  end
874
875  def test_delta_consistency
876    @tc.assert_in_delta 0, 1, 1
877
878    util_assert_triggered "Expected |0 - 1| (1) to not be <= 1." do
879      @tc.refute_in_delta 0, 1, 1
880    end
881  end
882
883  def test_assert_in_delta_triggered
884    x = maglev? ? "9.999999xxxe-07" : "1.0e-06"
885    util_assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do
886      @tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001
887    end
888  end
889
890  def test_assert_in_epsilon
891    @assertion_count = 10
892
893    @tc.assert_in_epsilon 10000, 9991
894    @tc.assert_in_epsilon 9991, 10000
895    @tc.assert_in_epsilon 1.0, 1.001
896    @tc.assert_in_epsilon 1.001, 1.0
897
898    @tc.assert_in_epsilon 10000, 9999.1, 0.0001
899    @tc.assert_in_epsilon 9999.1, 10000, 0.0001
900    @tc.assert_in_epsilon 1.0, 1.0001, 0.0001
901    @tc.assert_in_epsilon 1.0001, 1.0, 0.0001
902
903    @tc.assert_in_epsilon(-1, -1)
904    @tc.assert_in_epsilon(-10000, -9991)
905  end
906
907  def test_epsilon_consistency
908    @tc.assert_in_epsilon 1.0, 1.001
909
910    msg = "Expected |1.0 - 1.001| (0.000999xxx) to not be <= 0.001."
911    util_assert_triggered msg do
912      @tc.refute_in_epsilon 1.0, 1.001
913    end
914  end
915
916  def test_assert_in_epsilon_triggered
917    util_assert_triggered 'Expected |10000 - 9990| (10) to be <= 9.99.' do
918      @tc.assert_in_epsilon 10000, 9990
919    end
920  end
921
922  def test_assert_in_epsilon_triggered_negative_case
923    x = (RUBY18 and not maglev?) ? "0.1" : "0.100000xxx"
924    y = maglev? ? "0.100000xxx" : "0.1"
925    util_assert_triggered "Expected |-1.1 - -1| (#{x}) to be <= #{y}." do
926      @tc.assert_in_epsilon(-1.1, -1, 0.1)
927    end
928  end
929
930  def test_assert_includes
931    @assertion_count = 2
932
933    @tc.assert_includes [true], true
934  end
935
936  def test_assert_includes_triggered
937    @assertion_count = 3
938
939    e = @tc.assert_raises MiniTest::Assertion do
940      @tc.assert_includes [true], false
941    end
942
943    expected = "Expected [true] to include false."
944    assert_equal expected, e.message
945  end
946
947  def test_assert_instance_of
948    @tc.assert_instance_of String, "blah"
949  end
950
951  def test_assert_instance_of_triggered
952    util_assert_triggered 'Expected "blah" to be an instance of Array, not String.' do
953      @tc.assert_instance_of Array, "blah"
954    end
955  end
956
957  def test_assert_kind_of
958    @tc.assert_kind_of String, "blah"
959  end
960
961  def test_assert_kind_of_triggered
962    util_assert_triggered 'Expected "blah" to be a kind of Array, not String.' do
963      @tc.assert_kind_of Array, "blah"
964    end
965  end
966
967  def test_assert_match
968    @assertion_count = 2
969    @tc.assert_match(/\w+/, "blah blah blah")
970  end
971
972  def test_assert_match_matcher_object
973    @assertion_count = 2
974
975    pattern = Object.new
976    def pattern.=~(other) true end
977
978    @tc.assert_match pattern, 5
979  end
980
981  def test_assert_match_matchee_to_str
982    @assertion_count = 2
983
984    obj = Object.new
985    def obj.to_str; "blah" end
986
987    @tc.assert_match "blah", obj
988  end
989
990  def test_assert_match_object_triggered
991    @assertion_count = 2
992
993    pattern = Object.new
994    def pattern.=~(other) false end
995    def pattern.inspect; "[Object]" end
996
997    util_assert_triggered 'Expected [Object] to match 5.' do
998      @tc.assert_match pattern, 5
999    end
1000  end
1001
1002  def test_assert_match_triggered
1003    @assertion_count = 2
1004    util_assert_triggered 'Expected /\d+/ to match "blah blah blah".' do
1005      @tc.assert_match(/\d+/, "blah blah blah")
1006    end
1007  end
1008
1009  def test_assert_nil
1010    @tc.assert_nil nil
1011  end
1012
1013  def test_assert_nil_triggered
1014    util_assert_triggered 'Expected 42 to be nil.' do
1015      @tc.assert_nil 42
1016    end
1017  end
1018
1019  def test_assert_operator
1020    @tc.assert_operator 2, :>, 1
1021  end
1022
1023  def test_assert_operator_bad_object
1024    bad = Object.new
1025    def bad.==(other) true end
1026
1027    @tc.assert_operator bad, :equal?, bad
1028  end
1029
1030  def test_assert_operator_triggered
1031    util_assert_triggered "Expected 2 to be < 1." do
1032      @tc.assert_operator 2, :<, 1
1033    end
1034  end
1035
1036  def test_assert_output_both
1037    @assertion_count = 2
1038
1039    @tc.assert_output "yay", "blah" do
1040      print "yay"
1041      $stderr.print "blah"
1042    end
1043  end
1044
1045  def test_assert_output_both_regexps
1046    @assertion_count = 4
1047
1048    @tc.assert_output(/y.y/, /bl.h/) do
1049      print "yay"
1050      $stderr.print "blah"
1051    end
1052  end
1053
1054  def test_assert_output_err
1055    @tc.assert_output nil, "blah" do
1056      $stderr.print "blah"
1057    end
1058  end
1059
1060  def test_assert_output_neither
1061    @assertion_count = 0
1062
1063    @tc.assert_output do
1064      # do nothing
1065    end
1066  end
1067
1068  def test_assert_output_out
1069    @tc.assert_output "blah" do
1070      print "blah"
1071    end
1072  end
1073
1074  def test_assert_output_triggered_both
1075    util_assert_triggered util_msg("blah", "blah blah", "In stderr") do
1076      @tc.assert_output "yay", "blah" do
1077        print "boo"
1078        $stderr.print "blah blah"
1079      end
1080    end
1081  end
1082
1083  def test_assert_output_triggered_err
1084    util_assert_triggered util_msg("blah", "blah blah", "In stderr") do
1085      @tc.assert_output nil, "blah" do
1086        $stderr.print "blah blah"
1087      end
1088    end
1089  end
1090
1091  def test_assert_output_triggered_out
1092    util_assert_triggered util_msg("blah", "blah blah", "In stdout") do
1093      @tc.assert_output "blah" do
1094        print "blah blah"
1095      end
1096    end
1097  end
1098
1099  def test_assert_predicate
1100    @tc.assert_predicate "", :empty?
1101  end
1102
1103  def test_assert_predicate_triggered
1104    util_assert_triggered 'Expected "blah" to be empty?.' do
1105      @tc.assert_predicate "blah", :empty?
1106    end
1107  end
1108
1109  def test_assert_raises
1110    @tc.assert_raises RuntimeError do
1111      raise "blah"
1112    end
1113  end
1114
1115  def test_assert_raises_module
1116    @tc.assert_raises MyModule do
1117      raise AnError
1118    end
1119  end
1120
1121  ##
1122  # *sigh* This is quite an odd scenario, but it is from real (albeit
1123  # ugly) test code in ruby-core:
1124  #
1125  # https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
1126
1127  def test_assert_raises_skip
1128    @assertion_count = 0
1129
1130    util_assert_triggered "skipped", MiniTest::Skip do
1131      @tc.assert_raises ArgumentError do
1132        begin
1133          raise "blah"
1134        rescue
1135          skip "skipped"
1136        end
1137      end
1138    end
1139  end
1140
1141  def test_assert_raises_triggered_different
1142    e = assert_raises MiniTest::Assertion do
1143      @tc.assert_raises RuntimeError do
1144        raise SyntaxError, "icky"
1145      end
1146    end
1147
1148    expected = clean <<-EOM.chomp
1149      [RuntimeError] exception expected, not
1150      Class: <SyntaxError>
1151      Message: <\"icky\">
1152      ---Backtrace---
1153      FILE:LINE:in \`test_assert_raises_triggered_different\'
1154      ---------------
1155    EOM
1156
1157    actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
1158    actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION >= '1.9.0'
1159
1160    assert_equal expected, actual
1161  end
1162
1163  def test_assert_raises_triggered_different_msg
1164    e = assert_raises MiniTest::Assertion do
1165      @tc.assert_raises RuntimeError, "XXX" do
1166        raise SyntaxError, "icky"
1167      end
1168    end
1169
1170    expected = clean <<-EOM
1171      XXX.
1172      [RuntimeError] exception expected, not
1173      Class: <SyntaxError>
1174      Message: <\"icky\">
1175      ---Backtrace---
1176      FILE:LINE:in \`test_assert_raises_triggered_different_msg\'
1177      ---------------
1178    EOM
1179
1180    actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
1181    actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION >= '1.9.0'
1182
1183    assert_equal expected.chomp, actual
1184  end
1185
1186  def test_assert_raises_triggered_none
1187    e = assert_raises MiniTest::Assertion do
1188      @tc.assert_raises MiniTest::Assertion do
1189        # do nothing
1190      end
1191    end
1192
1193    expected = "MiniTest::Assertion expected but nothing was raised."
1194
1195    assert_equal expected, e.message
1196  end
1197
1198  def test_assert_raises_triggered_none_msg
1199    e = assert_raises MiniTest::Assertion do
1200      @tc.assert_raises MiniTest::Assertion, "XXX" do
1201        # do nothing
1202      end
1203    end
1204
1205    expected = "XXX.\nMiniTest::Assertion expected but nothing was raised."
1206
1207    assert_equal expected, e.message
1208  end
1209
1210  def test_assert_raises_triggered_subclass
1211    e = assert_raises MiniTest::Assertion do
1212      @tc.assert_raises StandardError do
1213        raise AnError
1214      end
1215    end
1216
1217    expected = clean <<-EOM.chomp
1218      [StandardError] exception expected, not
1219      Class: <AnError>
1220      Message: <\"AnError\">
1221      ---Backtrace---
1222      FILE:LINE:in \`test_assert_raises_triggered_subclass\'
1223      ---------------
1224    EOM
1225
1226    actual = e.message.gsub(/^.+:\d+/, 'FILE:LINE')
1227    actual.gsub!(/block \(\d+ levels\) in /, '') if RUBY_VERSION >= '1.9.0'
1228
1229    assert_equal expected, actual
1230  end
1231
1232  def test_assert_respond_to
1233    @tc.assert_respond_to "blah", :empty?
1234  end
1235
1236  def test_assert_respond_to_triggered
1237    util_assert_triggered 'Expected "blah" (String) to respond to #rawr!.' do
1238      @tc.assert_respond_to "blah", :rawr!
1239    end
1240  end
1241
1242  def test_assert_same
1243    @assertion_count = 3
1244
1245    o = "blah"
1246    @tc.assert_same 1, 1
1247    @tc.assert_same :blah, :blah
1248    @tc.assert_same o, o
1249  end
1250
1251  def test_assert_same_triggered
1252    @assertion_count = 2
1253
1254    util_assert_triggered 'Expected 2 (oid=N) to be the same as 1 (oid=N).' do
1255      @tc.assert_same 1, 2
1256    end
1257
1258    s1 = "blah"
1259    s2 = "blah"
1260
1261    util_assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do
1262      @tc.assert_same s1, s2
1263    end
1264  end
1265
1266  def test_assert_send
1267    @tc.assert_send [1, :<, 2]
1268  end
1269
1270  def test_assert_send_bad
1271    util_assert_triggered "Expected 1.>(*[2]) to return true." do
1272      @tc.assert_send [1, :>, 2]
1273    end
1274  end
1275
1276  def test_assert_silent
1277    @assertion_count = 2
1278
1279    @tc.assert_silent do
1280      # do nothing
1281    end
1282  end
1283
1284  def test_assert_silent_triggered_err
1285    util_assert_triggered util_msg("", "blah blah", "In stderr") do
1286      @tc.assert_silent do
1287        $stderr.print "blah blah"
1288      end
1289    end
1290  end
1291
1292  def test_assert_silent_triggered_out
1293    @assertion_count = 2
1294
1295    util_assert_triggered util_msg("", "blah blah", "In stdout") do
1296      @tc.assert_silent do
1297        print "blah blah"
1298      end
1299    end
1300  end
1301
1302  def test_assert_throws
1303    @tc.assert_throws :blah do
1304      throw :blah
1305    end
1306  end
1307
1308  def test_assert_throws_different
1309    util_assert_triggered 'Expected :blah to have been thrown, not :not_blah.' do
1310      @tc.assert_throws :blah do
1311        throw :not_blah
1312      end
1313    end
1314  end
1315
1316  def test_assert_throws_unthrown
1317    util_assert_triggered 'Expected :blah to have been thrown.' do
1318      @tc.assert_throws :blah do
1319        # do nothing
1320      end
1321    end
1322  end
1323
1324  def test_capture_io
1325    @assertion_count = 0
1326
1327    non_verbose do
1328      out, err = capture_io do
1329        puts 'hi'
1330        $stderr.puts 'bye!'
1331      end
1332
1333      assert_equal "hi\n", out
1334      assert_equal "bye!\n", err
1335    end
1336  end
1337
1338  def test_capture_subprocess_io
1339    @assertion_count = 0
1340
1341    non_verbose do
1342      out, err = capture_subprocess_io do
1343        system("echo", "hi")
1344        system("echo", "bye!", out: :err)
1345      end
1346
1347      assert_equal "hi\n", out
1348      assert_equal "bye!\n", err
1349    end
1350  end
1351
1352  def test_class_asserts_match_refutes
1353    @assertion_count = 0
1354
1355    methods = MiniTest::Assertions.public_instance_methods
1356    methods.map! { |m| m.to_s } if Symbol === methods.first
1357
1358    # These don't have corresponding refutes _on purpose_. They're
1359    # useless and will never be added, so don't bother.
1360    ignores = %w[assert_output assert_raises assert_send
1361                 assert_silent assert_throws]
1362
1363    # These are test/unit methods. I'm not actually sure why they're still here
1364    ignores += %w[assert_no_match assert_not_equal assert_not_nil
1365                  assert_not_same assert_nothing_raised
1366                  assert_nothing_thrown assert_raise]
1367
1368    asserts = methods.grep(/^assert/).sort - ignores
1369    refutes = methods.grep(/^refute/).sort - ignores
1370
1371    assert_empty refutes.map { |n| n.sub(/^refute/, 'assert') } - asserts
1372    assert_empty asserts.map { |n| n.sub(/^assert/, 'refute') } - refutes
1373  end
1374
1375  def test_flunk
1376    util_assert_triggered 'Epic Fail!' do
1377      @tc.flunk
1378    end
1379  end
1380
1381  def test_flunk_message
1382    util_assert_triggered @zomg do
1383      @tc.flunk @zomg
1384    end
1385  end
1386
1387  def test_message
1388    @assertion_count = 0
1389
1390    assert_equal "blah2.",         @tc.message          { "blah2" }.call
1391    assert_equal "blah2.",         @tc.message("")      { "blah2" }.call
1392    assert_equal "blah1.\nblah2.", @tc.message(:blah1)  { "blah2" }.call
1393    assert_equal "blah1.\nblah2.", @tc.message("blah1") { "blah2" }.call
1394
1395    message = proc { "blah1" }
1396    assert_equal "blah1.\nblah2.", @tc.message(message) { "blah2" }.call
1397
1398    message = @tc.message { "blah1" }
1399    assert_equal "blah1.\nblah2.", @tc.message(message) { "blah2" }.call
1400  end
1401
1402  def test_message_message
1403    util_assert_triggered "whoops.\nExpected: 1\n  Actual: 2" do
1404      @tc.assert_equal 1, 2, message { "whoops" }
1405    end
1406  end
1407
1408  def test_message_lambda
1409    util_assert_triggered "whoops.\nExpected: 1\n  Actual: 2" do
1410      @tc.assert_equal 1, 2, lambda { "whoops" }
1411    end
1412  end
1413
1414  def test_message_deferred
1415    @assertion_count, var = 0, nil
1416
1417    msg = message { var = "blah" }
1418
1419    assert_nil var
1420
1421    msg.call
1422
1423    assert_equal "blah", var
1424  end
1425
1426  def test_pass
1427    @tc.pass
1428  end
1429
1430  def test_prints
1431    printer = Class.new { extend MiniTest::Assertions }
1432    @tc.assert_equal '"test"', printer.mu_pp(ImmutableString.new 'test')
1433  end
1434
1435  def test_refute
1436    @assertion_count = 2
1437
1438    @tc.assert_equal false, @tc.refute(false), "returns false on success"
1439  end
1440
1441  def test_refute_empty
1442    @assertion_count = 2
1443
1444    @tc.refute_empty [1]
1445  end
1446
1447  def test_refute_empty_triggered
1448    @assertion_count = 2
1449
1450    util_assert_triggered "Expected [] to not be empty." do
1451      @tc.refute_empty []
1452    end
1453  end
1454
1455  def test_refute_equal
1456    @tc.refute_equal "blah", "yay"
1457  end
1458
1459  def test_refute_equal_triggered
1460    util_assert_triggered 'Expected "blah" to not be equal to "blah".' do
1461      @tc.refute_equal "blah", "blah"
1462    end
1463  end
1464
1465  def test_refute_in_delta
1466    @tc.refute_in_delta 0.0, 1.0 / 1000, 0.000001
1467  end
1468
1469  def test_refute_in_delta_triggered
1470    x = maglev? ? "0.100000xxx" : "0.1"
1471    util_assert_triggered "Expected |0.0 - 0.001| (0.001) to not be <= #{x}." do
1472      @tc.refute_in_delta 0.0, 1.0 / 1000, 0.1
1473    end
1474  end
1475
1476  def test_refute_in_epsilon
1477    @tc.refute_in_epsilon 10000, 9990-1
1478  end
1479
1480  def test_refute_in_epsilon_triggered
1481    util_assert_triggered 'Expected |10000 - 9990| (10) to not be <= 10.0.' do
1482      @tc.refute_in_epsilon 10000, 9990
1483      fail
1484    end
1485  end
1486
1487  def test_refute_includes
1488    @assertion_count = 2
1489
1490    @tc.refute_includes [true], false
1491  end
1492
1493  def test_refute_includes_triggered
1494    @assertion_count = 3
1495
1496    e = @tc.assert_raises MiniTest::Assertion do
1497      @tc.refute_includes [true], true
1498    end
1499
1500    expected = "Expected [true] to not include true."
1501    assert_equal expected, e.message
1502  end
1503
1504  def test_refute_instance_of
1505    @tc.refute_instance_of Array, "blah"
1506  end
1507
1508  def test_refute_instance_of_triggered
1509    util_assert_triggered 'Expected "blah" to not be an instance of String.' do
1510      @tc.refute_instance_of String, "blah"
1511    end
1512  end
1513
1514  def test_refute_kind_of
1515    @tc.refute_kind_of Array, "blah"
1516  end
1517
1518  def test_refute_kind_of_triggered
1519    util_assert_triggered 'Expected "blah" to not be a kind of String.' do
1520      @tc.refute_kind_of String, "blah"
1521    end
1522  end
1523
1524  def test_refute_match
1525    @assertion_count = 2
1526    @tc.refute_match(/\d+/, "blah blah blah")
1527  end
1528
1529  def test_refute_match_matcher_object
1530    @assertion_count = 2
1531    non_verbose do
1532      @tc.refute_match Object.new, 5 # default #=~ returns false
1533    end
1534  end
1535
1536  def test_refute_match_object_triggered
1537    @assertion_count = 2
1538
1539    pattern = Object.new
1540    def pattern.=~(other) true end
1541    def pattern.inspect; "[Object]" end
1542
1543    util_assert_triggered 'Expected [Object] to not match 5.' do
1544      @tc.refute_match pattern, 5
1545    end
1546  end
1547
1548  def test_refute_match_triggered
1549    @assertion_count = 2
1550    util_assert_triggered 'Expected /\w+/ to not match "blah blah blah".' do
1551      @tc.refute_match(/\w+/, "blah blah blah")
1552    end
1553  end
1554
1555  def test_refute_nil
1556    @tc.refute_nil 42
1557  end
1558
1559  def test_refute_nil_triggered
1560    util_assert_triggered 'Expected nil to not be nil.' do
1561      @tc.refute_nil nil
1562    end
1563  end
1564
1565  def test_refute_predicate
1566    @tc.refute_predicate "42", :empty?
1567  end
1568
1569  def test_refute_predicate_triggered
1570    util_assert_triggered 'Expected "" to not be empty?.' do
1571      @tc.refute_predicate "", :empty?
1572    end
1573  end
1574
1575  def test_refute_operator
1576    @tc.refute_operator 2, :<, 1
1577  end
1578
1579  def test_refute_operator_bad_object
1580    bad = Object.new
1581    def bad.==(other) true end
1582
1583    @tc.refute_operator true, :equal?, bad
1584  end
1585
1586  def test_refute_operator_triggered
1587    util_assert_triggered "Expected 2 to not be > 1." do
1588      @tc.refute_operator 2, :>, 1
1589    end
1590  end
1591
1592  def test_refute_respond_to
1593    @tc.refute_respond_to "blah", :rawr!
1594  end
1595
1596  def test_refute_respond_to_triggered
1597    util_assert_triggered 'Expected "blah" to not respond to empty?.' do
1598      @tc.refute_respond_to "blah", :empty?
1599    end
1600  end
1601
1602  def test_refute_same
1603    @tc.refute_same 1, 2
1604  end
1605
1606  def test_refute_same_triggered
1607    util_assert_triggered 'Expected 1 (oid=N) to not be the same as 1 (oid=N).' do
1608      @tc.refute_same 1, 1
1609    end
1610  end
1611
1612  def test_skip
1613    @assertion_count = 0
1614
1615    util_assert_triggered "haha!", MiniTest::Skip do
1616      @tc.skip "haha!"
1617    end
1618  end
1619
1620  def test_test_methods_random
1621    @assertion_count = 0
1622
1623    sample_test_case = Class.new MiniTest::Unit::TestCase do
1624      def self.test_order; :random; end
1625      def test_test1; assert "does not matter" end
1626      def test_test2; assert "does not matter" end
1627      def test_test3; assert "does not matter" end
1628      @test_order = [1, 0, 2]
1629      def self.rand(n) @test_order.shift; end
1630    end
1631
1632    expected = %w(test_test2 test_test1 test_test3)
1633    assert_equal expected, sample_test_case.test_methods
1634  end
1635
1636  def test_test_methods_sorted
1637    @assertion_count = 0
1638
1639    sample_test_case = Class.new MiniTest::Unit::TestCase do
1640      def self.test_order; :sorted end
1641      def test_test3; assert "does not matter" end
1642      def test_test2; assert "does not matter" end
1643      def test_test1; assert "does not matter" end
1644    end
1645
1646    expected = %w(test_test1 test_test2 test_test3)
1647    assert_equal expected, sample_test_case.test_methods
1648  end
1649
1650  def assert_triggered expected, klass = MiniTest::Assertion
1651    e = assert_raises klass do
1652      yield
1653    end
1654
1655    msg = e.message.sub(/(---Backtrace---).*/m, '\1')
1656    msg.gsub!(/\(oid=[-0-9]+\)/, '(oid=N)')
1657    msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform
1658
1659    assert_equal expected, msg
1660  end
1661  alias util_assert_triggered assert_triggered
1662
1663  def util_msg exp, act, msg = nil
1664    s = "Expected: #{exp.inspect}\n  Actual: #{act.inspect}"
1665    s = "#{msg}.\n#{s}" if msg
1666    s
1667  end
1668
1669  def without_diff
1670    old_diff = MiniTest::Assertions.diff
1671    MiniTest::Assertions.diff = nil
1672
1673    yield
1674  ensure
1675    MiniTest::Assertions.diff = old_diff
1676  end
1677end
1678
1679class TestMiniTestGuard < MiniTest::Unit::TestCase
1680  def test_mri_eh
1681    assert self.class.mri? "ruby blah"
1682    assert self.mri? "ruby blah"
1683  end
1684
1685  def test_jruby_eh
1686    assert self.class.jruby? "java"
1687    assert self.jruby? "java"
1688  end
1689
1690  def test_rubinius_eh
1691    assert self.class.rubinius? "rbx"
1692    assert self.rubinius? "rbx"
1693  end
1694
1695  def test_windows_eh
1696    assert self.class.windows? "mswin"
1697    assert self.windows? "mswin"
1698  end
1699end
1700
1701class TestMiniTestUnitRecording < MetaMetaMetaTestCase
1702  # do not parallelize this suite... it just can't handle it.
1703
1704  def assert_run_record(*expected, &block)
1705    def @tu.record suite, method, assertions, time, error
1706      recording[method] << error
1707    end
1708
1709    def @tu.recording
1710      @recording ||= Hash.new { |h,k| h[k] = [] }
1711    end
1712
1713    MiniTest::Unit.runner = @tu
1714
1715    Class.new MiniTest::Unit::TestCase, &block
1716
1717    with_output do
1718      @tu.run
1719    end
1720
1721    recorded = @tu.recording.fetch("test_method").map(&:class)
1722
1723    assert_equal expected, recorded
1724  end
1725
1726  def test_record_passing
1727    assert_run_record NilClass do
1728      def test_method
1729        assert true
1730      end
1731    end
1732  end
1733
1734  def test_record_failing
1735    assert_run_record MiniTest::Assertion do
1736      def test_method
1737        assert false
1738      end
1739    end
1740  end
1741
1742  def test_record_error
1743    assert_run_record RuntimeError do
1744      def test_method
1745        raise "unhandled exception"
1746      end
1747    end
1748  end
1749
1750  def test_record_error_teardown
1751    assert_run_record NilClass, RuntimeError do
1752      def test_method
1753        assert true
1754      end
1755
1756      def teardown
1757        raise "unhandled exception"
1758      end
1759    end
1760  end
1761
1762  def test_record_error_in_test_and_teardown
1763    assert_run_record AnError, RuntimeError do
1764      def test_method
1765        raise AnError
1766      end
1767
1768      def teardown
1769        raise "unhandled exception"
1770      end
1771    end
1772  end
1773
1774  def test_record_skip
1775    assert_run_record MiniTest::Skip do
1776      def test_method
1777        skip "not yet"
1778      end
1779    end
1780  end
1781end
1782