minitest 5.11.3 → 5.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c82c1408c60d4743cf06566256146090f22ab11bc5f024cbf4026fd967d7eb6
4
- data.tar.gz: 93e140e22554c00911e381fa0584c52add681e5adb34bc3e575ee79459d7df6e
3
+ metadata.gz: c0b1641b87002f1e0b64cc5e81815a6bdbd22e22fa25f54f80316fe009f5ad72
4
+ data.tar.gz: d63d8373fa0888051f79d4ca405e267e97a5334ffb22aee248227e1485400af3
5
5
  SHA512:
6
- metadata.gz: 3621855d2763f225b2b99061c9eed994040debd9b1b032ebb3318adc42413493458b5c47569b7305954fc7575e870ad97441ce8bec7ddadb92afdd126f1f4bda
7
- data.tar.gz: 19e04c6feff4f3d0cda89fadf4bd3f28415301d8adb2e5650a064cb74df57d8ee9885175738ac967d7a839496ac1c0f1c690627e8a2ca83f71edd6b0edb5b811
6
+ metadata.gz: 76fa5340f5d7f9086b802c13440dad142be63e81d7874d4eb4ec42f60f4530038b74cac18830e2066c80572408f095b45c5639879a38790bacfd3c4a4e13730d
7
+ data.tar.gz: 80e644aeb07febab6f16d32af2e8435045e415d86d145c37afba0a6f694cba304b934a1ff146186a34b108ae3039ff610318e585af6fd087b5b8143aa1f3808a
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,73 @@
1
+ === 5.14.0 / 2020-01-11
2
+
3
+ * 2 minor enhancements:
4
+
5
+ * Block-assertions (eg assert_output) now error if raised inside the block. (casperisfine)
6
+ * Changed assert_raises to only catch Assertion since that covers Skip and friends.
7
+
8
+ * 3 bug fixes:
9
+
10
+ * Added example for value wrapper with block to Expectations module. (stomar)
11
+ * Fixed use of must/wont_be_within_delta on Expectation instance. (stomar)
12
+ * Renamed UnexpectedError#exception to #error to avoid problems with reraising. (casperisfine)
13
+
14
+ === 5.13.0 / 2019-10-29
15
+
16
+ * 9 minor enhancements:
17
+
18
+ * Added Minitest::Guard#osx?
19
+ * Added examples to documentation for assert_raises. (lxxxvi)
20
+ * Added expectations #path_must_exist and #path_wont_exist. Not thrilled with the names.
21
+ * Added fail_after(year, month, day, msg) to allow time-bombing after a deadline.
22
+ * Added skip_until(year, month, day, msg) to allow deferring until a deadline.
23
+ * Deprecated Minitest::Guard#maglev?
24
+ * Deprecated Minitest::Guard#rubinius?
25
+ * Finally added assert_path_exists and refute_path_exists. (deivid-rodriguez)
26
+ * Refactored and pulled Assertions#things_to_diff out of #diff. (BurdetteLamar)
27
+
28
+ * 3 bug fixes:
29
+
30
+ * Fix autorun bug that affects fork exit status in tests. (dylanahsmith/jhawthorn)
31
+ * Improved documentation for _/value/expect, especially for blocks. (svoop)
32
+ * Support new Proc#to_s format. (ko1)
33
+
34
+ === 5.12.2 / 2019-09-28
35
+
36
+ * 1 bug fix:
37
+
38
+ * After chatting w/ @y-yagi and others, decided to lower support to include ruby 2.2.
39
+
40
+ === 5.12.1 / 2019-09-28
41
+
42
+ * 1 minor enhancement:
43
+
44
+ * Added documentation for Reporter classes. (sshaw)
45
+
46
+ * 3 bug fixes:
47
+
48
+ * Avoid using 'match?' to support older ruby versions. (y-yagi)
49
+ * Fixed broken link to reference on goodness-of-fit testing. (havenwood)
50
+ * Update requirements in readme and Rakefile/hoe spec.
51
+
52
+ === 5.12.0 / 2019-09-22
53
+
54
+ * 8 minor enhancements:
55
+
56
+ * Added a descriptive error if assert_output or assert_raises called without a block. (okuramasafumi)
57
+ * Changed mu_pp_for_diff to make having both \n and \\n easier to debug.
58
+ * Deprecated $N for specifying number of parallel test runners. Use MT_CPU.
59
+ * Deprecated use of global expectations. To be removed from MT6.
60
+ * Extended Assertions#mu_pp to encoding validity output for strings to improve diffs.
61
+ * Extended Assertions#mu_pp to output encoding and validity if invalid to improve diffs.
62
+ * Extended Assertions#mu_pp_for_diff to make escaped newlines more obvious in diffs.
63
+ * Fail gracefully when expectation used outside of `it`.
64
+
65
+ * 3 bug fixes:
66
+
67
+ * Check `option[:filter]` klass before match. Fixes 2.6 warning. (y-yagi)
68
+ * Fixed Assertions#diff from recalculating if set to nil
69
+ * Fixed spec section of readme to not use deprecated global expectations. (CheezItMan)
70
+
1
71
  === 5.11.3 / 2018-01-26
