OSDN Git Service

ruby-1.9.1-rc1
[splhack/AndroidRuby.git] / lib / ruby-1.9.1-rc1 / lib / minitest / unit.rb
1 ############################################################
2 # This file is imported from a different project.
3 # DO NOT make modifications in this repo.
4 # File a patch instead and assign it to Ryan Davis
5 ############################################################
6
7 ##
8 #
9 # Totally minimal drop-in replacement for test-unit
10 #
11 # TODO: refute -> debunk, prove/rebut, show/deny... lots of possibilities
12
13 module MiniTest
14   class Assertion < Exception; end
15   class Skip < Assertion; end
16
17   file = if RUBY_VERSION =~ /^1\.9/ then  # bt's expanded, but __FILE__ isn't :(
18            File.expand_path __FILE__
19          elsif  __FILE__ =~ /^[^\.]/ then # assume both relative
20            require 'pathname'
21            pwd = Pathname.new Dir.pwd
22            pn = Pathname.new File.expand_path(__FILE__)
23            pn = File.join(".", pn.relative_path_from(pwd)) unless pn.relative?
24            pn.to_s
25          else                             # assume both are expanded
26            __FILE__
27          end
28
29   # './lib' in project dir, or '/usr/local/blahblah' if installed
30   MINI_DIR = File.dirname(File.dirname(file))
31
32   def self.filter_backtrace bt
33     return ["No backtrace"] unless bt
34
35     new_bt = []
36     bt.each do |line|
37       break if line.rindex(MINI_DIR, 0)
38       new_bt << line
39     end
40
41     new_bt = bt.reject { |line| line.rindex(MINI_DIR, 0) } if new_bt.empty?
42     new_bt = bt.dup if new_bt.empty?
43     new_bt
44   end
45
46   module Assertions
47     def mu_pp(obj)
48       s = obj.inspect
49       s = s.force_encoding(Encoding.default_external) if defined? Encoding
50       s
51     end
52
53     def _assertions= n
54       @_assertions = n
55     end
56
57     def _assertions
58       @_assertions ||= 0
59     end
60
61     def assert test, msg = nil
62       msg ||= "Failed assertion, no message given."
63       self._assertions += 1
64       unless test then
65         msg = msg.call if Proc === msg
66         raise MiniTest::Assertion, msg
67       end
68       true
69     end
70
71     def assert_block msg = nil
72       msg = message(msg) { "Expected block to return true value" }
73       assert yield, msg
74     end
75
76     def assert_empty obj, msg = nil
77       msg = message(msg) { "Expected #{obj.inspect} to be empty" }
78       assert_respond_to obj, :empty?
79       assert obj.empty?, msg
80     end
81
82     def assert_equal exp, act, msg = nil
83       msg = message(msg) { "Expected #{mu_pp(exp)}, not #{mu_pp(act)}" }
84       assert(exp == act, msg)
85     end
86
87     def assert_in_delta exp, act, delta = 0.001, msg = nil
88       n = (exp - act).abs
89       msg = message(msg) { "Expected #{exp} - #{act} (#{n}) to be < #{delta}" }
90       assert delta >= n, msg
91     end
92
93     def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
94       assert_in_delta a, b, [a, b].min * epsilon, msg
95     end
96
97     def assert_includes collection, obj, msg = nil
98       msg = message(msg) { "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}" }
99       assert_respond_to collection, :include?
100       assert collection.include?(obj), msg
101     end
102
103     def assert_instance_of cls, obj, msg = nil
104       msg = message(msg) { "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}" }
105       flip = (Module === obj) && ! (Module === cls) # HACK for specs
106       obj, cls = cls, obj if flip
107       assert obj.instance_of?(cls), msg
108     end
109
110     def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of
111       msg = message(msg) {
112         "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
113       flip = (Module === obj) && ! (Module === cls) # HACK for specs
114       obj, cls = cls, obj if flip
115       assert obj.kind_of?(cls), msg
116     end
117
118     def assert_match exp, act, msg = nil
119       msg = message(msg) { "Expected #{mu_pp(exp)} to match #{mu_pp(act)}" }
120       assert_respond_to act, :"=~"
121       exp = /#{Regexp.escape(exp)}/ if String === exp && String === act
122       assert exp =~ act, msg
123     end
124
125     def assert_nil obj, msg = nil
126       msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
127       assert obj.nil?, msg
128     end
129
130     def assert_operator o1, op, o2, msg = nil
131       msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
132       assert o1.__send__(op, o2), msg
133     end
134
135     def assert_raises *exp
136       msg = String === exp.last ? exp.pop : nil
137       should_raise = false
138       begin
139         yield
140         should_raise = true
141       rescue Exception => e
142         assert(exp.any? { |ex|
143                  ex.instance_of?(Module) ? e.kind_of?(ex) : ex == e.class
144                }, exception_details(e, "#{mu_pp(exp)} exception expected, not"))
145
146         return e
147       end
148
149       exp = exp.first if exp.size == 1
150       flunk "#{mu_pp(exp)} expected but nothing was raised." if should_raise
151     end
152
153     def assert_respond_to obj, meth, msg = nil
154       msg = message(msg) {
155           "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
156         }
157       flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
158       obj, meth = meth, obj if flip
159       assert obj.respond_to?(meth), msg
160     end
161
162     def assert_same exp, act, msg = nil
163       msg = message(msg) {
164         data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
165         "Expected %s (0x%x) to be the same as %s (0x%x)" % data
166       }
167       assert exp.equal?(act), msg
168     end
169
170     def assert_send send_ary, m = nil
171       recv, msg, *args = send_ary
172       m = message(m) {
173         "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" }
174       assert recv.__send__(msg, *args), m
175     end
176
177     def assert_throws sym, msg = nil
178       default = "Expected #{mu_pp(sym)} to have been thrown"
179       caught = true
180       catch(sym) do
181         begin
182           yield
183         rescue ArgumentError => e     # 1.9 exception
184           default += ", not #{e.message.split(/ /).last}"
185         rescue NameError => e         # 1.8 exception
186           default += ", not #{e.name.inspect}"
187         end
188         caught = false
189       end
190
191       assert caught, message(msg) { default }
192     end
193
194     def capture_io
195       require 'stringio'
196
197       orig_stdout, orig_stderr         = $stdout, $stderr
198       captured_stdout, captured_stderr = StringIO.new, StringIO.new
199       $stdout, $stderr                 = captured_stdout, captured_stderr
200
201       yield
202
203       return captured_stdout.string, captured_stderr.string
204     ensure
205       $stdout = orig_stdout
206       $stderr = orig_stderr
207     end
208
209     def exception_details e, msg
210       "#{msg}\nClass: <#{e.class}>\nMessage: <#{e.message.inspect}>\n---Backtrace---\n#{MiniTest::filter_backtrace(e.backtrace).join("\n")}\n---------------"
211     end
212
213     def flunk msg = nil
214       msg ||= "Epic Fail!"
215       assert false, msg
216     end
217
218     def message msg = nil, &default
219       proc {
220         if msg then
221           msg = msg.to_s unless String === msg
222           msg += '.' unless msg.empty?
223           msg += "\n#{default.call}."
224           msg.strip
225         else
226           "#{default.call}."
227         end
228       }
229     end
230
231     # used for counting assertions
232     def pass msg = nil
233       assert true
234     end
235
236     def refute test, msg = nil
237       msg ||= "Failed refutation, no message given"
238       not assert(! test, msg)
239     end
240
241     def refute_empty obj, msg = nil
242       msg = message(msg) { "Expected #{obj.inspect} to not be empty" }
243       assert_respond_to obj, :empty?
244       refute obj.empty?, msg
245     end
246
247     def refute_equal exp, act, msg = nil
248       msg = message(msg) { "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}" }
249       refute exp == act, msg
250     end
251
252     def refute_in_delta exp, act, delta = 0.001, msg = nil
253       n = (exp - act).abs
254       msg = message(msg) { "Expected #{exp} - #{act} (#{n}) to not be < #{delta}" }
255       refute delta > n, msg
256     end
257
258     def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
259       refute_in_delta a, b, a * epsilon, msg
260     end
261
262     def refute_includes collection, obj, msg = nil
263       msg = message(msg) { "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}" }
264       assert_respond_to collection, :include?
265       refute collection.include?(obj), msg
266     end
267
268     def refute_instance_of cls, obj, msg = nil
269       msg = message(msg) { "Expected #{mu_pp(obj)} to not be an instance of #{cls}" }
270       flip = (Module === obj) && ! (Module === cls) # HACK for specs
271       obj, cls = cls, obj if flip
272       refute obj.instance_of?(cls), msg
273     end
274
275     def refute_kind_of cls, obj, msg = nil # TODO: merge with instance_of
276       msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
277       flip = (Module === obj) && ! (Module === cls) # HACK for specs
278       obj, cls = cls, obj if flip
279       refute obj.kind_of?(cls), msg
280     end
281
282     def refute_match exp, act, msg = nil
283       msg = message(msg) { "Expected #{mu_pp(exp)} to not match #{mu_pp(act)}" }
284       assert_respond_to act, :"=~"
285       exp = /#{Regexp.escape(exp)}/ if String === exp && String === act
286       refute exp =~ act, msg
287     end
288
289     def refute_nil obj, msg = nil
290       msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
291       refute obj.nil?, msg
292     end
293
294     def refute_operator o1, op, o2, msg = nil
295       msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}" }
296       refute o1.__send__(op, o2), msg
297     end
298
299     def refute_respond_to obj, meth, msg = nil
300       msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
301       flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
302       obj, meth = meth, obj if flip
303       refute obj.respond_to?(meth), msg
304     end
305
306     def refute_same exp, act, msg = nil
307       msg = message(msg) { "Expected #{mu_pp(act)} to not be the same as #{mu_pp(exp)}" }
308       refute exp.equal?(act), msg
309     end
310
311     def skip msg = nil, bt = caller
312       msg ||= "Skipped, no message given"
313       raise MiniTest::Skip, msg, bt
314     end
315   end
316
317   class Unit
318     VERSION = "1.3.1"
319
320     attr_accessor :report, :failures, :errors, :skips
321     attr_accessor :test_count, :assertion_count
322
323     @@installed_at_exit ||= false
324     @@out = $stdout
325
326     def self.autorun
327       at_exit {
328         return if $! # don't run if there was an exception
329         exit_code = MiniTest::Unit.new.run(ARGV)
330         exit false if exit_code && exit_code != 0
331       } unless @@installed_at_exit
332       @@installed_at_exit = true
333     end
334
335     def self.output= stream
336       @@out = stream
337     end
338
339     def location e
340       last_before_assertion = ""
341       e.backtrace.reverse_each do |s|
342         break if s =~ /in .(assert|refute|flunk|pass|fail|raise)/
343         last_before_assertion = s
344       end
345       last_before_assertion.sub(/:in .*$/, '')
346     end
347
348     def puke klass, meth, e
349       e = case e
350           when MiniTest::Skip then
351             @skips += 1
352             "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
353           when MiniTest::Assertion then
354             @failures += 1
355             "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
356           else
357             @errors += 1
358             bt = MiniTest::filter_backtrace(e.backtrace).join("\n    ")
359             "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n    #{bt}\n"
360           end
361       @report << e
362       e[0, 1]
363     end
364
365     def initialize
366       @report = []
367       @errors = @failures = @skips = 0
368       @verbose = false
369     end
370
371     ##
372     # Top level driver, controls all output and filtering.
373
374     def run args = []
375       @verbose = args.delete('-v')
376
377       filter = if args.first =~ /^(-n|--name)$/ then
378                  args.shift
379                  arg = args.shift
380                  arg =~ /\/(.*)\// ? Regexp.new($1) : arg
381                else
382                  /./ # anything - ^test_ already filtered by #tests
383                end
384
385       @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted"
386
387       start = Time.now
388       run_test_suites filter
389
390       @@out.puts
391       @@out.puts "Finished in #{'%.6f' % (Time.now - start)} seconds."
392
393       @report.each_with_index do |msg, i|
394         @@out.puts "\n%3d) %s" % [i + 1, msg]
395       end
396
397       @@out.puts
398
399       format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
400       @@out.puts format % [test_count, assertion_count, failures, errors, skips]
401
402       return failures + errors if @test_count > 0 # or return nil...
403     end
404
405     def run_test_suites filter = /./
406       @test_count, @assertion_count = 0, 0
407       old_sync, @@out.sync = @@out.sync, true if @@out.respond_to? :sync=
408       TestCase.test_suites.each do |suite|
409         suite.test_methods.grep(filter).each do |test|
410           inst = suite.new test
411           inst._assertions = 0
412           @@out.print "#{suite}##{test}: " if @verbose
413
414           t = Time.now if @verbose
415           result = inst.run(self)
416
417           @@out.print "%.2f s: " % (Time.now - t) if @verbose
418           @@out.print result
419           @@out.puts if @verbose
420           @test_count += 1
421           @assertion_count += inst._assertions
422         end
423       end
424       @@out.sync = old_sync if @@out.respond_to? :sync=
425       [@test_count, @assertion_count]
426     end
427
428     class TestCase
429       attr_reader :name
430
431       def run runner
432         result = '.'
433         begin
434           @passed = nil
435           self.setup
436           self.__send__ self.name
437           @passed = true
438         rescue Exception => e
439           @passed = false
440           result = runner.puke(self.class, self.name, e)
441         ensure
442           begin
443             self.teardown
444           rescue Exception => e
445             result = runner.puke(self.class, self.name, e)
446           end
447         end
448         result
449       end
450
451       def initialize name
452         @name = name
453         @passed = nil
454       end
455
456       def self.reset
457         @@test_suites = {}
458       end
459
460       reset
461
462       def self.inherited klass
463         @@test_suites[klass] = true
464       end
465
466       def self.test_order
467         :random
468       end
469
470       def self.test_suites
471         @@test_suites.keys.sort_by { |ts| ts.name }
472       end
473
474       def self.test_methods
475         methods = public_instance_methods(true).grep(/^test/).map { |m|
476           m.to_s
477         }.sort
478
479         if self.test_order == :random then
480           max = methods.size
481           methods = methods.sort_by { rand(max) }
482         end
483
484         methods
485       end
486
487       def setup; end
488       def teardown; end
489
490       def passed?
491         @passed
492       end
493
494       include MiniTest::Assertions
495     end # class TestCase
496   end # class Test
497 end # module Mini