[前][次][番号順一覧][スレッド一覧]

ruby-changes:15196

From: ryan <ko1@a...>
Date: Sun, 28 Mar 2010 10:37:43 +0900 (JST)
Subject: [ruby-changes:15196] Ruby:r27076 (trunk): Imported minitest 1.6.0 r5717.

ryan	2010-03-28 10:37:07 +0900 (Sun, 28 Mar 2010)

  New Revision: 27076

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27076

  Log:
    Imported minitest 1.6.0 r5717.

  Modified files:
    trunk/ChangeLog
    trunk/lib/minitest/mock.rb
    trunk/lib/minitest/spec.rb
    trunk/lib/minitest/unit.rb
    trunk/test/minitest/test_mini_spec.rb
    trunk/test/minitest/test_mini_test.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27075)
+++ ChangeLog	(revision 27076)
@@ -1,3 +1,8 @@
+Sun Mar 28 10:35:45 2010  Ryan Davis  <ryand-ruby@z...>
+
+	* lib/minitest/*.rb: Imported minitest 1.6.0 r5717.
+	* test/minitest/*.rb: ditto.
+
 Sun Mar 28 10:12:28 2010  Tanaka Akira  <akr@f...>
 
 	* time.c (rb_time_magnify): fix for LP64.
Index: lib/minitest/unit.rb
===================================================================
--- lib/minitest/unit.rb	(revision 27075)
+++ lib/minitest/unit.rb	(revision 27076)
@@ -4,14 +4,21 @@
 # File a patch instead and assign it to Ryan Davis
 ############################################################
 
+require 'optparse'
+
 ##
-#
-# Totally minimal drop-in replacement for test-unit
-#
-# TODO: refute -> debunk, prove/rebut, show/deny... lots of possibilities
+# Minimal (mostly drop-in) replacement for test-unit.
 
 module MiniTest
+
+  ##
+  # Assertion base class
+
   class Assertion < Exception; end
+
+  ##
+  # Assertion raised when skipping a test
+
   class Skip < Assertion; end
 
   file = if RUBY_VERSION =~ /^1\.9/ then  # bt's expanded, but __FILE__ isn't :(
@@ -27,9 +34,9 @@
          end
 
   # './lib' in project dir, or '/usr/local/blahblah' if installed
-  MINI_DIR = File.dirname(File.dirname(file))
+  MINI_DIR = File.dirname(File.dirname(file)) # :nodoc:
 
-  def self.filter_backtrace bt
+  def self.filter_backtrace bt # :nodoc:
     return ["No backtrace"] unless bt
 
     new_bt = []
@@ -43,21 +50,33 @@
     new_bt
   end
 
+  ##
+  # MiniTest Assertions.  All assertion methods accept a +msg+ which is
+  # printed if the assertion fails.
+
   module Assertions
-    def mu_pp(obj)
+
+    ##
+    # mu_pp gives a human-readable version of +obj+.  By default #inspect is
+    # called.  You can override this to use #pretty_print if you want.
+
+    def mu_pp obj
       s = obj.inspect
       s = s.force_encoding(Encoding.default_external) if defined? Encoding
       s
     end
 
-    def _assertions= n
+    def _assertions= n # :nodoc:
       @_assertions = n
     end
 
-    def _assertions
+    def _assertions # :nodoc:
       @_assertions ||= 0
     end
 
+    ##
+    # Fails unless +test+ is a true value.
+
     def assert test, msg = nil
       msg ||= "Failed assertion, no message given."
       self._assertions += 1
@@ -68,32 +87,56 @@
       true
     end
 
+    ##
+    # Fails unless the block returns a true value.
+
     def assert_block msg = nil
       msg = message(msg) { "Expected block to return true value" }
       assert yield, msg
     end
 
+    ##
+    # Fails unless +obj+ is empty.
+
     def assert_empty obj, msg = nil
       msg = message(msg) { "Expected #{obj.inspect} to be empty" }
       assert_respond_to obj, :empty?
       assert obj.empty?, msg
     end
 
+    ##
+    # Fails unless <tt>exp == act</tt>.
+    #
+    # For floats use assert_in_delta
+
     def assert_equal exp, act, msg = nil
       msg = message(msg) { "Expected #{mu_pp(exp)}, not #{mu_pp(act)}" }
       assert(exp == act, msg)
     end
 
+    ##
+    # For comparing Floats.  Fails unless +exp+ and +act+ are within +delta+
+    # of each other.
+    #
+    #   assert_in_delta Math::PI, (22.0 / 7.0), 0.01
+
     def assert_in_delta exp, act, delta = 0.001, msg = nil
       n = (exp - act).abs
       msg = message(msg) { "Expected #{exp} - #{act} (#{n}) to be < #{delta}" }
       assert delta >= n, msg
     end
 
+    ##
+    # For comparing Floats.  Fails unless +exp+ and +act+ have a relative
+    # error less than +epsilon+.
+
     def assert_in_epsilon a, b, epsilon = 0.001, msg = nil
       assert_in_delta a, b, [a, b].min * epsilon, msg
     end
 
+    ##
+    # Fails unless +collection+ includes +obj+.
+
     def assert_includes collection, obj, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}"
@@ -102,6 +145,9 @@
       assert collection.include?(obj), msg
     end
 
+    ##
+    # Fails unless +obj+ is an instace of +cls+.
+
     def assert_instance_of cls, obj, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}"
@@ -110,6 +156,9 @@
       assert obj.instance_of?(cls), msg
     end
 
+    ##
+    # Fails unless +obj+ is a kind of +cls+.
+
     def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of
       msg = message(msg) {
         "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" }
@@ -117,23 +166,37 @@
       assert obj.kind_of?(cls), msg
     end
 
+    ##
+    # Fails unless +exp+ is <tt>=~</tt> +act+.
+
     def assert_match exp, act, msg = nil
       msg = message(msg) { "Expected #{mu_pp(exp)} to match #{mu_pp(act)}" }
       assert_respond_to act, :"=~"
-      exp = /#{Regexp.escape(exp)}/ if String === exp && String === act
+      exp = /#{Regexp.escape exp}/ if String === exp && String === act
       assert exp =~ act, msg
     end
 
+    ##
+    # Fails unless +obj+ is nil
+
     def assert_nil obj, msg = nil
       msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
       assert obj.nil?, msg
     end
 
+    ##
+    # For testing equality operators and so-forth.
+    #
+    #   assert_operator 5, :<=, 4
+
     def assert_operator o1, op, o2, msg = nil
       msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
       assert o1.__send__(op, o2), msg
     end
 
+    ##
+    # Fails unless the block raises one of +exp+
+
     def assert_raises *exp
       msg = String === exp.last ? exp.pop : nil
       msg = msg.to_s + "\n" if msg
@@ -155,6 +218,9 @@
         should_raise
     end
 
+    ##
+    # Fails unless +obj+ responds to +meth+.
+
     def assert_respond_to obj, meth, msg = nil
       msg = message(msg) {
           "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}"
@@ -162,14 +228,22 @@
       assert obj.respond_to?(meth), msg
     end
 
+    ##
+    # Fails unless +exp+ and +act+ are #equal?
+
     def assert_same exp, act, msg = nil
       msg = message(msg) {
         data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
-        "Expected %s (0x%x) to be the same as %s (0x%x)" % data
+        "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data
       }
       assert exp.equal?(act), msg
     end
 
+    ##
+    # +send_ary+ is a receiver, message and arguments.
+    #
+    # Fails unless the call returns a true value
+
     def assert_send send_ary, m = nil
       recv, msg, *args = send_ary
       m = message(m) {
@@ -177,6 +251,9 @@
       assert recv.__send__(msg, *args), m
     end
 
+    ##
+    # Fails unless the block throws +sym+
+
     def assert_throws sym, msg = nil
       default = "Expected #{mu_pp(sym)} to have been thrown"
       caught = true
@@ -194,6 +271,15 @@
       assert caught, message(msg) { default }
     end
 
+    ##
+    # Captures $stdout and $stderr into strings:
+    #
+    #   out, err = capture_io do
+    #     warn "You did a bad thing"
+    #   end
+    #
+    #   assert_match %r%bad%, err
+
     def capture_io
       require 'stringio'
 
@@ -209,15 +295,24 @@
       $stderr = orig_stderr
     end
 
+    ##
+    # Returns details for exception +e+
+
     def exception_details e, msg
       "#{msg}\nClass: <#{e.class}>\nMessage: <#{e.message.inspect}>\n---Backtrace---\n#{MiniTest::filter_backtrace(e.backtrace).join("\n")}\n---------------"
     end
 
+    ##
+    # Fails with +msg+
+
     def flunk msg = nil
       msg ||= "Epic Fail!"
       assert false, msg
     end
 
+    ##
+    # Returns a proc that will output +msg+ along with the default message.
+
     def message msg = nil, &default
       proc {
         if msg then
@@ -231,22 +326,35 @@
       }
     end
 
+    ##
     # used for counting assertions
+
     def pass msg = nil
       assert true
     end
 
+    ##
+    # Fails if +test+ is a true value
+
     def refute test, msg = nil
       msg ||= "Failed refutation, no message given"
       not assert(! test, msg)
     end
 
+    ##
+    # Fails if +obj+ is empty.
+
     def refute_empty obj, msg = nil
       msg = message(msg) { "Expected #{obj.inspect} to not be empty" }
       assert_respond_to obj, :empty?
       refute obj.empty?, msg
     end
 
+    ##
+    # Fails if <tt>exp == act</tt>.
+    #
+    # For floats use refute_in_delta.
+
     def refute_equal exp, act, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}"
@@ -254,6 +362,11 @@
       refute exp == act, msg
     end
 
+    ##
+    # For comparing Floats.  Fails if +exp+ is within +delta+ of +act+
+    #
+    #   refute_in_delta Math::PI, (22.0 / 7.0)
+
     def refute_in_delta exp, act, delta = 0.001, msg = nil
       n = (exp - act).abs
       msg = message(msg) {
@@ -262,10 +375,17 @@
       refute delta > n, msg
     end
 
+    ##
+    # For comparing Floats.  Fails if +exp+ and +act+ have a relative error
+    # less than +epsilon+.
+
     def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
       refute_in_delta a, b, a * epsilon, msg
     end
 
+    ##
+    # Fails if +collection+ includes +obj+
+
     def refute_includes collection, obj, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}"
@@ -274,6 +394,9 @@
       refute collection.include?(obj), msg
     end
 
+    ##
+    # Fails if +obj+ is an instance of +cls+
+
     def refute_instance_of cls, obj, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(obj)} to not be an instance of #{cls}"
@@ -281,23 +404,38 @@
       refute obj.instance_of?(cls), msg
     end
 
+    ##
+    # Fails if +obj+ is a kind of +cls+
+
     def refute_kind_of cls, obj, msg = nil # TODO: merge with instance_of
       msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" }
       refute obj.kind_of?(cls), msg
     end
 
+    ##
+    # Fails if +exp+ <tt>=~</tt> +act+
+
     def refute_match exp, act, msg = nil
       msg = message(msg) { "Expected #{mu_pp(exp)} to not match #{mu_pp(act)}" }
       assert_respond_to act, :"=~"
-      exp = /#{Regexp.escape(exp)}/ if String === exp && String === act
+      exp = (/#{Regexp.escape exp}/) if String === exp and String === act
       refute exp =~ act, msg
     end
 
+    ##
+    # Fails if +obj+ is nil.
+
     def refute_nil obj, msg = nil
       msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
       refute obj.nil?, msg
     end
 
+    ##
+    # Fails if +o1+ is not +op+ +o2+ nil. eg:
+    #
+    #   refute_operator 1, :>, 2 #=> pass
+    #   refute_operator 1, :<, 2 #=> fail
+
     def refute_operator o1, op, o2, msg = nil
       msg = message(msg) {
         "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"
@@ -305,19 +443,30 @@
       refute o1.__send__(op, o2), msg
     end
 
+    ##
+    # Fails if +obj+ responds to the message +meth+.
+
     def refute_respond_to obj, meth, msg = nil
       msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
 
       refute obj.respond_to?(meth), msg
     end
 
+    ##
+    # Fails if +exp+ is the same (by object identity) as +act+.
+
     def refute_same exp, act, msg = nil
       msg = message(msg) {
-        "Expected #{mu_pp(act)} to not be the same as #{mu_pp(exp)}"
+        data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id]
+        "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data
       }
       refute exp.equal?(act), msg
     end
 
+    ##
+    # Skips the current test. Gets listed at the end of the run but
+    # doesn't cause a failure exit code.
+
     def skip msg = nil, bt = caller
       msg ||= "Skipped, no message given"
       raise MiniTest::Skip, msg, bt
@@ -325,15 +474,18 @@
   end
 
   class Unit
-    VERSION = "1.5.0"
+    VERSION = "1.6.0" # :nodoc:
 
-    attr_accessor :report, :failures, :errors, :skips
-    attr_accessor :test_count, :assertion_count
-    attr_accessor :start_time
+    attr_accessor :report, :failures, :errors, :skips # :nodoc:
+    attr_accessor :test_count, :assertion_count       # :nodoc:
+    attr_accessor :start_time                         # :nodoc:
 
     @@installed_at_exit ||= false
     @@out = $stdout
 
+    ##
+    # Registers MiniTest::Unit to run tests at process exit
+
     def self.autorun
       at_exit {
         next if $! # don't run if there was an exception
@@ -343,11 +495,15 @@
       @@installed_at_exit = true
     end
 
+    ##
+    # Sets MiniTest::Unit to write output to +stream+.  $stdout is the default
+    # output
+
     def self.output= stream
       @@out = stream
     end
 
-    def location e
+    def location e # :nodoc:
       last_before_assertion = ""
       e.backtrace.reverse_each do |s|
         break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
@@ -356,6 +512,10 @@
       last_before_assertion.sub(/:in .*$/, '')
     end
 
+    ##
+    # Writes status for failed test +meth+ in +klass+ which finished with
+    # exception +e+
+
     def puke klass, meth, e
       e = case e
           when MiniTest::Skip then
@@ -373,26 +533,61 @@
       e[0, 1]
     end
 
-    def initialize
+    def initialize # :nodoc:
       @report = []
       @errors = @failures = @skips = 0
       @verbose = false
     end
 
+    def process_args args = []
+      options = {}
+
+      OptionParser.new do |opts|
+        opts.banner  = 'minitest options:'
+        opts.version = MiniTest::Unit::VERSION
+
+        opts.on '-h', '--help', 'Display this help.' do
+          puts opts
+          exit
+        end
+
+        opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m|
+          options[:seed] = m.to_i
+        end
+
+        opts.on '-v', '--verbose', "Verbose. Show progress processing files." do
+          options[:verbose] = true
+        end
+
+        opts.on '-n', '--name PATTERN', "Filter test names on pattern." do |a|
+          options[:filter] = a
+        end
+
+        opts.parse args
+      end
+
+      options
+    end
+
     ##
     # Top level driver, controls all output and filtering.
 
     def run args = []
-      @verbose = args.delete('-v')
+      options = process_args args
 
-      filter = if args.first =~ /^(-n|--name)$/ then
-                 args.shift
-                 arg = args.shift
-                 arg =~ /\/(.*)\// ? Regexp.new($1) : arg
-               else
-                 /./ # anything - ^test_ already filtered by #tests
-               end
+      @verbose = options[:verbose]
 
+      filter = options[:filter] || '/./'
+      filter = Regexp.new $1 if filter and filter =~ /\/(.*)\//
+
+      seed = options[:seed]
+      unless seed then
+        srand
+        seed = srand % 0xFFFF
+      end
+
+      srand seed
+
       @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted"
 
       start = Time.now
@@ -409,16 +604,30 @@
 
       status
 
+      @@out.puts
+
+      help = ["--seed", seed]
+      help.push "--verbose" if @verbose
+      help.push("--name", options[:filter].inspect) if options[:filter]
+
+      @@out.puts "Test run options: #{help.join(" ")}"
+
       return failures + errors if @test_count > 0 # or return nil...
     rescue Interrupt
       abort 'Interrupted'
     end
 
+    ##
+    # Writes status to +io+
+
     def status io = @@out
       format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
       io.puts format % [test_count, assertion_count, failures, errors, skips]
     end
 
+    ##
+    # Runs test suites matching +filter+
+
     def run_test_suites filter = /./
       @test_count, @assertion_count = 0, 0
       old_sync, @@out.sync = @@out.sync, true if @@out.respond_to? :sync=
@@ -442,14 +651,21 @@
       [@test_count, @assertion_count]
     end
 
+    ##
+    # Subclass TestCase to create your own tests.  Typically you'll want a
+    # TestCase subclass per implementation class.
+
     class TestCase
-      attr_reader :__name__
+      attr_reader :__name__ # :nodoc:
 
-      PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,
-        SystemExit]
+      PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException,
+                                Interrupt, SystemExit] # :nodoc:
 
-      SUPPORTS_INFO_SIGNAL = Signal.list['INFO']
+      SUPPORTS_INFO_SIGNAL = Signal.list['INFO'] # :nodoc:
 
+      ##
+      # Runs the tests reporting the status to +runner+
+
       def run runner
         trap 'INFO' do
           warn '%s#%s %.2fs' % [self.class, self.__name__,
@@ -481,61 +697,79 @@
         result
       end
 
-      def initialize name
+      def initialize name # :nodoc:
         @__name__ = name
         @passed = nil
       end
 
-      def self.reset
+      def self.reset # :nodoc:
         @@test_suites = {}
       end
 
       reset
 
-      def self.inherited klass
+      def self.inherited klass # :nodoc:
         @@test_suites[klass] = true
       end
 
+      ##
+      # Defines test order and is subclassable. Defaults to :random
+      # but can be overridden to return :alpha if your tests are order
+      # dependent (read: weak).
+
       def self.test_order
         :random
       end
 
-      def self.test_suites
+      def self.test_suites # :nodoc:
         @@test_suites.keys.sort_by { |ts| ts.name }
       end
 
-      def self.test_methods
-        methods = public_instance_methods(true).grep(/^test/).map { |m|
-          m.to_s
-        }.sort
+      def self.test_methods # :nodoc:
+        methods = public_instance_methods(true).grep(/^test/).map { |m| m.to_s }
 
-        if self.test_order == :random then
+        case self.test_order
+        when :random then
           max = methods.size
-          methods = methods.sort_by { rand(max) }
+          methods.sort.sort_by { rand(max) }
+        when :alpha, :sorted then
+          methods.sort
+        else
+          raise "Unknown test_order: #{self.test_order.inspect}"
         end
-
-        methods
       end
 
-      def setup; end
-      def teardown; end
+      ##
+      # Returns true if the test passed.
 
       def passed?
         @passed
       end
 
+      ##
+      # Runs before every test. Use this to refactor test initialization.
+
+      def setup; end
+
+      ##
+      # Runs after every test. Use this to refactor test cleanup.
+
+      def teardown; end
+
       include MiniTest::Assertions
     end # class TestCase
   end # class Unit
 end # module MiniTest
 
 if $DEBUG then
-  # this helps me ferret out porting issues
-  module Test; end
-  module Test::Unit; end
-  class Test::Unit::TestCase
-    def self.inherited x
-      raise "You're running minitest and test/unit in the same process: #{x}"
+  module Test                # :nodoc:
+    module Unit              # :nodoc:
+      class TestCase         # :nodoc:
+        def self.inherited x # :nodoc:
+          # this helps me ferret out porting issues
+          raise "Using minitest and test/unit in the same process: #{x}"
+        end
+      end
     end
   end
 end
Index: lib/minitest/mock.rb
===================================================================
--- lib/minitest/mock.rb	(revision 27075)
+++ lib/minitest/mock.rb	(revision 27076)
@@ -16,6 +16,7 @@
     def expect(name, retval, args=[])
       n, r, a = name, retval, args # for the closure below
       @expected_calls[name] = { :retval => retval, :args => args }
+      self.class.__send__ :remove_method, name if respond_to? name
       self.class.__send__(:define_method, name) { |*x|
         raise ArgumentError unless @expected_calls[n][:args].size == x.size
         @actual_calls[n] << { :retval => r, :args => x }
Index: lib/minitest/spec.rb
===================================================================
--- lib/minitest/spec.rb	(revision 27075)
+++ lib/minitest/spec.rb	(revision 27076)
@@ -64,6 +64,14 @@
 end
 
 module Kernel
+  ##
+  # Describe a series of expectations for a given target +desc+.
+  #
+  # TODO: find good tutorial url.
+  #
+  # Defines a test class subclassing from either
+  # MiniTest::Unit::TestCase or from the surrounding describe's class.
+
   def describe desc, &block
     stack = MiniTest::Spec.describe_stack
     name  = desc.to_s.split(/\W+/).map { |s| s.capitalize }.join + "Spec"
@@ -80,28 +88,36 @@
   private :describe
 end
 
+class Module
+  def classes type = Object # :nodoc:
+    constants.map { |n| const_get n }.find_all { |c|
+      c.class == Class and type > c
+    } - [self]
+  end
+end
+
 class MiniTest::Spec < MiniTest::Unit::TestCase
   @@describe_stack = [MiniTest::Spec]
-  def self.describe_stack
+  def self.describe_stack # :nodoc:
     @@describe_stack
   end
 
-  def self.current
+  def self.current # :nodoc:
     @@current_spec
   end
 
-  def initialize name
+  def initialize name # :nodoc:
     super
     @@current_spec = self
   end
 
-  def self.nuke_test_methods!
+  def self.nuke_test_methods! # :nodoc:
     self.public_instance_methods.grep(/^test_/).each do |name|
       self.send :undef_method, name
     end
   end
 
-  def self.define_inheritable_method name, &block
+  def self.define_inheritable_method name, &block # :nodoc:
     super_method = self.superclass.instance_method name
 
     define_method name do
@@ -110,25 +126,167 @@
     end
   end
 
-  def self.before(type = :each, &block)
-    if type == :all
-      warn "change before :all to before :each"
-      type = :each
-    end
+  ##
+  # Define a 'before' action. Inherits the way normal methods should.
+  #
+  # NOTE: +type+ is ignored and is only there to make porting easier.
+  #
+  # Equivalent to MiniTest::Unit::TestCase#setup.
+
+  def self.before type = :each, &block
     raise "unsupported before type: #{type}" unless type == :each
     define_inheritable_method :setup, &block
   end
 
-  def self.after(type = :each, &block)
-    if type == :all # REFACTOR
-      warn "change before :all to before :each"
-      type = :each
-    end
+  ##
+  # Define an 'after' action. Inherits the way normal methods should.
+  #
+  # NOTE: +type+ is ignored and is only there to make porting easier.
+  #
+  # Equivalent to MiniTest::Unit::TestCase#teardown.
+
+  def self.after type = :each, &block
     raise "unsupported after type: #{type}" unless type == :each
     define_inheritable_method :teardown, &block
   end
 
+  ##
+  # Define an expectation with name +desc+. Name gets morphed to a
+  # proper test method name. For some freakish reason, people who
+  # write specs don't like class inheritence, so this goes way out of
+  # its way to make sure that expectations aren't inherited.
+  #
+  # Hint: If you _do_ want inheritence, use minitest/unit. You can mix
+  # and match between assertions and expectations as much as you want.
+
   def self.it desc, &block
-    define_method "test_#{desc.gsub(/\W+/, '_').downcase}", &block
+    block ||= proc { skip "(no tests defined)" }
+
+    @specs ||= 0
+    @specs += 1
+
+    name = "test_%04d_%s" % [ @specs, desc.gsub(/\W+/, '_').downcase ]
+
+    define_method name, &block
+
+    classes(MiniTest::Spec).each do |mod|
+      mod.send :undef_method, name if mod.respond_to? name
+    end
   end
+
+  ##
+  # :method: must_be
+  # See MiniTest::Assertions#assert
+
+  ##
+  # :method: must_be_close_to
+  # See MiniTest::Assertions#assert_in_delta
+
+  ##
+  # :method: must_be_empty
+  # See MiniTest::Assertions#assert_empty
+
+  ##
+  # :method: must_be_instance_of
+  # See MiniTest::Assertions#assert_instance_of
+
+  ##
+  # :method: must_be_kind_of
+  # See MiniTest::Assertions#assert_kind_of
+
+  ##
+  # :method: must_be_nil
+  # See MiniTest::Assertions#assert_nil
+
+  ##
+  # :method: must_be_same_as
+  # See MiniTest::Assertions#assert_same
+
+  ##
+  # :method: must_be_within_delta
+  # See MiniTest::Assertions#assert_in_delta
+
+  ##
+  # :method: must_be_within_epsilon
+  # See MiniTest::Assertions#assert_in_epsilon
+
+  ##
+  # :method: must_equal
+  # See MiniTest::Assertions#assert_equal
+
+  ##
+  # :method: must_include
+  # See MiniTest::Assertions#assert_includes
+
+  ##
+  # :method: must_match
+  # See MiniTest::Assertions#assert_match
+
+  ##
+  # :method: must_raise
+  # See MiniTest::Assertions#assert_raises
+
+  ##
+  # :method: must_respond_to
+  # See MiniTest::Assertions#assert_respond_to
+
+  ##
+  # :method: must_send
+  # See MiniTest::Assertions#assert_send
+
+  ##
+  # :method: must_throw
+  # See MiniTest::Assertions#assert_throw
+
+  ##
+  # :method: wont_be
+  # See MiniTest::Assertions#refute
+
+  ##
+  # :method: wont_be_close_to
+  # See MiniTest::Assertions#refute_in_delta
+
+  ##
+  # :method: wont_be_empty
+  # See MiniTest::Assertions#refute_empty
+
+  ##
+  # :method: wont_be_instance_of
+  # See MiniTest::Assertions#refute_instance_of
+
+  ##
+  # :method: wont_be_kind_of
+  # See MiniTest::Assertions#refute_kind_of
+
+  ##
+  # :method: wont_be_nil
+  # See MiniTest::Assertions#refute_nil
+
+  ##
+  # :method: wont_be_same_as
+  # See MiniTest::Assertions#refute_same
+
+  ##
+  # :method: wont_be_within_delta
+  # See MiniTest::Assertions#refute_in_delta
+
+  ##
+  # :method: wont_be_within_epsilon
+  # See MiniTest::Assertions#refute_in_epsilon
+
+  ##
+  # :method: wont_equal
+  # See MiniTest::Assertions#refute_equal
+
+  ##
+  # :method: wont_include
+  # See MiniTest::Assertions#refute_includes
+
+  ##
+  # :method: wont_match
+  # See MiniTest::Assertions#refute_match
+
+  ##
+  # :method: wont_respond_to
+  # See MiniTest::Assertions#refute_respond_to
 end
Index: test/minitest/test_mini_spec.rb
===================================================================
--- test/minitest/test_mini_spec.rb	(revision 27075)
+++ test/minitest/test_mini_spec.rb	(revision 27076)
@@ -17,6 +17,9 @@
     self._assertions.must_equal @assertion_count
   end
 
+  # TODO: figure out how the hell to write a test for this
+  # it "will skip if there is no block"
+
   it "needs to have all methods named well" do
     @assertion_count = 2
 
Index: test/minitest/test_mini_test.rb
===================================================================
--- test/minitest/test_mini_test.rb	(revision 27075)
+++ test/minitest/test_mini_test.rb	(revision 27076)
@@ -207,7 +207,7 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run
+    @tu.run %w[-s 42]
 
     expected = "Loaded suite blah
 Started
@@ -219,6 +219,8 @@
 Failed assertion, no message given.
 
 2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
+
+Test run options: --seed 42
 "
     util_assert_report expected
   end
@@ -236,7 +238,7 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run
+    @tu.run %w[-s 42]
 
     expected = "Loaded suite blah
 Started
@@ -249,6 +251,8 @@
     FILE:LINE:in `test_error'
 
 2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
+
+Test run options: --seed 42
 "
     util_assert_report expected
   end
@@ -266,7 +270,7 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run
+    @tu.run %w[-s 42]
 
     expected = "Loaded suite blah
 Started
@@ -279,6 +283,8 @@
     FILE:LINE:in `teardown'
 
 1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
+
+Test run options: --seed 42
 "
     util_assert_report expected
   end
@@ -296,7 +302,7 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run
+    @tu.run %w[-s 42]
 
     expected = "Loaded suite blah
 Started
@@ -308,6 +314,8 @@
 not yet
 
 2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
+
+Test run options: --seed 42
 "
     util_assert_report expected
   end
@@ -319,6 +327,8 @@
 Finished in 0.00
 
 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+
+Test run options: --seed 42
 "
     output = @output.string.sub(/Finished in .*/, "Finished in 0.00")
     output.sub!(/Loaded suite .*/, 'Loaded suite blah')
