[DRE-commits] [SCM] ruby-minitest.git branch, master, updated. upstream/2.1.0-12-gafd9b1c

Lucas Nussbaum lucas at lucas-nussbaum.net
Sun Oct 9 11:29:30 UTC 2011


The following commit has been merged in the master branch:
commit 6d57449532cd19fc00a90962e371dbf2ec488e8f
Author: Lucas Nussbaum <lucas at lucas-nussbaum.net>
Date:   Sun Oct 9 12:42:20 2011 +0200

    Imported Upstream version 2.6.1

diff --git a/History.txt b/History.txt
index 3a72582..b1ba8ec 100644
--- a/History.txt
+++ b/History.txt
@@ -1,3 +1,102 @@
+=== 2.6.1 / 2011-09-27
+
+* 2 bug fixes:
+
+  * Alias Spec.name from Spec.to_s so it works when @name is nil (nathany)
+  * Fixed assert and refute_operator where second object has a bad == method.
+
+=== 2.6.0 / 2011-09-13
+
+* 2 minor enhancements:
+
+  * Added specify alias for it and made desc optional.
+  * Spec#must_be and #wont_be can be used with predicates (metaskills)
+
+* 1 bug fix:
+
+  * Fixed Mock.respond_to?(var) to work with strings. (holli)
+
+=== 2.5.1 / 2011-08-27
+
+* 2 minor enhancements:
+
+  * Added gem activation for minitest in minitest/autoload to help out 1.9 users
+  * Extended Spec.register_spec_type to allow for procs instead of just regexps.
+
+=== 2.5.0 / 2011-08-18
+
+* 4 minor enhancements:
+
+  * Added 2 more arguments against rspec: let & subject in 9 loc! (emmanuel/luis)
+  * Added TestCase.i_suck_and_my_tests_are_order_dependent!
+  * Extended describe to take an optional method name (2 line change!). (emmanuel)
+  * Refactored and extended minitest/pride to do full 256 color support. (lolcat)
+
+* 1 bug fix:
+
+  * Doc fixes. (chastell)
+
+=== 2.4.0 / 2011-08-09
+
+* 4 minor enhancements:
+
+  * Added simple examples for all expectations.
+  * Improved Mock error output when args mismatch.
+  * Moved all expectations from Object to MiniTest::Expectations.
+  * infect_with_assertions has been removed due to excessive clever
+
+* 4 bug fixes:
+
+  * Fix Assertions#mu_pp to deal with immutable encoded strings. (ferrous26)
+  * Fix minitest/pride for MacRuby (ferrous26)
+  * Made error output less fancy so it is more readable
+  * Mock shouldn't undef === and inspect. (dgraham)
+
+=== 2.3.1 / 2011-06-22
+
+* 1 bug fix:
+
+  * Fixed minitest hoe plugin to be a spermy dep and not depend on itself.
+
+=== 2.3.0 / 2011-06-15
+
+* 5 minor enhancements:
+
+  * Add setup and teardown hooks to MiniTest::TestCase. (phiggins)
+  * Added nicer error messages for MiniTest::Mock. (phiggins)
+  * Allow for less specific expected arguments in Mock. (bhenderson/phiggins)
+  * Made MiniTest::Mock a blank slate. (phiggins)
+  * Refactored minitest/spec to use the hooks instead of define_inheritable_method. (phiggins)
+
+* 2 bug fixes:
+
+  * Fixed TestCase's inherited hook. (dchelimsky/phiggins/jamis, the 'good' neighbor)
+  * MiniTest::Assertions#refute_empty should use mu_pp in the default message. (whatthejeff)
+
+=== 2.2.2 / 2011-06-01
+
+* 2 bug fixes:
+
+  * Got rid of the trailing period in message for assert_equal. (tenderlove)
+  * Windows needs more flushing. (Akio Tajima)
+
+=== 2.2.1 / 2011-05-31
+
+* 1 bug fix:
+
+  * My _ONE_ non-rubygems-using minitest user goes to Seattle.rb!
+
+=== 2.2.0 / 2011-05-29
+
+* 6 minor enhancements:
+
+  * assert_equal (and must_equal) now tries to diff output where it makes sense.
+    * Added Assertions#diff(exp, act) to be used by assert_equal.
+    * Added Assertions#mu_pp_for_diff
+    * Added Assertions.diff and diff=
+  * Moved minitest hoe-plugin from hoe-seattlerb. (erikh)
+  * Skipped tests only output details in verbose mode. (tenderlove+zenspider=xoxo)
+
 === 2.1.0 / 2011-04-11
 
 * 5 minor enhancements:
diff --git a/Manifest.txt b/Manifest.txt
index 018b001..4fe8612 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -4,6 +4,7 @@ Manifest.txt
 README.txt
 Rakefile
 design_rationale.rb
+lib/hoe/minitest.rb
 lib/minitest/autorun.rb
 lib/minitest/benchmark.rb
 lib/minitest/mock.rb
diff --git a/README.txt b/README.txt
index 7b1e6e6..74a319e 100644
--- a/README.txt
+++ b/README.txt
@@ -1,12 +1,24 @@
-= minitest/*
+= minitest/{unit,spec,mock,benchmark}
 
-* http://rubyforge.org/projects/bfts
+home :: https://github.com/seattlerb/minitest
+rdoc :: http://docs.seattlerb.org/minitest
 
 == DESCRIPTION:
 
 minitest provides a complete suite of testing facilities supporting
 TDD, BDD, mocking, and benchmarking.
 
+    "I had a class with Jim Weirich on testing last week and we were
+     allowed to choose our testing frameworks. Kirk Haines and I were
+     paired up and we cracked open the code for a few test
+     frameworks...
+
+     I MUST say that mintiest is *very* readable / understandable
+     compared to the 'other two' options we looked at. Nicely done and
+     thank you for helping us keep our mental sanity."
+
+    -- Wayne E. Seguin
+
 minitest/unit is a small and incredibly fast unit testing framework.
 It provides a rich set of assertions to make your tests clean and
 readable.
@@ -24,13 +36,18 @@ minitest/mock by Steven Baker, is a beautifully tiny mock object
 framework.
 
 minitest/pride shows pride in testing and adds coloring to your test
-output.
+output. I guess it is an example of how to write IO pipes too. :P
 
 minitest/unit is meant to have a clean implementation for language
 implementors that need a minimal set of methods to bootstrap a working
 test suite. For example, there is no magic involved for test-case
 discovery.
 
+    "Again, I can’t praise enough the idea of a testing/specing
+     framework that I can actually read in full in one sitting!"
+
+    -- Piotr Szotkowski
+
 == FEATURES/PROBLEMS:
 
 * minitest/autorun - the easy and explicit way to run all your tests.
@@ -247,7 +264,7 @@ the gem, but you'll need to activate the gem explicitly to use it:
 
 (The MIT License)
 
-Copyright (c) Ryan Davis, Seattle.rb
+Copyright (c) Ryan Davis, seattle.rb
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/Rakefile b/Rakefile
index 56f7598..25d9b90 100644
--- a/Rakefile
+++ b/Rakefile
@@ -18,6 +18,57 @@ def loc dir
   system "find #{dir} -name \\*.rb | xargs wc -l | tail -1"
 end
 
+desc "Find missing expectations"
+task :specs do
+  $:.unshift "lib"
+  require "minitest/unit"
+  require "minitest/spec"
+
+  pos_prefix, neg_prefix = "must", "wont"
+  skip_re = /^(must|wont)$|wont_(throw)|must_(block|not?_|nothing|raise$)/x
+  dont_flip_re = /(must|wont)_(include|respond_to)/
+
+  map = {
+    /(must_throw)s/                        => '\1',
+    /(?!not)_same/                         => '_be_same_as',
+    /_in_/                                 => '_be_within_',
+    /_operator/                            => '_be',
+    /_includes/                            => '_include',
+    /(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2',
+    /must_raises/                          => 'must_raise',
+  }
+
+  expectations = MiniTest::Expectations.public_instance_methods.map(&:to_s)
+  assertions   = MiniTest::Assertions.public_instance_methods.map(&:to_s)
+
+  assertions.sort.each do |assertion|
+    expectation = case assertion
+                  when /^assert/ then
+                    assertion.sub(/^assert/, pos_prefix.to_s)
+                  when /^refute/ then
+                    assertion.sub(/^refute/, neg_prefix.to_s)
+                  end
+
+    next unless expectation
+    next if expectation =~ skip_re
+
+    regexp, replacement = map.find { |re, _| expectation =~ re }
+    expectation.sub! regexp, replacement if replacement
+
+    next if expectations.include? expectation
+
+    args = [assertion, expectation].map(&:to_sym).map(&:inspect)
+    args << :reverse if expectation =~ dont_flip_re
+
+    puts
+    puts "##"
+    puts "# :method: #{expectation}"
+    puts "# See MiniTest::Assertions##{assertion}"
+    puts
+    puts "infect_an_assertion #{args.join ", "}"
+  end
+end
+
 desc "stupid line count"
 task :dickwag do
   puts
diff --git a/data.tar.gz.sig b/data.tar.gz.sig
index eb3b1c2..b7560ef 100644
Binary files a/data.tar.gz.sig and b/data.tar.gz.sig differ
diff --git a/lib/hoe/minitest.rb b/lib/hoe/minitest.rb
new file mode 100644
index 0000000..d67a3b8
--- /dev/null
+++ b/lib/hoe/minitest.rb
@@ -0,0 +1,16 @@
+module Hoe::Minitest
+  def initialize_minitest
+    require 'minitest/unit'
+    version = MiniTest::Unit::VERSION.split(/\./).first(2).join(".")
+
+    dependency 'minitest', "~> #{version}", :development unless
+      self.name == "minitest"
+  end
+
+  def define_minitest_tasks
+    self.testlib = :minitest
+
+    # make sure we use the gemmed minitest on 1.9
+    self.test_prelude = 'gem "minitest"'
+  end
+end
diff --git a/lib/minitest/autorun.rb b/lib/minitest/autorun.rb
index 3cf64fc..15bbe43 100644
--- a/lib/minitest/autorun.rb
+++ b/lib/minitest/autorun.rb
@@ -1,3 +1,10 @@
+begin
+  require 'rubygems'
+  gem 'minitest'
+rescue Gem::LoadError
+  # do nothing
+end
+
 require 'minitest/unit'
 require 'minitest/spec'
 require 'minitest/mock'
diff --git a/lib/minitest/mock.rb b/lib/minitest/mock.rb
index 00bee3b..acb978e 100644
--- a/lib/minitest/mock.rb
+++ b/lib/minitest/mock.rb
@@ -9,20 +9,39 @@ module MiniTest
   # All mock objects are an instance of Mock
 
   class Mock
+    alias :__respond_to? :respond_to?
+
+    skip_methods = %w(object_id respond_to_missing? inspect === to_s)
+
+    instance_methods.each do |m|
+      undef_method m unless skip_methods.include?(m.to_s) || m =~ /^__/
+    end
+
     def initialize # :nodoc:
       @expected_calls = {}
       @actual_calls = Hash.new {|h,k| h[k] = [] }
     end
 
     ##
-    # Expect that method +name+ is called, optionally with +args+, and
-    # returns +retval+.
+    # Expect that method +name+ is called, optionally with +args+, and returns
+    # +retval+.
     #
     #   @mock.expect(:meaning_of_life, 42)
     #   @mock.meaning_of_life # => 42
     #
     #   @mock.expect(:do_something_with, true, [some_obj, true])
     #   @mock.do_something_with(some_obj, true) # => true
+    #
+    # +args+ is compared to the expected args using case equality (ie, the
+    # '===' operator), allowing for less specific expectations.
+    #
+    #   @mock.expect(:uses_any_string, true, [String])
+    #   @mock.uses_any_string("foo") # => true
+    #   @mock.verify  # => true
+    #
+    #   @mock.expect(:uses_one_string, true, ["foo"]
+    #   @mock.uses_one_string("bar") # => true
+    #   @mock.verify  # => raises MockExpectationError
 
     def expect(name, retval, args=[])
       @expected_calls[name] = { :retval => retval, :args => args }
@@ -37,25 +56,45 @@ module MiniTest
     def verify
       @expected_calls.each_key do |name|
         expected = @expected_calls[name]
-        msg = "expected #{name}, #{expected.inspect}"
-        raise MockExpectationError, msg unless
+        msg1 = "expected #{name}, #{expected.inspect}"
+        msg2 = "#{msg1}, got #{@actual_calls[name].inspect}"
+
+        raise MockExpectationError, msg2 if
+          @actual_calls.has_key? name and
+          not @actual_calls[name].include?(expected)
+
+        raise MockExpectationError, msg1 unless
           @actual_calls.has_key? name and @actual_calls[name].include?(expected)
       end
       true
     end
 
     def method_missing(sym, *args) # :nodoc:
-      raise NoMethodError unless @expected_calls.has_key?(sym)
-      raise ArgumentError unless @expected_calls[sym][:args].size == args.size
-      retval = @expected_calls[sym][:retval]
-      @actual_calls[sym] << { :retval => retval, :args => args }
+      expected = @expected_calls[sym]
+
+      unless expected then
+        raise NoMethodError, "unmocked method %p, expected one of %p" %
+          [sym, @expected_calls.keys.sort_by(&:to_s)]
+      end
+
+      expected_args, retval = expected[:args], expected[:retval]
+
+      unless expected_args.size == args.size
+        raise ArgumentError, "mocked method %p expects %d arguments, got %d" %
+          [sym, expected[:args].size, args.size]
+      end
+
+      @actual_calls[sym] << {
+        :retval => retval,
+        :args => expected_args.zip(args).map { |mod, a| mod if mod === a }
+      }
+
       retval
     end
 
-    alias :original_respond_to? :respond_to?
     def respond_to?(sym) # :nodoc:
-      return true if @expected_calls.has_key?(sym)
-      return original_respond_to?(sym)
+      return true if @expected_calls.has_key?(sym.to_sym)
+      return __respond_to?(sym)
     end
   end
 end
diff --git a/lib/minitest/pride.rb b/lib/minitest/pride.rb
index ebf6e30..3d9e458 100644
--- a/lib/minitest/pride.rb
+++ b/lib/minitest/pride.rb
@@ -4,32 +4,90 @@ require "minitest/unit"
 # Show your testing pride!
 
 class PrideIO
-  attr_reader :io
+  ESC = "\e["
+  NND = "#{ESC}0m"
 
-  # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
-  COLORS = (31..36).to_a
-  CHARS = ["*"]
+  attr_reader :io
 
   def initialize io
     @io = io
-    @colors = COLORS.cycle
-    @chars  = CHARS.cycle
+    # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm
+    # also reference http://en.wikipedia.org/wiki/ANSI_escape_code
+    @colors ||= (31..36).to_a
+    @size   = @colors.size
+    @index  = 0
+    # io.sync = true
   end
 
   def print o
     case o
     when "." then
-      io.print "\e[#{@colors.next}m#{@chars.next}\e[0m"
+      io.print pride o
     when "E", "F" then
-      io.print "\e[41m\e[37m#{o}\e[0m"
+      io.print "#{ESC}41m#{ESC}37m#{o}#{NND}"
     else
       io.print o
     end
   end
 
+  def puts(*o)
+    o.map! { |s|
+      s.sub(/Finished tests/) {
+        @index = 0
+        'Fabulous tests'.split(//).map { |c|
+          pride(c)
+        }.join
+      }
+    }
+
+    super
+  end
+
+  def pride string
+    string = "*" if string == "."
+    c = @colors[@index % @size]
+    @index += 1
+    "#{ESC}#{c}m#{string}#{NND}"
+  end
+
   def method_missing msg, *args
     io.send(msg, *args)
   end
 end
 
-MiniTest::Unit.output = PrideIO.new(MiniTest::Unit.output)
+class PrideLOL < PrideIO # inspired by lolcat, but massively cleaned up
+  PI_3 = Math::PI / 3
+
+  def initialize io
+    # walk red, green, and blue around a circle separated by equal thirds.
+    #
+    # To visualize, type this into wolfram-alpha:
+    #
+    #   plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3)
+
+    # 6 has wide pretty gradients. 3 == lolcat, about half the width
+    @colors = (0...(6 * 7)).map { |n|
+      n *= 1.0 / 6
+      r  = (3 * Math.sin(n           ) + 3).to_i
+      g  = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
+      b  = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
+
+      # Then we take rgb and encode them in a single number using base 6.
+      # For some mysterious reason, we add 16... to clear the bottom 4 bits?
+      # Yes... they're ugly.
+
+      36 * r + 6 * g + b + 16
+    }
+
+    super
+  end
+
+  def pride string
+    c = @colors[@index % @size]
+    @index += 1
+    "#{ESC}38;5;#{c}m#{string}#{NND}"
+  end
+end
+
+klass = ENV['TERM'] =~ /^xterm(-256color)?$/ ? PrideLOL : PrideIO
+MiniTest::Unit.output = klass.new(MiniTest::Unit.output)
diff --git a/lib/minitest/spec.rb b/lib/minitest/spec.rb
index 29b4ba8..fd24d5e 100644
--- a/lib/minitest/spec.rb
+++ b/lib/minitest/spec.rb
@@ -2,7 +2,7 @@
 
 require 'minitest/unit'
 
-class Module
+class Module # :nodoc:
   def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
     # warn "%-22p -> %p %p" % [meth, new_name, dont_flip]
     self.class_eval <<-EOM
@@ -17,39 +17,18 @@ class Module
   end
 
   ##
-  # Create your own expectations from MiniTest::Assertions using a
-  # flexible set of rules. If you don't like must/wont, then this
-  # method is your friend. For an example of its usage see the bottom
-  # of minitest/spec.rb.
+  # infect_with_assertions has been removed due to excessive clever.
+  # Use infect_an_assertion directly instead.
 
   def infect_with_assertions(pos_prefix, neg_prefix,
                              skip_re,
                              dont_flip_re = /\c0/,
                              map = {})
-    MiniTest::Assertions.public_instance_methods(false).sort.each do |meth|
-      meth = meth.to_s
-
-      new_name = case meth
-                 when /^assert/ then
-                   meth.sub(/^assert/, pos_prefix.to_s)
-                 when /^refute/ then
-                   meth.sub(/^refute/, neg_prefix.to_s)
-                 end
-      next unless new_name
-      next if new_name =~ skip_re
-
-      regexp, replacement = map.find { |re, _| new_name =~ re }
-      new_name.sub! regexp, replacement if replacement
-
-      puts "\n##\n# :method: #{new_name}\n# See MiniTest::Assertions##{meth}" if
-        $0 == __FILE__
-
-      infect_an_assertion meth, new_name, new_name =~ dont_flip_re
-    end
+    abort "infect_with_assertions is dead. Use infect_an_assertion directly"
   end
 end
 
-module Kernel
+module Kernel # :nodoc:
   ##
   # Describe a series of expectations for a given target +desc+.
   #
@@ -74,25 +53,16 @@ module Kernel
   #       end
   #     end
 
-  def describe desc, &block # :doc:
+  def describe desc, additional_desc = nil, &block # :doc:
     stack = MiniTest::Spec.describe_stack
-    name  = [stack.last, desc].compact.join("::")
+    name  = [stack.last, desc, additional_desc].compact.join("::")
     sclas = stack.last || if Class === self && self < MiniTest::Spec then
                             self
                           else
                             MiniTest::Spec.spec_type desc
                           end
-    cls   = Class.new sclas
-
-    sclas.children << cls unless cls == MiniTest::Spec
 
-    # :stopdoc:
-    # omg this sucks
-    (class << cls; self; end).send(:define_method, :to_s) { name }
-    (class << cls; self; end).send(:define_method, :desc) { desc }
-    # :startdoc:
-
-    cls.nuke_test_methods!
+    cls = sclas.create name, desc
 
     stack.push cls
     cls.class_eval(&block)
@@ -105,7 +75,7 @@ end
 ##
 # MiniTest::Spec -- The faster, better, less-magical spec framework!
 #
-# For a list of expectations, see Object.
+# For a list of expectations, see MiniTest::Expectations.
 
 class MiniTest::Spec < MiniTest::Unit::TestCase
   ##
@@ -118,11 +88,27 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
   TYPES = [[//, MiniTest::Spec]]
 
   ##
-  # Register a new type of spec that matches the spec's description. Eg:
+  # Register a new type of spec that matches the spec's description.
+  # This method can take either a Regexp and a spec class or a spec
+  # class and a block that takes the description and returns true if
+  # it matches.
+  #
+  # Eg:
   #
-  #     register_spec_plugin(/Controller$/, MiniTest::Spec::Rails)
+  #     register_spec_type(/Controller$/, MiniTest::Spec::Rails)
+  #
+  # or:
+  #
+  #     register_spec_type(MiniTest::Spec::RailsModel) do |desc|
+  #       desc.superclass == ActiveRecord::Base
+  #     end
 
-  def self.register_spec_type matcher, klass
+  def self.register_spec_type(*args, &block)
+    if block then
+      matcher, klass = block, args.first
+    else
+      matcher, klass = *args
+    end
     TYPES.unshift [matcher, klass]
   end
 
@@ -132,8 +118,13 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
   #     spec_type("BlahController") # => MiniTest::Spec::Rails
 
   def self.spec_type desc
-    desc = desc.to_s
-    TYPES.find { |re, klass| re === desc }.last
+    TYPES.find { |matcher, klass|
+      if matcher.respond_to? :call then
+        matcher.call desc
+      else
+        matcher === desc.to_s
+      end
+    }.last
   end
 
   @@describe_stack = []
@@ -145,6 +136,9 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
     @@current_spec
   end
 
+  ##
+  # Returns the children of this spec.
+
   def self.children
     @children ||= []
   end
@@ -161,25 +155,6 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
   end
 
   ##
-  # Spec users want setup/teardown to be inherited and NOTHING ELSE.
-  # It is almost like method reuse is lost on them.
-
-  def self.define_inheritable_method name, &block # :nodoc:
-    # regular super() warns
-    super_method = self.superclass.instance_method name
-
-    teardown     = name.to_s == "teardown"
-    super_before = super_method && ! teardown
-    super_after  = super_method && teardown
-
-    define_method name do
-      super_method.bind(self).call if super_before
-      instance_eval(&block)
-      super_method.bind(self).call if super_after
-    end
-  end
-
-  ##
   # Define a 'before' action. Inherits the way normal methods should.
   #
   # NOTE: +type+ is ignored and is only there to make porting easier.
@@ -188,7 +163,8 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
 
   def self.before type = :each, &block
     raise "unsupported before type: #{type}" unless type == :each
-    define_inheritable_method :setup, &block
+
+    add_setup_hook {|tc| tc.instance_eval(&block) }
   end
 
   ##
@@ -200,7 +176,8 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
 
   def self.after type = :each, &block
     raise "unsupported after type: #{type}" unless type == :each
-    define_inheritable_method :teardown, &block
+
+    add_teardown_hook {|tc| tc.instance_eval(&block) }
   end
 
   ##
@@ -209,10 +186,12 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
   # write specs don't like class inheritence, so this goes way out of
   # its way to make sure that expectations aren't inherited.
   #
+  # This is also aliased to #specify and doesn't require a +desc+ arg.
+  #
   # 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
+  def self.it desc = "anonymous", &block
     block ||= proc { skip "(no tests defined)" }
 
     @specs ||= 0
@@ -226,154 +205,321 @@ class MiniTest::Spec < MiniTest::Unit::TestCase
       mod.send :undef_method, name if mod.public_method_defined? name
     end
   end
-end
 
-Object.infect_with_assertions(:must, :wont,
-                              /^(must|wont)$|wont_(throw)|
-                                 must_(block|not?_|nothing|raise$)/x,
-                              /(must|wont)_(include|respond_to)/,
-                              /(must_throw)s/                 => '\1',
-                              /(?!not)_same/                  => '_be_same_as',
-                              /_in_/                          => '_be_within_',
-                              /_operator/                     => '_be',
-                              /_includes/                     => '_include',
-                       /(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2',
-                              /must_raises/                   => 'must_raise')
+  def self.let name, &block
+    define_method name do
+      @_memoized ||= {}
+      @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
+    end
+  end
 
-class Object
-  alias :must_be_close_to :must_be_within_delta
-  alias :wont_be_close_to :wont_be_within_delta
+  def self.subject &block
+    let :subject, &block
+  end
 
-  if $0 == __FILE__ then
-    { "must" => "assert", "wont" => "refute" }.each do |a, b|
-      puts "\n"
-      puts "##"
-      puts "# :method: #{a}_be_close_to"
-      puts "# See MiniTest::Assertions##{b}_in_delta"
+  def self.create name, desc # :nodoc:
+    cls = Class.new(self) do
+      @name = name
+      @desc = desc
+
+      nuke_test_methods!
     end
+
+    children << cls
+
+    cls
   end
 
-  ##
-  # :method: must_be
-  # See MiniTest::Assertions#assert_operator
+  def self.to_s # :nodoc:
+    defined?(@name) ? @name : super
+  end
 
-  ##
-  # :method: must_be_close_to
-  # See MiniTest::Assertions#assert_in_delta
+  # :stopdoc:
+  class << self
+    attr_reader :desc
+    alias :specify :it
+    alias :name :to_s
+  end
+  # :startdoc:
+end
 
+module MiniTest::Expectations
   ##
+  # See MiniTest::Assertions#assert_empty.
+  #
+  #    collection.must_be_empty
+  #
   # :method: must_be_empty
-  # See MiniTest::Assertions#assert_empty
 
-  ##
-  # :method: must_be_instance_of
-  # See MiniTest::Assertions#assert_instance_of
+  infect_an_assertion :assert_empty, :must_be_empty
 
   ##
-  # :method: must_be_kind_of
-  # See MiniTest::Assertions#assert_kind_of
+  # See MiniTest::Assertions#assert_equal
+  #
+  #    a.must_equal b
+  #
+  # :method: must_equal
+
+  infect_an_assertion :assert_equal, :must_equal
 
   ##
-  # :method: must_be_nil
-  # See MiniTest::Assertions#assert_nil
+  # See MiniTest::Assertions#assert_in_delta
+  #
+  #    n.must_be_close_to m [, delta]
+  #
+  # :method: must_be_within_delta
+
+  infect_an_assertion :assert_in_delta, :must_be_close_to
+
+  alias :must_be_within_delta :must_be_close_to
 
   ##
-  # :method: must_be_same_as
-  # See MiniTest::Assertions#assert_same
+  # See MiniTest::Assertions#assert_in_epsilon
+  #
+  #    n.must_be_within_epsilon m [, epsilon]
+  #
+  # :method: must_be_within_epsilon
+
+  infect_an_assertion :assert_in_epsilon, :must_be_within_epsilon
 
   ##
-  # :method: must_be_silent
-  # See MiniTest::Assertions#assert_silent
+  # See MiniTest::Assertions#assert_includes
+  #
+  #    collection.must_include obj
+  #
+  # :method: must_include
+
+  infect_an_assertion :assert_includes, :must_include, :reverse
 
   ##
-  # :method: must_be_within_delta
-  # See MiniTest::Assertions#assert_in_delta
+  # See MiniTest::Assertions#assert_instance_of
+  #
+  #    obj.must_be_instance_of klass
+  #
+  # :method: must_be_instance_of
+
+  infect_an_assertion :assert_instance_of, :must_be_instance_of
 
   ##
-  # :method: must_be_within_epsilon
-  # See MiniTest::Assertions#assert_in_epsilon
+  # See MiniTest::Assertions#assert_kind_of
+  #
+  #    obj.must_be_kind_of mod
+  #
+  # :method: must_be_kind_of
+
+  infect_an_assertion :assert_kind_of, :must_be_kind_of
 
   ##
-  # :method: must_equal
-  # See MiniTest::Assertions#assert_equal
+  # See MiniTest::Assertions#assert_match
+  #
+  #    a.must_match b
+  #
+  # :method: must_match
+
+  infect_an_assertion :assert_match, :must_match
 
   ##
-  # :method: must_include
-  # See MiniTest::Assertions#assert_includes
+  # See MiniTest::Assertions#assert_nil
+  #
+  #    obj.must_be_nil
+  #
+  # :method: must_be_nil
+
+  infect_an_assertion :assert_nil, :must_be_nil
 
   ##
-  # :method: must_match
-  # See MiniTest::Assertions#assert_match
+  # See MiniTest::Assertions#assert_operator
+  #
+  #    n.must_be :<=, 42
+  #
+  # This can also do predicates:
+  #
+  #    str.must_be :empty?
+  #
+  # :method: must_be
+
+  infect_an_assertion :assert_operator, :must_be, :reverse
 
   ##
-  # :method: must_output
   # See MiniTest::Assertions#assert_output
+  #
+  #    proc { ... }.must_output out_or_nil [, err]
+  #
+  # :method: must_output
+
+  infect_an_assertion :assert_output, :must_output
 
   ##
-  # :method: must_raise
   # See MiniTest::Assertions#assert_raises
+  #
+  #    proc { ... }.must_raise exception
+  #
+  # :method: must_raise
+
+  infect_an_assertion :assert_raises, :must_raise
 
   ##
-  # :method: must_respond_to
   # See MiniTest::Assertions#assert_respond_to
+  #
+  #    obj.must_respond_to msg
+  #
+  # :method: must_respond_to
+
+  infect_an_assertion :assert_respond_to, :must_respond_to, :reverse
 
   ##
-  # :method: must_send
-  # See MiniTest::Assertions#assert_send
+  # See MiniTest::Assertions#assert_same
+  #
+  #    a.must_be_same_as b
+  #
+  # :method: must_be_same_as
+
+  infect_an_assertion :assert_same, :must_be_same_as
 
   ##
-  # :method: must_throw
-  # See MiniTest::Assertions#assert_throws
+  # See MiniTest::Assertions#assert_send
+  # TODO: remove me
+  #
+  #    a.must_send
+  #
+  # :method: must_send
+
+  infect_an_assertion :assert_send, :must_send
 
   ##
-  # :method: wont_be
-  # See MiniTest::Assertions#refute_operator
+  # See MiniTest::Assertions#assert_silent
+  #
+  #    proc { ... }.must_be_silent
+  #
+  # :method: must_be_silent
+
+  infect_an_assertion :assert_silent, :must_be_silent
 
   ##
-  # :method: wont_be_close_to
-  # See MiniTest::Assertions#refute_in_delta
+  # See MiniTest::Assertions#assert_throws
+  #
+  #    proc { ... }.must_throw sym
+  #
+  # :method: must_throw
+
+  infect_an_assertion :assert_throws, :must_throw
 
   ##
-  # :method: wont_be_empty
   # See MiniTest::Assertions#refute_empty
+  #
+  #    collection.wont_be_empty
+  #
+  # :method: wont_be_empty
+
+  infect_an_assertion :refute_empty, :wont_be_empty
 
   ##
-  # :method: wont_be_instance_of
-  # See MiniTest::Assertions#refute_instance_of
+  # See MiniTest::Assertions#refute_equal
+  #
+  #    a.wont_equal b
+  #
+  # :method: wont_equal
+
+  infect_an_assertion :refute_equal, :wont_equal
 
   ##
-  # :method: wont_be_kind_of
-  # See MiniTest::Assertions#refute_kind_of
+  # See MiniTest::Assertions#refute_in_delta
+  #
+  #    n.wont_be_close_to m [, delta]
+  #
+  # :method: wont_be_within_delta
+
+  infect_an_assertion :refute_in_delta, :wont_be_within_delta
+
+  alias :wont_be_close_to :wont_be_within_delta
+  # FIX: reverse aliases
 
   ##
-  # :method: wont_be_nil
-  # See MiniTest::Assertions#refute_nil
+  # See MiniTest::Assertions#refute_in_epsilon
+  #
+  #    n.wont_be_within_epsilon m [, epsilon]
+  #
+  # :method: wont_be_within_epsilon
+
+  infect_an_assertion :refute_in_epsilon, :wont_be_within_epsilon
 
   ##
-  # :method: wont_be_same_as
-  # See MiniTest::Assertions#refute_same
+  # See MiniTest::Assertions#refute_includes
+  #
+  #    collection.wont_include obj
+  #
+  # :method: wont_include
+
+  infect_an_assertion :refute_includes, :wont_include, :reverse
 
   ##
-  # :method: wont_be_within_delta
-  # See MiniTest::Assertions#refute_in_delta
+  # See MiniTest::Assertions#refute_instance_of
+  #
+  #    obj.wont_be_instance_of klass
+  #
+  # :method: wont_be_instance_of
+
+  infect_an_assertion :refute_instance_of, :wont_be_instance_of
 
   ##
-  # :method: wont_be_within_epsilon
-  # See MiniTest::Assertions#refute_in_epsilon
+  # See MiniTest::Assertions#refute_kind_of
+  #
+  #    obj.wont_be_kind_of mod
+  #
+  # :method: wont_be_kind_of
+
+  infect_an_assertion :refute_kind_of, :wont_be_kind_of
 
   ##
-  # :method: wont_equal
-  # See MiniTest::Assertions#refute_equal
+  # See MiniTest::Assertions#refute_match
+  #
+  #    a.wont_match b
+  #
+  # :method: wont_match
+
+  infect_an_assertion :refute_match, :wont_match
 
   ##
-  # :method: wont_include
-  # See MiniTest::Assertions#refute_includes
+  # See MiniTest::Assertions#refute_nil
+  #
+  #    obj.wont_be_nil
+  #
+  # :method: wont_be_nil
+
+  infect_an_assertion :refute_nil, :wont_be_nil
 
   ##
-  # :method: wont_match
-  # See MiniTest::Assertions#refute_match
+  # See MiniTest::Assertions#refute_operator
+  #
+  #    n.wont_be :<=, 42
+  #
+  # This can also do predicates:
+  #
+  #    str.wont_be :empty?
+  #
+  # :method: wont_be
+
+  infect_an_assertion :refute_operator, :wont_be, :reverse
 
   ##
-  # :method: wont_respond_to
   # See MiniTest::Assertions#refute_respond_to
+  #
+  #    obj.wont_respond_to msg
+  #
+  # :method: wont_respond_to
+
+  infect_an_assertion :refute_respond_to, :wont_respond_to, :reverse
+
+  ##
+  # See MiniTest::Assertions#refute_same
+  #
+  #    a.wont_be_same_as b
+  #
+  # :method: wont_be_same_as
+
+  infect_an_assertion :refute_same, :wont_be_same_as
+end
+
+class Object
+  include MiniTest::Expectations
 end
diff --git a/lib/minitest/unit.rb b/lib/minitest/unit.rb
index f1f0b3e..b9871ec 100644
--- a/lib/minitest/unit.rb
+++ b/lib/minitest/unit.rb
@@ -1,4 +1,5 @@
 require 'optparse'
+require 'rbconfig'
 
 ##
 # Minimal (mostly drop-in) replacement for test-unit.
@@ -59,16 +60,106 @@ module MiniTest
 
   module Assertions
 
+    WINDOZE = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
+
+    ##
+    # Returns the diff command to use in #diff. Tries to intelligently
+    # figure out what diff to use.
+
+    def self.diff
+      @diff = if WINDOZE
+                "diff.exe -u"
+              else
+                if system("gdiff", __FILE__, __FILE__)
+                  "gdiff -u" # solaris and kin suck
+                elsif system("diff", __FILE__, __FILE__)
+                  "diff -u"
+                else
+                  nil
+                end
+              end unless defined? @diff
+
+      @diff
+    end
+
+    ##
+    # Set the diff command to use in #diff.
+
+    def self.diff= o
+      @diff = o
+    end
+
     ##
-    # 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.
+    # Returns a diff between +exp+ and +act+. If there is no known
+    # diff command or if it doesn't make sense to diff the output
+    # (single line, short output), then it simply returns a basic
+    # comparison between the two.
+
+    def diff exp, act
+      require "tempfile"
+
+      expect = mu_pp_for_diff exp
+      butwas = mu_pp_for_diff act
+      result = nil
+
+      need_to_diff =
+        MiniTest::Assertions.diff &&
+        (expect.include?("\n")    ||
+         butwas.include?("\n")    ||
+         expect.size > 30         ||
+         butwas.size > 30         ||
+         expect == butwas)
+
+      return "Expected: #{mu_pp exp}\n  Actual: #{mu_pp act}" unless
+        need_to_diff
+
+      Tempfile.open("expect") do |a|
+        a.puts expect
+        a.flush
+
+        Tempfile.open("butwas") do |b|
+          b.puts butwas
+          b.flush
+
+          result = `#{MiniTest::Assertions.diff} #{a.path} #{b.path}`
+          result.sub!(/^\-\-\- .+/, "--- expected")
+          result.sub!(/^\+\+\+ .+/, "+++ actual")
+
+          if result.empty? then
+            klass = exp.class
+            result = [
+                      "No visible difference.",
+                      "You should look at your implementation of #{klass}#==.",
+                      expect
+                     ].join "\n"
+          end
+        end
+      end
+
+      result
+    end
+
+    ##
+    # This returns 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 = s.encode Encoding.default_external if defined? Encoding
       s
     end
 
+    ##
+    # This returns a diff-able human-readable version of +obj+. This
+    # differs from the regular mu_pp because it expands escaped
+    # newlines and makes hex-values generic (like object_ids). This
+    # uses mu_pp to do the first pass and then cleans it up.
+
+    def mu_pp_for_diff obj # TODO: possibly rename
+      mu_pp(obj).gsub(/\\n/, "\n").gsub(/0x[a-f0-9]+/m, '0xXXXXXX')
+    end
+
     def _assertions= n # :nodoc:
       @_assertions = n
     end
@@ -108,12 +199,19 @@ module MiniTest
     end
 
     ##
-    # Fails unless <tt>exp == act</tt>.
+    # Fails unless <tt>exp == act</tt> printing the difference between
+    # the two, if possible.
+    #
+    # If there is no visible difference but the assertion fails, you
+    # should suspect that your #== is buggy, or your inspect output is
+    # missing crucial details.
+    #
+    # For floats use assert_in_delta.
     #
-    # For floats use assert_in_delta
+    # See also: MiniTest::Assertions.diff
 
     def assert_equal exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(exp)}, not #{mu_pp(act)}" }
+      msg = message(msg, "") { diff exp, act }
       assert(exp == act, msg)
     end
 
@@ -187,12 +285,16 @@ module MiniTest
       assert obj.nil?, msg
     end
 
+    UNDEFINED = Object.new
+    def UNDEFINED.inspect; "UNDEFINED"; end
+
     ##
-    # For testing equality operators and so-forth.
+    # For testing with binary operators.
     #
     #   assert_operator 5, :<=, 4
 
-    def assert_operator o1, op, o2, msg = nil
+    def assert_operator o1, op, o2 = UNDEFINED, msg = nil
+      return assert_predicate o1, op, msg if UNDEFINED == o2
       msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
       assert o1.__send__(op, o2), msg
     end
@@ -216,6 +318,20 @@ module MiniTest
     end
 
     ##
+    # For testing with predicates.
+    #
+    #   assert_predicate str, :empty?
+    #
+    # This is really meant for specs and is front-ended by assert_operator:
+    #
+    #   str.must_be :empty?
+
+    def assert_predicate o1, op, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" }
+      assert o1.__send__(op), msg
+    end
+
+    ##
     # Fails unless the block raises one of +exp+
 
     def assert_raises *exp
@@ -361,10 +477,10 @@ module MiniTest
     ##
     # Returns a proc that will output +msg+ along with the default message.
 
-    def message msg = nil, &default
+    def message msg = nil, ending = ".", &default
       proc {
         custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty?
-        "#{custom_message}#{default.call}."
+        "#{custom_message}#{default.call}#{ending}"
       }
     end
 
@@ -387,7 +503,7 @@ module MiniTest
     # Fails if +obj+ is empty.
 
     def refute_empty obj, msg = nil
-      msg = message(msg) { "Expected #{obj.inspect} to not be empty" }
+      msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" }
       assert_respond_to obj, :empty?
       refute obj.empty?, msg
     end
@@ -473,19 +589,32 @@ module MiniTest
     end
 
     ##
-    # Fails if +o1+ is not +op+ +o2+ nil. eg:
+    # Fails if +o1+ is not +op+ +o2+. 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)}"
-      }
+    def refute_operator o1, op, o2 = UNDEFINED, msg = nil
+      return refute_predicate o1, op, msg if UNDEFINED == o2
+      msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}"}
       refute o1.__send__(op, o2), msg
     end
 
     ##
+    # For testing with predicates.
+    #
+    #   refute_predicate str, :empty?
+    #
+    # This is really meant for specs and is front-ended by refute_operator:
+    #
+    #   str.wont_be :empty?
+
+    def refute_predicate o1, op, msg = nil
+      msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" }
+      refute o1.__send__(op), msg
+    end
+
+    ##
     # Fails if +obj+ responds to the message +meth+.
 
     def refute_respond_to obj, meth, msg = nil
@@ -516,7 +645,7 @@ module MiniTest
   end
 
   class Unit
-    VERSION = "2.1.0" # :nodoc:
+    VERSION = "2.6.1" # :nodoc:
 
     attr_accessor :report, :failures, :errors, :skips # :nodoc:
     attr_accessor :test_count, :assertion_count       # :nodoc:
@@ -710,6 +839,7 @@ module MiniTest
       e = case e
           when MiniTest::Skip then
             @skips += 1
+            return "S" unless @verbose
             "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
           when MiniTest::Assertion then
             @failures += 1
@@ -840,6 +970,7 @@ module MiniTest
         begin
           @passed = nil
           self.setup
+          self.run_setup_hooks
           self.__send__ self.__name__
           result = "." unless io?
           @passed = true
@@ -850,6 +981,7 @@ module MiniTest
           result = runner.puke self.class, self.__name__, e
         ensure
           begin
+            self.run_teardown_hooks
             self.teardown
           rescue *PASSTHROUGH_EXCEPTIONS
             raise
@@ -882,16 +1014,24 @@ module MiniTest
 
       reset
 
+      ##
+      # Call this at the top of your tests when you absolutely
+      # positively need to have ordered tests. In doing so, you're
+      # admitting that you suck and your tests are weak.
+
+      def self.i_suck_and_my_tests_are_order_dependent!
+        class << self
+          define_method :test_order do :alpha end
+        end
+      end
+
       def self.inherited klass # :nodoc:
         @@test_suites[klass] = true
+        klass.reset_setup_teardown_hooks
+        super
       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
+      def self.test_order # :nodoc:
         :random
       end
 
@@ -930,6 +1070,111 @@ module MiniTest
 
       def teardown; end
 
+      def self.reset_setup_teardown_hooks # :nodoc:
+        @setup_hooks = []
+        @teardown_hooks = []
+      end
+
+      reset_setup_teardown_hooks
+
+      ##
+      # Adds a block of code that will be executed before every TestCase is
+      # run. Equivalent to +setup+, but usable multiple times and without
+      # re-opening any classes.
+      #
+      # All of the setup hooks will run in order after the +setup+ method, if
+      # one is defined.
+      #
+      # The argument can be any object that responds to #call or a block.
+      # That means that this call,
+      #
+      #     MiniTest::TestCase.add_setup_hook { puts "foo" }
+      #
+      # ... is equivalent to:
+      #
+      #     module MyTestSetup
+      #       def call
+      #         puts "foo"
+      #       end
+      #     end
+      #
+      #     MiniTest::TestCase.add_setup_hook MyTestSetup
+      #
+      # The blocks passed to +add_setup_hook+ take an optional parameter that
+      # will be the TestCase instance that is executing the block.
+
+      def self.add_setup_hook arg=nil, &block
+        hook = arg || block
+        @setup_hooks << hook
+      end
+
+      def self.setup_hooks # :nodoc:
+        if superclass.respond_to? :setup_hooks then
+          superclass.setup_hooks
+        else
+          []
+        end + @setup_hooks
+      end
+
+      def run_setup_hooks # :nodoc:
+        self.class.setup_hooks.each do |hook|
+          if hook.respond_to?(:arity) && hook.arity == 1
+            hook.call(self)
+          else
+            hook.call
+          end
+        end
+      end
+
+      ##
+      # Adds a block of code that will be executed after every TestCase is
+      # run. Equivalent to +teardown+, but usable multiple times and without
+      # re-opening any classes.
+      #
+      # All of the teardown hooks will run in reverse order after the
+      # +teardown+ method, if one is defined.
+      #
+      # The argument can be any object that responds to #call or a block.
+      # That means that this call,
+      #
+      #     MiniTest::TestCase.add_teardown_hook { puts "foo" }
+      #
+      # ... is equivalent to:
+      #
+      #     module MyTestTeardown
+      #       def call
+      #         puts "foo"
+      #       end
+      #     end
+      #
+      #     MiniTest::TestCase.add_teardown_hook MyTestTeardown
+      #
+      # The blocks passed to +add_teardown_hook+ take an optional parameter
+      # that will be the TestCase instance that is executing the block.
+
+      def self.add_teardown_hook arg=nil, &block
+        hook = arg || block
+        @teardown_hooks << hook
+      end
+
+      def self.teardown_hooks # :nodoc:
+        if superclass.respond_to? :teardown_hooks then
+          superclass.teardown_hooks
+        else
+          []
+        end + @teardown_hooks
+      end
+
+      def run_teardown_hooks # :nodoc:
+        self.class.teardown_hooks.reverse.each do |hook|
+          if hook.respond_to?(:arity) && hook.arity == 1
+            hook.call(self)
+          else
+            hook.call
+          end
+        end
+      end
+
       include MiniTest::Assertions
     end # class TestCase
   end # class Unit
diff --git a/metadata.gz.sig b/metadata.gz.sig
index c11f08c..5a14e1f 100644
Binary files a/metadata.gz.sig and b/metadata.gz.sig differ
diff --git a/metadata.yml b/metadata.yml
index 88a5a85..9c12ff0 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,13 +1,13 @@
 --- !ruby/object:Gem::Specification 
 name: minitest
 version: !ruby/object:Gem::Version 
-  hash: 11
+  hash: 21
   prerelease: 
   segments: 
   - 2
+  - 6
   - 1
-  - 0
-  version: 2.1.0
+  version: 2.6.1
 platform: ruby
 authors: 
 - Ryan Davis
@@ -36,68 +36,43 @@ cert_chain:
   FBHgymkyj/AOSqKRIpXPhjC6
   -----END CERTIFICATE-----
 
-date: 2011-04-11 00:00:00 -07:00
-default_executable: 
+date: 2011-09-28 00:00:00 Z
 dependencies: 
 - !ruby/object:Gem::Dependency 
-  name: minitest
+  name: hoe
   prerelease: false
   requirement: &id001 !ruby/object:Gem::Requirement 
     none: false
     requirements: 
-    - - ">="
+    - - ~>
       - !ruby/object:Gem::Version 
-        hash: 11
+        hash: 27
         segments: 
         - 2
-        - 0
-        - 2
-        version: 2.0.2
+        - 12
+        version: "2.12"
   type: :development
   version_requirements: *id001
-- !ruby/object:Gem::Dependency 
-  name: hoe
-  prerelease: false
-  requirement: &id002 !ruby/object:Gem::Requirement 
-    none: false
-    requirements: 
-    - - ">="
-      - !ruby/object:Gem::Version 
-        hash: 41
-        segments: 
-        - 2
-        - 9
-        - 1
-        version: 2.9.1
-  type: :development
-  version_requirements: *id002
-description: |-
-  minitest provides a complete suite of testing facilities supporting
-  TDD, BDD, mocking, and benchmarking.
-  
-  minitest/unit is a small and incredibly fast unit testing framework.
-  It provides a rich set of assertions to make your tests clean and
-  readable.
-  
-  minitest/spec is a functionally complete spec engine. It hooks onto
-  minitest/unit and seamlessly bridges test assertions over to spec
-  expectations.
-  
-  minitest/benchmark is an awesome way to assert the performance of your
-  algorithms in a repeatable manner. Now you can assert that your newb
-  co-worker doesn't replace your linear algorithm with an exponential
-  one!
-  
-  minitest/mock by Steven Baker, is a beautifully tiny mock object
-  framework.
-  
-  minitest/pride shows pride in testing and adds coloring to your test
-  output.
-  
-  minitest/unit is meant to have a clean implementation for language
-  implementors that need a minimal set of methods to bootstrap a working
-  test suite. For example, there is no magic involved for test-case
-  discovery.
+description: "minitest provides a complete suite of testing facilities supporting\n\
+  TDD, BDD, mocking, and benchmarking.\n\n    \"I had a class with Jim Weirich on testing last week and we were\n     allowed to choose our testing frameworks. Kirk Haines and I were\n     paired up and we cracked open the code for a few test\n     frameworks...\n\n     I MUST say that mintiest is *very* readable / understandable\n     compared to the 'other two' options we looked at. Nicely done and\n     thank you for helping us keep our mental sanity.\"\n\n    -- Wayne E. Seguin\n\n\
+  minitest/unit is a small and incredibly fast unit testing framework.\n\
+  It provides a rich set of assertions to make your tests clean and\n\
+  readable.\n\n\
+  minitest/spec is a functionally complete spec engine. It hooks onto\n\
+  minitest/unit and seamlessly bridges test assertions over to spec\n\
+  expectations.\n\n\
+  minitest/benchmark is an awesome way to assert the performance of your\n\
+  algorithms in a repeatable manner. Now you can assert that your newb\n\
+  co-worker doesn't replace your linear algorithm with an exponential\n\
+  one!\n\n\
+  minitest/mock by Steven Baker, is a beautifully tiny mock object\n\
+  framework.\n\n\
+  minitest/pride shows pride in testing and adds coloring to your test\n\
+  output. I guess it is an example of how to write IO pipes too. :P\n\n\
+  minitest/unit is meant to have a clean implementation for language\n\
+  implementors that need a minimal set of methods to bootstrap a working\n\
+  test suite. For example, there is no magic involved for test-case\n\
+  discovery.\n\n    \"Again, I can\xE2\x80\x99t praise enough the idea of a testing/specing\n     framework that I can actually read in full in one sitting!\"\n\n    -- Piotr Szotkowski"
 email: 
 - ryand-ruby at zenspider.com
 executables: []
@@ -115,6 +90,7 @@ files:
 - README.txt
 - Rakefile
 - design_rationale.rb
+- lib/hoe/minitest.rb
 - lib/minitest/autorun.rb
 - lib/minitest/benchmark.rb
 - lib/minitest/mock.rb
@@ -126,8 +102,7 @@ files:
 - test/test_minitest_spec.rb
 - test/test_minitest_unit.rb
 - .gemtest
-has_rdoc: true
-homepage: http://rubyforge.org/projects/bfts
+homepage: https://github.com/seattlerb/minitest
 licenses: []
 
 post_install_message: 
@@ -157,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
 requirements: []
 
 rubyforge_project: bfts
-rubygems_version: 1.6.2
+rubygems_version: 1.8.10
 signing_key: 
 specification_version: 3
 summary: minitest provides a complete suite of testing facilities supporting TDD, BDD, mocking, and benchmarking
diff --git a/test/test_minitest_mock.rb b/test/test_minitest_mock.rb
index ddf44e6..b33057f 100644
--- a/test/test_minitest_mock.rb
+++ b/test/test_minitest_mock.rb
@@ -43,20 +43,34 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
     util_verify_bad
   end
 
-  def test_not_verify_if_unexpected_method_is_called
-    assert_raises NoMethodError do
-      @mock.unexpected
-    end
-  end
-
   def test_blow_up_on_wrong_number_of_arguments
     @mock.foo
     @mock.meaning_of_life
     @mock.expect(:sum, 3, [1, 2])
 
-    assert_raises ArgumentError do
+    e = assert_raises ArgumentError do
       @mock.sum
     end
+
+    assert_equal "mocked method :sum expects 2 arguments, got 0", e.message
+  end
+
+  def test_return_mock_does_not_raise
+    retval = MiniTest::Mock.new
+    mock = MiniTest::Mock.new
+    mock.expect(:foo, retval)
+    mock.foo
+
+    assert mock.verify
+  end
+
+  def test_mock_args_does_not_raise
+    arg = MiniTest::Mock.new
+    mock = MiniTest::Mock.new
+    mock.expect(:foo, nil, [arg])
+    mock.foo(arg)
+
+    assert mock.verify
   end
 
   def test_blow_up_on_wrong_arguments
@@ -71,22 +85,27 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
 
   def test_respond_appropriately
     assert @mock.respond_to?(:foo)
+    assert @mock.respond_to?('foo')
     assert !@mock.respond_to?(:bar)
   end
 
   def test_no_method_error_on_unexpected_methods
-    assert_raises NoMethodError do
+    e = assert_raises NoMethodError do
       @mock.bar
     end
+
+    expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]"
+
+    assert_equal expected, e.message
   end
 
   def test_assign_per_mock_return_values
     a = MiniTest::Mock.new
     b = MiniTest::Mock.new
-    
+
     a.expect(:foo, :a)
     b.expect(:foo, :b)
-    
+
     assert_equal :a, a.foo
     assert_equal :b, b.foo
   end
@@ -98,6 +117,30 @@ class TestMiniTestMock < MiniTest::Unit::TestCase
     assert !MiniTest::Mock.new.respond_to?(:foo)
   end
 
+  def test_mock_is_a_blank_slate
+    @mock.expect :kind_of?, true, [Fixnum]
+    @mock.expect :==, true, [1]
+
+    assert @mock.kind_of?(Fixnum), "didn't mock :kind_of\?"
+    assert @mock == 1, "didn't mock :=="
+  end
+
+  def test_verify_allows_called_args_to_be_loosely_specified
+    mock = MiniTest::Mock.new
+    mock.expect :loose_expectation, true, [Integer]
+    mock.loose_expectation 1
+
+    assert mock.verify
+  end
+
+  def test_verify_raises_with_strict_args
+    mock = MiniTest::Mock.new
+    mock.expect :strict_expectation, true, [2]
+    mock.strict_expectation 1
+
+    util_verify_bad
+  end
+
   def util_verify_bad
     assert_raises MockExpectationError do
       @mock.verify
diff --git a/test/test_minitest_spec.rb b/test/test_minitest_spec.rb
index 892e7b6..b9379d0 100755
--- a/test/test_minitest_spec.rb
+++ b/test/test_minitest_spec.rb
@@ -1,7 +1,10 @@
-require 'minitest/spec'
+require 'minitest/autorun'
 require 'stringio'
 
-MiniTest::Unit.autorun
+class MiniSpecA < MiniTest::Spec; end
+class MiniSpecB < MiniTest::Spec; end
+class ExampleA; end
+class ExampleB < ExampleA; end
 
 describe MiniTest::Spec do
   before do
@@ -86,11 +89,16 @@ describe MiniTest::Spec do
     proc { 42.must_be_nil }.must_raise MiniTest::Assertion
   end
 
-  it "needs to verify using any operator" do
+  it "needs to verify using any binary operator" do
     41.must_be(:<, 42).must_equal true
     proc { 42.must_be(:<, 41) }.must_raise MiniTest::Assertion
   end
 
+  it "needs to verify using any predicate" do
+    "".must_be(:empty?).must_equal true
+    proc { "blah".must_be(:empty?) }.must_raise MiniTest::Assertion
+  end
+
   it "needs to catch an expected exception" do
     @assertion_count = 2
 
@@ -147,6 +155,11 @@ describe MiniTest::Spec do
     proc { "blah".wont_match(/\w+/) }.must_raise MiniTest::Assertion
   end
 
+  it "needs to verify using any (negative) predicate" do
+    "blah".wont_be(:empty?).must_equal false
+    proc { "".wont_be(:empty?) }.must_raise MiniTest::Assertion
+  end
+
   it "needs to verify non-nil" do
     42.wont_be_nil.must_equal false
     proc { nil.wont_be_nil }.must_raise MiniTest::Assertion
@@ -196,6 +209,53 @@ describe MiniTest::Spec do
   end
 end
 
+describe MiniTest::Spec, :let do
+  i_suck_and_my_tests_are_order_dependent!
+
+  def _count
+    $let_count ||= 0
+  end
+
+  let :count do
+    $let_count += 1
+    $let_count
+  end
+
+  it "is evaluated once per example" do
+    _count.must_equal 0
+
+    count.must_equal 1
+    count.must_equal 1
+
+    _count.must_equal 1
+  end
+
+  it "is REALLY evaluated once per example" do
+    _count.must_equal 1
+
+    count.must_equal 2
+    count.must_equal 2
+
+    _count.must_equal 2
+  end
+end
+
+describe MiniTest::Spec, :subject do
+  attr_reader :subject_evaluation_count
+
+  subject do
+    @subject_evaluation_count ||= 0
+    @subject_evaluation_count  += 1
+    @subject_evaluation_count
+  end
+
+  it "is evaluated once per example" do
+    subject.must_equal 1
+    subject.must_equal 1
+    subject_evaluation_count.must_equal 1
+  end
+end
+
 class TestMeta < MiniTest::Unit::TestCase
   def test_setup
     srand 42
@@ -221,6 +281,9 @@ class TestMeta < MiniTest::Unit::TestCase
           before { before_list << 3 }
           after  { after_list  << 3 }
           it "inner-it" do end
+
+          it      {} # ignore me
+          specify {} # anonymous it
         end
       end
     end
@@ -228,6 +291,38 @@ class TestMeta < MiniTest::Unit::TestCase
     return x, y, z, before_list, after_list
   end
 
+  def test_register_spec_type
+    original_types = MiniTest::Spec::TYPES.dup
+
+    assert_equal [[//, MiniTest::Spec]], MiniTest::Spec::TYPES
+
+    MiniTest::Spec.register_spec_type(/woot/, TestMeta)
+
+    p = lambda do |x| true end
+    MiniTest::Spec.register_spec_type TestMeta, &p
+
+    keys = MiniTest::Spec::TYPES.map(&:first)
+
+    assert_includes keys, /woot/
+    assert_includes keys, p
+  ensure
+    MiniTest::Spec::TYPES.replace original_types
+  end
+
+  def test_spec_type
+    original_types = MiniTest::Spec::TYPES.dup
+
+    MiniTest::Spec.register_spec_type(/A$/, MiniSpecA)
+    MiniTest::Spec.register_spec_type MiniSpecB do |desc|
+      desc.superclass == ExampleA
+    end
+
+    assert_equal MiniSpecA, MiniTest::Spec.spec_type(ExampleA)
+    assert_equal MiniSpecB, MiniTest::Spec.spec_type(ExampleB)
+  ensure
+    MiniTest::Spec::TYPES.replace original_types
+  end
+
   def test_structure
     x, y, z, * = util_structure
 
@@ -239,20 +334,23 @@ class TestMeta < MiniTest::Unit::TestCase
     assert_equal "inner thingy", y.desc
     assert_equal "very inner thingy", z.desc
 
-    top_methods = %w(setup teardown test_0001_top_level_it)
-    inner_methods = %w(setup teardown test_0001_inner_it)
+    top_methods = %w(test_0001_top_level_it)
+    inner_methods1 = %w(test_0001_inner_it)
+    inner_methods2 = inner_methods1 +
+      %w(test_0002_anonymous test_0003_anonymous)
 
-    assert_equal top_methods,   x.instance_methods(false).sort.map {|o| o.to_s }
-    assert_equal inner_methods, y.instance_methods(false).sort.map {|o| o.to_s }
-    assert_equal inner_methods, z.instance_methods(false).sort.map {|o| o.to_s }
+    assert_equal top_methods,   x.instance_methods(false).sort.map(&:to_s)
+    assert_equal inner_methods1, y.instance_methods(false).sort.map(&:to_s)
+    assert_equal inner_methods2, z.instance_methods(false).sort.map(&:to_s)
   end
 
   def test_setup_teardown_behavior
     _, _, z, before_list, after_list = util_structure
 
     tc = z.new(nil)
-    tc.setup
-    tc.teardown
+
+    tc.run_setup_hooks
+    tc.run_teardown_hooks
 
     assert_equal [1, 2, 3], before_list
     assert_equal [3, 2, 1], after_list
diff --git a/test/test_minitest_unit.rb b/test/test_minitest_unit.rb
index ccab757..32a9767 100755
--- a/test/test_minitest_unit.rb
+++ b/test/test_minitest_unit.rb
@@ -6,6 +6,7 @@ MiniTest::Unit.autorun
 
 module MyModule; end
 class AnError < StandardError; include MyModule; end
+class ImmutableString < String; def inspect; super.freeze; end; end
 
 class TestMiniTestUnit < MiniTest::Unit::TestCase
   pwd = Pathname.new(File.expand_path(Dir.pwd))
@@ -40,12 +41,12 @@ Finished tests in 0.00
     MiniTest::Unit::TestCase.reset
     @tu = MiniTest::Unit.new
     @output = StringIO.new("")
+    MiniTest::Unit.runner = nil # protect the outer runner from the inner tests
     MiniTest::Unit.output = @output
   end
 
   def teardown
     MiniTest::Unit.output = $stdout
-    MiniTest::Unit.runner = nil
     Object.send :remove_const, :ATestCase if defined? ATestCase
   end
 
@@ -346,6 +347,36 @@ S.
 
 Finished tests in 0.00
 
+2 tests, 1 assertions, 0 failures, 0 errors, 1 skips
+"
+    assert_report expected
+  end
+
+  def test_run_skip_verbose
+    tc = Class.new(MiniTest::Unit::TestCase) do
+      def test_something
+        assert true
+      end
+
+      def test_skip
+        skip "not yet"
+      end
+    end
+
+    Object.const_set(:ATestCase, tc)
+
+    @tu.run %w[--seed 42 --verbose]
+
+    expected = "Run options: --seed 42 --verbose
+
+# Running tests:
+
+ATestCase#test_skip = 0.00 s = S
+ATestCase#test_something = 0.00 s = .
+
+
+Finished tests in 0.00
+
   1) Skipped:
 test_skip(ATestCase) [FILE:LINE]:
 not yet
@@ -406,6 +437,149 @@ Finished tests in 0.00
     assert_report expected
   end
 
+  def with_overridden_include
+    Class.class_eval do
+      def inherited_with_hacks klass
+        throw :inherited_hook
+      end
+
+      alias inherited_without_hacks inherited
+      alias inherited               inherited_with_hacks
+      alias IGNORE_ME!              inherited # 1.8 bug. god I love venture bros
+    end
+
+    yield
+
+  ensure
+    Class.class_eval do
+      alias inherited inherited_without_hacks
+
+      undef_method :inherited_with_hacks
+      undef_method :inherited_without_hacks
+    end
+
+    refute_respond_to Class, :inherited_with_hacks
+    refute_respond_to Class, :inherited_without_hacks
+  end
+
+  def test_inherited_hook_plays_nice_with_others
+    with_overridden_include do
+      assert_throws :inherited_hook do
+        Class.new MiniTest::Unit::TestCase
+      end
+    end
+  end
+
+  def test_setup_hooks
+    call_order = []
+
+    tc = Class.new(MiniTest::Unit::TestCase) do
+      define_method :setup do
+        super()
+        call_order << :method
+      end
+
+      define_method :test2 do
+        call_order << :test2
+      end
+
+      define_method :test1 do
+        call_order << :test1
+      end
+    end
+
+    tc.add_setup_hook lambda { call_order << :proc }
+
+    argument = nil
+
+    tc.add_setup_hook do |arg|
+      argument = arg
+      call_order << :block
+    end
+
+    @tu.run %w[--seed 42]
+
+    assert_kind_of tc, argument
+
+    expected = [:method, :proc, :block, :test1,
+                :method, :proc, :block, :test2]
+
+    assert_equal expected, call_order
+  end
+
+  def test_teardown_hooks
+    call_order = []
+
+    tc = Class.new(MiniTest::Unit::TestCase) do
+      define_method :teardown do
+        super()
+        call_order << :method
+      end
+
+      define_method :test2 do
+        call_order << :test2
+      end
+
+      define_method :test1 do
+        call_order << :test1
+      end
+    end
+
+    tc.add_teardown_hook lambda { call_order << :proc }
+
+    argument = nil
+
+    tc.add_teardown_hook do |arg|
+      argument = arg
+      call_order << :block
+    end
+
+    @tu.run %w[--seed 42]
+
+    assert_kind_of tc, argument
+
+    expected = [:test1, :block, :proc, :method,
+                :test2, :block, :proc, :method]
+
+    assert_equal expected, call_order
+  end
+
+  def test_setup_and_teardown_hooks_survive_inheritance
+    call_order = []
+
+    parent = Class.new(MiniTest::Unit::TestCase) do
+      define_method :setup do
+        super()
+        call_order << :setup_method
+      end
+
+      define_method :teardown do
+        super()
+        call_order << :teardown_method
+      end
+
+      define_method :test_something do
+        call_order << :test
+      end
+    end
+
+    parent.add_setup_hook     { call_order << :setup_hook }
+    parent.add_teardown_hook  { call_order << :teardown_hook }
+
+    _ = Class.new parent
+
+    parent.add_setup_hook     { call_order << :setup_after }
+    parent.add_teardown_hook  { call_order << :teardown_after }
+
+    @tu.run %w[--seed 42]
+
+    # Once for the parent class, once for the child
+    expected = [:setup_method, :setup_hook, :setup_after, :test,
+                :teardown_after, :teardown_hook, :teardown_method] * 2
+
+    assert_equal expected, call_order
+  end
+
   def util_expand_bt bt
     if RUBY_VERSION =~ /^1\.9/ then
       bt.map { |f| (f =~ /^\./) ? File.expand_path(f) : f }
@@ -480,12 +654,115 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
     @tc.assert_equal 1, 1
   end
 
-  def test_assert_equal_different
-    util_assert_triggered "Expected 1, not 2." do
+  def test_assert_equal_different_diff_deactivated
+    without_diff do
+      util_assert_triggered util_msg("haha" * 10, "blah" * 10) do
+        o1 = "haha" * 10
+        o2 = "blah" * 10
+
+        @tc.assert_equal o1, o2
+      end
+    end
+  end
+
+  def test_assert_equal_different_hex
+    c = Class.new do
+      def initialize s; @name = s; end
+    end
+
+    o1 = c.new "a"
+    o2 = c.new "b"
+    msg = "--- expected
+           +++ actual
+           @@ -1 +1 @@
+           -#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"a\">
+           +#<#<Class:0xXXXXXX>:0xXXXXXX @name=\"b\">
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_hex_invisible
+    o1 = Object.new
+    o2 = Object.new
+
+    msg = "No visible difference.
+           You should look at your implementation of Object#==.
+           #<Object:0xXXXXXX>".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long
+    msg = "--- expected
+           +++ actual
+           @@ -1 +1 @@
+           -\"hahahahahahahahahahahahahahahahahahahaha\"
+           +\"blahblahblahblahblahblahblahblahblahblah\"
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "haha" * 10
+      o2 = "blah" * 10
+
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long_invisible
+    msg = "No visible difference.
+           You should look at your implementation of String#==.
+           \"blahblahblahblahblahblahblahblahblahblah\"".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "blah" * 10
+      o2 = "blah" * 10
+      def o1.== o
+        false
+      end
+      @tc.assert_equal o1, o2
+    end
+  end
+
+  def test_assert_equal_different_long_msg
+    msg = "message.
+           --- expected
+           +++ actual
+           @@ -1 +1 @@
+           -\"hahahahahahahahahahahahahahahahahahahaha\"
+           +\"blahblahblahblahblahblahblahblahblahblah\"
+           ".gsub(/^ +/, "")
+
+    util_assert_triggered msg do
+      o1 = "haha" * 10
+      o2 = "blah" * 10
+      @tc.assert_equal o1, o2, "message"
+    end
+  end
+
+  def test_assert_equal_different_short
+    util_assert_triggered util_msg(1, 2) do
       @tc.assert_equal 1, 2
     end
   end
 
+  def test_assert_equal_different_short_msg
+    util_assert_triggered util_msg(1, 2, "message") do
+      @tc.assert_equal 1, 2, "message"
+    end
+  end
+
+  def test_assert_equal_different_short_multiline
+    msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n"
+    util_assert_triggered msg do
+      @tc.assert_equal "a\nb", "a\nc"
+    end
+  end
+
   def test_assert_in_delta
     @tc.assert_in_delta 0.0, 1.0 / 1000, 0.1
   end
@@ -600,6 +877,13 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
     @tc.assert_operator 2, :>, 1
   end
 
+  def test_assert_operator_bad_object
+    bad = Object.new
+    def bad.==(other) true end
+
+    @tc.assert_operator bad, :equal?, bad
+  end
+
   def test_assert_operator_triggered
     util_assert_triggered "Expected 2 to be < 1." do
       @tc.assert_operator 2, :<, 1
@@ -636,7 +920,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
   end
 
   def test_assert_output_triggered_both
-    util_assert_triggered "In stdout.\nExpected \"yay\", not \"boo\"." do
+    util_assert_triggered util_msg("yay", "boo", "In stdout") do
       @tc.assert_output "yay", "blah" do
         print "boo"
         $stderr.print "blah blah"
@@ -645,7 +929,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
   end
 
   def test_assert_output_triggered_err
-    util_assert_triggered "In stderr.\nExpected \"blah\", not \"blah blah\"." do
+    util_assert_triggered util_msg("blah", "blah blah", "In stderr") do
       @tc.assert_output nil, "blah" do
         $stderr.print "blah blah"
       end
@@ -653,7 +937,7 @@ class TestMiniTestUnitTestCase < MiniTest::Unit::TestCase
   end
 
   def test_assert_output_triggered_out
-    util_assert_triggered "In stdout.\nExpected \"blah\", not \"blah blah\"." do
+    util_assert_triggered util_msg("blah", "blah blah", "In stdout") do
       @tc.assert_output "blah" do
         print "blah blah"
       end
@@ -832,7 +1116,7 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
   def test_assert_silent_triggered_err
     @assertion_count = 2
 
-    util_assert_triggered "In stderr.\nExpected \"\", not \"blah blah\"." do
+    util_assert_triggered util_msg("", "blah blah", "In stderr") do
       @tc.assert_silent do
         $stderr.print "blah blah"
       end
@@ -840,7 +1124,7 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
   end
 
   def test_assert_silent_triggered_out
-    util_assert_triggered "In stdout.\nExpected \"\", not \"blah blah\"." do
+    util_assert_triggered util_msg("", "blah blah", "In stdout") do
       @tc.assert_silent do
         print "blah blah"
       end
@@ -945,6 +1229,11 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
     @tc.pass
   end
 
+  def test_prints
+    printer = Class.new { extend MiniTest::Assertions }
+    @tc.assert_equal '"test"', printer.mu_pp(ImmutableString.new 'test')
+  end
+
   def test_refute
     @assertion_count = 2
 
@@ -1076,6 +1365,13 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
     @tc.refute_operator 2, :<, 1
   end
 
+  def test_refute_operator_bad_object
+    bad = Object.new
+    def bad.==(other) true end
+
+    @tc.refute_operator true, :equal?, bad
+  end
+
   def test_refute_operator_triggered
     util_assert_triggered "Expected 2 to not be > 1." do
       @tc.refute_operator 2, :>, 1
@@ -1148,4 +1444,19 @@ FILE:LINE:in `test_assert_raises_triggered_subclass'
 
     assert_equal expected, msg
   end
+
+  def util_msg exp, act, msg = nil
+    s = "Expected: #{exp.inspect}\n  Actual: #{act.inspect}"
+    s = "#{msg}.\n#{s}" if msg
+    s
+  end
+
+  def without_diff
+    old_diff = MiniTest::Assertions.diff
+    MiniTest::Assertions.diff = nil
+
+    yield
+  ensure
+    MiniTest::Assertions.diff = old_diff
+  end
 end

-- 
ruby-minitest.git



More information about the Pkg-ruby-extras-commits mailing list