minitest 1.7.2 → 2.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.
@@ -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
-