@@ -340,9 +350,18 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run(%w(-n /something/))
+    @tu.run %w[-n /something/ -s 42]
 
-    util_assert_report
+    expected = "Loaded suite blah
+Started
+.
+Finished in 0.00
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+
+Test run options: --seed 42 --name \"/something/\"
+"
+    util_assert_report expected
   end
 
   def test_run_passing
@@ -354,7 +373,7 @@
 
     Object.const_set(:ATestCase, tc)
 
-    @tu.run
+    @tu.run %w[-s 42]
 
     util_assert_report
   end
@@ -703,14 +722,14 @@
   def test_assert_same_triggered
     @assertion_count = 2
 
-    util_assert_triggered 'Expected 2 (0xXXX) to be the same as 1 (0xXXX).' do
+    util_assert_triggered 'Expected 2 (oid=N) to be the same as 1 (oid=N).' do
       @tc.assert_same 1, 2
     end
 
     s1 = "blah"
     s2 = "blah"
 
-    util_assert_triggered 'Expected "blah" (0xXXX) to be the same as "blah" (0xXXX).' do
+    util_assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do
       @tc.assert_same s1, s2
     end
   end
@@ -786,18 +805,13 @@
   def test_test_methods_sorted
     @assertion_count = 0
 
-    sample_test_case = Class.new(MiniTest::Unit::TestCase)
-
-    class << sample_test_case
-      def test_order; :sorted end
+    sample_test_case = Class.new(MiniTest::Unit::TestCase) do
+      def self.test_order; :sorted end
+      def test_test3; assert "does not matter" end
+      def test_test2; assert "does not matter" end
+      def test_test1; assert "does not matter" end
     end
 
-    sample_test_case.instance_eval do
-      define_method :test_test3 do assert "does not matter" end
-      define_method :test_test2 do assert "does not matter" end
-      define_method :test_test1 do assert "does not matter" end
-    end
-
     expected = %w(test_test1 test_test2 test_test3)
     assert_equal expected, sample_test_case.test_methods
   end
@@ -805,27 +819,15 @@
   def test_test_methods_random
     @assertion_count = 0
 
-    sample_test_case = Class.new(MiniTest::Unit::TestCase)
-
-    class << sample_test_case
-      def test_order; :random end
+    sample_test_case = Class.new(MiniTest::Unit::TestCase) do
+      def test_test1; assert "does not matter" end
+      def test_test2; assert "does not matter" end
+      def test_test3; assert "does not matter" end
     end
 
-    sample_test_case.instance_eval do
-      define_method :test_test1 do assert "does not matter" end
-      define_method :test_test2 do assert "does not matter" end
-      define_method :test_test3 do assert "does not matter" end
-    end
-
     srand 42
-    expected = %w(test_test1 test_test2 test_test3)
-    max = expected.size
-    expected = expected.sort_by { rand(max) }
-
-    srand 42
-    result = sample_test_case.test_methods
-
-    assert_equal expected, result
+    expected = %w(test_test2 test_test1 test_test3)
+    assert_equal expected, sample_test_case.test_methods
   end
 
   def test_refute
@@ -991,9 +993,8 @@
     @tc.refute_same 1, 2
   end
 
-  # TODO: "with id <id>" crap from assertions.rb
   def test_refute_same_triggered
-    util_assert_triggered 'Expected 1 to not be the same as 1.' do
+    util_assert_triggered 'Expected 1 (oid=N) to not be the same as 1 (oid=N).' do
       @tc.refute_same 1, 1
     end
   end
@@ -1012,7 +1013,7 @@
     end
 
     msg = e.message.sub(/(---Backtrace---).*/m, '\1')
-    msg.gsub!(/\(0x[0-9a-f]+\)/, '(0xXXX)')
+    msg.gsub!(/\(oid=[-0-9]+\)/, '(oid=N)')
 
     assert_equal expected, msg
   end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]