minitest 5.11.3 → 5.27.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/test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "minitest" unless defined? Minitest::Runnable
1
+ require_relative "../minitest" unless defined? Minitest::Runnable
2
2
 
3
3
  module Minitest
4
4
  ##
@@ -8,9 +8,9 @@ module Minitest
8
8
  # See Minitest::Assertions
9
9
 
10
10
  class Test < Runnable
11
- require "minitest/assertions"
12
- include Minitest::Assertions
11
+ require_relative "assertions"
13
12
  include Minitest::Reportable
13
+ include Minitest::Assertions
14
14
 
15
15
  def class_name # :nodoc:
16
16
  self.class.name # for Minitest::Reportable
@@ -18,6 +18,10 @@ module Minitest
18
18
 
19
19
  PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, SystemExit] # :nodoc:
20
20
 
21
+ SETUP_METHODS = %w[ before_setup setup after_setup ] # :nodoc:
22
+
23
+ TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
24
+
21
25
  # :stopdoc:
22
26
  class << self; attr_accessor :io_lock; end
23
27
  self.io_lock = Mutex.new
@@ -48,11 +52,13 @@ module Minitest
48
52
  end
49
53
 
50
54
  ##
51
- # Call this at the top of your tests when you want to run your
52
- # tests in parallel. In doing so, you're admitting that you rule
53
- # and your tests are awesome.
55
+ # Call this at the top of your tests (inside the +Minitest::Test+
56
+ # subclass or +describe+ block) when you want to run your tests in
57
+ # parallel. In doing so, you're admitting that you rule and your
58
+ # tests are awesome.
54
59
 
55
60
  def self.parallelize_me!
61
+ return unless Minitest.parallel_executor
56
62
  include Minitest::Parallel::Test
57
63
  extend Minitest::Parallel::Test::ClassMethods
58
64
  end
@@ -67,8 +73,8 @@ module Minitest
67
73
 
68
74
  case self.test_order
69
75
  when :random, :parallel then
70
- max = methods.size
71
- methods.sort.sort_by { rand max }
76
+ srand Minitest.seed
77
+ methods.sort.shuffle
72
78
  when :alpha, :sorted then
73
79
  methods.sort
74
80
  else
@@ -76,32 +82,22 @@ module Minitest
76
82
  end
77
83
  end
78
84
 
79
- ##
80
- # Defines the order to run tests (:random by default). Override
81
- # this or use a convenience method to change it for your tests.
82
-
83
- def self.test_order
84
- :random
85
- end
86
-
87
- TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc:
88
-
89
85
  ##
90
86
  # Runs a single test with setup/teardown hooks.
91
87
 
92
88
  def run
93
- with_info_handler do
94
- time_it do
95
- capture_exceptions do
96
- before_setup; setup; after_setup
97
-
98
- self.send self.name
89
+ time_it do
90
+ capture_exceptions do
91
+ SETUP_METHODS.each do |hook|
92
+ self.send hook
99
93
  end
100
94
 
101
- TEARDOWN_METHODS.each do |hook|
102
- capture_exceptions do
103
- self.send hook
104
- end
95
+ self.send self.name
96
+ end
97
+
98
+ TEARDOWN_METHODS.each do |hook|
99
+ capture_exceptions do
100
+ self.send hook
105
101
  end
106
102
  end
107
103
  end
@@ -145,7 +141,7 @@ module Minitest
145
141
  # end
146
142
  # end
147
143
  #
148
- # class MiniTest::Test
144
+ # class Minitest::Test
149
145
  # include MyMinitestPlugin
150
146
  # end
151
147
 
@@ -198,17 +194,39 @@ module Minitest
198
194
  rescue Assertion => e
199
195
  self.failures << e
200
196
  rescue Exception => e
201
- self.failures << UnexpectedError.new(e)
197
+ self.failures << UnexpectedError.new(sanitize_exception e)
198
+ end
199
+
200
+ def sanitize_exception e # :nodoc:
201
+ Marshal.dump e
202
+ e # good: use as-is
203
+ rescue
204
+ neuter_exception e
202
205
  end
203
206
 
204
- def with_info_handler &block # :nodoc:
205
- t0 = Minitest.clock_time
207
+ def neuter_exception e # :nodoc:
208
+ bt = e.backtrace
209
+ msg = e.message.dup
206
210
 
