minitest 5.12.0 → 5.22.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/minitest/test.rb CHANGED
@@ -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
@@ -67,8 +71,8 @@ module Minitest
67
71
 
68
72
  case self.test_order
69
73
  when :random, :parallel then
70
- max = methods.size
71
- methods.sort.sort_by { rand max }
74
+ srand Minitest.seed
75
+ methods.sort.shuffle
72
76
  when :alpha, :sorted then
73
77
  methods.sort
74
78
  else
@@ -76,16 +80,6 @@ module Minitest
76
80
  end
77
81
  end
78
82
 
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
83
  ##
90
84
  # Runs a single test with setup/teardown hooks.
91
85
 
@@ -93,7 +87,9 @@ module Minitest
93
87
  with_info_handler do
94
88
  time_it do
95
89
  capture_exceptions do
96
- before_setup; setup; after_setup
90
+ SETUP_METHODS.each do |hook|
91
+ self.send hook
92
+ end
97
93
 
98
94
  self.send self.name
99
95
  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,7 +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
205
+ end
206
+
207
+ def neuter_exception e # :nodoc:
208
+ bt = e.backtrace
209
+ msg = e.message.dup
210
+
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
226
+ end
227
+
228
+ Marshal.dump ne # can raise TypeError
229
+ ne
202
230
  end
203
231
 
204
232
  def with_info_handler &block # :nodoc:
@@ -217,4 +245,4 @@ module Minitest
217
245
  end # Test
218
246
  end
219
247
 
