test-unit-minitest 0.9.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 +7 -0
- data/LICENSE +56 -0
- data/README.md +29 -0
- data/bin/testrb +3 -0
- data/lib/test/unit.rb +876 -0
- data/lib/test/unit/assertions.rb +403 -0
- data/lib/test/unit/parallel.rb +189 -0
- data/lib/test/unit/testcase.rb +34 -0
- metadata +70 -0
@@ -0,0 +1,403 @@
|
|
1
|
+
require 'minitest/unit'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
module Test
|
5
|
+
module Unit
|
6
|
+
module Assertions
|
7
|
+
include MiniTest::Assertions
|
8
|
+
|
9
|
+
def mu_pp(obj) #:nodoc:
|
10
|
+
obj.pretty_inspect.chomp
|
11
|
+
end
|
12
|
+
|
13
|
+
MINI_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), "minitest") #:nodoc:
|
14
|
+
|
15
|
+
# :call-seq:
|
16
|
+
# assert(test, [failure_message])
|
17
|
+
#
|
18
|
+
#Tests if +test+ is true.
|
19
|
+
#
|
20
|
+
#+msg+ may be a String or a Proc. If +msg+ is a String, it will be used
|
21
|
+
#as the failure message. Otherwise, the result of calling +msg+ will be
|
22
|
+
#used as the message if the assertion fails.
|
23
|
+
#
|
24
|
+
#If no +msg+ is given, a default message will be used.
|
25
|
+
#
|
26
|
+
# assert(false, "This was expected to be true")
|
27
|
+
def assert(test, *msgs)
|
28
|
+
case msg = msgs.first
|
29
|
+
when String, Proc
|
30
|
+
when nil
|
31
|
+
msgs.shift
|
32
|
+
else
|
33
|
+
bt = caller.reject { |s| s.start_with?(MINI_DIR) }
|
34
|
+
raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt
|
35
|
+
end unless msgs.empty?
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
# :call-seq:
|
40
|
+
# assert_block( failure_message = nil )
|
41
|
+
#
|
42
|
+
#Tests the result of the given block. If the block does not return true,
|
43
|
+
#the assertion will fail. The optional +failure_message+ argument is the same as in
|
44
|
+
#Assertions#assert.
|
45
|
+
#
|
46
|
+
# assert_block do
|
47
|
+
# [1, 2, 3].any? { |num| num < 1 }
|
48
|
+
# end
|
49
|
+
def assert_block(*msgs)
|
50
|
+
assert yield, *msgs
|
51
|
+
end
|
52
|
+
|
53
|
+
# :call-seq:
|
54
|
+
# assert_raise( *args, &block )
|
55
|
+
#
|
56
|
+
#Tests if the given block raises an exception. Acceptable exception
|
57
|
+
#types may be given as optional arguments. If the last argument is a
|
58
|
+
#String, it will be used as the error message.
|
59
|
+
#
|
60
|
+
# assert_raise do #Fails, no Exceptions are raised
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# assert_raise NameError do
|
64
|
+
# puts x #Raises NameError, so assertion succeeds
|
65
|
+
# end
|
66
|
+
def assert_raise(*args, &b)
|
67
|
+
assert_raises(*args, &b)
|
68
|
+
end
|
69
|
+
|
70
|
+
# :call-seq:
|
71
|
+
# assert_raise_with_message(exception, expected, msg = nil, &block)
|
72
|
+
#
|
73
|
+
#Tests if the given block raises an exception with the expected
|
74
|
+
#message.
|
75
|
+
#
|
76
|
+
# assert_raise_with_message(RuntimeError, "foo") do
|
77
|
+
# nil #Fails, no Exceptions are raised
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# assert_raise_with_message(RuntimeError, "foo") do
|
81
|
+
# raise ArgumentError, "foo" #Fails, different Exception is raised
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# assert_raise_with_message(RuntimeError, "foo") do
|
85
|
+
# raise "bar" #Fails, RuntimeError is raised but the message differs
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# assert_raise_with_message(RuntimeError, "foo") do
|
89
|
+
# raise "foo" #Raises RuntimeError with the message, so assertion succeeds
|
90
|
+
# end
|
91
|
+
def assert_raise_with_message(exception, expected, msg = nil, &block)
|
92
|
+
case expected
|
93
|
+
when String
|
94
|
+
assert = :assert_equal
|
95
|
+
when Regexp
|
96
|
+
assert = :assert_match
|
97
|
+
else
|
98
|
+
raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}"
|
99
|
+
end
|
100
|
+
|
101
|
+
ex = assert_raise(exception, *msg) {yield}
|
102
|
+
msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"}
|
103
|
+
|
104
|
+
if assert == :assert_equal
|
105
|
+
assert_equal(expected, ex.message, msg)
|
106
|
+
else
|
107
|
+
msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp ex.message}" }
|
108
|
+
assert expected =~ ex.message, msg
|
109
|
+
block.binding.eval("proc{|_|$~=_}").call($~)
|
110
|
+
end
|
111
|
+
ex
|
112
|
+
end
|
113
|
+
|
114
|
+
# :call-seq:
|
115
|
+
# assert_nothing_raised( *args, &block )
|
116
|
+
#
|
117
|
+
#If any exceptions are given as arguments, the assertion will
|
118
|
+
#fail if one of those exceptions are raised. Otherwise, the test fails
|
119
|
+
#if any exceptions are raised.
|
120
|
+
#
|
121
|
+
#The final argument may be a failure message.
|
122
|
+
#
|
123
|
+
# assert_nothing_raised RuntimeError do
|
124
|
+
# raise Exception #Assertion passes, Exception is not a RuntimeError
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# assert_nothing_raised do
|
128
|
+
# raise Exception #Assertion fails
|
129
|
+
# end
|
130
|
+
def assert_nothing_raised(*args)
|
131
|
+
self._assertions += 1
|
132
|
+
if Module === args.last
|
133
|
+
msg = nil
|
134
|
+
else
|
135
|
+
msg = args.pop
|
136
|
+
end
|
137
|
+
begin
|
138
|
+
line = __LINE__; yield
|
139
|
+
rescue MiniTest::Skip
|
140
|
+
raise
|
141
|
+
rescue Exception => e
|
142
|
+
bt = e.backtrace
|
143
|
+
as = e.instance_of?(MiniTest::Assertion)
|
144
|
+
if as
|
145
|
+
ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o
|
146
|
+
bt.reject! {|ln| ans =~ ln}
|
147
|
+
end
|
148
|
+
if ((args.empty? && !as) ||
|
149
|
+
args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a })
|
150
|
+
msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" }
|
151
|
+
raise MiniTest::Assertion, msg.call, bt
|
152
|
+
else
|
153
|
+
raise
|
154
|
+
end
|
155
|
+
end
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
|
159
|
+
# :call-seq:
|
160
|
+
# assert_nothing_thrown( failure_message = nil, &block )
|
161
|
+
#
|
162
|
+
#Fails if the given block uses a call to Kernel#throw, and
|
163
|
+
#returns the result of the block otherwise.
|
164
|
+
#
|
165
|
+
#An optional failure message may be provided as the final argument.
|
166
|
+
#
|
167
|
+
# assert_nothing_thrown "Something was thrown!" do
|
168
|
+
# throw :problem?
|
169
|
+
# end
|
170
|
+
def assert_nothing_thrown(msg=nil)
|
171
|
+
begin
|
172
|
+
ret = yield
|
173
|
+
rescue ArgumentError => error
|
174
|
+
raise error if /\Auncaught throw (.+)\z/m !~ error.message
|
175
|
+
msg = message(msg) { "<#{$1}> was thrown when nothing was expected" }
|
176
|
+
flunk(msg)
|
177
|
+
end
|
178
|
+
assert(true, "Expected nothing to be thrown")
|
179
|
+
ret
|
180
|
+
end
|
181
|
+
|
182
|
+
# :call-seq:
|
183
|
+
# assert_throw( tag, failure_message = nil, &block )
|
184
|
+
#
|
185
|
+
#Fails unless the given block throws +tag+, returns the caught
|
186
|
+
#value otherwise.
|
187
|
+
#
|
188
|
+
#An optional failure message may be provided as the final argument.
|
189
|
+
#
|
190
|
+
# tag = Object.new
|
191
|
+
# assert_throw(tag, "#{tag} was not thrown!") do
|
192
|
+
# throw tag
|
193
|
+
# end
|
194
|
+
def assert_throw(tag, msg = nil)
|
195
|
+
catch(tag) do
|
196
|
+
yield(tag)
|
197
|
+
assert(false, message(msg) {"Expected #{mu_pp(tag)} to have been thrown"})
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# :call-seq:
|
202
|
+
# assert_equal( expected, actual, failure_message = nil )
|
203
|
+
#
|
204
|
+
#Tests if +expected+ is equal to +actual+.
|
205
|
+
#
|
206
|
+
#An optional failure message may be provided as the final argument.
|
207
|
+
def assert_equal(exp, act, msg = nil)
|
208
|
+
msg = message(msg) {
|
209
|
+
exp_str = mu_pp(exp)
|
210
|
+
act_str = mu_pp(act)
|
211
|
+
exp_comment = ''
|
212
|
+
act_comment = ''
|
213
|
+
if exp_str == act_str
|
214
|
+
if (exp.is_a?(String) && act.is_a?(String)) ||
|
215
|
+
(exp.is_a?(Regexp) && act.is_a?(Regexp))
|
216
|
+
exp_comment = " (#{exp.encoding})"
|
217
|
+
act_comment = " (#{act.encoding})"
|
218
|
+
elsif exp.is_a?(Float) && act.is_a?(Float)
|
219
|
+
exp_str = "%\#.#{Float::DIG+2}g" % exp
|
220
|
+
act_str = "%\#.#{Float::DIG+2}g" % act
|
221
|
+
elsif exp.is_a?(Time) && act.is_a?(Time)
|
222
|
+
if exp.subsec * 1000_000_000 == exp.nsec
|
223
|
+
exp_comment = " (#{exp.nsec}[ns])"
|
224
|
+
else
|
225
|
+
exp_comment = " (subsec=#{exp.subsec})"
|
226
|
+
end
|
227
|
+
if act.subsec * 1000_000_000 == act.nsec
|
228
|
+
act_comment = " (#{act.nsec}[ns])"
|
229
|
+
else
|
230
|
+
act_comment = " (subsec=#{act.subsec})"
|
231
|
+
end
|
232
|
+
elsif exp.class != act.class
|
233
|
+
# a subclass of Range, for example.
|
234
|
+
exp_comment = " (#{exp.class})"
|
235
|
+
act_comment = " (#{act.class})"
|
236
|
+
end
|
237
|
+
elsif !Encoding.compatible?(exp_str, act_str)
|
238
|
+
if exp.is_a?(String) && act.is_a?(String)
|
239
|
+
exp_str = exp.dump
|
240
|
+
act_str = act.dump
|
241
|
+
exp_comment = " (#{exp.encoding})"
|
242
|
+
act_comment = " (#{act.encoding})"
|
243
|
+
else
|
244
|
+
exp_str = exp_str.dump
|
245
|
+
act_str = act_str.dump
|
246
|
+
end
|
247
|
+
end
|
248
|
+
"<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}"
|
249
|
+
}
|
250
|
+
assert(exp == act, msg)
|
251
|
+
end
|
252
|
+
|
253
|
+
# :call-seq:
|
254
|
+
# assert_not_nil( expression, failure_message = nil )
|
255
|
+
#
|
256
|
+
#Tests if +expression+ is not nil.
|
257
|
+
#
|
258
|
+
#An optional failure message may be provided as the final argument.
|
259
|
+
def assert_not_nil(exp, msg=nil)
|
260
|
+
msg = message(msg) { "<#{mu_pp(exp)}> expected to not be nil" }
|
261
|
+
assert(!exp.nil?, msg)
|
262
|
+
end
|
263
|
+
|
264
|
+
# :call-seq:
|
265
|
+
# assert_not_equal( expected, actual, failure_message = nil )
|
266
|
+
#
|
267
|
+
#Tests if +expected+ is not equal to +actual+.
|
268
|
+
#
|
269
|
+
#An optional failure message may be provided as the final argument.
|
270
|
+
def assert_not_equal(exp, act, msg=nil)
|
271
|
+
msg = message(msg) { "<#{mu_pp(exp)}> expected to be != to\n<#{mu_pp(act)}>" }
|
272
|
+
assert(exp != act, msg)
|
273
|
+
end
|
274
|
+
|
275
|
+
# :call-seq:
|
276
|
+
# assert_no_match( regexp, string, failure_message = nil )
|
277
|
+
#
|
278
|
+
#Tests if the given Regexp does not match a given String.
|
279
|
+
#
|
280
|
+
#An optional failure message may be provided as the final argument.
|
281
|
+
def assert_no_match(regexp, string, msg=nil)
|
282
|
+
assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.")
|
283
|
+
self._assertions -= 1
|
284
|
+
msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" }
|
285
|
+
assert(regexp !~ string, msg)
|
286
|
+
end
|
287
|
+
|
288
|
+
# :call-seq:
|
289
|
+
# assert_not_same( expected, actual, failure_message = nil )
|
290
|
+
#
|
291
|
+
#Tests if +expected+ is not the same object as +actual+.
|
292
|
+
#This test uses Object#equal? to test equality.
|
293
|
+
#
|
294
|
+
#An optional failure message may be provided as the final argument.
|
295
|
+
#
|
296
|
+
# assert_not_same("x", "x") #Succeeds
|
297
|
+
def assert_not_same(expected, actual, message="")
|
298
|
+
msg = message(msg) { build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__) }
|
299
|
+
<?>
|
300
|
+
with id <?> expected to not be equal\\? to
|
301
|
+
<?>
|
302
|
+
with id <?>.
|
303
|
+
EOT
|
304
|
+
assert(!actual.equal?(expected), msg)
|
305
|
+
end
|
306
|
+
|
307
|
+
# :call-seq:
|
308
|
+
# assert_respond_to( object, method, failure_message = nil )
|
309
|
+
#
|
310
|
+
#Tests if the given Object responds to +method+.
|
311
|
+
#
|
312
|
+
#An optional failure message may be provided as the final argument.
|
313
|
+
#
|
314
|
+
# assert_respond_to("hello", :reverse) #Succeeds
|
315
|
+
# assert_respond_to("hello", :does_not_exist) #Fails
|
316
|
+
def assert_respond_to obj, (meth, priv), msg = nil
|
317
|
+
if priv
|
318
|
+
msg = message(msg) {
|
319
|
+
"Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv}"
|
320
|
+
}
|
321
|
+
return assert obj.respond_to?(meth, priv), msg
|
322
|
+
end
|
323
|
+
#get rid of overcounting
|
324
|
+
super if !caller[0].rindex(MINI_DIR, 0) || !obj.respond_to?(meth)
|
325
|
+
end
|
326
|
+
|
327
|
+
# :call-seq:
|
328
|
+
# assert_send( +send_array+, failure_message = nil )
|
329
|
+
#
|
330
|
+
# Passes if the method send returns a true value.
|
331
|
+
#
|
332
|
+
# +send_array+ is composed of:
|
333
|
+
# * A receiver
|
334
|
+
# * A method
|
335
|
+
# * Arguments to the method
|
336
|
+
#
|
337
|
+
# Example:
|
338
|
+
# assert_send(["Hello world", :include?, "Hello"]) # -> pass
|
339
|
+
# assert_send(["Hello world", :include?, "Goodbye"]) # -> fail
|
340
|
+
def assert_send send_ary, m = nil
|
341
|
+
recv, msg, *args = send_ary
|
342
|
+
m = message(m) {
|
343
|
+
if args.empty?
|
344
|
+
argsstr = ""
|
345
|
+
else
|
346
|
+
(argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)')
|
347
|
+
end
|
348
|
+
"Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return true"
|
349
|
+
}
|
350
|
+
assert recv.__send__(msg, *args), m
|
351
|
+
end
|
352
|
+
|
353
|
+
# :call-seq:
|
354
|
+
# assert_not_send( +send_array+, failure_message = nil )
|
355
|
+
#
|
356
|
+
# Passes if the method send doesn't return a true value.
|
357
|
+
#
|
358
|
+
# +send_array+ is composed of:
|
359
|
+
# * A receiver
|
360
|
+
# * A method
|
361
|
+
# * Arguments to the method
|
362
|
+
#
|
363
|
+
# Example:
|
364
|
+
# assert_not_send([[1, 2], :member?, 1]) # -> fail
|
365
|
+
# assert_not_send([[1, 2], :member?, 4]) # -> pass
|
366
|
+
def assert_not_send send_ary, m = nil
|
367
|
+
recv, msg, *args = send_ary
|
368
|
+
m = message(m) {
|
369
|
+
if args.empty?
|
370
|
+
argsstr = ""
|
371
|
+
else
|
372
|
+
(argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)')
|
373
|
+
end
|
374
|
+
"Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return false"
|
375
|
+
}
|
376
|
+
assert !recv.__send__(msg, *args), m
|
377
|
+
end
|
378
|
+
|
379
|
+
ms = instance_methods(true).map {|sym| sym.to_s }
|
380
|
+
ms.grep(/\Arefute_/) do |m|
|
381
|
+
mname = ('assert_not_' << m.to_s[/.*?_(.*)/, 1])
|
382
|
+
alias_method(mname, m) unless ms.include? mname
|
383
|
+
end
|
384
|
+
alias assert_include assert_includes
|
385
|
+
alias assert_not_include assert_not_includes
|
386
|
+
|
387
|
+
def build_message(head, template=nil, *arguments) #:nodoc:
|
388
|
+
template &&= template.chomp
|
389
|
+
template.gsub(/\G((?:[^\\]|\\.)*?)(\\)?\?/) { $1 + ($2 ? "?" : mu_pp(arguments.shift)) }
|
390
|
+
end
|
391
|
+
|
392
|
+
def message(msg = nil, *args, &default) # :nodoc:
|
393
|
+
if Proc === msg
|
394
|
+
super(nil, *args) do
|
395
|
+
[msg.call, (default.call if default)].compact.reject(&:empty?).join(".\n")
|
396
|
+
end
|
397
|
+
else
|
398
|
+
super
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
class Worker < Runner # :nodoc:
|
6
|
+
class << self
|
7
|
+
undef autorun
|
8
|
+
end
|
9
|
+
|
10
|
+
alias orig_run_suite mini_run_suite
|
11
|
+
undef _run_suite
|
12
|
+
undef _run_suites
|
13
|
+
undef run
|
14
|
+
|
15
|
+
def increment_io(orig) # :nodoc:
|
16
|
+
*rest, io = 32.times.inject([orig.dup]){|ios, | ios << ios.last.dup }
|
17
|
+
rest.each(&:close)
|
18
|
+
io
|
19
|
+
end
|
20
|
+
|
21
|
+
def _run_suites(suites, type) # :nodoc:
|
22
|
+
suites.map do |suite|
|
23
|
+
_run_suite(suite, type)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def _run_suite(suite, type) # :nodoc:
|
28
|
+
@partial_report = []
|
29
|
+
orig_testout = MiniTest::Unit.output
|
30
|
+
i,o = IO.pipe
|
31
|
+
|
32
|
+
MiniTest::Unit.output = o
|
33
|
+
orig_stdin, orig_stdout = $stdin, $stdout
|
34
|
+
|
35
|
+
th = Thread.new do
|
36
|
+
begin
|
37
|
+
while buf = (self.verbose ? i.gets : i.read(5))
|
38
|
+
_report "p", buf
|
39
|
+
end
|
40
|
+
rescue IOError
|
41
|
+
rescue Errno::EPIPE
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
e, f, s = @errors, @failures, @skips
|
46
|
+
|
47
|
+
begin
|
48
|
+
result = orig_run_suite(suite, type)
|
49
|
+
rescue Interrupt
|
50
|
+
@need_exit = true
|
51
|
+
result = [nil,nil]
|
52
|
+
end
|
53
|
+
|
54
|
+
MiniTest::Unit.output = orig_testout
|
55
|
+
$stdin = orig_stdin
|
56
|
+
$stdout = orig_stdout
|
57
|
+
|
58
|
+
o.close
|
59
|
+
begin
|
60
|
+
th.join
|
61
|
+
rescue IOError
|
62
|
+
raise unless ["stream closed","closed stream"].include? $!.message
|
63
|
+
end
|
64
|
+
i.close
|
65
|
+
|
66
|
+
result << @partial_report
|
67
|
+
@partial_report = nil
|
68
|
+
result << [@errors-e,@failures-f,@skips-s]
|
69
|
+
result << ($: - @old_loadpath)
|
70
|
+
result << suite.name
|
71
|
+
|
72
|
+
begin
|
73
|
+
_report "done", Marshal.dump(result)
|
74
|
+
rescue Errno::EPIPE; end
|
75
|
+
return result
|
76
|
+
ensure
|
77
|
+
MiniTest::Unit.output = orig_stdout
|
78
|
+
$stdin = orig_stdin
|
79
|
+
$stdout = orig_stdout
|
80
|
+
o.close if o && !o.closed?
|
81
|
+
i.close if i && !i.closed?
|
82
|
+
end
|
83
|
+
|
84
|
+
def run(args = []) # :nodoc:
|
85
|
+
process_args args
|
86
|
+
@@stop_auto_run = true
|
87
|
+
@opts = @options.dup
|
88
|
+
@need_exit = false
|
89
|
+
|
90
|
+
@old_loadpath = []
|
91
|
+
begin
|
92
|
+
begin
|
93
|
+
@stdout = increment_io(STDOUT)
|
94
|
+
@stdin = increment_io(STDIN)
|
95
|
+
rescue
|
96
|
+
exit 2
|
97
|
+
end
|
98
|
+
exit 2 unless @stdout && @stdin
|
99
|
+
|
100
|
+
@stdout.sync = true
|
101
|
+
_report "ready!"
|
102
|
+
while buf = @stdin.gets
|
103
|
+
case buf.chomp
|
104
|
+
when /^loadpath (.+?)$/
|
105
|
+
@old_loadpath = $:.dup
|
106
|
+
$:.push(*Marshal.load($1.unpack("m")[0].force_encoding("ASCII-8BIT"))).uniq!
|
107
|
+
when /^run (.+?) (.+?)$/
|
108
|
+
_report "okay"
|
109
|
+
|
110
|
+
@options = @opts.dup
|
111
|
+
suites = MiniTest::Unit::TestCase.test_suites
|
112
|
+
|
113
|
+
begin
|
114
|
+
require $1
|
115
|
+
rescue LoadError
|
116
|
+
_report "after", Marshal.dump([$1, ProxyError.new($!)])
|
117
|
+
_report "ready"
|
118
|
+
next
|
119
|
+
end
|
120
|
+
_run_suites MiniTest::Unit::TestCase.test_suites-suites, $2.to_sym
|
121
|
+
|
122
|
+
if @need_exit
|
123
|
+
begin
|
124
|
+
_report "bye"
|
125
|
+
rescue Errno::EPIPE; end
|
126
|
+
exit
|
127
|
+
else
|
128
|
+
_report "ready"
|
129
|
+
end
|
130
|
+
when /^quit$/
|
131
|
+
begin
|
132
|
+
_report "bye"
|
133
|
+
rescue Errno::EPIPE; end
|
134
|
+
exit
|
135
|
+
end
|
136
|
+
end
|
137
|
+
rescue Errno::EPIPE
|
138
|
+
rescue Exception => e
|
139
|
+
begin
|
140
|
+
trace = e.backtrace
|
141
|
+
err = ["#{trace.shift}: #{e.message} (#{e.class})"] + trace.map{|t| t.prepend("\t") }
|
142
|
+
|
143
|
+
_report "bye", Marshal.dump(err.join("\n"))
|
144
|
+
rescue Errno::EPIPE;end
|
145
|
+
exit
|
146
|
+
ensure
|
147
|
+
@stdin.close if @stdin
|
148
|
+
@stdout.close if @stdout
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def _report(res, *args) # :nodoc:
|
153
|
+
res = "#{res} #{args.pack("m0")}" unless args.empty?
|
154
|
+
@stdout.puts(res)
|
155
|
+
end
|
156
|
+
|
157
|
+
def puke(klass, meth, e) # :nodoc:
|
158
|
+
if e.is_a?(MiniTest::Skip)
|
159
|
+
new_e = MiniTest::Skip.new(e.message)
|
160
|
+
new_e.set_backtrace(e.backtrace)
|
161
|
+
e = new_e
|
162
|
+
end
|
163
|
+
@partial_report << [klass.name, meth, e.is_a?(MiniTest::Assertion) ? e : ProxyError.new(e)]
|
164
|
+
super
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if $0 == __FILE__
|
171
|
+
module Test
|
172
|
+
module Unit
|
173
|
+
class TestCase < MiniTest::Unit::TestCase # :nodoc: all
|
174
|
+
undef on_parallel_worker?
|
175
|
+
def on_parallel_worker?
|
176
|
+
true
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
require 'rubygems'
|
182
|
+
module Gem # :nodoc:
|
183
|
+
end
|
184
|
+
class Gem::TestCase < MiniTest::Unit::TestCase # :nodoc:
|
185
|
+
@@project_dir = File.expand_path('../../../..', __FILE__)
|
186
|
+
end
|
187
|
+
|
188
|
+
Test::Unit::Worker.new.run(ARGV)
|
189
|
+
end
|