benchmarker 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES.md +9 -0
- data/MIT-LICENSE +20 -0
- data/README.md +26 -0
- data/Rakefile +107 -0
- data/benchmarker.gemspec +20 -34
- data/lib/benchmarker.rb +1041 -0
- data/test/benchmarker_test.rb +1532 -560
- metadata +53 -79
- data/CHANGES.txt +0 -6
- data/examples/bench_loop.rb +0 -51
- data/examples/bench_require.rb +0 -34
- data/test/oktest.rb +0 -825
data/test/oktest.rb
DELETED
@@ -1,825 +0,0 @@
|
|
1
|
-
###
|
2
|
-
### $Release: $
|
3
|
-
### $Copyright: copyright(c) 2010 kuwata-lab.com all rights reserved $
|
4
|
-
### $License: MIT License $
|
5
|
-
###
|
6
|
-
|
7
|
-
module Oktest
|
8
|
-
|
9
|
-
DIFF = ENV['DIFF'] || File.file?('/usr/bin/diff')
|
10
|
-
|
11
|
-
def self.DIFF=(command)
|
12
|
-
remove_const(:DIFF)
|
13
|
-
const_set(:DIFF, command)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.diff(actual, expected)
|
17
|
-
## actual and expected should be different
|
18
|
-
return nil if actual == expected
|
19
|
-
## both actual and expected should be String
|
20
|
-
return nil unless actual.is_a?(String) && expected.is_a?(String)
|
21
|
-
## either actual or expected should contain "\n"
|
22
|
-
return nil unless actual.index("\n") || expected.index("\n")
|
23
|
-
## diff command
|
24
|
-
command = Oktest::DIFF
|
25
|
-
return nil unless command
|
26
|
-
command = 'diff -u' if command == true
|
27
|
-
## diff
|
28
|
-
require 'tempfile' unless defined?(Tempfile)
|
29
|
-
output = nil
|
30
|
-
#Tempfile.open('actual') do |af| # af.path file is not removed. why?
|
31
|
-
# af.write(actual); af.flush()
|
32
|
-
# Tempfile.open('expected') do |ef|
|
33
|
-
# ef.write(expected); ef.flush()
|
34
|
-
# #output = `#{command} #{ef.path} #{af.path}`
|
35
|
-
# output = IO.popen(cmd="#{command} #{ef.path} #{af.path}") {|io| io.read }
|
36
|
-
# end
|
37
|
-
#end
|
38
|
-
af = ef = nil
|
39
|
-
begin
|
40
|
-
af = Tempfile.open('actual') ; af.write(actual) ; af.flush
|
41
|
-
ef = Tempfile.open('expected') ; ef.write(expected) ; ef.flush
|
42
|
-
#output = `#{command} #{ef.path} #{af.path}`
|
43
|
-
output = IO.popen("#{command} #{ef.path} #{af.path}") {|io| io.read() }
|
44
|
-
ensure
|
45
|
-
af.close if ef
|
46
|
-
ef.close if ef
|
47
|
-
end
|
48
|
-
return output.sub(/\A.*?\n.*?\n/, "--- expected\n+++ actual\n")
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
class AssertionFailed < Exception
|
53
|
-
attr_accessor :diff
|
54
|
-
end
|
55
|
-
|
56
|
-
ASSERTION_FAILED = AssertionFailed
|
57
|
-
|
58
|
-
|
59
|
-
class AssertionObject
|
60
|
-
|
61
|
-
attr_reader :actual, :negative
|
62
|
-
|
63
|
-
def initialize(this, actual, negative=false)
|
64
|
-
@this = this
|
65
|
-
@actual = actual
|
66
|
-
@negative = negative
|
67
|
-
end
|
68
|
-
|
69
|
-
def ==(expected)
|
70
|
-
begin
|
71
|
-
do_assert(@actual == expected, expected, '==', '!=')
|
72
|
-
rescue AssertionFailed => ex
|
73
|
-
ex.diff = Oktest.diff(@actual, expected) if @actual != expected
|
74
|
-
raise ex
|
75
|
-
rescue ASSERTION_FAILED => ex
|
76
|
-
diff = Oktest.diff(@actual, expected) if @actual != expected
|
77
|
-
ex.message << "\n" << diff.chomp() if diff && ! diff.empty?
|
78
|
-
raise ex
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
if Object.new.respond_to?(:'!=')
|
83
|
-
eval <<-'END'
|
84
|
-
def !=(expected)
|
85
|
-
do_assert(@actual == expected, expected, '!=', '==')
|
86
|
-
end
|
87
|
-
END
|
88
|
-
end
|
89
|
-
|
90
|
-
def >(expected)
|
91
|
-
do_assert(@actual > expected, expected, '>', '<=')
|
92
|
-
end
|
93
|
-
|
94
|
-
def <(expected)
|
95
|
-
do_assert(@actual < expected, expected, '<', '>=')
|
96
|
-
end
|
97
|
-
|
98
|
-
def >=(expected)
|
99
|
-
do_assert(@actual >= expected, expected, '>=', '<')
|
100
|
-
end
|
101
|
-
|
102
|
-
def <=(expected)
|
103
|
-
do_assert(@actual <= expected, expected, '<=', '>')
|
104
|
-
end
|
105
|
-
|
106
|
-
def ===(expected)
|
107
|
-
do_assert(@actual === expected, expected, '===', '!==')
|
108
|
-
end
|
109
|
-
|
110
|
-
def =~(expected)
|
111
|
-
do_assert(@actual =~ expected, expected, '=~', '!~')
|
112
|
-
end
|
113
|
-
|
114
|
-
def in_delta?(expected, delta)
|
115
|
-
flag = expected - delta <= @actual && @actual <= expected + delta
|
116
|
-
check2(flag) { "(#{(expected - delta).inspect} <= #{@actual.inspect} <= #{(expected + delta).inspect})" }
|
117
|
-
end
|
118
|
-
|
119
|
-
def file?
|
120
|
-
check2(File.file?(@actual)) { "File.file?(#{@actual.inspect})" }
|
121
|
-
end
|
122
|
-
|
123
|
-
def dir?
|
124
|
-
check2(File.directory?(@actual)) { "File.directory?(#{@actual.inspect})" }
|
125
|
-
end
|
126
|
-
|
127
|
-
def exist?
|
128
|
-
check2(File.exist?(@actual)) { "File.exist?(#{@actual.inspect})" }
|
129
|
-
end
|
130
|
-
|
131
|
-
def same?(expected)
|
132
|
-
check2(@actual.equal?(expected)) { "#{@actual.inspect}.equal?(#{expected.inspect})" }
|
133
|
-
end
|
134
|
-
|
135
|
-
def in?(expected)
|
136
|
-
check2(expected.include?(@actual)) { "#{expected.inspect}.include?(#{@actual.inspect})" }
|
137
|
-
end
|
138
|
-
|
139
|
-
def include?(expected)
|
140
|
-
check2(@actual.include?(expected)) { "#{@actual.inspect}.include?(#{expected.inspect})" }
|
141
|
-
end
|
142
|
-
|
143
|
-
def is_a?(expected)
|
144
|
-
check2(@actual.is_a?(expected)) { "#{@actual.inspect}.is_a?(#{expected})" }
|
145
|
-
end
|
146
|
-
alias kind_of? is_a?
|
147
|
-
|
148
|
-
def nil?
|
149
|
-
check2(@actual.nil?) { "#{@actual.inspect}.nil?" }
|
150
|
-
end
|
151
|
-
|
152
|
-
def empty?
|
153
|
-
check2(@actual.empty?) { "#{@actual.inspect}.empty?" }
|
154
|
-
end
|
155
|
-
|
156
|
-
def raise?(exception_class, message=nil)
|
157
|
-
if @negative
|
158
|
-
_should_not_raise(exception_class)
|
159
|
-
ex = nil
|
160
|
-
else
|
161
|
-
ex = _should_raise(exception_class, message)
|
162
|
-
end
|
163
|
-
return ex
|
164
|
-
end
|
165
|
-
|
166
|
-
private
|
167
|
-
|
168
|
-
def _should_raise(exception_class, message)
|
169
|
-
not_raised = false
|
170
|
-
begin
|
171
|
-
@actual.call
|
172
|
-
not_raised = true
|
173
|
-
rescue Exception => ex
|
174
|
-
@actual.instance_variable_set('@exception', ex)
|
175
|
-
def @actual.exception; @exception; end
|
176
|
-
ex.class <= exception_class or
|
177
|
-
raise new_assertion_failed("#{exception_class.name} expected but #{ex.class.name} raised.", 2)
|
178
|
-
if message
|
179
|
-
op = message.is_a?(Regexp) ? '=~' : '=='
|
180
|
-
ex.message.__send__(op, message) or
|
181
|
-
raise new_assertion_failed("#{ex.message.inspect} #{op} #{message.inspect}: failed.", 2)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
raise new_assertion_failed("#{exception_class.name} expected but not raised.", 2) if not_raised
|
185
|
-
return ex
|
186
|
-
end
|
187
|
-
|
188
|
-
def _should_not_raise(exception_class=Exception)
|
189
|
-
begin
|
190
|
-
@actual.call
|
191
|
-
rescue Exception => ex
|
192
|
-
@actual.instance_variable_set('@exception', ex)
|
193
|
-
def @actual.exception; @exception; end
|
194
|
-
if ex.class <= exception_class
|
195
|
-
raise new_assertion_failed("unexpected #{ex.class.name} raised.", 2)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def do_assert(flag, expected, op, negative_op)
|
201
|
-
flag, msg = check(flag, expected, op, negative_op)
|
202
|
-
return true if flag
|
203
|
-
raise new_assertion_failed(msg)
|
204
|
-
end
|
205
|
-
|
206
|
-
def new_assertion_failed(msg, depth=2)
|
207
|
-
ex = AssertionFailed.new(msg)
|
208
|
-
ex.set_backtrace(caller(depth+1)) # manipulate backtrace
|
209
|
-
return ex
|
210
|
-
end
|
211
|
-
|
212
|
-
def check(flag, expected, op, negative_op)
|
213
|
-
if @negative
|
214
|
-
flag = ! flag
|
215
|
-
op = negative_op
|
216
|
-
end
|
217
|
-
msg = flag ? nil : failed_message(expected, op)
|
218
|
-
return flag, msg
|
219
|
-
end
|
220
|
-
|
221
|
-
def failed_message(expected, op)
|
222
|
-
"#{@actual.inspect} #{op} #{expected.inspect}: failed."
|
223
|
-
end
|
224
|
-
|
225
|
-
def check2(flag)
|
226
|
-
flag = ! flag if @negative
|
227
|
-
return true if flag
|
228
|
-
expr = yield
|
229
|
-
expr = "! #{expr}" if @negative
|
230
|
-
raise new_assertion_failed("#{expr}: failed.")
|
231
|
-
end
|
232
|
-
|
233
|
-
end
|
234
|
-
|
235
|
-
|
236
|
-
module Helper
|
237
|
-
|
238
|
-
module_function
|
239
|
-
|
240
|
-
def ok
|
241
|
-
actual = yield
|
242
|
-
return Oktest::AssertionObject.new(self, actual, false)
|
243
|
-
end
|
244
|
-
|
245
|
-
def ok_(actual)
|
246
|
-
return Oktest::AssertionObject.new(self, actual, false)
|
247
|
-
end
|
248
|
-
|
249
|
-
def not_ok
|
250
|
-
actual = yield
|
251
|
-
return Oktest::AssertionObject.new(self, actual, true)
|
252
|
-
end
|
253
|
-
|
254
|
-
def not_ok_(actual)
|
255
|
-
return Oktest::AssertionObject.new(self, actual, true)
|
256
|
-
end
|
257
|
-
|
258
|
-
def dummy_io(stdin_str=nil)
|
259
|
-
require 'stringio' unless defined?(StringIO)
|
260
|
-
stdout, $stdout = $stdout, StringIO.new
|
261
|
-
stderr, $stderr = $stderr, StringIO.new
|
262
|
-
stdin, $stdin = $stdin, StringIO.new(stdin_str) if stdin_str
|
263
|
-
begin
|
264
|
-
yield
|
265
|
-
return [$stdout.string, $stderr.string]
|
266
|
-
ensure
|
267
|
-
$stdout = stdout
|
268
|
-
$stderr = stderr
|
269
|
-
$stdin = stdin if stdin_str
|
270
|
-
end
|
271
|
-
end
|
272
|
-
alias capture_io dummy_io # for backward compatibility
|
273
|
-
|
274
|
-
def dummy_file(pairs)
|
275
|
-
fnames = []
|
276
|
-
begin
|
277
|
-
pairs.each do |fname, content|
|
278
|
-
fnames << fname
|
279
|
-
File.open(fname, 'wb') {|f| f.write(content) }
|
280
|
-
yield
|
281
|
-
end
|
282
|
-
ensure
|
283
|
-
File.unlink(*fnames)
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
def dummy_dir(*paths)
|
288
|
-
require 'fileutils' unless defined?(FileUtils)
|
289
|
-
begin
|
290
|
-
paths.each {|path| FileUtils.mkdir_p(path) }
|
291
|
-
yield
|
292
|
-
ensure
|
293
|
-
paths.reverse.each {|path| FileUtils.rm_rf(path) }
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
## marker method to represent pre-condition
|
298
|
-
def pre_cond; yield; end
|
299
|
-
|
300
|
-
## marker method to represent post-condition
|
301
|
-
def post_cond; yield; end
|
302
|
-
|
303
|
-
## marker method to describe target of specification
|
304
|
-
def target(desc); yield; end
|
305
|
-
|
306
|
-
## marker method to describe specification
|
307
|
-
#def spec(desc); yield if block_given?; end
|
308
|
-
def spec(desc)
|
309
|
-
reporter = @_oktest_runner && @_oktest_runner.reporter
|
310
|
-
status = nil
|
311
|
-
begin
|
312
|
-
reporter.enter_spec(self, desc) if reporter
|
313
|
-
if block_given?
|
314
|
-
yield
|
315
|
-
status = :ok
|
316
|
-
else
|
317
|
-
status = :empty
|
318
|
-
end
|
319
|
-
rescue AssertionFailed => ex
|
320
|
-
status = :fail
|
321
|
-
raise ex
|
322
|
-
rescue => ex
|
323
|
-
status = :error
|
324
|
-
raise ex
|
325
|
-
ensure
|
326
|
-
reporter.exit_spec(self, status) if reporter
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
def tracer(*args)
|
331
|
-
return Oktest::Util::Tracer.new(*args)
|
332
|
-
end
|
333
|
-
|
334
|
-
end
|
335
|
-
|
336
|
-
|
337
|
-
module ClassMethodHelper
|
338
|
-
|
339
|
-
def method_added(name)
|
340
|
-
super
|
341
|
-
dict = (@_test_method_names_dict ||= {})
|
342
|
-
name = name.to_s
|
343
|
-
if name =~ /\Atest_?/
|
344
|
-
## if test method name is duplicated, raise error
|
345
|
-
dict[name].nil? or
|
346
|
-
raise NameError.new("#{self.name}##{name}(): already defined (please change test method name).")
|
347
|
-
dict[name] = dict.size()
|
348
|
-
## if ENV['TEST'] is set, remove unmatched method
|
349
|
-
if ENV['TEST']
|
350
|
-
remove_method(name) unless name.sub(/\Atest_?/, '').index(ENV['TEST'])
|
351
|
-
end
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
def method_undefined(method)
|
356
|
-
super
|
357
|
-
dict = @_test_method_names_dict
|
358
|
-
dict.delete(method.to_s) if dict
|
359
|
-
end
|
360
|
-
|
361
|
-
def test(desc, &block)
|
362
|
-
@_test_count ||= 0
|
363
|
-
@_test_count += 1
|
364
|
-
method_name = "test_%03d_%s" % [@_test_count, desc.to_s.gsub(/[^\w]/, '_')]
|
365
|
-
define_method(method_name, block)
|
366
|
-
end
|
367
|
-
|
368
|
-
end
|
369
|
-
|
370
|
-
|
371
|
-
module TestCase
|
372
|
-
include Helper
|
373
|
-
|
374
|
-
@_subclasses = []
|
375
|
-
|
376
|
-
def self._subclasses # :nodoc:
|
377
|
-
return @_subclasses
|
378
|
-
end
|
379
|
-
|
380
|
-
def self.included(klass)
|
381
|
-
@_subclasses << klass if klass.is_a?(Class)
|
382
|
-
klass.class_eval do
|
383
|
-
extend Oktest::ClassMethodHelper
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
end
|
388
|
-
|
389
|
-
|
390
|
-
class Reporter
|
391
|
-
|
392
|
-
def before_all(klass)
|
393
|
-
end
|
394
|
-
|
395
|
-
def after_all(klass)
|
396
|
-
end
|
397
|
-
|
398
|
-
def before(obj)
|
399
|
-
end
|
400
|
-
|
401
|
-
def after(obj)
|
402
|
-
end
|
403
|
-
|
404
|
-
def print_ok(obj)
|
405
|
-
end
|
406
|
-
|
407
|
-
def print_failed(obj, ex)
|
408
|
-
end
|
409
|
-
|
410
|
-
def print_error(obj, ex)
|
411
|
-
end
|
412
|
-
|
413
|
-
def enter_spec(obj, desc)
|
414
|
-
end
|
415
|
-
|
416
|
-
def exit_spec(obj, status)
|
417
|
-
end
|
418
|
-
|
419
|
-
end
|
420
|
-
|
421
|
-
|
422
|
-
class BaseReporter < Reporter
|
423
|
-
|
424
|
-
def initialize(out=nil)
|
425
|
-
@out = out || $stdout
|
426
|
-
@_flush = @out.respond_to?(:flush)
|
427
|
-
end
|
428
|
-
|
429
|
-
def before_all(klass)
|
430
|
-
@count_test = 0
|
431
|
-
@count_spec = 0
|
432
|
-
end
|
433
|
-
|
434
|
-
def before(obj)
|
435
|
-
@count_test += 1
|
436
|
-
@spec_status = nil
|
437
|
-
end
|
438
|
-
|
439
|
-
def after(obj)
|
440
|
-
end
|
441
|
-
|
442
|
-
def enter_spec(obj, desc)
|
443
|
-
@count_spec += 1
|
444
|
-
end
|
445
|
-
|
446
|
-
def exit_spec(obj, status)
|
447
|
-
@spec_status = status
|
448
|
-
case status
|
449
|
-
when :ok ; write('.')
|
450
|
-
when :empty ; write('_')
|
451
|
-
when :fail ; write('f')
|
452
|
-
when :error ; write('E')
|
453
|
-
when nil ; write('?')
|
454
|
-
else
|
455
|
-
raise "** internal error: status=#{status.inspect}"
|
456
|
-
end
|
457
|
-
end
|
458
|
-
|
459
|
-
private
|
460
|
-
|
461
|
-
def _test_ident(obj)
|
462
|
-
return obj.instance_variable_get('@_test_method')
|
463
|
-
end
|
464
|
-
|
465
|
-
def write(str)
|
466
|
-
@out << str
|
467
|
-
@out.flush if @_flush
|
468
|
-
end
|
469
|
-
|
470
|
-
def print_backtrace(ex, out=@out)
|
471
|
-
ex.backtrace.each do |str|
|
472
|
-
out << " #{str}\n"
|
473
|
-
if str =~ /\A(.*):(\d+):in `(.*?)'/
|
474
|
-
filepath, linenum, method = $1, $2.to_i, $3
|
475
|
-
#break if method =~ /\Atest_?/
|
476
|
-
line = get_line(filepath, linenum)
|
477
|
-
out << " #{line.strip}\n" if line
|
478
|
-
break if method =~ /\Atest_?/
|
479
|
-
end
|
480
|
-
end
|
481
|
-
end
|
482
|
-
|
483
|
-
def get_line(filepath, linenum)
|
484
|
-
return nil unless File.file?(filepath)
|
485
|
-
linenum = linenum.to_i
|
486
|
-
line = File.open(filepath) do |f|
|
487
|
-
i = 0
|
488
|
-
f.find { (i += 1) == linenum }
|
489
|
-
end
|
490
|
-
return line
|
491
|
-
end
|
492
|
-
|
493
|
-
end
|
494
|
-
|
495
|
-
|
496
|
-
class SimpleReporter < BaseReporter
|
497
|
-
|
498
|
-
def before_all(klass)
|
499
|
-
super
|
500
|
-
write("### %s: " % klass.name)
|
501
|
-
@buf = ""
|
502
|
-
end
|
503
|
-
|
504
|
-
def after_all(klass)
|
505
|
-
super
|
506
|
-
write(" (#{@count_test} tests, #{@count_spec} specs)\n")
|
507
|
-
@out << @buf.to_s
|
508
|
-
@buf = nil
|
509
|
-
end
|
510
|
-
|
511
|
-
def print_ok(obj)
|
512
|
-
write(".") unless @spec_status
|
513
|
-
end
|
514
|
-
|
515
|
-
def print_failed(obj, ex)
|
516
|
-
write("f") unless @spec_status
|
517
|
-
@buf << "Failed: #{_test_ident(obj)}()\n"
|
518
|
-
@buf << " #{ex.message}\n"
|
519
|
-
print_backtrace(ex, @buf)
|
520
|
-
#assert ex.is_a?(AssertionFailed)
|
521
|
-
@buf << ex.diff if ex.diff
|
522
|
-
end
|
523
|
-
|
524
|
-
def print_error(obj, ex)
|
525
|
-
write("E") unless @spec_status
|
526
|
-
@buf << "ERROR: #{_test_ident(obj)}()\n"
|
527
|
-
@buf << " #{ex.class.name}: #{ex.message}\n"
|
528
|
-
print_backtrace(ex, @buf)
|
529
|
-
end
|
530
|
-
|
531
|
-
end
|
532
|
-
|
533
|
-
|
534
|
-
class VerboseReporter < BaseReporter
|
535
|
-
|
536
|
-
def before_all(klass)
|
537
|
-
super
|
538
|
-
write("### %s\n" % klass.name)
|
539
|
-
end
|
540
|
-
|
541
|
-
def after_all(klass)
|
542
|
-
super
|
543
|
-
write(" (#{@count_test} tests, #{@count_spec} specs)\n")
|
544
|
-
end
|
545
|
-
|
546
|
-
def before(obj)
|
547
|
-
super
|
548
|
-
write("- #{_test_ident(obj)}: ")
|
549
|
-
end
|
550
|
-
|
551
|
-
def print_ok(obj)
|
552
|
-
write(" ok\n")
|
553
|
-
end
|
554
|
-
|
555
|
-
def print_failed(obj, ex)
|
556
|
-
write(" FAILED\n")
|
557
|
-
write(" #{ex.message}\n")
|
558
|
-
print_backtrace(ex, @out)
|
559
|
-
#assert ex.is_a?(AssertionFailed)
|
560
|
-
write(ex.diff) if ex.diff
|
561
|
-
end
|
562
|
-
|
563
|
-
def print_error(obj, ex)
|
564
|
-
write(" ERROR\n")
|
565
|
-
write(" #{ex.class.name}: #{ex.message}\n")
|
566
|
-
print_backtrace(ex, @out)
|
567
|
-
end
|
568
|
-
|
569
|
-
end
|
570
|
-
|
571
|
-
|
572
|
-
REPORTER = SimpleReporter
|
573
|
-
#REPORTER = VerboseReporter
|
574
|
-
|
575
|
-
def self.REPORTER=(reporter_class)
|
576
|
-
remove_const(:REPORTER)
|
577
|
-
const_set(:REPORTER, reporter_class)
|
578
|
-
end
|
579
|
-
|
580
|
-
|
581
|
-
class Runner
|
582
|
-
|
583
|
-
def initialize(reporter=nil)
|
584
|
-
@reporter = reporter || REPORTER.new
|
585
|
-
end
|
586
|
-
attr_accessor :reporter
|
587
|
-
|
588
|
-
def test_method_names_from(klass)
|
589
|
-
test_method_names = klass.instance_methods(true).collect {|sym| sym.to_s }.grep(/\Atest/).sort()
|
590
|
-
dict = klass.instance_variable_get('@_test_method_names_dict')
|
591
|
-
if dict
|
592
|
-
dict = dict.dup() # key: test method name (String), value: index (Integer)
|
593
|
-
i = 0
|
594
|
-
test_method_names.select {|name| ! dict.key?(name) }.reverse.each {|name| dict[name] = (i -= 1) }
|
595
|
-
test_method_names = dict.sort_by {|k, v| v }.collect {|k, v| k }
|
596
|
-
end
|
597
|
-
return test_method_names
|
598
|
-
end
|
599
|
-
|
600
|
-
def warning(msg)
|
601
|
-
warn "WARNING: #{msg}"
|
602
|
-
end
|
603
|
-
|
604
|
-
def run(klass)
|
605
|
-
reporter = @reporter
|
606
|
-
## gather test methods
|
607
|
-
test_method_names = test_method_names_from(klass)
|
608
|
-
## filer by $TEST environment variable
|
609
|
-
pattern = ENV['TEST']
|
610
|
-
test_method_names.delete_if {|x| x.index(pattern).nil? } if pattern
|
611
|
-
## sort by linenumber
|
612
|
-
# nothing
|
613
|
-
## invoke before_all()
|
614
|
-
reporter.before_all(klass)
|
615
|
-
if klass.respond_to?(:before_all)
|
616
|
-
klass.before_all()
|
617
|
-
elsif klass.method_defined?(:before_all)
|
618
|
-
warning "#{klass.name}#before_all() should be class method (but defined as instance method)"
|
619
|
-
end
|
620
|
-
## invoke test methods
|
621
|
-
count = 0
|
622
|
-
flag_before = klass.method_defined?(:before)
|
623
|
-
flag_setup = klass.method_defined?(:setup)
|
624
|
-
flag_after = klass.method_defined?(:after)
|
625
|
-
flag_teardown = klass.method_defined?(:teardown)
|
626
|
-
test_method_names.each do |method_name|
|
627
|
-
## create instance object for each test
|
628
|
-
begin
|
629
|
-
obj = klass.new
|
630
|
-
rescue ArgumentError
|
631
|
-
obj = klass.new(method_name)
|
632
|
-
end
|
633
|
-
obj.instance_variable_set('@_name', method_name.sub(/\Atest_?/, ''))
|
634
|
-
obj.instance_variable_set('@_test_method', method_name)
|
635
|
-
obj.instance_variable_set('@_oktest_runner', self)
|
636
|
-
## invoke before() or setup()
|
637
|
-
reporter.before(obj)
|
638
|
-
flag_before ? obj.before() : flag_setup ? obj.setup() : nil
|
639
|
-
## invoke test method
|
640
|
-
begin
|
641
|
-
obj.__send__(method_name)
|
642
|
-
reporter.print_ok(obj)
|
643
|
-
rescue Oktest::AssertionFailed => ex
|
644
|
-
count += 1
|
645
|
-
reporter.print_failed(obj, ex)
|
646
|
-
rescue Exception => ex
|
647
|
-
count += 1
|
648
|
-
reporter.print_error(obj, ex)
|
649
|
-
ensure
|
650
|
-
## invoke after() or teardown()
|
651
|
-
flag_after ? obj.after() : flag_teardown ? obj.teardown() : nil
|
652
|
-
reporter.after(obj)
|
653
|
-
end
|
654
|
-
end
|
655
|
-
## invoke after_all()
|
656
|
-
if klass.respond_to?(:after_all)
|
657
|
-
klass.after_all()
|
658
|
-
elsif klass.method_defined?(:after_all)
|
659
|
-
warning "#{klass.name}#after_all() should be class method (but defined as instance method)"
|
660
|
-
end
|
661
|
-
reporter.after_all(klass)
|
662
|
-
##
|
663
|
-
return count
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
|
668
|
-
def self.run(*classes)
|
669
|
-
opts = classes.last.is_a?(Hash) ? classes.pop() : {}
|
670
|
-
reporter_class = opts[:verbose] ? VerboseReporter : REPORTER
|
671
|
-
reporter = reporter_class.new(opts[:out])
|
672
|
-
runner = Runner.new(reporter)
|
673
|
-
classes.each {|cls| runner.run(cls) }
|
674
|
-
self.run_at_exit = false
|
675
|
-
end
|
676
|
-
|
677
|
-
def self.run_all(opts={})
|
678
|
-
classes = Oktest::TestCase._subclasses()
|
679
|
-
args = classes + [opts]
|
680
|
-
self.run(*args)
|
681
|
-
end
|
682
|
-
|
683
|
-
@_run_at_exit = true
|
684
|
-
|
685
|
-
def self.run_at_exit?
|
686
|
-
return @_run_at_exit
|
687
|
-
end
|
688
|
-
|
689
|
-
def self.run_at_exit=(flag)
|
690
|
-
@_run_at_exit = flag
|
691
|
-
end
|
692
|
-
|
693
|
-
|
694
|
-
module Util
|
695
|
-
|
696
|
-
|
697
|
-
class Call
|
698
|
-
|
699
|
-
def initialize(name, args, ret)
|
700
|
-
@name, @args, @ret = name, args, ret
|
701
|
-
end
|
702
|
-
|
703
|
-
attr_accessor :name, :args, :ret
|
704
|
-
|
705
|
-
def to_a
|
706
|
-
return [@name, @args, @ret]
|
707
|
-
end
|
708
|
-
|
709
|
-
end
|
710
|
-
|
711
|
-
|
712
|
-
class FakeObject
|
713
|
-
|
714
|
-
def initialize(*args)
|
715
|
-
if (hash = args[-1]).is_a?(Hash)
|
716
|
-
hash.each do |k, v|
|
717
|
-
v.is_a?(Proc) ? add_response(k, &v) : add_response(k, v)
|
718
|
-
end
|
719
|
-
end
|
720
|
-
@_calls = []
|
721
|
-
end
|
722
|
-
|
723
|
-
attr_reader :_calls
|
724
|
-
|
725
|
-
def add_response(name, return_value=nil, &block)
|
726
|
-
#if block
|
727
|
-
(class << self; self; end).class_eval do
|
728
|
-
define_method name do |*args|
|
729
|
-
@_calls << (call = Call.new(name, args, return_value))
|
730
|
-
call.ret = block.call(*args) if block
|
731
|
-
call.ret
|
732
|
-
end
|
733
|
-
end
|
734
|
-
#else
|
735
|
-
# (class << self; self; end).class_eval do
|
736
|
-
# define_method name do |*args, &blk|
|
737
|
-
# @calls << (call = Call.new(name, args, return_value))
|
738
|
-
# call.ret
|
739
|
-
# end
|
740
|
-
# end
|
741
|
-
#end
|
742
|
-
end
|
743
|
-
|
744
|
-
end
|
745
|
-
|
746
|
-
|
747
|
-
class Tracer
|
748
|
-
|
749
|
-
def initialize
|
750
|
-
@calls = []
|
751
|
-
end
|
752
|
-
|
753
|
-
attr_reader :calls
|
754
|
-
|
755
|
-
def [](index)
|
756
|
-
@calls[index]
|
757
|
-
end
|
758
|
-
|
759
|
-
def length
|
760
|
-
@calls.length
|
761
|
-
end
|
762
|
-
|
763
|
-
alias size length
|
764
|
-
|
765
|
-
def trace_method(obj, *method_names)
|
766
|
-
#tracer = self
|
767
|
-
#method_names.each do |method_name|
|
768
|
-
# (class << obj; self; end).class_eval do
|
769
|
-
# alias_method "__orig_#{method_name}", method_name
|
770
|
-
# define_method method_name do |*args|
|
771
|
-
# tracer.calls << (call = Call.new(method_name, args, nil))
|
772
|
-
# call.ret = obj.__send__("__orig_#{method_name}", *args)
|
773
|
-
# call.ret
|
774
|
-
# end
|
775
|
-
# end
|
776
|
-
#end
|
777
|
-
obj.instance_variable_set("@__calls", @calls)
|
778
|
-
method_names.each do |method_name|
|
779
|
-
(class << obj; self; end).class_eval <<-"END"
|
780
|
-
alias_method :__orig_#{method_name}, :#{method_name}
|
781
|
-
def #{method_name}(*args, &blk)
|
782
|
-
@__calls << (call = Call.new(:#{method_name}, args, nil))
|
783
|
-
#call.ret = self.__orig_#{method_name}(*args, &blk)
|
784
|
-
call.ret = self.__send__(:__orig_#{method_name}, *args, &blk)
|
785
|
-
call.ret
|
786
|
-
end
|
787
|
-
END
|
788
|
-
end
|
789
|
-
nil
|
790
|
-
end
|
791
|
-
|
792
|
-
def fake_method(obj, method_name, return_value=nil, &block)
|
793
|
-
tracer = self
|
794
|
-
(class << obj; self; end).class_eval do
|
795
|
-
define_method method_name do |*args|
|
796
|
-
tracer.calls << (call = Call.new(method_name, args, return_value))
|
797
|
-
call.ret = block.call(*args) if block
|
798
|
-
call.ret
|
799
|
-
end
|
800
|
-
end
|
801
|
-
nil
|
802
|
-
end
|
803
|
-
|
804
|
-
def fake_object(*args)
|
805
|
-
fake_obj = FakeObject.new(*args)
|
806
|
-
fake_obj.instance_variable_set('@_calls', @calls)
|
807
|
-
return fake_obj
|
808
|
-
end
|
809
|
-
|
810
|
-
end
|
811
|
-
|
812
|
-
|
813
|
-
end #Util
|
814
|
-
|
815
|
-
|
816
|
-
end
|
817
|
-
|
818
|
-
|
819
|
-
at_exit do
|
820
|
-
ex = $!
|
821
|
-
if (! ex || ex.is_a?(SystemExit)) && Oktest.run_at_exit? # && ! defined?(Test::Unit)
|
822
|
-
Oktest.run_all()
|
823
|
-
raise ex if ex
|
824
|
-
end
|
825
|
-
end
|