220
- require "minitest/unit" unless defined?(MiniTest) # compatibility layer only
248
+ require "minitest/unit" if ENV["MT_COMPAT"] # compatibility layer only
@@ -0,0 +1,301 @@
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
+ # NOTE: To hook this task up to the default, make it a dependency:
34
+ #
35
+ # task default: :unit
36
+
37
+ class TestTask < Rake::TaskLib
38
+ WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc:
39
+
40
+ ##
41
+ # Create several test-oriented tasks under +name+. Takes an
42
+ # optional block to customize variables.
43
+
44
+ def self.create name = :test, &block
45
+ task = new name
46
+ task.instance_eval(&block) if block
47
+ task.process_env
48
+ task.define
49
+ task
50
+ end
51
+
52
+ ##
53
+ # Extra arguments to pass to the tests. Defaults empty but gets
54
+ # populated by a number of enviroment variables:
55
+ #
56
+ # N (-n flag) :: a string or regexp of tests to run.
57
+ # X (-e flag) :: a string or regexp of tests to exclude.
58
+ # A (arg) :: quick way to inject an arbitrary argument (eg A=--help).
59
+ #
60
+ # See #process_env
61
+
62
+ attr_accessor :extra_args
63
+
64
+ ##
65
+ # The code to load the framework. Defaults to requiring
66
+ # minitest/autorun...
67
+ #
68
+ # Why do I have this as an option?
69
+
70
+ attr_accessor :framework
71
+
72
+ ##
73
+ # Extra library directories to include. Defaults to %w[lib test
74
+ # .]. Also uses $MT_LIB_EXTRAS allowing you to dynamically
75
+ # override/inject directories for custom runs.
76
+
77
+ attr_accessor :libs
78
+
79
+ ##
80
+ # The name of the task and base name for the other tasks generated.
81
+
82
+ attr_accessor :name
83
+
84
+ ##
85
+ # File globs to find test files. Defaults to something sensible to
86
+ # find test files under the test directory.
87
+
88
+ attr_accessor :test_globs
89
+
90
+ ##
91
+ # Turn on ruby warnings (-w flag). Defaults to true.
92
+
93
+ attr_accessor :warning
94
+
95
+ ##
96
+ # Optional: Additional ruby to run before the test framework is loaded.
97
+
98
+ attr_accessor :test_prelude
99
+
100
+ ##
101
+ # Print out commands as they run. Defaults to Rake's +trace+ (-t
102
+ # flag) option.
103
+
104
+ attr_accessor :verbose
105
+
106
+ ##
107
+ # Use TestTask.create instead.
108
+
109
+ def initialize name = :test # :nodoc:
110
+ self.extra_args = []
111
+ self.framework = %(require "minitest/autorun")
112
+ self.libs = %w[lib test .]
113
+ self.name = name
114
+ self.test_globs = ["test/**/test_*.rb",
115
+ "test/**/*_test.rb"]
116
+ self.test_prelude = nil
117
+ self.verbose = Rake.application.options.trace
118
+ self.warning = true
119
+ end
120
+
121
+ ##
122
+ # Extract variables from the environment and convert them to
123
+ # command line arguments. See #extra_args.
124
+ #
125
+ # Environment Variables:
126
+ #
127
+ # MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs.
128
+ # N :: Tests to run (string or /regexp/).
129
+ # X :: Tests to exclude (string or /regexp/).
130
+ # A :: Any extra arguments. Honors shell quoting.
131
+ #
132
+ # Deprecated:
133
+ #
134
+ # TESTOPTS :: For argument passing, use +A+.
135
+ # N :: For parallel testing, use +MT_CPU+.
136
+ # FILTER :: Same as +TESTOPTS+.
137
+
138
+ def process_env
139
+ warn "TESTOPTS is deprecated in Minitest::TestTask. Use A instead" if
140
+ ENV["TESTOPTS"]
141
+ warn "FILTER is deprecated in Minitest::TestTask. Use A instead" if
142
+ ENV["FILTER"]
143
+ warn "N is deprecated in Minitest::TestTask. Use MT_CPU instead" if
144
+ ENV["N"] && ENV["N"].to_i > 0
145
+
146
+ lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR
147
+ self.libs[0,0] = lib_extras
148
+
149
+ extra_args << "-n" << ENV["N"] if ENV["N"]
150
+ extra_args << "-e" << ENV["X"] if ENV["X"]
151
+ extra_args.concat Shellwords.split(ENV["TESTOPTS"]) if ENV["TESTOPTS"]
152
+ extra_args.concat Shellwords.split(ENV["FILTER"]) if ENV["FILTER"]
153
+ extra_args.concat Shellwords.split(ENV["A"]) if ENV["A"]
154
+
155
+ ENV.delete "N" if ENV["N"]
156
+
157
+ # TODO? RUBY_DEBUG = ENV["RUBY_DEBUG"]
158
+ # TODO? ENV["RUBY_FLAGS"]
159
+
160
+ extra_args.compact!
161
+ end
162
+
163
+ def define # :nodoc:
164
+ desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args."
165
+ task name do
166
+ ruby make_test_cmd, verbose:verbose
167
+ end
168
+
169
+ desc "Print out the test command. Good for profiling and other tools."
170
+ task "#{name}:cmd" do
171
+ puts "ruby #{make_test_cmd}"
172
+ end
173
+
174
+ desc "Show which test files fail when run in isolation."
175
+ task "#{name}:isolated" do
176
+ tests = Dir[*self.test_globs].uniq
177
+
178
+ # 3 seems to be the magic number... (tho not by that much)
179
+ bad, good, n = {}, [], (ENV.delete("K") || 3).to_i
180
+ file = ENV.delete("F")
181
+ times = {}
182
+
183
+ tt0 = Time.now
184
+
185
+ n.threads_do tests.sort do |path|
186
+ t0 = Time.now
187
+ output = `#{Gem.ruby} #{make_test_cmd path} 2>&1`
188
+ t1 = Time.now - t0
189
+
190
+ times[path] = t1
191
+
192
+ if $?.success?
193
+ $stderr.print "."
194
+ good << path
195
+ else
196
+ $stderr.print "x"
197
+ bad[path] = output
198
+ end
199
+ end
200
+
201
+ puts "done"
202
+ puts "Ran in %.2f seconds" % [ Time.now - tt0 ]
203
+
204
+ if file then
205
+ require "json"
206
+ File.open file, "w" do |io|
207
+ io.puts JSON.pretty_generate times
208
+ end
209
+ end
210
+
211
+ unless good.empty?
212
+ puts
213
+ puts "# Good tests:"
214
+ puts
215
+ good.sort.each do |path|
216
+ puts "%.2fs: %s" % [times[path], path]
217
+ end
218
+ end
219
+
220
+ unless bad.empty?
221
+ puts
222
+ puts "# Bad tests:"
223
+ puts
224
+ bad.keys.sort.each do |path|
225
+ puts "%.2fs: %s" % [times[path], path]
226
+ end
227
+ puts
228
+ puts "# Bad Test Output:"
229
+ puts
230
+ bad.sort.each do |path, output|
231
+ puts
232
+ puts "# #{path}:"
233
+ puts output
234
+ end
235
+ exit 1
236
+ end
237
+ end
238
+
239
+ task "#{name}:deps" => "#{name}:isolated" # now just an alias
240
+
241
+ desc "Show bottom 25 tests wrt time."
242
+ task "#{name}:slow" do
243
+ sh ["rake #{name} A=-v",
244
+ "egrep '#test_.* s = .'",
245
+ "sort -n -k2 -t=",
246
+ "tail -25"].join " | "
247
+ end
248
+ end
249
+
250
+ ##
251
+ # Generate the test command-line.
252
+
253
+ def make_test_cmd globs = test_globs
254
+ tests = []
255
+ tests.concat Dir[*globs].sort.shuffle # TODO: SEED -> srand first?
256
+ tests.map! { |f| %(require "#{f}") }
257
+
258
+ runner = []
259
+ runner << test_prelude if test_prelude
260
+ runner << framework
261
+ runner.concat tests
262
+ runner = runner.join "; "
263
+
264
+ args = []
265
+ args << "-I#{libs.join(File::PATH_SEPARATOR)}" unless libs.empty?
266
+ args << "-w" if warning
267
+ args << '-e'
268
+ args << "'#{runner}'"
269
+ args << '--'
270
+ args << extra_args.map(&:shellescape)
271
+
272
+ args.join " "
273
+ end
274
+ end
275
+ end
276
+
277
+ class Work < Queue # :nodoc:
278
+ def initialize jobs = [] # :nodoc:
279
+ super()
280
+
281
+ jobs.each do |job|
282
+ self << job
283
+ end
284
+
285
+ close
286
+ end
287
+ end
288
+
289
+ class Integer # :nodoc:
290
+ def threads_do(jobs) # :nodoc:
291
+ q = Work.new jobs
292
+
293
+ self.times.map {
294
+ Thread.new do
295
+ while job = q.pop # go until quit value
296
+ yield job
297
+ end
298
+ end
299
+ }.each(&:join)
300
+ end
301
+ 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: