1# encoding: utf-8 2###################################################################### 3# This file is imported from the minitest project. 4# DO NOT make modifications in this repo. They _will_ be reverted! 5# File a patch instead and assign it to Ryan Davis. 6###################################################################### 7 8require 'optparse' 9require 'rbconfig' 10require 'thread' # required for 1.8 11require 'minitest/parallel_each' 12 13## 14# Minimal (mostly drop-in) replacement for test-unit. 15# 16# :include: README.txt 17 18module MiniTest 19 20 def self.const_missing name # :nodoc: 21 case name 22 when :MINI_DIR then 23 msg = "MiniTest::MINI_DIR was removed. Don't violate other's internals." 24 warn "WAR\NING: #{msg}" 25 warn "WAR\NING: Used by #{caller.first}." 26 const_set :MINI_DIR, "bad value" 27 else 28 super 29 end 30 end 31 32 ## 33 # Assertion base class 34 35 class Assertion < Exception; end 36 37 ## 38 # Assertion raised when skipping a test 39 40 class Skip < Assertion; end 41 42 class << self 43 attr_accessor :backtrace_filter 44 end 45 46 class BacktraceFilter # :nodoc: 47 def filter bt 48 return ["No backtrace"] unless bt 49 50 new_bt = [] 51 52 unless $DEBUG then 53 bt.each do |line| 54 break if line =~ /lib\/minitest/ 55 new_bt << line 56 end 57 58 new_bt = bt.reject { |line| line =~ /lib\/minitest/ } if new_bt.empty? 59 new_bt = bt.dup if new_bt.empty? 60 else 61 new_bt = bt.dup 62 end 63 64 new_bt 65 end 66 end 67 68 self.backtrace_filter = BacktraceFilter.new 69 70 def self.filter_backtrace bt # :nodoc: 71 backtrace_filter.filter bt 72 end 73 74 ## 75 # MiniTest Assertions. All assertion methods accept a +msg+ which is 76 # printed if the assertion fails. 77 78 module Assertions 79 UNDEFINED = Object.new # :nodoc: 80 81 def UNDEFINED.inspect # :nodoc: 82 "UNDEFINED" # again with the rdoc bugs... :( 83 end 84 85 ## 86 # Returns the diff command to use in #diff. Tries to intelligently 87 # figure out what diff to use. 88 89 def self.diff 90 @diff = if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ then 91 "diff.exe -u" 92 else 93 if system("gdiff", __FILE__, __FILE__) 94 "gdiff -u" # solaris and kin suck 95 elsif system("diff", __FILE__, __FILE__) 96 "diff -u" 97 else 98 nil 99 end 100 end unless defined? @diff 101 102 @diff 103 end 104 105 ## 106 # Set the diff command to use in #diff. 107 108 def self.diff= o 109 @diff = o 110 end 111 112 ## 113 # Returns a diff between +exp+ and +act+. If there is no known 114 # diff command or if it doesn't make sense to diff the output 115 # (single line, short output), then it simply returns a basic 116 # comparison between the two. 117 118 def diff exp, act 119 require "tempfile" 120 121 expect = mu_pp_for_diff exp 122 butwas = mu_pp_for_diff act 123 result = nil 124 125 need_to_diff = 126 MiniTest::Assertions.diff && 127 (expect.include?("\n") || 128 butwas.include?("\n") || 129 expect.size > 30 || 130 butwas.size > 30 || 131 expect == butwas) 132 133 return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless 134 need_to_diff 135 136 Tempfile.open("expect") do |a| 137 a.puts expect 138 a.flush 139 140 Tempfile.open("butwas") do |b| 141 b.puts butwas 142 b.flush 143 144 result = `#{MiniTest::Assertions.diff} #{a.path} #{b.path}` 145 result.sub!(/^\-\-\- .+/, "--- expected") 146 result.sub!(/^\+\+\+ .+/, "+++ actual") 147 148 if result.empty? then 149 klass = exp.class 150 result = [ 151 "No visible difference in the #{klass}#inspect output.\n", 152 "You should look at the implementation of #== on ", 153 "#{klass} or its members.\n", 154 expect, 155 ].join 156 end 157 end 158 end 159 160 result 161 end 162 163 ## 164 # This returns a human-readable version of +obj+. By default 165 # #inspect is called. You can override this to use #pretty_print 166 # if you want. 167 168 def mu_pp obj 169 s = obj.inspect 170 s = s.encode Encoding.default_external if defined? Encoding 171 s 172 end 173 174 ## 175 # This returns a diff-able human-readable version of +obj+. This 176 # differs from the regular mu_pp because it expands escaped 177 # newlines and makes hex-values generic (like object_ids). This 178 # uses mu_pp to do the first pass and then cleans it up. 179 180 def mu_pp_for_diff obj # TODO: possibly rename 181 mu_pp(obj).gsub(/\\n/, "\n").gsub(/0x[a-f0-9]+/m, '0xXXXXXX') 182 end 183 184 def _assertions= n # :nodoc: 185 @_assertions = n 186 end 187 188 def _assertions # :nodoc: 189 @_assertions ||= 0 190 end 191 192 ## 193 # Fails unless +test+ is a true value. 194 195 def assert test, msg = nil 196 msg ||= "Failed assertion, no message given." 197 self._assertions += 1 198 unless test then 199 msg = msg.call if Proc === msg 200 raise MiniTest::Assertion, msg 201 end 202 true 203 end 204 205 ## 206 # Fails unless the block returns a true value. 207 # 208 # NOTE: This method is deprecated, use assert. It will be removed 209 # on 2013-01-01." 210 211 def assert_block msg = nil 212 warn "NOTE: MiniTest::Unit::TestCase#assert_block is deprecated, use assert. It will be removed on 2013-01-01. Called from #{caller.first}" 213 msg = message(msg) { "Expected block to return true value" } 214 assert yield, msg 215 end 216 217 ## 218 # Fails unless +obj+ is empty. 219 220 def assert_empty obj, msg = nil 221 msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" } 222 assert_respond_to obj, :empty? 223 assert obj.empty?, msg 224 end 225 226 ## 227 # Fails unless <tt>exp == act</tt> printing the difference between 228 # the two, if possible. 229 # 230 # If there is no visible difference but the assertion fails, you 231 # should suspect that your #== is buggy, or your inspect output is 232 # missing crucial details. 233 # 234 # For floats use assert_in_delta. 235 # 236 # See also: MiniTest::Assertions.diff 237 238 def assert_equal exp, act, msg = nil 239 msg = message(msg, "") { diff exp, act } 240 assert(exp == act, msg) 241 end 242 243 ## 244 # For comparing Floats. Fails unless +exp+ and +act+ are within +delta+ 245 # of each other. 246 # 247 # assert_in_delta Math::PI, (22.0 / 7.0), 0.01 248 249 def assert_in_delta exp, act, delta = 0.001, msg = nil 250 n = (exp - act).abs 251 msg = message(msg) { "Expected |#{exp} - #{act}| (#{n}) to be < #{delta}"} 252 assert delta >= n, msg 253 end 254 255 ## 256 # For comparing Floats. Fails unless +exp+ and +act+ have a relative 257 # error less than +epsilon+. 258 259 def assert_in_epsilon a, b, epsilon = 0.001, msg = nil 260 assert_in_delta a, b, [a.abs, b.abs].min * epsilon, msg 261 end 262 263 ## 264 # Fails unless +collection+ includes +obj+. 265 266 def assert_includes collection, obj, msg = nil 267 msg = message(msg) { 268 "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}" 269 } 270 assert_respond_to collection, :include? 271 assert collection.include?(obj), msg 272 end 273 274 ## 275 # Fails unless +obj+ is an instance of +cls+. 276 277 def assert_instance_of cls, obj, msg = nil 278 msg = message(msg) { 279 "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}" 280 } 281 282 assert obj.instance_of?(cls), msg 283 end 284 285 ## 286 # Fails unless +obj+ is a kind of +cls+. 287 288 def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of 289 msg = message(msg) { 290 "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" } 291 292 assert obj.kind_of?(cls), msg 293 end 294 295 ## 296 # Fails unless +matcher+ <tt>=~</tt> +obj+. 297 298 def assert_match matcher, obj, msg = nil 299 msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" } 300 assert_respond_to matcher, :"=~" 301 matcher = Regexp.new Regexp.escape matcher if String === matcher 302 assert matcher =~ obj, msg 303 end 304 305 ## 306 # Fails unless +obj+ is nil 307 308 def assert_nil obj, msg = nil 309 msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" } 310 assert obj.nil?, msg 311 end 312 313 ## 314 # For testing with binary operators. 315 # 316 # assert_operator 5, :<=, 4 317 318 def assert_operator o1, op, o2 = UNDEFINED, msg = nil 319 return assert_predicate o1, op, msg if UNDEFINED == o2 320 msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" } 321 assert o1.__send__(op, o2), msg 322 end 323 324 ## 325 # Fails if stdout or stderr do not output the expected results. 326 # Pass in nil if you don't care about that streams output. Pass in 327 # "" if you require it to be silent. Pass in a regexp if you want 328 # to pattern match. 329 # 330 # NOTE: this uses #capture_io, not #capture_subprocess_io. 331 # 332 # See also: #assert_silent 333 334 def assert_output stdout = nil, stderr = nil 335 out, err = capture_io do 336 yield 337 end 338 339 err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr 340 out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout 341 342 y = send err_msg, stderr, err, "In stderr" if err_msg 343 x = send out_msg, stdout, out, "In stdout" if out_msg 344 345 (!stdout || x) && (!stderr || y) 346 end 347 348 ## 349 # For testing with predicates. 350 # 351 # assert_predicate str, :empty? 352 # 353 # This is really meant for specs and is front-ended by assert_operator: 354 # 355 # str.must_be :empty? 356 357 def assert_predicate o1, op, msg = nil 358 msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" } 359 assert o1.__send__(op), msg 360 end 361 362 ## 363 # Fails unless the block raises one of +exp+. Returns the 364 # exception matched so you can check the message, attributes, etc. 365 366 def assert_raises *exp 367 msg = "#{exp.pop}.\n" if String === exp.last 368 369 begin 370 yield 371 rescue MiniTest::Skip => e 372 return e if exp.include? MiniTest::Skip 373 raise e 374 rescue Exception => e 375 expected = exp.any? { |ex| 376 if ex.instance_of? Module then 377 e.kind_of? ex 378 else 379 e.instance_of? ex 380 end 381 } 382 383 assert expected, proc { 384 exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not") 385 } 386 387 return e 388 end 389 390 exp = exp.first if exp.size == 1 391 392 flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised." 393 end 394 395 ## 396 # Fails unless +obj+ responds to +meth+. 397 398 def assert_respond_to obj, meth, msg = nil 399 msg = message(msg) { 400 "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}" 401 } 402 assert obj.respond_to?(meth), msg 403 end 404 405 ## 406 # Fails unless +exp+ and +act+ are #equal? 407 408 def assert_same exp, act, msg = nil 409 msg = message(msg) { 410 data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] 411 "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data 412 } 413 assert exp.equal?(act), msg 414 end 415 416 ## 417 # +send_ary+ is a receiver, message and arguments. 418 # 419 # Fails unless the call returns a true value 420 # TODO: I should prolly remove this from specs 421 422 def assert_send send_ary, m = nil 423 recv, msg, *args = send_ary 424 m = message(m) { 425 "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" } 426 assert recv.__send__(msg, *args), m 427 end 428 429 ## 430 # Fails if the block outputs anything to stderr or stdout. 431 # 432 # See also: #assert_output 433 434 def assert_silent 435 assert_output "", "" do 436 yield 437 end 438 end 439 440 ## 441 # Fails unless the block throws +sym+ 442 443 def assert_throws sym, msg = nil 444 default = "Expected #{mu_pp(sym)} to have been thrown" 445 caught = true 446 catch(sym) do 447 begin 448 yield 449 rescue ThreadError => e # wtf?!? 1.8 + threads == suck 450 default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}" 451 rescue ArgumentError => e # 1.9 exception 452 default += ", not #{e.message.split(/ /).last}" 453 rescue NameError => e # 1.8 exception 454 default += ", not #{e.name.inspect}" 455 end 456 caught = false 457 end 458 459 assert caught, message(msg) { default } 460 end 461 462 ## 463 # Captures $stdout and $stderr into strings: 464 # 465 # out, err = capture_io do 466 # puts "Some info" 467 # warn "You did a bad thing" 468 # end 469 # 470 # assert_match %r%info%, out 471 # assert_match %r%bad%, err 472 # 473 # NOTE: For efficiency, this method uses StringIO and does not 474 # capture IO for subprocesses. Use #capture_subprocess_io for 475 # that. 476 477 def capture_io 478 require 'stringio' 479 480 captured_stdout, captured_stderr = StringIO.new, StringIO.new 481 482 synchronize do 483 orig_stdout, orig_stderr = $stdout, $stderr 484 $stdout, $stderr = captured_stdout, captured_stderr 485 486 begin 487 yield 488 ensure 489 $stdout = orig_stdout 490 $stderr = orig_stderr 491 end 492 end 493 494 return captured_stdout.string, captured_stderr.string 495 end 496 497 ## 498 # Captures $stdout and $stderr into strings, using Tempfile to 499 # ensure that subprocess IO is captured as well. 500 # 501 # out, err = capture_subprocess_io do 502 # system "echo Some info" 503 # system "echo You did a bad thing 1>&2" 504 # end 505 # 506 # assert_match %r%info%, out 507 # assert_match %r%bad%, err 508 # 509 # NOTE: This method is approximately 10x slower than #capture_io so 510 # only use it when you need to test the output of a subprocess. 511 512 def capture_subprocess_io 513 require 'tempfile' 514 515 captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") 516 517 synchronize do 518 orig_stdout, orig_stderr = $stdout.dup, $stderr.dup 519 $stdout.reopen captured_stdout 520 $stderr.reopen captured_stderr 521 522 begin 523 yield 524 525 $stdout.rewind 526 $stderr.rewind 527 528 [captured_stdout.read, captured_stderr.read] 529 ensure 530 captured_stdout.unlink 531 captured_stderr.unlink 532 $stdout.reopen orig_stdout 533 $stderr.reopen orig_stderr 534 end 535 end 536 end 537 538 ## 539 # Returns details for exception +e+ 540 541 def exception_details e, msg 542 [ 543 "#{msg}", 544 "Class: <#{e.class}>", 545 "Message: <#{e.message.inspect}>", 546 "---Backtrace---", 547 "#{MiniTest::filter_backtrace(e.backtrace).join("\n")}", 548 "---------------", 549 ].join "\n" 550 end 551 552 ## 553 # Fails with +msg+ 554 555 def flunk msg = nil 556 msg ||= "Epic Fail!" 557 assert false, msg 558 end 559 560 ## 561 # Returns a proc that will output +msg+ along with the default message. 562 563 def message msg = nil, ending = ".", &default 564 proc { 565 custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? 566 "#{custom_message}#{default.call}#{ending}" 567 } 568 end 569 570 ## 571 # used for counting assertions 572 573 def pass msg = nil 574 assert true 575 end 576 577 ## 578 # Fails if +test+ is a true value 579 580 def refute test, msg = nil 581 msg ||= "Failed refutation, no message given" 582 not assert(! test, msg) 583 end 584 585 ## 586 # Fails if +obj+ is empty. 587 588 def refute_empty obj, msg = nil 589 msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" } 590 assert_respond_to obj, :empty? 591 refute obj.empty?, msg 592 end 593 594 ## 595 # Fails if <tt>exp == act</tt>. 596 # 597 # For floats use refute_in_delta. 598 599 def refute_equal exp, act, msg = nil 600 msg = message(msg) { 601 "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}" 602 } 603 refute exp == act, msg 604 end 605 606 ## 607 # For comparing Floats. Fails if +exp+ is within +delta+ of +act+. 608 # 609 # refute_in_delta Math::PI, (22.0 / 7.0) 610 611 def refute_in_delta exp, act, delta = 0.001, msg = nil 612 n = (exp - act).abs 613 msg = message(msg) { 614 "Expected |#{exp} - #{act}| (#{n}) to not be < #{delta}" 615 } 616 refute delta > n, msg 617 end 618 619 ## 620 # For comparing Floats. Fails if +exp+ and +act+ have a relative error 621 # less than +epsilon+. 622 623 def refute_in_epsilon a, b, epsilon = 0.001, msg = nil 624 refute_in_delta a, b, a * epsilon, msg 625 end 626 627 ## 628 # Fails if +collection+ includes +obj+. 629 630 def refute_includes collection, obj, msg = nil 631 msg = message(msg) { 632 "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}" 633 } 634 assert_respond_to collection, :include? 635 refute collection.include?(obj), msg 636 end 637 638 ## 639 # Fails if +obj+ is an instance of +cls+. 640 641 def refute_instance_of cls, obj, msg = nil 642 msg = message(msg) { 643 "Expected #{mu_pp(obj)} to not be an instance of #{cls}" 644 } 645 refute obj.instance_of?(cls), msg 646 end 647 648 ## 649 # Fails if +obj+ is a kind of +cls+. 650 651 def refute_kind_of cls, obj, msg = nil # TODO: merge with instance_of 652 msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" } 653 refute obj.kind_of?(cls), msg 654 end 655 656 ## 657 # Fails if +matcher+ <tt>=~</tt> +obj+. 658 659 def refute_match matcher, obj, msg = nil 660 msg = message(msg) {"Expected #{mu_pp matcher} to not match #{mu_pp obj}"} 661 assert_respond_to matcher, :"=~" 662 matcher = Regexp.new Regexp.escape matcher if String === matcher 663 refute matcher =~ obj, msg 664 end 665 666 ## 667 # Fails if +obj+ is nil. 668 669 def refute_nil obj, msg = nil 670 msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" } 671 refute obj.nil?, msg 672 end 673 674 ## 675 # Fails if +o1+ is not +op+ +o2+. Eg: 676 # 677 # refute_operator 1, :>, 2 #=> pass 678 # refute_operator 1, :<, 2 #=> fail 679 680 def refute_operator o1, op, o2 = UNDEFINED, msg = nil 681 return refute_predicate o1, op, msg if UNDEFINED == o2 682 msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"} 683 refute o1.__send__(op, o2), msg 684 end 685 686 ## 687 # For testing with predicates. 688 # 689 # refute_predicate str, :empty? 690 # 691 # This is really meant for specs and is front-ended by refute_operator: 692 # 693 # str.wont_be :empty? 694 695 def refute_predicate o1, op, msg = nil 696 msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" } 697 refute o1.__send__(op), msg 698 end 699 700 ## 701 # Fails if +obj+ responds to the message +meth+. 702 703 def refute_respond_to obj, meth, msg = nil 704 msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" } 705 706 refute obj.respond_to?(meth), msg 707 end 708 709 ## 710 # Fails if +exp+ is the same (by object identity) as +act+. 711 712 def refute_same exp, act, msg = nil 713 msg = message(msg) { 714 data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] 715 "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data 716 } 717 refute exp.equal?(act), msg 718 end 719 720 ## 721 # Skips the current test. Gets listed at the end of the run but 722 # doesn't cause a failure exit code. 723 724 def skip msg = nil, bt = caller 725 msg ||= "Skipped, no message given" 726 raise MiniTest::Skip, msg, bt 727 end 728 729 ## 730 # Takes a block and wraps it with the runner's shared mutex. 731 732 def synchronize 733 Minitest::Unit.runner.synchronize do 734 yield 735 end 736 end 737 end 738 739 class Unit # :nodoc: 740 VERSION = "4.3.2" # :nodoc: 741 742 attr_accessor :report, :failures, :errors, :skips # :nodoc: 743 attr_accessor :test_count, :assertion_count # :nodoc: 744 attr_accessor :start_time # :nodoc: 745 attr_accessor :help # :nodoc: 746 attr_accessor :verbose # :nodoc: 747 attr_writer :options # :nodoc: 748 749 ## 750 # Lazy accessor for options. 751 752 def options 753 @options ||= {} 754 end 755 756 @@installed_at_exit ||= false 757 @@out = $stdout 758 @@after_tests = [] 759 760 ## 761 # A simple hook allowing you to run a block of code after _all_ of 762 # the tests are done. Eg: 763 # 764 # MiniTest::Unit.after_tests { p $debugging_info } 765 766 def self.after_tests &block 767 @@after_tests << block 768 end 769 770 ## 771 # Registers MiniTest::Unit to run tests at process exit 772 773 def self.autorun 774 at_exit { 775 # don't run if there was a non-exit exception 776 next if $! and not $!.kind_of? SystemExit 777 778 # the order here is important. The at_exit handler must be 779 # installed before anyone else gets a chance to install their 780 # own, that way we can be assured that our exit will be last 781 # to run (at_exit stacks). 782 exit_code = nil 783 784 at_exit { 785 @@after_tests.reverse_each(&:call) 786 exit false if exit_code && exit_code != 0 787 } 788 789 exit_code = MiniTest::Unit.new.run ARGV 790 } unless @@installed_at_exit 791 @@installed_at_exit = true 792 end 793 794 ## 795 # Returns the stream to use for output. 796 797 def self.output 798 @@out 799 end 800 801 ## 802 # Sets MiniTest::Unit to write output to +stream+. $stdout is the default 803 # output 804 805 def self.output= stream 806 @@out = stream 807 end 808 809 ## 810 # Tells MiniTest::Unit to delegate to +runner+, an instance of a 811 # MiniTest::Unit subclass, when MiniTest::Unit#run is called. 812 813 def self.runner= runner 814 @@runner = runner 815 end 816 817 ## 818 # Returns the MiniTest::Unit subclass instance that will be used 819 # to run the tests. A MiniTest::Unit instance is the default 820 # runner. 821 822 def self.runner 823 @@runner ||= self.new 824 end 825 826 ## 827 # Return all plugins' run methods (methods that start with "run_"). 828 829 def self.plugins 830 @@plugins ||= (["run_tests"] + 831 public_instance_methods(false). 832 grep(/^run_/).map { |s| s.to_s }).uniq 833 end 834 835 ## 836 # Return the IO for output. 837 838 def output 839 self.class.output 840 end 841 842 def puts *a # :nodoc: 843 output.puts(*a) 844 end 845 846 def print *a # :nodoc: 847 output.print(*a) 848 end 849 850 ## 851 # Runner for a given +type+ (eg, test vs bench). 852 853 def _run_anything type 854 suites = TestCase.send "#{type}_suites" 855 return if suites.empty? 856 857 start = Time.now 858 859 puts 860 puts "# Running #{type}s:" 861 puts 862 863 @test_count, @assertion_count = 0, 0 864 sync = output.respond_to? :"sync=" # stupid emacs 865 old_sync, output.sync = output.sync, true if sync 866 867 results = _run_suites suites, type 868 869 @test_count = results.inject(0) { |sum, (tc, _)| sum + tc } 870 @assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac } 871 872 output.sync = old_sync if sync 873 874 t = Time.now - start 875 876 puts 877 puts 878 puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." % 879 [t, test_count / t, assertion_count / t] 880 881 report.each_with_index do |msg, i| 882 puts "\n%3d) %s" % [i + 1, msg] 883 end 884 885 puts 886 887 status 888 end 889 890 ## 891 # Runs all the +suites+ for a given +type+. Runs suites declaring 892 # a test_order of +:parallel+ in parallel, and everything else 893 # serial. 894 895 def _run_suites suites, type 896 parallel, serial = suites.partition { |s| s.test_order == :parallel } 897 898 ParallelEach.new(parallel).map { |suite| _run_suite suite, type } + 899 serial.map { |suite| _run_suite suite, type } 900 end 901 902 ## 903 # Run a single +suite+ for a given +type+. 904 905 def _run_suite suite, type 906 header = "#{type}_suite_header" 907 puts send(header, suite) if respond_to? header 908 909 filter = options[:filter] || '/./' 910 filter = Regexp.new $1 if filter =~ /\/(.*)\// 911 912 assertions = suite.send("#{type}_methods").grep(filter).map { |method| 913 inst = suite.new method 914 inst._assertions = 0 915 916 print "#{suite}##{method} = " if @verbose 917 918 start_time = Time.now if @verbose 919 result = inst.run self 920 921 print "%.2f s = " % (Time.now - start_time) if @verbose 922 print result 923 puts if @verbose 924 925 inst._assertions 926 } 927 928 return assertions.size, assertions.inject(0) { |sum, n| sum + n } 929 end 930 931 ## 932 # Record the result of a single run. Makes it very easy to gather 933 # information. Eg: 934 # 935 # class StatisticsRecorder < MiniTest::Unit 936 # def record suite, method, assertions, time, error 937 # # ... record the results somewhere ... 938 # end 939 # end 940 # 941 # MiniTest::Unit.runner = StatisticsRecorder.new 942 943 def record suite, method, assertions, time, error 944 end 945 946 def location e # :nodoc: 947 last_before_assertion = "" 948 e.backtrace.reverse_each do |s| 949 break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/ 950 last_before_assertion = s 951 end 952 last_before_assertion.sub(/:in .*$/, '') 953 end 954 955 ## 956 # Writes status for failed test +meth+ in +klass+ which finished with 957 # exception +e+ 958 959 def puke klass, meth, e 960 e = case e 961 when MiniTest::Skip then 962 @skips += 1 963 return "S" unless @verbose 964 "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" 965 when MiniTest::Assertion then 966 @failures += 1 967 "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n" 968 else 969 @errors += 1 970 bt = MiniTest::filter_backtrace(e.backtrace).join "\n " 971 "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n #{bt}\n" 972 end 973 @report << e 974 e[0, 1] 975 end 976 977 def initialize # :nodoc: 978 @report = [] 979 @errors = @failures = @skips = 0 980 @verbose = false 981 @mutex = Mutex.new 982 end 983 984 def synchronize # :nodoc: 985 @mutex.synchronize { yield } 986 end 987 988 def process_args args = [] # :nodoc: 989 options = {} 990 orig_args = args.dup 991 992 OptionParser.new do |opts| 993 opts.banner = 'minitest options:' 994 opts.version = MiniTest::Unit::VERSION 995 996 opts.on '-h', '--help', 'Display this help.' do 997 puts opts 998 exit 999 end 1000 1001 opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m| 1002 options[:seed] = m.to_i 1003 end 1004 1005 opts.on '-v', '--verbose', "Verbose. Show progress processing files." do 1006 options[:verbose] = true 1007 end 1008 1009 opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |a| 1010 options[:filter] = a 1011 end 1012 1013 opts.parse! args 1014 orig_args -= args 1015 end 1016 1017 unless options[:seed] then 1018 srand 1019 options[:seed] = srand % 0xFFFF 1020 orig_args << "--seed" << options[:seed].to_s 1021 end 1022 1023 srand options[:seed] 1024 1025 self.verbose = options[:verbose] 1026 @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " " 1027 1028 options 1029 end 1030 1031 ## 1032 # Begins the full test run. Delegates to +runner+'s #_run method. 1033 1034 def run args = [] 1035 self.class.runner._run(args) 1036 end 1037 1038 ## 1039 # Top level driver, controls all output and filtering. 1040 1041 def _run args = [] 1042 self.options = process_args args 1043 1044 puts "Run options: #{help}" 1045 1046 self.class.plugins.each do |plugin| 1047 send plugin 1048 break unless report.empty? 1049 end 1050 1051 return failures + errors if @test_count > 0 # or return nil... 1052 rescue Interrupt 1053 abort 'Interrupted' 1054 end 1055 1056 ## 1057 # Runs test suites matching +filter+. 1058 1059 def run_tests 1060 _run_anything :test 1061 end 1062 1063 ## 1064 # Writes status to +io+ 1065 1066 def status io = self.output 1067 format = "%d tests, %d assertions, %d failures, %d errors, %d skips" 1068 io.puts format % [test_count, assertion_count, failures, errors, skips] 1069 end 1070 1071 ## 1072 # Provides a simple set of guards that you can use in your tests 1073 # to skip execution if it is not applicable. These methods are 1074 # mixed into TestCase as both instance and class methods so you 1075 # can use them inside or outside of the test methods. 1076 # 1077 # def test_something_for_mri 1078 # skip "bug 1234" if jruby? 1079 # # ... 1080 # end 1081 # 1082 # if windows? then 1083 # # ... lots of test methods ... 1084 # end 1085 1086 module Guard 1087 1088 ## 1089 # Is this running on jruby? 1090 1091 def jruby? platform = RUBY_PLATFORM 1092 "java" == platform 1093 end 1094 1095 ## 1096 # Is this running on mri? 1097 1098 def mri? platform = RUBY_DESCRIPTION 1099 /^ruby/ =~ platform 1100 end 1101 1102 ## 1103 # Is this running on rubinius? 1104 1105 def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE 1106 "rbx" == platform 1107 end 1108 1109 ## 1110 # Is this running on windows? 1111 1112 def windows? platform = RUBY_PLATFORM 1113 /mswin|mingw/ =~ platform 1114 end 1115 end 1116 1117 ## 1118 # Provides before/after hooks for setup and teardown. These are 1119 # meant for library writers, NOT for regular test authors. See 1120 # #before_setup for an example. 1121 1122 module LifecycleHooks 1123 ## 1124 # Runs before every test, after setup. This hook is meant for 1125 # libraries to extend minitest. It is not meant to be used by 1126 # test developers. 1127 # 1128 # See #before_setup for an example. 1129 1130 def after_setup; end 1131 1132 ## 1133 # Runs before every test, before setup. This hook is meant for 1134 # libraries to extend minitest. It is not meant to be used by 1135 # test developers. 1136 # 1137 # As a simplistic example: 1138 # 1139 # module MyMinitestPlugin 1140 # def before_setup 1141 # super 1142 # # ... stuff to do before setup is run 1143 # end 1144 # 1145 # def after_setup 1146 # # ... stuff to do after setup is run 1147 # super 1148 # end 1149 # 1150 # def before_teardown 1151 # super 1152 # # ... stuff to do before teardown is run 1153 # end 1154 # 1155 # def after_teardown 1156 # # ... stuff to do after teardown is run 1157 # super 1158 # end 1159 # end 1160 # 1161 # class MiniTest::Unit::TestCase 1162 # include MyMinitestPlugin 1163 # end 1164 1165 def before_setup; end 1166 1167 ## 1168 # Runs after every test, before teardown. This hook is meant for 1169 # libraries to extend minitest. It is not meant to be used by 1170 # test developers. 1171 # 1172 # See #before_setup for an example. 1173 1174 def before_teardown; end 1175 1176 ## 1177 # Runs after every test, after teardown. This hook is meant for 1178 # libraries to extend minitest. It is not meant to be used by 1179 # test developers. 1180 # 1181 # See #before_setup for an example. 1182 1183 def after_teardown; end 1184 end 1185 1186 module Deprecated # :nodoc: 1187 1188 ## 1189 # This entire module is deprecated and slated for removal on 2013-01-01. 1190 1191 module Hooks 1192 def run_setup_hooks # :nodoc: 1193 _run_hooks self.class.setup_hooks 1194 end 1195 1196 def _run_hooks hooks # :nodoc: 1197 hooks.each do |hook| 1198 if hook.respond_to?(:arity) && hook.arity == 1 1199 hook.call(self) 1200 else 1201 hook.call 1202 end 1203 end 1204 end 1205 1206 def run_teardown_hooks # :nodoc: 1207 _run_hooks self.class.teardown_hooks.reverse 1208 end 1209 end 1210 1211 ## 1212 # This entire module is deprecated and slated for removal on 2013-01-01. 1213 1214 module HooksCM 1215 ## 1216 # Adds a block of code that will be executed before every 1217 # TestCase is run. 1218 # 1219 # NOTE: This method is deprecated, use before/after_setup. It 1220 # will be removed on 2013-01-01. 1221 1222 def add_setup_hook arg=nil, &block 1223 warn "NOTE: MiniTest::Unit::TestCase.add_setup_hook is deprecated, use before/after_setup via a module (and call super!). It will be removed on 2013-01-01. Called from #{caller.first}" 1224 hook = arg || block 1225 @setup_hooks << hook 1226 end 1227 1228 def setup_hooks # :nodoc: 1229 if superclass.respond_to? :setup_hooks then 1230 superclass.setup_hooks 1231 else 1232 [] 1233 end + @setup_hooks 1234 end 1235 1236 ## 1237 # Adds a block of code that will be executed after every 1238 # TestCase is run. 1239 # 1240 # NOTE: This method is deprecated, use before/after_teardown. It 1241 # will be removed on 2013-01-01. 1242 1243 def add_teardown_hook arg=nil, &block 1244 warn "NOTE: MiniTest::Unit::TestCase#add_teardown_hook is deprecated, use before/after_teardown. It will be removed on 2013-01-01. Called from #{caller.first}" 1245 hook = arg || block 1246 @teardown_hooks << hook 1247 end 1248 1249 def teardown_hooks # :nodoc: 1250 if superclass.respond_to? :teardown_hooks then 1251 superclass.teardown_hooks 1252 else 1253 [] 1254 end + @teardown_hooks 1255 end 1256 end 1257 end 1258 1259 ## 1260 # Subclass TestCase to create your own tests. Typically you'll want a 1261 # TestCase subclass per implementation class. 1262 # 1263 # See MiniTest::Assertions 1264 1265 class TestCase 1266 include LifecycleHooks 1267 include Deprecated::Hooks 1268 extend Deprecated::HooksCM # UGH... I can't wait 'til 2013! 1269 include Guard 1270 extend Guard 1271 1272 attr_reader :__name__ # :nodoc: 1273 1274 PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, 1275 Interrupt, SystemExit] # :nodoc: 1276 1277 SUPPORTS_INFO_SIGNAL = Signal.list['INFO'] # :nodoc: 1278 1279 ## 1280 # Runs the tests reporting the status to +runner+ 1281 1282 def run runner 1283 trap "INFO" do 1284 runner.report.each_with_index do |msg, i| 1285 warn "\n%3d) %s" % [i + 1, msg] 1286 end 1287 warn '' 1288 time = runner.start_time ? Time.now - runner.start_time : 0 1289 warn "Current Test: %s#%s %.2fs" % [self.class, self.__name__, time] 1290 runner.status $stderr 1291 end if SUPPORTS_INFO_SIGNAL 1292 1293 start_time = Time.now 1294 1295 result = "" 1296 begin 1297 @passed = nil 1298 self.before_setup 1299 self.setup 1300 self.after_setup 1301 self.run_test self.__name__ 1302 result = "." unless io? 1303 time = Time.now - start_time 1304 runner.record self.class, self.__name__, self._assertions, time, nil 1305 @passed = true 1306 rescue *PASSTHROUGH_EXCEPTIONS 1307 raise 1308 rescue Exception => e 1309 @passed = false 1310 time = Time.now - start_time 1311 runner.record self.class, self.__name__, self._assertions, time, e 1312 result = runner.puke self.class, self.__name__, e 1313 ensure 1314 %w{ before_teardown teardown after_teardown }.each do |hook| 1315 begin 1316 self.send hook 1317 rescue *PASSTHROUGH_EXCEPTIONS 1318 raise 1319 rescue Exception => e 1320 @passed = false 1321 result = runner.puke self.class, self.__name__, e 1322 end 1323 end 1324 trap 'INFO', 'DEFAULT' if SUPPORTS_INFO_SIGNAL 1325 end 1326 result 1327 end 1328 1329 alias :run_test :__send__ 1330 1331 def initialize name # :nodoc: 1332 @__name__ = name 1333 @__io__ = nil 1334 @passed = nil 1335 @@current = self 1336 end 1337 1338 def self.current # :nodoc: 1339 @@current 1340 end 1341 1342 ## 1343 # Return the output IO object 1344 1345 def io 1346 @__io__ = true 1347 MiniTest::Unit.output 1348 end 1349 1350 ## 1351 # Have we hooked up the IO yet? 1352 1353 def io? 1354 @__io__ 1355 end 1356 1357 def self.reset # :nodoc: 1358 @@test_suites = {} 1359 end 1360 1361 reset 1362 1363 ## 1364 # Call this at the top of your tests when you absolutely 1365 # positively need to have ordered tests. In doing so, you're 1366 # admitting that you suck and your tests are weak. 1367 1368 def self.i_suck_and_my_tests_are_order_dependent! 1369 class << self 1370 undef_method :test_order if method_defined? :test_order 1371 define_method :test_order do :alpha end 1372 end 1373 end 1374 1375 ## 1376 # Make diffs for this TestCase use #pretty_inspect so that diff 1377 # in assert_equal can be more details. NOTE: this is much slower 1378 # than the regular inspect but much more usable for complex 1379 # objects. 1380 1381 def self.make_my_diffs_pretty! 1382 require 'pp' 1383 1384 define_method :mu_pp do |o| 1385 o.pretty_inspect 1386 end 1387 end 1388 1389 ## 1390 # Call this at the top of your tests when you want to run your 1391 # tests in parallel. In doing so, you're admitting that you rule 1392 # and your tests are awesome. 1393 1394 def self.parallelize_me! 1395 class << self 1396 undef_method :test_order if method_defined? :test_order 1397 define_method :test_order do :parallel end 1398 end 1399 end 1400 1401 def self.inherited klass # :nodoc: 1402 @@test_suites[klass] = true 1403 klass.reset_setup_teardown_hooks 1404 super 1405 end 1406 1407 def self.test_order # :nodoc: 1408 :random 1409 end 1410 1411 def self.test_suites # :nodoc: 1412 @@test_suites.keys.sort_by { |ts| ts.name.to_s } 1413 end 1414 1415 def self.test_methods # :nodoc: 1416 methods = public_instance_methods(true).grep(/^test/).map { |m| m.to_s } 1417 1418 case self.test_order 1419 when :parallel 1420 max = methods.size 1421 ParallelEach.new methods.sort.sort_by { rand max } 1422 when :random then 1423 max = methods.size 1424 methods.sort.sort_by { rand max } 1425 when :alpha, :sorted then 1426 methods.sort 1427 else 1428 raise "Unknown test_order: #{self.test_order.inspect}" 1429 end 1430 end 1431 1432 ## 1433 # Returns true if the test passed. 1434 1435 def passed? 1436 @passed 1437 end 1438 1439 ## 1440 # Runs before every test. Use this to set up before each test 1441 # run. 1442 1443 def setup; end 1444 1445 ## 1446 # Runs after every test. Use this to clean up after each test 1447 # run. 1448 1449 def teardown; end 1450 1451 def self.reset_setup_teardown_hooks # :nodoc: 1452 # also deprecated... believe it. 1453 @setup_hooks = [] 1454 @teardown_hooks = [] 1455 end 1456 1457 reset_setup_teardown_hooks 1458 1459 include MiniTest::Assertions 1460 end # class TestCase 1461 end # class Unit 1462end # module MiniTest 1463 1464Minitest = MiniTest # :nodoc: because ugh... I typo this all the time 1465 1466if $DEBUG then 1467 module Test # :nodoc: 1468 module Unit # :nodoc: 1469 class TestCase # :nodoc: 1470 def self.inherited x # :nodoc: 1471 # this helps me ferret out porting issues 1472 raise "Using minitest and test/unit in the same process: #{x}" 1473 end 1474 end 1475 end 1476 end 1477end 1478