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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +187 -4
- data/Manifest.txt +3 -0
- data/README.rdoc +100 -15
- data/Rakefile +4 -16
- data/lib/hoe/minitest.rb +0 -4
- data/lib/minitest/assertions.rb +144 -29
- data/lib/minitest/benchmark.rb +7 -7
- data/lib/minitest/expectations.rb +54 -35
- data/lib/minitest/mock.rb +119 -32
- data/lib/minitest/pride_plugin.rb +1 -1
- data/lib/minitest/spec.rb +27 -9
- data/lib/minitest/test.rb +42 -6
- data/lib/minitest/test_task.rb +305 -0
- data/lib/minitest/unit.rb +5 -8
- data/lib/minitest.rb +133 -42
- data/test/minitest/metametameta.rb +43 -9
- data/test/minitest/test_minitest_assertions.rb +1591 -0
- data/test/minitest/test_minitest_benchmark.rb +2 -2
- data/test/minitest/test_minitest_mock.rb +288 -16
- data/test/minitest/test_minitest_reporter.rb +30 -17
- data/test/minitest/test_minitest_spec.rb +273 -155
- data/test/minitest/test_minitest_test.rb +271 -1141
- data/test/minitest/test_minitest_test_task.rb +46 -0
- data.tar.gz.sig +0 -0
- metadata +35 -22
- metadata.gz.sig +0 -0
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.
|
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
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
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
|
-
|
50
|
+
cattr_accessor :reporter
|
37
51
|
|
38
52
|
##
|
39
53
|
# Names of known extension plugins.
|
40
54
|
|
41
|
-
|
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
|
-
|
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.
|
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.
|
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
|
-
#
|
564
|
-
# result
|
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
|
-
|
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
|
-
|
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
|
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(
|
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
|
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
|
-
|
934
|
+
# TODO: figure out how to use `cause` instead
|
935
|
+
attr_accessor :error # :nodoc:
|
855
936
|
|
856
|
-
def initialize
|
937
|
+
def initialize error # :nodoc:
|
857
938
|
super "Unexpected exception"
|
858
|
-
self.
|
939
|
+
self.error = error
|
859
940
|
end
|
860
941
|
|
861
942
|
def backtrace # :nodoc:
|
862
|
-
self.
|
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.
|
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
|
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
|
-
|
64
|
+
with_stderr @output do
|
65
|
+
reporter.start
|
35
66
|
|
36
|
-
|
67
|
+
yield(reporter) if block_given?
|
37
68
|
|
38
|
-
|
39
|
-
|
40
|
-
|
69
|
+
@tus ||= [@tu]
|
70
|
+
@tus.each do |tu|
|
71
|
+
Minitest::Runnable.runnables.delete tu
|
41
72
|
|
42
|
-
|
43
|
-
|
73
|
+
tu.run reporter, options
|
74
|
+
end
|
44
75
|
|
45
|
-
|
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
|
-
|
132
|
+
Minitest.seed = 42
|
99
133
|
Minitest::Test.reset
|
100
134
|
@tu = nil
|
101
135
|
end
|