benchmarker 0.1.0 → 1.0.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/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
|