minitest 5.15.0 → 5.16.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.
@@ -0,0 +1,305 @@
1
+ require "shellwords"
2
+ require "rbconfig"
3
+ require "rake/tasklib"
4
+
5
+ module Minitest # :nodoc:
6
+
7
+ ##
8
+ # Minitest::TestTask is a rake helper that generates several rake
9
+ # tasks under the main test task's name-space.
10
+ #
11
+ # task <name> :: the main test task
12
+ # task <name>:cmd :: prints the command to use
13
+ # task <name>:deps :: runs each test file by itself to find dependency errors
14
+ # task <name>:slow :: runs the tests and reports the slowest 25 tests.
15
+ #
16
+ # Examples:
17
+ #
18
+ # Minitest::TestTask.create
19
+ #
20
+ # The most basic and default setup.
21
+ #
22
+ # Minitest::TestTask.create :my_tests
23
+ #
24
+ # The most basic/default setup, but with a custom name
25
+ #
26
+ # Minitest::TestTask.create :unit do |t|
27
+ # t.test_globs = ["test/unit/**/*_test.rb"]
28
+ # t.warning = false
29
+ # end
30
+ #
31
+ # Customize the name and only run unit tests.
32
+
33
+ class TestTask < Rake::TaskLib
34
+ WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc:
35
+
36
+ ##
37
+ # Create several test-oriented tasks under +name+. Takes an
38
+ # optional block to customize variables.
39
+
40
+ def self.create name = :test, &block
41
+ task = new name
42
+ task.instance_eval(&block) if block
43
+ task.process_env
44
+ task.define
45
+ task
46
+ end
47
+
48
+ ##
49
+ # Extra arguments to pass to the tests. Defaults empty but gets
50
+ # populated by a number of enviroment variables:
51
+ #
52
+ # N (-n flag) :: a string or regexp of tests to run.
53
+ # X (-e flag) :: a string or regexp of tests to exclude.
54
+ # A (arg) :: quick way to inject an arbitrary argument (eg A=--help).
55
+ #
56
+ # See #process_env
57
+
58
+ attr_accessor :extra_args
59
+
60
+ ##
61
+ # The code to load the framework. Defaults to requiring
62
+ # minitest/autorun...
63
+ #
64
+ # Why do I have this as an option?
65
+
66
+ attr_accessor :framework
67
+
68
+ ##
69
+ # Extra library directories to include. Defaults to %w[lib test
70
+ # .]. Also uses $MT_LIB_EXTRAS allowing you to dynamically
71
+ # override/inject directories for custom runs.
72
+
73
+ attr_accessor :libs
74
+
75
+ ##
76
+ # The name of the task and base name for the other tasks generated.
77
+
78
+ attr_accessor :name
79
+
80
+ ##
81
+ # File globs to find test files. Defaults to something sensible to
82
+ # find test files under the test directory.
83
+
84
+ attr_accessor :test_globs
85
+
86
+ ##
87
+ # Turn on ruby warnings (-w flag). Defaults to true.
88
+
89
+ attr_accessor :warning
90
+
91
+ ##
92
+ # Optional: Additional ruby to run before the test framework is loaded.
93
+
94
+ attr_accessor :test_prelude
95
+
96
+ ##
97
+ # Print out commands as they run. Defaults to Rake's +trace+ (-t
98
+ # flag) option.
99
+
100
+ attr_accessor :verbose
101
+
102
+ ##
103
+ # Use TestTask.create instead.
104
+
105
+ def initialize name = :test # :nodoc:
106
+ self.extra_args = []
107
+ self.framework = %(require "minitest/autorun")
108
+ self.libs = %w[lib test .]
109
+ self.name = name
110
+ self.test_globs = ["test/**/test_*.rb",
111
+ "test/**/*_test.rb"]
112
+ self.test_prelude = nil
113
+ self.verbose = Rake.application.options.trace
114
+ self.warning = true
115
+ end
116
+
117
+ ##
118
+ # Extract variables from the environment and convert them to
119
+ # command line arguments. See #extra_args.
120
+ #
121
+ # Environment Variables:
122
+ #
123
+ # MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
124
+ # N :: Tests to run (string or /regexp/).
125
+ # X :: Tests to exclude (string or /regexp/).
126
+ # A :: Any extra arguments. Honors shell quoting.
127
+ #
128
+ # Deprecated:
129
+ #
130
+ # TESTOPTS :: For argument passing, use +A+.
131
+ # N :: For parallel testing, use +MT_CPU+.
132
+ # FILTER :: Same as +TESTOPTS+.
133
+
134
+ def process_env
135
+ warn "TESTOPTS is deprecated in Minitest::TestTask. Use A instead" if
136
+ ENV["TESTOPTS"]
137
+ warn "FILTER is deprecated in Minitest::TestTask. Use A instead" if
138
+ ENV["FILTER"]
139
+ warn "N is deprecated in Minitest::TestTask. Use MT_CPU instead" if
140
+ ENV["N"] && ENV["N"].to_i > 0
141
+
142
+ lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR
143
+ self.libs[0,0] = lib_extras
144
+
145
+ extra_args << "-n" << ENV["N"] if ENV["N"]
146
+ extra_args << "-e" << ENV["X"] if ENV["X"]
147
+ extra_args.concat Shellwords.split(ENV["TESTOPTS"]) if ENV["TESTOPTS"]
148
+ extra_args.concat Shellwords.split(ENV["FILTER"]) if ENV["FILTER"]
149
+ extra_args.concat Shellwords.split(ENV["A"]) if ENV["A"]
150
+
151
+ ENV.delete "N" if ENV["N"]
152
+
153
+ # TODO? RUBY_DEBUG = ENV["RUBY_DEBUG"]
154
+ # TODO? ENV["RUBY_FLAGS"]
155
+
156
+ extra_args.compact!
157
+ end
158
+
159
+ def define # :nodoc:
160
+ default_tasks = []
161
+
162
+ desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args."
163
+ task name do
164
+ ruby make_test_cmd, verbose:verbose
165
+ end
166
+
167
+ desc "Print out the test command. Good for profiling and other tools."
168
+ task "#{name}:cmd" do
169
+ puts "ruby #{make_test_cmd}"
170
+ end
171
+
172
+ desc "Show which test files fail when run in isolation."
173
+ task "#{name}:isolated" do
174
+ tests = Dir[*self.test_globs].uniq
175
+
176
+ # 3 seems to be the magic number... (tho not by that much)
177
+ bad, good, n = {}, [], (ENV.delete("K") || 3).to_i
178
+ file = ENV.delete("F")
179
+ times = {}
180
+
181
+ tt0 = Time.now
182
+
183
+ n.threads_do tests.sort do |path|
184
+ t0 = Time.now
185
+ output = `#{Gem.ruby} #{make_test_cmd path} 2>&1`
186
+ t1 = Time.now - t0
187
+
188
+ times[path] = t1
189
+
190
+ if $?.success?
191
+ $stderr.print "."
192
+ good << path
193
+ else
194
+ $stderr.print "x"
195
+ bad[path] = output
196
+ end
197
+ end
198
+
199
+ puts "done"
200
+ puts "Ran in %.2f seconds" % [ Time.now - tt0 ]
201
+
202
+ if file then
203
+ require "json"
204
+ File.open file, "w" do |io|
205
+ io.puts JSON.pretty_generate times
206
+ end
207
+ end
208
+
209
+ unless good.empty?
210
+ puts
211
+ puts "# Good tests:"
212
+ puts
213
+ good.sort.each do |path|
214
+ puts "%.2fs: %s" % [times[path], path]
215
+ end
216
+ end
217
+
218
+ unless bad.empty?
219
+ puts
220
+ puts "# Bad tests:"
221
+ puts
222
+ bad.keys.sort.each do |path|
223
+ puts "%.2fs: %s" % [times[path], path]
224
+ end
225
+ puts
226
+ puts "# Bad Test Output:"
227
+ puts
228
+ bad.sort.each do |path, output|
229
+ puts
230
+ puts "# #{path}:"
231
+ puts output
232
+ end
233
+ exit 1
234
+ end
235
+ end
236
+
237
+ task "#{name}:deps" => "#{name}:isolated" # now just an alias
238
+
239
+ desc "Show bottom 25 tests wrt time."
240
+ task "#{name}:slow" do
241
+ sh ["rake #{name} TESTOPTS=-v",
242
+ "egrep '#test_.* s = .'",
243
+ "sort -n -k2 -t=",
244
+ "tail -25"].join " | "
245
+ end
246
+
247
+ default_tasks << name
248
+
249
+ desc "Run the default task(s)."
250
+ task :default => default_tasks
251
+ end
252
+
253
+ ##
254
+ # Generate the test command-line.
255
+
256
+ def make_test_cmd globs = test_globs
257
+ tests = []
258
+ tests.concat Dir[*globs].sort.shuffle # TODO: SEED -> srand first?
259
+ tests.map! { |f| %(require "#{f}") }
260
+
261
+ runner = []
262
+ runner << test_prelude if test_prelude
263
+ runner << framework
264
+ runner.concat tests
265
+ runner = runner.join "; "
266
+
267
+ args = []
268
+ args << "-I#{libs.join(File::PATH_SEPARATOR)}" unless libs.empty?
269
+ args << "-w" if warning
270
+ args << '-e'
271
+ args << "'#{runner}'"
272
+ args << '--'
273
+ args << extra_args.map(&:shellescape)
274
+
275
+ args.join " "
276
+ end
277
+ end
278
+ end
279
+
280
+ class Work < Queue
281
+ def initialize jobs = []
282
+ super()
283
+
284
+ jobs.each do |job|
285
+ self << job
286
+ end
287
+
288
+ close
289
+ end
290
+ end
291
+
292
+ class Integer
293
+ def threads_do(jobs) # :nodoc:
294
+ require "thread"
295
+ q = Work.new jobs
296
+
297
+ self.times.map {
298
+ Thread.new do
299
+ while job = q.pop # go until quit value
300
+ yield job
301
+ end
302
+ end
303
+ }.each(&:join)
304
+ end
305
+ end
data/lib/minitest/unit.rb CHANGED
@@ -1,5 +1,3 @@
1
- # :stopdoc:
2
-
3
1
  unless defined?(Minitest) then
4
2
  # all of this crap is just to avoid circular requires and is only
5
3
  # needed if a user requires "minitest/unit" directly instead of
@@ -10,17 +8,18 @@ unless defined?(Minitest) then
10
8
  warn %(Warning: or add 'gem "minitest"' before 'require "minitest/autorun"')
11
9
  warn "From:\n #{from}"
12
10
 
13
- module Minitest; end
14
- MiniTest = Minitest # prevents minitest.rb from requiring back to us
11
+ module Minitest # :nodoc:
12
+ end
13
+ MiniTest = Minitest # :nodoc: # prevents minitest.rb from requiring back to us
15
14
  require "minitest"
16
15
  end
17
16
 
18
17
  MiniTest = Minitest unless defined?(MiniTest)
19
18
 
20
19
  module Minitest
21
- class Unit
20
+ class Unit # :nodoc:
22
21
  VERSION = Minitest::VERSION
23
- class TestCase < Minitest::Test
22
+ class TestCase < Minitest::Test # :nodoc:
24
23
  def self.inherited klass # :nodoc:
25
24
  from = caller.first
26
25
  warn "MiniTest::Unit::TestCase is now Minitest::Test. From #{from}"
@@ -41,5 +40,3 @@ module Minitest
41
40
  end
42
41
  end