207
- handler = lambda do
208
- warn "\nCurrent: %s#%s %.2fs" % [self.class, self.name, Minitest.clock_time - t0]
211
+ new_exception e.class, msg, bt # e.class can be a problem...
212
+ rescue
213
+ msg.prepend "Neutered Exception #{e.class}: "
214
+
215
+ new_exception RuntimeError, msg, bt, true # but if this raises, we die
216
+ end
217
+
218
+ def new_exception klass, msg, bt, kill = false # :nodoc:
219
+ ne = klass.new msg
220
+ ne.set_backtrace bt
221
+
222
+ if kill then
223
+ ne.instance_variables.each do |v|
224
+ ne.remove_instance_variable v
225
+ end
209
226
  end
210
227
 
211
- self.class.on_signal ::Minitest.info_signal, handler, &block
228
+ Marshal.dump ne # can raise TypeError
229
+ ne
212
230
  end
213
231
 
214
232
  include LifecycleHooks
@@ -217,4 +235,4 @@ module Minitest
217
235
  end # Test
218
236
  end
219
237
 
220
- require "minitest/unit" unless defined?(MiniTest) # compatibility layer only
238
+ require_relative "unit" if ENV["MT_COMPAT"] # compatibility layer only
@@ -0,0 +1,324 @@
1
+ require "shellwords"
2
+ require "rbconfig"
3
+
4
+ begin
5
+ require "rake/tasklib"
6
+ rescue LoadError => e
7
+ warn e.message
8
+ return
9
+ end
10
+
11
+ module Minitest # :nodoc:
12
+
13
+ ##
14
+ # Minitest::TestTask is a rake helper that generates several rake
15
+ # tasks under the main test task's name-space.
16
+ #
17
+ # task <name> :: the main test task
18
+ # task <name>:cmd :: prints the command to use
19
+ # task <name>:deps :: runs each test file by itself to find dependency errors
20
+ # task <name>:slow :: runs the tests and reports the slowest 25 tests.
21
+ #
22
+ # Examples:
23
+ #
24
+ # Minitest::TestTask.create
25
+ #
26
+ # The most basic and default setup.
27
+ #
28
+ # Minitest::TestTask.create :my_tests
29
+ #
30
+ # The most basic/default setup, but with a custom name
31
+ #
32
+ # Minitest::TestTask.create :unit do |t|
33
+ # t.test_globs = ["test/unit/**/*_test.rb"]
34
+ # t.warning = false
35
+ # end
36
+ #
37
+ # Customize the name and only run unit tests.
38
+ #
39
+ # NOTE: To hook this task up to the default, make it a dependency:
40
+ #
41
+ # task default: :unit
42
+
43
+ class TestTask < Rake::TaskLib
44
+ WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc:
45
+
46
+ ##
47
+ # Create several test-oriented tasks under +name+ (default:
48
+ # "test"). Takes an optional block to customize variables.
49
+ # Examples:
50
+ #
51
+ # Minitest::TestTask.create # named "test", all defaults
52
+ #
53
+ # Minitest::TestTask.create do |t|
54
+ # t.warning = false # my tests are noisy
55
+ # t.framework = %(require_relative "./test/helper.rb")
56
+ # end
57
+
58
+ def self.create name = :test, &block
59
+ task = new name
60
+ task.instance_eval(&block) if block
61
+ task.process_env
62
+ task.define
63
+ task
64
+ end
65
+
66
+ ##
67
+ # Extra arguments to pass to the tests. Defaults empty but gets
68
+ # populated by a number of enviroment variables:
69
+ #
70
+ # N (-n flag) :: a string or regexp of tests to run.
71
+ # X (-e flag) :: a string or regexp of tests to exclude.
72
+ # A (arg) :: quick way to inject an arbitrary argument (eg A=--help).
73
+ #
74
+ # See #process_env
75
+
76
+ attr_accessor :extra_args
77
+
78
+ ##
79
+ # The code to load the framework. Defaults to requiring
80
+ # minitest/autorun.
81
+ #
82
+ # If you have a test helper file that requires minitest/autorun
83
+ # and anything else your project standardizes on, then you'll
84
+ # probably want to change this to:
85
+ #
86
+ # Minitest::TestTask.create do |t|
87
+ # t.framework = %(require_relative "./test/helper.rb")
88
+ # end
89
+ #
90
+ # or something similar. NOTE: if you do this, then helper must
91
+ # require "minitest/autorun" at the top to start the tests.
92
+
93
+ attr_accessor :framework
94
+
95
+ ##
96
+ # Extra library directories to include. Defaults to %w[lib test
97
+ # .]. Also uses $MT_LIB_EXTRAS allowing you to dynamically
98
+ # override/inject directories for custom runs.
99
+
100
+ attr_accessor :libs
101
+
102
+ ##
103
+ # The name of the task and base name for the other tasks generated.
104
+
105
+ attr_accessor :name
106
+
107
+ ##
108
+ # File globs to find test files. Defaults to something sensible to
109
+ # find test files under the test directory.
110
+
111
+ attr_accessor :test_globs
112
+
113
+ ##
114
+ # Turn on ruby warnings (-w flag). Defaults to true.
115
+
116
+ attr_accessor :warning
117
+
118
+ ##
119
+ # Optional: Additional ruby to run before the test framework is loaded.
120
+ # Example:
121
+ #
122
+ # Minitest::TestTask.create "test:cov" do |t|
123
+ # t.test_prelude = %(require "simplecov")
124
+ # end
125
+
126
+ attr_accessor :test_prelude
127
+
128
+ ##
129
+ # Print out commands as they run. Defaults to Rake's +trace+ (-t
130
+ # flag) option.
131
+
132
+ attr_accessor :verbose
133
+
134
+ ##
135
+ # Use TestTask.create instead.
136
+
137
+ def initialize name = :test # :nodoc:
138
+ self.extra_args = []
139
+ self.framework = %(require "minitest/autorun")
140
+ self.libs = %w[lib test .]
141
+ self.name = name
142
+ self.test_globs = ["test/**/test_*.rb",
143
+ "test/**/*_test.rb"]
144
+ self.test_prelude = nil
145
+ self.verbose = Rake.application.options.trace || Rake.verbose == true
146
+ self.warning = true
147
+ end
148
+
149
+ ##
150
+ # Extract variables from the environment and convert them to
151
+ # command line arguments. See #extra_args.
152
+ #
153
+ # Environment Variables:
154
+ #
155
+ # MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
156
+ # N :: Tests to run (string or /regexp/).
157
+ # X :: Tests to exclude (string or /regexp/).
158
+ # A :: Any extra arguments. Honors shell quoting.
159
+ #
160
+ # Deprecated:
161
+ #
162
+ # TESTOPTS :: For argument passing, use +A+.
163
+ # N :: For parallel testing, use +MT_CPU+.
164
+ # FILTER :: Same as +TESTOPTS+.
165
+
166
+ def process_env
167
+ warn "TESTOPTS is deprecated in Minitest::TestTask. Use A instead" if
168
+ ENV["TESTOPTS"]
169
+ warn "FILTER is deprecated in Minitest::TestTask. Use A instead" if
170
+ ENV["FILTER"]
171
+ warn "N is deprecated in Minitest::TestTask. Use MT_CPU instead" if
172
+ ENV["N"] && ENV["N"].to_i > 0
173
+
174
+ lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR
175
+ self.libs[0, 0] = lib_extras
176
+
177
+ extra_args << "-n" << ENV["N"] if ENV["N"]
178
+ extra_args << "-e" << ENV["X"] if ENV["X"]
179
+ extra_args.concat Shellwords.split(ENV["TESTOPTS"]) if ENV["TESTOPTS"]
180
+ extra_args.concat Shellwords.split(ENV["FILTER"]) if ENV["FILTER"]
181
+ extra_args.concat Shellwords.split(ENV["A"]) if ENV["A"]
182
+
183
+ ENV.delete "N" if ENV["N"]
184
+
185
+ # TODO? RUBY_DEBUG = ENV["RUBY_DEBUG"]
186
+ # TODO? ENV["RUBY_FLAGS"]
187
+
188
+ extra_args.compact!
189
+ end
190
+
191
+ def define # :nodoc:
192
+ desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args."
193
+ task name do
194
+ ruby make_test_cmd, verbose: verbose
195
+ end
196
+
197
+ desc "Print out the test command. Good for profiling and other tools."
198
+ task "#{name}:cmd" do
199
+ puts "ruby #{make_test_cmd}"
200
+ end
201
+
202
+ desc "Show which test files fail when run in isolation."
203
+ task "#{name}:isolated" do
204
+ tests = Dir[*self.test_globs].uniq
205
+
206
+ # 3 seems to be the magic number... (tho not by that much)
207
+ bad, good, n = {}, [], (ENV.delete("K") || 3).to_i
208
+ file = ENV.delete "F"
209
+ times = {}
210
+
211
+ tt0 = Time.now
212
+
213
+ n.threads_do tests.sort do |path|
214
+ t0 = Time.now
215
+ output = `#{Gem.ruby} #{make_test_cmd path} 2>&1`
216
+ t1 = Time.now - t0
217
+
218
+ times[path] = t1
219
+
220
+ if $?.success?
221
+ $stderr.print "."
222
+ good << path
223
+ else
224
+ $stderr.print "x"
225
+ bad[path] = output
226
+ end
227
+ end
228
+
229
+ puts "done"
230
+ puts "Ran in %.2f seconds" % [ Time.now - tt0 ]
231
+
232
+ if file then
233
+ require "json"
234
+ File.open file, "w" do |io|
235
+ io.puts JSON.pretty_generate times
236
+ end
237
+ end
238
+
239
+ unless good.empty?
240
+ puts
241
+ puts "# Good tests:"
242
+ puts
243
+ good.sort.each do |path|
244
+ puts "%.2fs: %s" % [times[path], path]
245
+ end
246
+ end
247
+
248
+ unless bad.empty?
249
+ puts
250
+ puts "# Bad tests:"
251
+ puts
252
+ bad.keys.sort.each do |path|
253
+ puts "%.2fs: %s" % [times[path], path]
254
+ end
255
+ puts
256
+ puts "# Bad Test Output:"
257
+ puts
258
+ bad.sort.each do |path, output|
259
+ puts
260
+ puts "# #{path}:"
261
+ puts output
262
+ end
263
+ exit 1
264
+ end
265
+ end
266
+
267
+ task "#{name}:deps" => "#{name}:isolated" # now just an alias
268
+
269
+ desc "Run the test suite and report the slowest 25 tests."
270
+ task "#{name}:slow" do
271
+ sh ["rake #{name} A=-v",
272
+ "egrep '#test_.* s = .'",
273
+ "sort -n -k2 -t=",
274
+ "tail -25"].join " | "
275
+ end
276
+ end
277
+
278
+ ##
279
+ # Generate the test command-line.
280
+
281
+ def make_test_cmd globs = test_globs
282
+ tests = []
283
+ tests.concat Dir[*globs].sort.shuffle # TODO: SEED -> srand first?
284
+ tests.map! { |f| %(require "#{f}") }
285
+
286
+ runner = []
287
+ runner << test_prelude if test_prelude
288
+ runner << framework
289
+ runner.concat tests
290
+ runner = runner.join "; "
291
+
292
+ args = []
293
+ args << "-I#{libs.join File::PATH_SEPARATOR}" unless libs.empty?
294
+ args << "-w" if warning
295
+ args << "-e"
296
+ args << "'#{runner}'"
297
+ args << "--"
298
+ args << extra_args.map(&:shellescape)
299
+
300
+ args.join " "
301
+ end
302
+ end
303
+ end
304
+
305
+ class Work < Queue # :nodoc:
306
+ def initialize jobs # :nodoc:
307
+ super
308
+ close
309
+ end
310
+ end
311
+
312
+ class Integer # :nodoc:
313
+ def threads_do jobs # :nodoc:
314
+ q = Work.new jobs
315
+
316
+ Array.new(self) {
317
+ Thread.new do
318
+ while job = q.pop # go until quit value
319
+ yield job
320
+ end
321
+ end
322
+ }.each(&:join)
323
+ end
324
+ 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
15
- require "minitest"
11
+ module Minitest # :nodoc:
12
+ end
13
+ MiniTest = Minitest # :nodoc: # prevents minitest.rb from requiring back to us
14
+ require_relative "../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: