minitest 1.7.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,14 +8,7 @@ module MiniTest
8
8
  end
9
9
 
10
10
  def expect(name, retval, args=[])
11
- n, r, a = name, retval, args # for the closure below
12
11
  @expected_calls[name] = { :retval => retval, :args => args }
13
- self.class.__send__ :remove_method, name if respond_to? name
14
- self.class.__send__(:define_method, name) { |*x|
15
- raise ArgumentError unless @expected_calls[n][:args].size == x.size
16
- @actual_calls[n] << { :retval => r, :args => x }
17
- retval
18
- }
19
12
  self
20
13
  end
21
14
 
@@ -28,5 +21,19 @@ module MiniTest
28
21
  end
29
22
  true
30
23
  end
24
+
25
+ def method_missing(sym, *args)
26
+ raise NoMethodError unless @expected_calls.has_key?(sym)
27
+ raise ArgumentError unless @expected_calls[sym][:args].size == args.size
28
+ retval = @expected_calls[sym][:retval]
29
+ @actual_calls[sym] << { :retval => retval, :args => args }
30
+ retval
31
+ end
32
+
33
+ alias :original_respond_to? :respond_to?
34
+ def respond_to?(sym)
35
+ return true if @expected_calls.has_key?(sym)
36
+ return original_respond_to?(sym)
37
+ end
31
38
  end
32
39
  end
@@ -0,0 +1,35 @@
1
+ require "minitest/unit"
2
+
3
+ ##
4
+ # Show your testing pride!
5
+
6
+ class PrideIO
7
+ attr_reader :io
8
+
9
+ # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
10
+ COLORS = (31..36).to_a
11
+ CHARS = ["*"]
12
+
13
+ def initialize io
14
+ @io = io
15
+ @colors = COLORS.cycle
16
+ @chars = CHARS.cycle
17
+ end
18
+
19
+ def print o
20
+ case o
21
+ when "." then
22
+ io.print "\e[#{@colors.next}m#{@chars.next}\e[0m"
23
+ when "E", "F" then
24
+ io.print "\e[41m\e[37m#{o}\e[0m"
25
+ else
26
+ io.print o
27
+ end
28
+ end
29
+
30
+ def method_missing msg, *args
31
+ io.send(msg, *args)
32
+ end
33
+ end
34
+
35
+ MiniTest::Unit.output = PrideIO.new(MiniTest::Unit.output)
@@ -60,10 +60,13 @@ module Kernel
60
60
 
61
61
  def describe desc, &block
62
62
  stack = MiniTest::Spec.describe_stack
63
- name = desc.to_s.split(/\W+/).map { |s| s.capitalize }.join + "Spec"
64
- prev = stack.last
65
- name = "#{prev == MiniTest::Spec ? nil : prev}::#{name}"
66
- cls = Object.class_eval "class #{name} < #{prev}; end; #{name}"
63
+ name = [stack.last, desc].compact.join("::")
64
+ cls = Class.new(stack.last || MiniTest::Spec)
65
+
66
+ # :stopdoc:
67
+ # omg this sucks
68
+ (class << cls; self; end).send(:define_method, :to_s) { name }
69
+ # :startdoc:
67
70
 
68
71
  cls.nuke_test_methods!
69
72
 
@@ -90,7 +93,7 @@ end
90
93
 
91
94
 
92
95
  class MiniTest::Spec < MiniTest::Unit::TestCase
93
- @@describe_stack = [MiniTest::Spec]
96
+ @@describe_stack = []
94
97
  def self.describe_stack # :nodoc:
95
98
  @@describe_stack
96
99
  end
@@ -2,6 +2,8 @@ require 'optparse'
2
2
 
3
3
  ##
4
4
  # Minimal (mostly drop-in) replacement for test-unit.
5
+ #
6
+ # :include: README.txt
5
7
 
6
8
  module MiniTest
7
9
 
@@ -21,7 +23,8 @@ module MiniTest
21
23
  require 'pathname'
22
24
  pwd = Pathname.new Dir.pwd
23
25
  pn = Pathname.new File.expand_path(__FILE__)
24
- pn = File.join(".", pn.relative_path_from(pwd)) unless pn.relative?
26
+ relpath = pn.relative_path_from(pwd) rescue pn
27
+ pn = File.join ".", relpath unless pn.relative?
25
28
  pn.to_s
26
29
  else # assume both are expanded
27
30
  __FILE__
@@ -35,11 +38,11 @@ module MiniTest
35
38
 
36
39
  new_bt = []
37
40
  bt.each do |line|
38
- break if line.rindex(MINI_DIR, 0)
41
+ break if line.rindex MINI_DIR, 0
39
42
  new_bt << line
40
43
  end
41
44
 
42
- new_bt = bt.reject { |line| line.rindex(MINI_DIR, 0) } if new_bt.empty?
45
+ new_bt = bt.reject { |line| line.rindex MINI_DIR, 0 } if new_bt.empty?
43
46
  new_bt = bt.dup if new_bt.empty?
44
47
  new_bt
45
48
  end
@@ -56,7 +59,7 @@ module MiniTest
56
59
 
57
60
  def mu_pp obj
58
61
  s = obj.inspect
59
- s = s.force_encoding(Encoding.default_external) if defined? Encoding
62
+ s = s.force_encoding Encoding.default_external if defined? Encoding
60
63
  s
61
64
  end
62
65
 
@@ -85,15 +88,14 @@ module MiniTest
85
88
  # Fails unless the block returns a true value.
86
89
 
87
90
  def assert_block msg = nil
88
- msg = message(msg) { "Expected block to return true value" }
89
- assert yield, msg
91
+ assert yield, "Expected block to return true value."
90
92
  end
91
93
 
92
94
  ##
93
95
  # Fails unless +obj+ is empty.
94
96
 
95
97
  def assert_empty obj, msg = nil
96
- msg = message(msg) { "Expected #{obj.inspect} to be empty" }
98
+ msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" }
97
99
  assert_respond_to obj, :empty?
98
100
  assert obj.empty?, msg
99
101
  end
@@ -243,8 +245,8 @@ module MiniTest
243
245
 
244
246
  def assert_respond_to obj, meth, msg = nil
245
247
  msg = message(msg) {
246
- "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
247
- }
248
+ "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
249
+ }
248
250
  assert obj.respond_to?(meth), msg
249
251
  end
250
252
 
@@ -506,27 +508,57 @@ module MiniTest
506
508
  end
507
509
 
508
510
  class Unit
509
- VERSION = "1.7.2" # :nodoc:
511
+ VERSION = "2.0.0" # :nodoc:
510
512
 
511
513
  attr_accessor :report, :failures, :errors, :skips # :nodoc:
512
514
  attr_accessor :test_count, :assertion_count # :nodoc:
513
515
  attr_accessor :start_time # :nodoc:
516
+ attr_accessor :options # :nodoc:
517
+ attr_accessor :help # :nodoc:
518
+ attr_accessor :verbose # :nodoc:
514
519
 
515
520
  @@installed_at_exit ||= false
516
521
  @@out = $stdout
517
522
 
523
+ ##
524
+ # A simple hook allowing you to run a block of code after the
525
+ # tests are done. Eg:
526
+ #
527
+ # MiniTest::Unit.after_tests { p $debugging_info }
528
+
529
+ def self.after_tests
530
+ at_exit { at_exit { yield } }
531
+ end
532
+
518
533
  ##
519
534
  # Registers MiniTest::Unit to run tests at process exit
520
535
 
521
536
  def self.autorun
522
537
  at_exit {
523
538
  next if $! # don't run if there was an exception
524
- exit_code = MiniTest::Unit.new.run(ARGV)
539
+ exit_code = MiniTest::Unit.new.run ARGV
525
540
  exit false if exit_code && exit_code != 0
526
541
  } unless @@installed_at_exit
527
542
  @@installed_at_exit = true
528
543
  end
529
544
 
545
+ ##
546
+ # Returns the stream to use for output.
547
+
548
+ def self.output
549
+ @@out
550
+ end
551
+
552
+ ##
553
+ # Returns the stream to use for output.
554
+ #
555
+ # DEPRECATED: use ::output instead.
556
+
557
+ def self.out
558
+ warn "::out deprecated, use ::output instead." if $VERBOSE
559
+ output
560
+ end
561
+
530
562
  ##
531
563
  # Sets MiniTest::Unit to write output to +stream+. $stdout is the default
532
564
  # output
@@ -535,6 +567,93 @@ module MiniTest
535
567
  @@out = stream
536
568
  end
537
569
 
570
+ ##
571
+ # Return all plugins' run methods (methods that start with "run_").
572
+
573
+ def self.plugins
574
+ @@plugins ||= (["run_tests"] +
575
+ public_instance_methods(false).
576
+ grep(/^run_/).map { |s| s.to_s }).uniq
577
+ end
578
+
579
+ def output
580
+ self.class.output
581
+ end
582
+
583
+ def puts *a # :nodoc:
584
+ output.puts(*a)
585
+ end
586
+
587
+ def print *a # :nodoc:
588
+ output.print(*a)
589
+ end
590
+
591
+ def _run_anything type
592
+ suites = TestCase.send "#{type}_suites"
593
+ return if suites.empty?
594
+
595
+ start = Time.now
596
+
597
+ puts
598
+ puts "# Running #{type}s:"
599
+ puts
600
+
601
+ @test_count, @assertion_count = 0, 0
602
+ sync = output.respond_to? :"sync=" # stupid emacs
603
+ old_sync, output.sync = output.sync, true if sync
604
+
605
+ results = _run_suites suites, type
606
+
607
+ @test_count = results.inject(0) { |sum, (tc, ac)| sum + tc }
608
+ @assertion_count = results.inject(0) { |sum, (tc, ac)| sum + ac }
609
+
610
+ output.sync = old_sync if sync
611
+
612
+ t = Time.now - start
613
+
614
+ puts
615
+ puts
616
+ puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." %
617
+ [t, test_count / t, assertion_count / t]
618
+
619
+ report.each_with_index do |msg, i|
620
+ puts "\n%3d) %s" % [i + 1, msg]
621
+ end
622
+
623
+ puts
624
+
625
+ status
626
+ end
627
+
628
+ def _run_suites suites, type
629
+ suites.map { |suite| _run_suite suite, type }
630
+ end
631
+
632
+ def _run_suite suite, type
633
+ header = "#{type}_suite_header"
634
+ puts send(header, suite) if respond_to? header
635
+
636
+ filter = options[:filter] || '/./'
637
+ filter = Regexp.new $1 if filter =~ /\/(.*)\//
638
+
639
+ assertions = suite.send("#{type}_methods").grep(filter).map { |method|
640
+ inst = suite.new method
641
+ inst._assertions = 0
642
+
643
+ start_time = Time.now
644
+ result = inst.run self
645
+ time = Time.now - start_time
646
+
647
+ print "#{suite}##{method} = %.2f s = " % time if @verbose
648
+ print result
649
+ puts if @verbose
650
+
651
+ inst._assertions
652
+ }
653
+
654
+ return assertions.size, assertions.inject(0) { |sum, n| sum + n }
655
+ end
656
+
538
657
  def location e # :nodoc:
539
658
  last_before_assertion = ""
540
659
  e.backtrace.reverse_each do |s|
@@ -558,7 +677,7 @@ module MiniTest
558
677
  "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
559
678
  else
560
679
  @errors += 1
561
- bt = MiniTest::filter_backtrace(e.backtrace).join("\n ")
680
+ bt = MiniTest::filter_backtrace(e.backtrace).join "\n "
562
681
  "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n #{bt}\n"
563
682
  end
564
683
  @report << e
@@ -573,6 +692,7 @@ module MiniTest
573
692
 
574
693
  def process_args args = []
575
694
  options = {}
695
+ orig_args = args.dup
576
696
 
577
697
  OptionParser.new do |opts|
578
698
  opts.banner = 'minitest options:'
@@ -595,9 +715,21 @@ module MiniTest
595
715
  options[:filter] = a
596
716
  end
597
717
 
598
- opts.parse args
718
+ opts.parse! args
719
+ orig_args -= args
720
+ end
721
+
722
+ unless options[:seed] then
723
+ srand
724
+ options[:seed] = srand % 0xFFFF
725
+ orig_args << "--seed" << options[:seed].to_s
599
726
  end
600
727
 
728
+ srand options[:seed]
729
+
730
+ self.verbose = options[:verbose]
731
+ @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " "
732
+
601
733
  options
602
734
  end
603
735
 
@@ -605,89 +737,40 @@ module MiniTest
605
737
  # Top level driver, controls all output and filtering.
606
738
 
607
739
  def run args = []
608
- options = process_args args
609
-
610
- @verbose = options[:verbose]
740
+ self.options = process_args args
611
741
 
612
- filter = options[:filter] || '/./'
613
- filter = Regexp.new $1 if filter and filter =~ /\/(.*)\//
742
+ puts "Run options: #{help}"
614
743
 
615
- seed = options[:seed]
616
- unless seed then
617
- srand
618
- seed = srand % 0xFFFF
744
+ self.class.plugins.each do |plugin|
745
+ send plugin
746
+ break unless report.empty?
619
747
  end
620
748
 
621
- srand seed
622
-
623
- help = ["--seed", seed]
624
- help.push "--verbose" if @verbose
625
- help.push("--name", options[:filter].inspect) if options[:filter]
626
-
627
- @@out.puts "Test run options: #{help.join(" ")}"
628
- @@out.puts
629
- @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted"
630
-
631
- start = Time.now
632
- run_test_suites filter
633
-
634
- @@out.puts
635
- @@out.puts "Finished in #{'%.6f' % (Time.now - start)} seconds."
636
-
637
- @report.each_with_index do |msg, i|
638
- @@out.puts "\n%3d) %s" % [i + 1, msg]
639
- end
640
-
641
- @@out.puts
642
-
643
- status
644
-
645
- @@out.puts
646
-
647
- @@out.puts "Test run options: #{help.join(" ")}"
648
-
649
749
  return failures + errors if @test_count > 0 # or return nil...
650
750
  rescue Interrupt
651
751
  abort 'Interrupted'
652
752
  end
653
753
 
654
754
  ##
655
- # Writes status to +io+
755
+ # Runs test suites matching +filter+.
656
756
 
657
- def status io = @@out
658
- format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
659
- io.puts format % [test_count, assertion_count, failures, errors, skips]
757
+ def run_tests
758
+ _run_anything :test
660
759
  end
661
760
 
662
761
  ##
663
- # Runs test suites matching +filter+
762
+ # Writes status to +io+
664
763
 
665
- def run_test_suites filter = /./
666
- @test_count, @assertion_count = 0, 0
667
- old_sync, @@out.sync = @@out.sync, true if @@out.respond_to? :sync=
668
- TestCase.test_suites.each do |suite|
669
- suite.test_methods.grep(filter).each do |test|
670
- inst = suite.new test
671
- inst._assertions = 0
672
- @@out.print "#{suite}##{test}: " if @verbose
673
-
674
- @start_time = Time.now
675
- result = inst.run(self)
676
-
677
- @@out.print "%.2f s: " % (Time.now - @start_time) if @verbose
678
- @@out.print result
679
- @@out.puts if @verbose
680
- @test_count += 1
681
- @assertion_count += inst._assertions
682
- end
683
- end
684
- @@out.sync = old_sync if @@out.respond_to? :sync=
685
- [@test_count, @assertion_count]
764
+ def status io = self.output
765
+ format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
766
+ io.puts format % [test_count, assertion_count, failures, errors, skips]
686
767
  end
687
768
 
688
769
  ##
689
- # Subclass TestCase to create your own tests. Typically you'll want a
770
+ # Subclass TestCase to create your own tests. Typically you'll want a
690
771
  # TestCase subclass per implementation class.
772
+ #
773
+ # See MiniTest::Assertions
691
774
 
692
775
  class TestCase
693
776
  attr_reader :__name__ # :nodoc:
@@ -701,30 +784,31 @@ module MiniTest
701
784
  # Runs the tests reporting the status to +runner+
702
785
 
703
786
  def run runner
704
- trap 'INFO' do
705
- warn '%s#%s %.2fs' % [self.class, self.__name__,
706
- (Time.now - runner.start_time)]
787
+ trap "INFO" do
788
+ time = Time.now - runner.start_time
789
+ warn "%s#%s %.2fs" % [self.class, self.__name__, time]
707
790
  runner.status $stderr
708
791
  end if SUPPORTS_INFO_SIGNAL
709
792
 
710
- result = '.'
793
+ result = ""
711
794
  begin
712
795
  @passed = nil
713
796
  self.setup
714
797
  self.__send__ self.__name__
798
+ result = "." unless io?
715
799
  @passed = true
716
800
  rescue *PASSTHROUGH_EXCEPTIONS
717
801
  raise
718
802
  rescue Exception => e
719
803
  @passed = false
720
- result = runner.puke(self.class, self.__name__, e)
804
+ result = runner.puke self.class, self.__name__, e
721
805
  ensure
722
806
  begin
723
807
  self.teardown
724
808
  rescue *PASSTHROUGH_EXCEPTIONS
725
809
  raise
726
810
  rescue Exception => e
727
- result = runner.puke(self.class, self.__name__, e)
811
+ result = runner.puke self.class, self.__name__, e
728
812
  end
729
813
  trap 'INFO', 'DEFAULT' if SUPPORTS_INFO_SIGNAL
730
814
  end
@@ -733,9 +817,19 @@ module MiniTest
733
817
 
734
818
  def initialize name # :nodoc:
735
819
  @__name__ = name
820
+ @__io__ = nil
736
821
  @passed = nil
737
822
  end
738
823
 
824
+ def io
825
+ @__io__ = true
826
+ MiniTest::Unit.output
827
+ end
828
+
829
+ def io?
830
+ @__io__
831
+ end
832
+
739
833
  def self.reset # :nodoc:
740
834
  @@test_suites = {}
741
835
  end
@@ -756,7 +850,7 @@ module MiniTest
756
850
  end
757
851
 
758
852
  def self.test_suites # :nodoc:
759
- @@test_suites.keys.sort_by { |ts| ts.name }
853
+ @@test_suites.keys.sort_by { |ts| ts.name.to_s }
760
854
  end
761
855
 
762
856
  def self.test_methods # :nodoc:
@@ -765,7 +859,7 @@ module MiniTest
765
859
  case self.test_order
766
860
  when :random then
767
861
  max = methods.size
768
- methods.sort.sort_by { rand(max) }
862
+ methods.sort.sort_by { rand max }
769
863
  when :alpha, :sorted then
770
864
  methods.sort
771
865
  else
@@ -807,4 +901,3 @@ if $DEBUG then
807
901
  end
808
902
  end
809
903
  end
810
-