43
42
  end
44
-
45
- # :startdoc:
data/lib/minitest.rb CHANGED
@@ -9,45 +9,55 @@ require "etc"
9
9
  # :include: README.rdoc
10
10
 
11
11
  module Minitest
12
- VERSION = "5.15.0" # :nodoc:
13
- ENCS = "".respond_to? :encoding # :nodoc:
12
+ VERSION = "5.16.0" # :nodoc:
14
13
 
15
14
  @@installed_at_exit ||= false
16
15
  @@after_run = []
17
16
  @extensions = []
18
17
 
19
- 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
20
29
 
21
30
  ##
22
31
  # Parallel test executor
23
32
 
24
- mc.send :attr_accessor, :parallel_executor
33
+ cattr_accessor :parallel_executor
25
34
 
26
35
  warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"]
27
36
  n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i
37
+
28
38
  self.parallel_executor = Parallel::Executor.new n_threads
29
39
 
30
40
  ##
31
41
  # Filter object for backtraces.
32
42
 
33
- mc.send :attr_accessor, :backtrace_filter
43
+ cattr_accessor :backtrace_filter
34
44
 
35
45
  ##
36
46
  # Reporter object to be used for all runs.
37
47
  #
38
48
  # NOTE: This accessor is only available during setup, not during runs.
39
49
 
40
- mc.send :attr_accessor, :reporter
50
+ cattr_accessor :reporter
41
51
 
42
52
  ##
43
53
  # Names of known extension plugins.
44
54
 
45
- mc.send :attr_accessor, :extensions
55
+ cattr_accessor :extensions
46
56
 
47
57
  ##
48
58
  # The signal to use for dumping information to STDERR. Defaults to "INFO".
49
59
 
50
- mc.send :attr_accessor, :info_signal
60
+ cattr_accessor :info_signal
51
61
  self.info_signal = "INFO"
52
62
 
53
63
  ##
@@ -132,6 +142,9 @@ module Minitest
132
142
 
133
143
  options = process_args args
134
144
 
145
+ Minitest.seed = options[:seed]
146
+ srand Minitest.seed
147
+
135
148
  reporter = CompositeReporter.new
136
149
  reporter << SummaryReporter.new(options[:io], options)
137
150
  reporter << ProgressReporter.new(options[:io], options)
@@ -158,7 +171,7 @@ module Minitest
158
171
  # sub-classes to run.
159
172
 
160
173
  def self.__run reporter, options
161
- suites = Runnable.runnables.reject { |s| s.runnable_methods.empty? }.shuffle
174
+ suites = Runnable.runnables.shuffle
162
175
  parallel, serial = suites.partition { |s| s.test_order == :parallel }
163
176
 
164
177
  # If we run the parallel tests before the serial tests, the parallel tests
@@ -196,6 +209,10 @@ module Minitest
196
209
  options[:verbose] = true
197
210
  end
198
211
 
212
+ opts.on "--show-skips", "Show skipped at the end of run." do
213
+ options[:show_skips] = true
214
+ end
215
+
199
216
  opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a|
200
217
  options[:filter] = a
201
218
  end
@@ -237,8 +254,6 @@ module Minitest
237
254
  orig_args << "--seed" << options[:seed].to_s
238
255
  end
239
256
 
240
- srand options[:seed]
241
-
242
257
  options[:args] = orig_args.map { |s|
243
258
  s =~ /[\s|&<>$()]/ ? s.inspect : s
244
259
  }.join " "
@@ -793,7 +808,8 @@ module Minitest
793
808
 
794
809
  def aggregated_results io # :nodoc:
795
810
  filtered_results = results.dup
796
- filtered_results.reject!(&:skipped?) unless options[:verbose]
811
+ filtered_results.reject!(&:skipped?) unless
812
+ options[:verbose] or options[:show_skips]
797
813
 
798
814
  skip = options[:skip] || []
799
815
 
@@ -814,7 +830,8 @@ module Minitest
814
830
  extra = ""
815
831
 
816
832
  extra = "\n\nYou have skipped tests. Run with --verbose for details." if
817
- 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"]
818
835
 
819
836
  "%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
820
837
  [count, assertions, failures, errors, skips, extra]
@@ -129,7 +129,7 @@ class MetaMetaMetaTestCase < Minitest::Test
129
129
 