2
72
 
3
73
  * 1 bug fix:
@@ -19,6 +19,7 @@ lib/minitest/spec.rb
19
19
  lib/minitest/test.rb
20
20
  lib/minitest/unit.rb
21
21
  test/minitest/metametameta.rb
22
+ test/minitest/test_minitest_assertions.rb
22
23
  test/minitest/test_minitest_benchmark.rb
23
24
  test/minitest/test_minitest_mock.rb
24
25
  test/minitest/test_minitest_reporter.rb
@@ -126,13 +126,13 @@ Define your tests as methods beginning with +test_+.
126
126
 
127
127
  describe "when asked about cheeseburgers" do
128
128
  it "must respond positively" do
129
- @meme.i_can_has_cheezburger?.must_equal "OHAI!"
129
+ _(@meme.i_can_has_cheezburger?).must_equal "OHAI!"
130
130
  end
131
131
  end
132
132
 
133
133
  describe "when asked about blending possibilities" do
134
134
  it "won't say no" do
135
- @meme.will_it_blend?.wont_match /^no/i
135
+ _(@meme.will_it_blend?).wont_match /^no/i
136
136
  end
137
137
  end
138
138
  end
@@ -220,9 +220,9 @@ verification to ensure they got all the calls they were expecting."
220
220
  end
221
221
  end
222
222
 
223
- **Multi-threading and Mocks**
223
+ ==== Multi-threading and Mocks
224
224
 
225
- Minitest mocks do not support multi-threading if it works, fine, if it doesn't
225
+ Minitest mocks do not support multi-threading. If it works, fine, if it doesn't
226
226
  you can use regular ruby patterns and facilities like local variables. Here's
227
227
  an example of asserting that code inside a thread is run:
228
228
 
@@ -294,6 +294,18 @@ provided via plugins. To see them, simply run with +--help+:
294
294
  -p, --pride Pride. Show your testing pride!
295
295
  -a, --autotest Connect to autotest server.
296
296
 
297
+ You can set up a rake task to run all your tests by adding this to your Rakefile:
298
+
299
+ require "rake/testtask"
300
+
301
+ Rake::TestTask.new(:test) do |t|
302
+ t.libs << "test"
303
+ t.libs << "lib"
304
+ t.test_files = FileList["test/**/test_*.rb"]
305
+ end
306
+
307
+ task :default => :test
308
+
297
309
  == Writing Extensions
298
310
 
299
311
  To define a plugin, add a file named minitest/XXX_plugin.rb to your
@@ -379,7 +391,7 @@ The following implementation and test:
379
391
  end
380
392
 
381
393
  it "must respond to work" do
382
- @worker.must_respond_to :work
394
+ _(@worker).must_respond_to :work
383
395
  end
384
396
  end
385
397
 
@@ -469,6 +481,8 @@ able to require minitest and run your tests.
469
481
 
470
482
  == Developing Minitest:
471
483
 
484
+ Minitest requires {Hoe}[https://rubygems.org/gems/hoe].
485
+
472
486
  === Minitest's own tests require UTF-8 external encoding.
473
487
 
474
488
  This is a common problem in Windows, where the default external Encoding is
@@ -547,6 +561,7 @@ minispec-metadata :: Metadata for describe/it blocks & CLI tag filter.
547
561
  E.g. <tt>it "requires JS driver", js: true do</tt> &
548
562
  <tt>ruby test.rb --tag js</tt> runs tests tagged :js.
549
563
  minispec-rails :: Minimal support to use Spec style in Rails 5+.
564
+ mini-apivore :: for swagger based automated API testing.
550
565
  minitest-around :: Around block for minitest. An alternative to
551
566
  setup/teardown dance.
552
567
  minitest-assert_errors :: Adds Minitest assertions to test for errors raised
@@ -589,6 +604,7 @@ minitest-firemock :: Makes your Minitest mocks more resilient.
589
604
  minitest-focus :: Focus on one test at a time.
590
605
  minitest-gcstats :: A minitest plugin that adds a report of the top
591
606
  tests by number of objects allocated.
607
+ minitest-global_expectations:: Support minitest expectation methods for all objects
592
608
  minitest-great_expectations :: Generally useful additions to minitest's
593
609
  assertions and expectations.
594
610
  minitest-growl :: Test notifier for minitest via growl.
@@ -615,6 +631,7 @@ minitest-matchers :: Adds support for RSpec-style matchers to
615
631
  minitest-matchers_vaccine :: Adds assertions that adhere to the matcher spec,
616
632
  but without any expectation infections.
617
633
  minitest-metadata :: Annotate tests with metadata (key-value).
634
+ minitest-mock_expectations :: Provides method call assertions for minitest.
618
635
  minitest-mongoid :: Mongoid assertion matchers for Minitest.
619
636
  minitest-must_not :: Provides must_not as an alias for wont in
620
637
  Minitest.
@@ -660,10 +677,12 @@ minitest-unordered :: Adds a new assertion to minitest for checking the
660
677
  contents of a collection, ignoring element order.
661
678
  minitest-vcr :: Automatic cassette managment with Minitest::Spec
662
679
  and VCR.
680
+ minitest_log :: Adds structured logging, data explication, and verdicts.
663
681
  minitest_owrapper :: Get tests results as a TestResult object.
664
682
  minitest_should :: Shoulda style syntax for minitest test::unit.
665
683
  minitest_tu_shim :: Bridges between test/unit and minitest.
666
684
  mongoid-minitest :: Minitest matchers for Mongoid.
685
+ mutant-minitest :: Minitest integration for mutant.
667
686
  pry-rescue :: A pry plugin w/ minitest support. See
668
687
  pry-rescue/minitest.rb.
669
688
  rspec2minitest :: Easily translate any RSpec matchers to Minitest
@@ -697,8 +716,7 @@ Authors... Please send me a pull request with a description of your minitest ext
697
716
 
698
717
  == REQUIREMENTS:
699
718
 
700
- * Ruby 1.8.7+. No magic is involved. I hope.
701
- * NOTE: 1.8 and 1.9 will be dropped in minitest 6+.
719
+ * Ruby 2.3+. No magic is involved. I hope.
702
720
 
703
721
  == INSTALL:
704
722
 
data/Rakefile CHANGED
@@ -11,21 +11,7 @@ Hoe.spec "minitest" do
11
11
 
12
12
  license "MIT"
13
13
 
14
- ## TODO: uncomment this on the last point release on 5.x
15
- #
16
- # self.post_install_message = <<-"EOM"
17
- # NOTE: minitest 5 will be the last in the minitest family to support
18
- # ruby 1.8 and 1.9 (and maybe 2.0?). If you need to keep using 1.8
19
- # or 1.9, you need to pin your dependency to minitest with
20
- # something like "~> 5.0".
21
- #
22
- # Further, minitest 6 will be dropping the following:
23
- #
24
- # + MiniTest (it's been Minitest for *years*)
25
- # + MiniTest::Unit
26
- # + MiniTest::Unit::TestCase
27
- # + assert_send (unless you argue for it well)
28
- # EOM
14
+ require_ruby_version "~> 2.2"
29
15
  end
30
16
 
31
17
  desc "Find missing expectations"
@@ -8,7 +8,7 @@ require "stringio"
8
8
  # :include: README.rdoc
9
9
 
10
10
  module Minitest
11
- VERSION = "5.11.3" # :nodoc:
11
+ VERSION = "5.14.0" # :nodoc:
12
12
  ENCS = "".respond_to? :encoding # :nodoc:
13
13
 
14
14
  @@installed_at_exit ||= false
@@ -21,7 +21,10 @@ module Minitest
21
21
  # Parallel test executor
22
22
 
23
23
  mc.send :attr_accessor, :parallel_executor
24
- self.parallel_executor = Parallel::Executor.new((ENV["N"] || 2).to_i)
24
+
25
+ warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
26
+ n_threads = (ENV["MT_CPU"] || ENV["N"] || 2).to_i
27
+ self.parallel_executor = Parallel::Executor.new n_threads
25
28
 
26
29
  ##
27
30
  # Filter object for backtraces.
@@ -55,7 +58,9 @@ module Minitest
55
58
 
56
59
  exit_code = nil
57
60
 
61
+ pid = Process.pid
58
62
  at_exit {
63
+ next if Process.pid != pid
59
64
  @@after_run.reverse_each(&:call)
60
65
  exit exit_code || false
61
66
  }
@@ -301,7 +306,7 @@ module Minitest
301
306
 
302
307
  def self.run reporter, options = {}
303
308
  filter = options[:filter] || "/./"
304
- filter = Regexp.new $1 if filter =~ %r%/(.*)/%
309
+ filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
305
310
 
306
311
  filtered_methods = self.runnable_methods.find_all { |m|
307
312
  filter === m || filter === "#{self}##{m}"
@@ -422,7 +427,8 @@ module Minitest
422
427
 
423
428
  ##
424
429
  # Returns a single character string to print based on the result
425
- # of the run. Eg ".", "F", or "E".
430
+ # of the run. One of <tt>"."</tt>, <tt>"F"</tt>,
431
+ # <tt>"E"</tt> or <tt>"S"</tt>.
426
432
 
427
433
  def result_code
428
434
  raise NotImplementedError, "subclass responsibility"
@@ -560,8 +566,10 @@ module Minitest
560
566
  end
561
567
 
562
568
  ##
563
- # Record a result and output the Runnable#result_code. Stores the
564
- # result of the run if the run did not pass.
569
+ # Output and record the result of the test. Call
570
+ # {result#result_code}[rdoc-ref:Runnable#result_code] to get the
571
+ # result character string. Stores the result of the run if the run
572
+ # did not pass.
565
573
 
566
574
  def record result
567
575
  end
@@ -628,18 +636,63 @@ module Minitest
628
636
  #
629
637
  # If you want to create an entirely different type of output (eg,
630
638
  # CI, HTML, etc), this is the place to start.
639
+ #
640
+ # Example:
641
+ #
642
+ # class JenkinsCIReporter < StatisticsReporter
643
+ # def report
644
+ # super # Needed to calculate some statistics
645
+ #
646
+ # print "<testsuite "
647
+ # print "tests='#{count}' "
648
+ # print "failures='#{failures}' "
649
+ # # Remaining XML...
650
+ # end
651
+ # end
631
652
 
632
653
  class StatisticsReporter < Reporter
633
- # :stopdoc:
654
+ ##
655
+ # Total number of assertions.
656
+
634
657
  attr_accessor :assertions
658
+
659
+ ##
660
+ # Total number of test cases.
661
+
635
662
  attr_accessor :count
663
+
664
+ ##
665
+ # An +Array+ of test cases that failed or were skipped.
666
+
636
667
  attr_accessor :results
668
+
669
+ ##
670
+ # Time the test run started. If available, the monotonic clock is
671
+ # used and this is a +Float+, otherwise it's an instance of
672
+ # +Time+.
673
+
637
674
  attr_accessor :start_time
675
+
676
+ ##
677
+ # Test run time. If available, the monotonic clock is used and
678
+ # this is a +Float+, otherwise it's an instance of +Time+.
679
+
638
680
  attr_accessor :total_time
681
+
682
+ ##
683
+ # Total number of tests that failed.
684
+
639
685
  attr_accessor :failures
686
+
687
+ ##
688
+ # Total number of tests that erred.
689
+
640
690
  attr_accessor :errors
691
+
692
+ ##
693
+ # Total number of tests that where skipped.
694
+
641
695
  attr_accessor :skips
642
- # :startdoc:
643
696
 
644
697
  def initialize io = $stdout, options = {} # :nodoc:
645
698
  super
@@ -669,7 +722,10 @@ module Minitest
669
722
  results << result if not result.passed? or result.skipped?
670
723
  end
671
724
 
672
- def report # :nodoc:
725
+ ##
726
+ # Report on the tracked statistics.
727
+
728
+ def report
673
729
  aggregate = results.group_by { |r| r.failure.class }
674
730
  aggregate.default = [] # dumb. group_by should provide this
675
731
 
@@ -851,24 +907,21 @@ module Minitest
851
907
  # Assertion wrapping an unexpected error that was raised during a run.
852
908
 
853
909
  class UnexpectedError < Assertion
854
- attr_accessor :exception # :nodoc:
910
+ # TODO: figure out how to use `cause` instead
911
+ attr_accessor :error # :nodoc:
855
912
 
856
- def initialize exception # :nodoc:
913
+ def initialize error # :nodoc:
857
914
  super "Unexpected exception"
858
- self.exception = exception
915
+ self.error = error
859
916
  end
860
917
 
861
918
  def backtrace # :nodoc:
862
- self.exception.backtrace
863
- end
864
-
865
- def error # :nodoc:
866
- self.exception
919
+ self.error.backtrace
867
920
  end
868
921
 
869
922
  def message # :nodoc:
870
923
  bt = Minitest.filter_backtrace(self.backtrace).join "\n "
871
- "#{self.exception.class}: #{self.exception.message}\n #{bt}"
924
+ "#{self.error.class}: #{self.error.message}\n #{bt}"
872
925
  end
873
926
 
874
927
  def result_label # :nodoc:
@@ -904,6 +957,9 @@ module Minitest
904
957
  # Is this running on maglev?
905
958
 
906
959
  def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
960
+ where = Minitest.filter_backtrace(caller).first
961
+ where = where.split(/:in /, 2).first # clean up noise
962
+ warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6."
907
963
  "maglev" == platform
908
964
  end
909
965
 
@@ -914,10 +970,20 @@ module Minitest
914
970
  /^ruby/ =~ platform
915
971
  end
916
972
 
973
+ ##
974
+ # Is this running on macOS?
975
+
976
+ def osx? platform = RUBY_PLATFORM
977
+ /darwin/ =~ platform
978
+ end
979
+
917
980
  ##
918
981
  # Is this running on rubinius?
919
982
 
920
983
  def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
984
+ where = Minitest.filter_backtrace(caller).first
985
+ where = where.split(/:in /, 2).first # clean up noise
986
+ warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
921
987
  "rbx" == platform
922
988
  end
923
989
 
@@ -27,20 +27,18 @@ module Minitest
27
27
  # figure out what diff to use.
28
28
 
29
29
  def self.diff
30
+ return @diff if defined? @diff
31
+
30
32
  @diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ &&
31
33
  system("diff.exe", __FILE__, __FILE__)) then
32
34
  "diff.exe -u"
33
- elsif Minitest::Test.maglev? then
34
- "diff -u"
35
35
  elsif system("gdiff", __FILE__, __FILE__)
36
36
  "gdiff -u" # solaris and kin suck
37
37
  elsif system("diff", __FILE__, __FILE__)
38
38
  "diff -u"
39
39
  else
40
40
  nil
41
- end unless defined? @diff
42
-
43
- @diff
41
+ end
44
42
  end
45
43
 
46
44
  ##
@@ -55,22 +53,16 @@ module Minitest
55
53
  # diff command or if it doesn't make sense to diff the output
56
54
  # (single line, short output), then it simply returns a basic
57
55
  # comparison between the two.
56
+ #
57
+ # See +things_to_diff+ for more info.
58
58
 
59
59
  def diff exp, act
60
- expect = mu_pp_for_diff exp
61
- butwas = mu_pp_for_diff act
62
60
  result = nil
63
61
 
64
- need_to_diff =
65
- (expect.include?("\n") ||
66
- butwas.include?("\n") ||
67
- expect.size > 30 ||
68
- butwas.size > 30 ||
69
- expect == butwas) &&
70
- Minitest::Assertions.diff
62
+ expect, butwas = things_to_diff(exp, act)
71
63
 
72
64
  return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless
73
- need_to_diff
65
+ expect
74
66
 
75
67
  Tempfile.open("expect") do |a|
76
68
  a.puts expect
@@ -99,10 +91,40 @@ module Minitest
99
91
  result
100
92
  end
101
93
 
94
+ ##
95
+ # Returns things to diff [expect, butwas], or [nil, nil] if nothing to diff.
96
+ #
97
+ # Criterion:
98
+ #
99
+ # 1. Strings include newlines or escaped newlines, but not both.
100
+ # 2. or: String lengths are > 30 characters.
101
+ # 3. or: Strings are equal to each other (but maybe different encodings?).
102
+ # 4. and: we found a diff executable.
103
+
104
+ def things_to_diff exp, act
105
+ expect = mu_pp_for_diff exp
106
+ butwas = mu_pp_for_diff act
107
+
108
+ e1, e2 = expect.include?("\n"), expect.include?("\\n")
109
+ b1, b2 = butwas.include?("\n"), butwas.include?("\\n")
110
+
111
+ need_to_diff =
112
+ (e1 ^ e2 ||
113
+ b1 ^ b2 ||
114
+ expect.size > 30 ||
115
+ butwas.size > 30 ||
116
+ expect == butwas) &&
117
+ Minitest::Assertions.diff
118
+
119
+ need_to_diff && [expect, butwas]
120
+ end
121
+
102
122
  ##
103
123
  # This returns a human-readable version of +obj+. By default
104
- # #inspect is called. You can override this to use #pretty_print
124
+ # #inspect is called. You can override this to use #pretty_inspect
105
125
  # if you want.
126
+ #
127
+ # See Minitest::Test.make_my_diffs_pretty!
106
128
 
107
129
  def mu_pp obj
108
130
  s = obj.inspect
@@ -110,8 +132,11 @@ module Minitest
110
132
  if defined? Encoding then
111
133
  s = s.encode Encoding.default_external
112
134
 
113
- if String === obj && obj.encoding != Encoding.default_external then
114
- s = "# encoding: #{obj.encoding}\n#{s}"
135
+ if String === obj && (obj.encoding != Encoding.default_external ||
136
+ !obj.valid_encoding?) then
137
+ enc = "# encoding: #{obj.encoding}"
138
+ val = "# valid: #{obj.valid_encoding?}"
139
+ s = "#{enc}\n#{val}\n#{s}"
115
140
  end
116
141
  end
117
142
 
@@ -119,13 +144,32 @@ module Minitest
119
144
  end
120
145
 
121
146
  ##
122
- # This returns a diff-able human-readable version of +obj+. This
123
- # differs from the regular mu_pp because it expands escaped
124
- # newlines and makes hex-values generic (like object_ids). This
147
+ # This returns a diff-able more human-readable version of +obj+.
148
+ # This differs from the regular mu_pp because it expands escaped
149
+ # newlines and makes hex-values (like object_ids) generic. This
125
150
  # uses mu_pp to do the first pass and then cleans it up.
126
151
 
127
152
  def mu_pp_for_diff obj
128
- mu_pp(obj).gsub(/\\n/, "\n").gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX")
153
+ str = mu_pp obj
154
+
155
+ # both '\n' & '\\n' (_after_ mu_pp (aka inspect))
156
+ single = !!str.match(/(?<!\\|^)\\n/)
157
+ double = !!str.match(/(?<=\\|^)\\n/)
158
+
159
+ process =
160
+ if single ^ double then
161
+ if single then
162
+ lambda { |s| s == "\\n" ? "\n" : s } # unescape
163
+ else
164
+ lambda { |s| s == "\\\\n" ? "\\n\n" : s } # unescape a bit, add nls
165
+ end
166
+ else
167
+ :itself # leave it alone
168
+ end
169
+
170
+ str.
171
+ gsub(/\\?\\n/, &process).
172
+ gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX") # anonymize hex values
129
173
  end
130
174
 
131
175
  ##
@@ -283,6 +327,9 @@ module Minitest
283
327
  # See also: #assert_silent
284
328
 
285
329
  def assert_output stdout = nil, stderr = nil
330
+ flunk "assert_output requires a block to capture output." unless
331
+ block_given?
332
+
286
333
  out, err = capture_io do
287
334
  yield
288
335
  end
@@ -294,6 +341,18 @@ module Minitest
294
341
  x = send out_msg, stdout, out, "In stdout" if out_msg
295
342
 
296
343
  (!stdout || x) && (!stderr || y)
344
+ rescue Assertion
345
+ raise
346
+ rescue => e
347
+ raise UnexpectedError, e
348
+ end
349
+
350
+ ##
351
+ # Fails unless +path+ exists.
352
+
353
+ def assert_path_exists path, msg = nil
354
+ msg = message(msg) { "Expected path '#{path}' to exist" }
355
+ assert File.exist?(path), msg
297
356
  end
298
357
 
299
358
  ##
@@ -316,9 +375,26 @@ module Minitest
316
375
  #
317
376
  # +exp+ takes an optional message on the end to help explain
318
377
  # failures and defaults to StandardError if no exception class is
319
- # passed.
378
+ # passed. Eg:
379
+ #
380
+ # assert_raises(CustomError) { method_with_custom_error }
381
+ #
382
+ # With custom error message:
383
+ #
384
+ # assert_raises(CustomError, 'This should have raised CustomError') { method_with_custom_error }
385
+ #
386
+ # Using the returned object:
387
+ #
388
+ # error = assert_raises(CustomError) do
389
+ # raise CustomError, 'This is really bad'
390
+ # end
391
+ #
392
+ # assert_equal 'This is really bad', error.message
320
393
 
321
394
  def assert_raises *exp
395
+ flunk "assert_raises requires a block to capture errors." unless
396
+ block_given?
397
+
322
398
  msg = "#{exp.pop}.\n" if String === exp.last
323
399
  exp << StandardError if exp.empty?
324
400
 
@@ -327,7 +403,7 @@ module Minitest
327
403
  rescue *exp => e
328
404
  pass # count assertion
329
405
  return e
330
- rescue Minitest::Skip, Minitest::Assertion
406
+ rescue Minitest::Assertion # incl Skip & UnexpectedError
331
407
  # don't count assertion
332
408
  raise
333
409
  rescue SignalException, SystemExit
@@ -413,6 +489,10 @@ module Minitest
413
489
  end
414
490
 
415
491
  assert caught, message(msg) { default }
492
+ rescue Assertion
493
+ raise
494
+ rescue => e
495
+ raise UnexpectedError, e
416
496
  end
417
497
 
418
498
  ##
@@ -485,6 +565,11 @@ module Minitest
485
565
  captured_stderr.unlink
486
566
  $stdout.reopen orig_stdout
487
567
  $stderr.reopen orig_stderr
568
+
569
+ orig_stdout.close
570
+ orig_stderr.close
571
+ captured_stdout.close
572
+ captured_stderr.close
488
573
  end
489
574
  end
490
575
  end
@@ -504,7 +589,16 @@ module Minitest
504
589
  end
505
590
 
506
591
  ##
507
- # Fails with +msg+
592
+ # Fails after a given date (in the local time zone). This allows
593
+ # you to put time-bombs in your tests if you need to keep
594
+ # something around until a later date lest you forget about it.
595
+
596
+ def fail_after y,m,d,msg
597
+ flunk msg if Time.now > Time.local(y, m, d)
598
+ end
599
+
600
+ ##
601
+ # Fails with +msg+.
508
602
 
509
603
  def flunk msg = nil
510
604
  msg ||= "Epic Fail!"
@@ -638,6 +732,14 @@ module Minitest
638
732
  refute o1.__send__(op, o2), msg
639
733
  end
640
734
 
735
+ ##
736
+ # Fails if +path+ exists.
737
+
738
+ def refute_path_exists path, msg = nil
739
+ msg = message(msg) { "Expected path '#{path}' to not exist" }
740
+ refute File.exist?(path), msg
741
+ end
742
+
641
743
  ##
642
744
  # For testing with predicates.
643
745
  #
@@ -683,6 +785,18 @@ module Minitest
683
785
  raise Minitest::Skip, msg, bt
684
786
  end
685
787
 
788
+ ##
789
+ # Skips the current run until a given date (in the local time
790
+ # zone). This allows you to put some fixes on hold until a later
791
+ # date, but still holds you accountable and prevents you from
792
+ # forgetting it.
793
+
794
+ def skip_until y,m,d,msg
795
+ skip msg if Time.now < Time.local(y, m, d)
796
+ where = caller.first.split(/:/, 3).first(2).join ":"
797
+ warn "Stale skip_until %p at %s" % [msg, where]
798
+ end
799
+
686
800
  ##
687
801
  # Was this testcase skipped? Meant for #teardown.
688
802