minitest 5.11.3 → 5.17.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.
data/lib/minitest.rb CHANGED
@@ -3,59 +3,79 @@ require "thread"
3
3
  require "mutex_m"
4
4
  require "minitest/parallel"
5
5
  require "stringio"
6
+ require "etc"
6
7
 
7
8
  ##
8
9
  # :include: README.rdoc
9
10
 
10
11
  module Minitest
11
- VERSION = "5.11.3" # :nodoc:
12
- ENCS = "".respond_to? :encoding # :nodoc:
12
+ VERSION = "5.17.0" # :nodoc:
13
13
 
14
14
  @@installed_at_exit ||= false
15
15
  @@after_run = []
16
16
  @extensions = []
17
17
 
18
- mc = (class << self; self; end)
18
+ def self.cattr_accessor name # :nodoc:
19
+ (class << self; self; end).attr_accessor name
20
+ end
21
+
22
+ ##
23
+ # The random seed used for this run. This is used to srand at the
24
+ # start of the run and between each +Runnable.run+.
25
+ #
26
+ # Set via Minitest.run after processing args.
27
+
28
+ cattr_accessor :seed
19
29
 
20
30
  ##
21
31
  # Parallel test executor
22
32
 
23
- mc.send :attr_accessor, :parallel_executor
24
- self.parallel_executor = Parallel::Executor.new((ENV["N"] || 2).to_i)
33
+ cattr_accessor :parallel_executor
34
+
35
+ warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
36
+ n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
37
+
38
+ self.parallel_executor = Parallel::Executor.new n_threads
25
39
 
26
40
  ##
27
41
  # Filter object for backtraces.
28
42
 
29
- mc.send :attr_accessor, :backtrace_filter
43
+ cattr_accessor :backtrace_filter
30
44
 
31
45
  ##
32
46
  # Reporter object to be used for all runs.
33
47
  #
34
48
  # NOTE: This accessor is only available during setup, not during runs.
35
49
 
36
- mc.send :attr_accessor, :reporter
50
+ cattr_accessor :reporter
37
51
 
38
52
  ##
39
53
  # Names of known extension plugins.
40
54
 
41
- mc.send :attr_accessor, :extensions
55
+ cattr_accessor :extensions
42
56
 
43
57
  ##
44
58
  # The signal to use for dumping information to STDERR. Defaults to "INFO".
45
59
 
46
- mc.send :attr_accessor, :info_signal
60
+ cattr_accessor :info_signal
47
61
  self.info_signal = "INFO"
48
62
 
49
63
  ##
50
64
  # Registers Minitest to run at process exit
51
65
 
52
66
  def self.autorun
67
+ if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=)
68
+ Warning[:deprecated] = true
69
+ end
70
+
53
71
  at_exit {
54
72
  next if $! and not ($!.kind_of? SystemExit and $!.success?)
55
73
 
56
74
  exit_code = nil
57
75
 
76
+ pid = Process.pid
58
77
  at_exit {
78
+ next if Process.pid != pid
59
79
  @@after_run.reverse_each(&:call)
60
80
  exit exit_code || false
61
81
  }
@@ -122,6 +142,9 @@ module Minitest
122
142
 
123
143
  options = process_args args
124
144
 
145
+ Minitest.seed = options[:seed]
146
+ srand Minitest.seed
147
+
125
148
  reporter = CompositeReporter.new
126
149
  reporter << SummaryReporter.new(options[:io], options)
127
150
  reporter << ProgressReporter.new(options[:io], options)
@@ -148,7 +171,7 @@ module Minitest
148
171
  # sub-classes to run.
149
172
 
150
173
  def self.__run reporter, options
151
- suites = Runnable.runnables.reject { |s| s.runnable_methods.empty? }.shuffle
174
+ suites = Runnable.runnables.shuffle
152
175
  parallel, serial = suites.partition { |s| s.test_order == :parallel }
153
176
 
154
177
  # If we run the parallel tests before the serial tests, the parallel tests
@@ -186,6 +209,10 @@ module Minitest
186
209
  options[:verbose] = true
187
210
  end
188
211
 
212
+ opts.on "--show-skips", "Show skipped at the end of run." do
213
+ options[:show_skips] = true
214
+ end
215
+
189
216
  opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
190
217
  options[:filter] = a
191
218
  end
@@ -194,6 +221,10 @@ module Minitest
194
221
  options[:exclude] = a
195
222
  end
196
223
 
224
+ opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s|
225
+ options[:skip] = s.chars.to_a
226
+ end
227
+
197
228
  unless extensions.empty?
198
229
  opts.separator ""
199
230
  opts.separator "Known extensions: #{extensions.join(", ")}"
@@ -223,8 +254,6 @@ module Minitest
223
254
  orig_args << "--seed" << options[:seed].to_s
224
255
  end
225
256
 
226
- srand options[:seed]
227
-
228
257
  options[:args] = orig_args.map { |s|
229
258
  s =~ /[\s|&<>$()]/ ? s.inspect : s
230
259
  }.join " "
@@ -233,7 +262,9 @@ module Minitest
233
262
  end
234
263
 
235
264
  def self.filter_backtrace bt # :nodoc:
236
- backtrace_filter.filter bt
265
+ result = backtrace_filter.filter bt
266
+ result = bt.dup if result.empty?
267
+ result
237
268
  end
238
269
 
239
270
  ##
@@ -301,7 +332,7 @@ module Minitest
301
332
 
302
333
  def self.run reporter, options = {}
303
334
  filter = options[:filter] || "/./"
304
- filter = Regexp.new $1 if filter =~ %r%/(.*)/%
335
+ filter = Regexp.new $1 if filter.is_a?(String) && filter =~ %r%/(.*)/%
305
336
 
306
337
  filtered_methods = self.runnable_methods.find_all { |m|
307
338
  filter === m || filter === "#{self}##{m}"
@@ -422,7 +453,8 @@ module Minitest
422
453
 
423
454
  ##
424
455
  # Returns a single character string to print based on the result
425
- # of the run. Eg ".", "F", or "E".
456
+ # of the run. One of <tt>"."</tt>, <tt>"F"</tt>,
457
+ # <tt>"E"</tt> or <tt>"S"</tt>.
426
458
 
427
459
  def result_code
428
460
  raise NotImplementedError, "subclass responsibility"
@@ -560,8 +592,10 @@ module Minitest
560
592
  end
561
593
 
562
594
  ##
563
- # Record a result and output the Runnable#result_code. Stores the
564
- # result of the run if the run did not pass.
595
+ # Output and record the result of the test. Call
596
+ # {result#result_code}[rdoc-ref:Runnable#result_code] to get the
597
+ # result character string. Stores the result of the run if the run
598
+ # did not pass.
565
599
 
566
600
  def record result
567
601
  end
@@ -628,18 +662,63 @@ module Minitest
628
662
  #
629
663
  # If you want to create an entirely different type of output (eg,
630
664
  # CI, HTML, etc), this is the place to start.
665
+ #
666
+ # Example:
667
+ #
668
+ # class JenkinsCIReporter < StatisticsReporter
669
+ # def report
670
+ # super # Needed to calculate some statistics
671
+ #
672
+ # print "<testsuite "
673
+ # print "tests='#{count}' "
674
+ # print "failures='#{failures}' "
675
+ # # Remaining XML...
676
+ # end
677
+ # end
631
678
 
632
679
  class StatisticsReporter < Reporter
633
- # :stopdoc:
680
+ ##
681
+ # Total number of assertions.
682
+
634
683
  attr_accessor :assertions
684
+
685
+ ##
686
+ # Total number of test cases.
687
+
635
688
  attr_accessor :count
689
+
690
+ ##
691
+ # An +Array+ of test cases that failed or were skipped.
692
+
636
693
  attr_accessor :results
694
+
695
+ ##
696
+ # Time the test run started. If available, the monotonic clock is
697
+ # used and this is a +Float+, otherwise it's an instance of
698
+ # +Time+.
699
+
637
700
  attr_accessor :start_time
701
+
702
+ ##
703
+ # Test run time. If available, the monotonic clock is used and
704
+ # this is a +Float+, otherwise it's an instance of +Time+.
705
+
638
706
  attr_accessor :total_time
707
+
708
+ ##
709
+ # Total number of tests that failed.
710
+
639
711
  attr_accessor :failures
712
+
713
+ ##
714
+ # Total number of tests that erred.
715
+
640
716
  attr_accessor :errors
717
+
718
+ ##
719
+ # Total number of tests that where skipped.
720
+
641
721
  attr_accessor :skips
642
- # :startdoc:
643
722
 
644
723
  def initialize io = $stdout, options = {} # :nodoc:
645
724
  super
@@ -669,7 +748,10 @@ module Minitest
669
748
  results << result if not result.passed? or result.skipped?
670
749
  end
671
750
 
672
- def report # :nodoc:
751
+ ##
752
+ # Report on the tracked statistics.
753
+
754
+ def report
673
755
  aggregate = results.group_by { |r| r.failure.class }
674
756
  aggregate.default = [] # dumb. group_by should provide this
675
757
 
@@ -726,9 +808,14 @@ module Minitest
726
808
 
727
809
  def aggregated_results io # :nodoc:
728
810
  filtered_results = results.dup
729
- filtered_results.reject!(&:skipped?) unless options[:verbose]
811
+ filtered_results.reject!(&:skipped?) unless
812
+ options[:verbose] or options[:show_skips]
813
+
814
+ skip = options[:skip] || []
730
815
 
731
816
  filtered_results.each_with_index { |result, i|
817
+ next if skip.include? result.result_code
818
+
732
819
  io.puts "\n%3d) %s" % [i+1, result]
733
820
  }
734
821
  io.puts
@@ -736,26 +823,19 @@ module Minitest
736
823
  end
737
824
 
738
825
  def to_s # :nodoc:
739
- aggregated_results(StringIO.new(binary_string)).string
826
+ aggregated_results(StringIO.new(''.b)).string
740
827
  end
741
828
 
742
829
  def summary # :nodoc:
743
830
  extra = ""
744
831
 
745
832
  extra = "\n\nYou have skipped tests. Run with --verbose for details." if
746
- results.any?(&:skipped?) unless options[:verbose] or ENV["MT_NO_SKIP_MSG"]
833
+ results.any?(&:skipped?) unless
834
+ options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
747
835
 
748
836
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
749
837
  [count, assertions, failures, errors, skips, extra]
750
838
  end
751
-
752
- private
753
-
754
- if '<3'.respond_to? :b
755
- def binary_string; ''.b; end
756
- else
757
- def binary_string; ''.force_encoding(Encoding::ASCII_8BIT); end
758
- end
759
839
  end
760
840
 
761
841
  ##
@@ -851,24 +931,21 @@ module Minitest
851
931
  # Assertion wrapping an unexpected error that was raised during a run.
852
932
 
853
933
  class UnexpectedError < Assertion
854
- attr_accessor :exception # :nodoc:
934
+ # TODO: figure out how to use `cause` instead
935
+ attr_accessor :error # :nodoc:
855
936
 
856
- def initialize exception # :nodoc:
937
+ def initialize error # :nodoc:
857
938
  super "Unexpected exception"
858
- self.exception = exception
939
+ self.error = error
859
940
  end
860
941
 
861
942
  def backtrace # :nodoc:
862
- self.exception.backtrace
863
- end
864
-
865
- def error # :nodoc:
866
- self.exception
943
+ self.error.backtrace
867
944
  end
868
945
 
869
946
  def message # :nodoc:
870
947
  bt = Minitest.filter_backtrace(self.backtrace).join "\n "
871
- "#{self.exception.class}: #{self.exception.message}\n #{bt}"
948
+ "#{self.error.class}: #{self.error.message}\n #{bt}"
872
949
  end
873
950
 
874
951
  def result_label # :nodoc:
@@ -904,6 +981,9 @@ module Minitest
904
981
  # Is this running on maglev?
905
982
 
906
983
  def maglev? 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: `maglev?` called from #{where}. This will fail in Minitest 6."
907
987
  "maglev" == platform
908
988
  end
909
989
 
@@ -914,10 +994,20 @@ module Minitest
914
994
  /^ruby/ =~ platform
915
995
  end
916
996
 
997
+ ##
998
+ # Is this running on macOS?
999
+
1000
+ def osx? platform = RUBY_PLATFORM
1001
+ /darwin/ =~ platform
1002
+ end
1003
+
917
1004
  ##
918
1005
  # Is this running on rubinius?
919
1006
 
920
1007
  def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE
1008
+ where = Minitest.filter_backtrace(caller).first
1009
+ where = where.split(/:in /, 2).first # clean up noise
1010
+ warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6."
921
1011
  "rbx" == platform
922
1012
  end
923
1013
 
@@ -939,12 +1029,13 @@ module Minitest
939
1029
  MT_RE = %r%lib/minitest% #:nodoc:
940
1030
 
941
1031
  ##
942
- # Filter +bt+ to something useful. Returns the whole thing if $DEBUG.
1032
+ # Filter +bt+ to something useful. Returns the whole thing if
1033
+ # $DEBUG (ruby) or $MT_DEBUG (env).
943
1034
 
944
1035
  def filter bt
945
1036
  return ["No backtrace"] unless bt
946
1037
 
947
- return bt.dup if $DEBUG
1038
+ return bt.dup if $DEBUG || ENV["MT_DEBUG"]
948
1039
 
949
1040
  new_bt = bt.take_while { |line| line !~ MT_RE }
950
1041
  new_bt = bt.select { |line| line !~ MT_RE } if new_bt.empty?
@@ -6,8 +6,27 @@ class Minitest::Test
6
6
  def clean s
7
7
  s.gsub(/^ {6}/, "")
8
8
  end
9
+
10
+ def with_empty_backtrace_filter
11
+ original = Minitest.backtrace_filter
12
+
13
+ obj = Minitest::BacktraceFilter.new
14
+ def obj.filter _bt
15
+ []
16
+ end
17
+
18
+ Minitest::Test.io_lock.synchronize do # try not to trounce in parallel
19
+ begin
20
+ Minitest.backtrace_filter = obj
21
+ yield
22
+ ensure
23
+ Minitest.backtrace_filter = original
24
+ end
25
+ end
26
+ end
9
27
  end
10
28
 
29
+
11
30
  class FakeNamedTest < Minitest::Test
12
31
  @@count = 0
13
32
 
@@ -19,9 +38,20 @@ class FakeNamedTest < Minitest::Test
19
38
  end
20
39
  end
21
40
 
41
+ module MyModule; end
42
+ class AnError < StandardError; include MyModule; end
43
+
22
44
  class MetaMetaMetaTestCase < Minitest::Test
23
45
  attr_accessor :reporter, :output, :tu
24
46
 
47
+ def with_stderr err
48
+ old = $stderr
49
+ $stderr = err
50
+ yield
51
+ ensure
52
+ $stderr = old
53
+ end
54
+
25
55
  def run_tu_with_fresh_reporter flags = %w[--seed 42]
26
56
  options = Minitest.process_args flags
27
57
 
@@ -31,18 +61,20 @@ class MetaMetaMetaTestCase < Minitest::Test
31
61
  reporter << Minitest::SummaryReporter.new(@output, options)
32
62
  reporter << Minitest::ProgressReporter.new(@output, options)
33
63
 
34
- reporter.start
64
+ with_stderr @output do
65
+ reporter.start
35
66
 
36
- yield(reporter) if block_given?
67
+ yield(reporter) if block_given?
37
68
 
38
- @tus ||= [@tu]
39
- @tus.each do |tu|
40
- Minitest::Runnable.runnables.delete tu
69
+ @tus ||= [@tu]
70
+ @tus.each do |tu|
71
+ Minitest::Runnable.runnables.delete tu
41
72
 
42
- tu.run reporter, options
43
- end
73
+ tu.run reporter, options
74
+ end
44
75
 
45
- reporter.report
76
+ reporter.report
77
+ end
46
78
  end
47
79
 
48
80
  def first_reporter
@@ -81,6 +113,8 @@ class MetaMetaMetaTestCase < Minitest::Test
81
113
  output.gsub!(/^(\s+)[^:]+:\d+:in/, '\1FILE:LINE:in')
82
114
  end
83
115
 
116
+ output.gsub!(/( at )[^:]+:\d+/, '\1[FILE:LINE]')
117
+
84
118
  output
85
119
  end
86
120
 
@@ -95,7 +129,7 @@ class MetaMetaMetaTestCase < Minitest::Test
95
129
 
96
130
  def setup
97
131
  super
98
- srand 42
132
+ Minitest.seed = 42
99
133
  Minitest::Test.reset
100
134
  @tu = nil
101
135
  end