130
130
  def setup
131
131
  super
132
- srand 42
132
+ Minitest.seed = 42
133
133
  Minitest::Test.reset
134
134
  @tu = nil
135
135
  end
@@ -354,7 +354,7 @@ class TestMinitestAssertions < Minitest::Test
354
354
  @@ -1,3 +1,3 @@
355
355
  -# encoding: UTF-8
356
356
  -# valid: false
357
- +# encoding: ASCII-8BIT
357
+ +# encoding: #{Encoding::BINARY.name}
358
358
  +# valid: true
359
359
  "bad-utf8-\\xF1.txt"
360
360
  EOM
@@ -373,7 +373,7 @@ class TestMinitestAssertions < Minitest::Test
373
373
  @@ -1,3 +1,3 @@
374
374
  -# encoding: US-ASCII
375
375
  -# valid: false
376
- +# encoding: ASCII-8BIT
376
+ +# encoding: #{Encoding::BINARY.name}
377
377
  +# valid: true
378
378
  "bad-utf8-\\xF1.txt"
379
379
  EOM
@@ -484,7 +484,10 @@ class TestMinitestAssertions < Minitest::Test
484
484
 
485
485
  def test_assert_match
486
486
  @assertion_count = 2
487
- @tc.assert_match(/\w+/, "blah blah blah")
487
+ m = @tc.assert_match(/\w+/, "blah blah blah")
488
+
489
+ assert_kind_of MatchData, m
490
+ assert_equal "blah", m[0]
488
491
  end
489
492
 
490
493
  def test_assert_match_matchee_to_str
@@ -804,7 +807,7 @@ class TestMinitestAssertions < Minitest::Test
804
807
  # *sigh* This is quite an odd scenario, but it is from real (albeit
805
808
  # ugly) test code in ruby-core:
806
809
 
807
- # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
810
+ # https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259
808
811
 
809
812
  def test_assert_raises_skip
810
813
  @assertion_count = 0
@@ -1528,14 +1531,14 @@ class TestMinitestAssertionHelpers < Minitest::Test
1528
1531
 
1529
1532
  def test_mu_pp_for_diff_str_encoding
1530
1533
  str = "A\nB".b
1531
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\nB\""
1534
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\nB\""
1532
1535
 
1533
1536
  assert_mu_pp_for_diff exp, str, :raw
1534
1537
  end
1535
1538
 
1536
1539
  def test_mu_pp_for_diff_str_encoding_both
1537
1540
  str = "A\\n\nB".b
1538
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\\\\n\\nB\""
1541
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\\\n\\nB\""
1539
1542
 
1540
1543
  assert_mu_pp_for_diff exp, str, :raw
1541
1544
  end
@@ -1575,7 +1578,7 @@ class TestMinitestAssertionHelpers < Minitest::Test
1575
1578
 
1576
1579
  def test_mu_pp_str_encoding
1577
1580
  str = "A\nB".b
1578
- exp = "# encoding: ASCII-8BIT\n# valid: true\n\"A\\nB\""
1581
+ exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\nB\""
1579
1582
 
1580
1583
  assert_mu_pp exp, str, :raw
1581
1584
  end
@@ -3,7 +3,7 @@ require "minitest/benchmark"
3
3
 
4
4
  ##
5
5
  # Used to verify data:
6
- # http://www.wolframalpha.com/examples/RegressionAnalysis.html
6
+ # https://www.wolframalpha.com/examples/RegressionAnalysis.html
7
7
 
8
8
  class TestMinitestBenchmark < Minitest::Test
9
9
  def test_cls_bench_exp
@@ -110,7 +110,7 @@ class TestMinitestBenchmark < Minitest::Test
110
110
  assert_fit :power, x, y, 0.90, 2.6217, 1.4556
111
111
 
112
112
  # income to % of households below income amount
113
- # http://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
113
+ # https://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb
114
114
  x = [15_000, 25_000, 35_000, 50_000, 75_000, 100_000]
115
115
  y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843]
116
116