benchmarker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,825 @@
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