Hi,

The output format of miniunit changed dramatically from one of Test::Unit.
I think that compatibility must be more respected because Test::Unit is not
deprecated but removed and because we don't have the time to discuss change
of the behavior/specification.
In addition, I believe that the old format is easy to see in many aspects.


So I insist:

(1) miniunit should use pretty_inspect.  Currently, long message that
    spreads to multiple lines is never human-readable.  If you mind speed,
    I think it's a good solution to provide a command-line option that
    disables use of pretty_print.  At least, it should provide a option
    that enables pretty_inspect.

(2) An expected and actual values should be put in angle brackets, like
    <"foo">.  This is very helpful to distinguish values and template
    messages by a glance.

(3) An expected and actual values should be put at head of line.  This also
    improves visibility much.


Thank you for consideration,


Here is an instant patch (I didn't test enough):

Index: lib/mini/test.rb
===================================================================
--- lib/mini/test.rb	(revision 19552)
+++ lib/mini/test.rb	(working copy)
@@ -43,11 +43,28 @@

   module Assertions
     def mu_pp(obj)
-      s = obj.inspect
+      if Assertions.use_pp
+        begin
+          require 'pp'
+        rescue LoadError
+          Assertions.use_pp = false
+        end
+        s = obj.pretty_inspect.chomp
+      else
+        s = obj.inspect
+      end
       s = s.force_encoding(Encoding.default_external) if defined? Encoding
       s
     end

+    def Assertions.use_pp=(f)
+      @use_pp = f
+    end
+
+    def Assertions.use_pp
+      @use_pp
+    end
+
     def _assertions= n
       @_assertions = n
     end
@@ -57,7 +74,7 @@
     end

     def assert test, msg = nil
-      msg ||= "Failed assertion, no message given."
+      msg ||= "failed assertion, no message given."
       self._assertions += 1
       unless test then
         msg = msg.call if Proc === msg
@@ -67,24 +84,24 @@
     end

     def assert_block msg = nil
-      msg = message(msg) { "Expected block to return true value" }
+      msg = message(msg) { "block expected to return true value" }
       assert yield, msg
     end

     def assert_empty obj, msg = nil
-      msg = message(msg) { "Expected #{obj.inspect} to be empty" }
+      msg = message(msg) { "empty expected but was\n<#{mu_pp(obj)}>" }
       assert_respond_to obj, :empty?
       assert obj.empty?, msg
     end

     def assert_equal exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(exp)}, not #{mu_pp(act)}" }
+      msg = message(msg) { "<#{mu_pp(exp)}> expected but
was\n<#{mu_pp(act)}>" }
       assert(exp == act, msg)
     end

     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}" }
+      msg = message(msg) { "<#{exp}> and\n<#{act}> expected to be
within\n<#{delta}> of each other" }
       assert delta > n, msg
     end

@@ -93,39 +110,39 @@
     end

     def assert_includes collection, obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(collection)} to include
#{mu_pp(obj)}" }
+      msg = message(msg) { "<#{mu_pp(collection)}> expected to
include\n<#{mu_pp(obj)}>" }
       assert_respond_to collection, :include?
       assert collection.include?(obj), msg
     end

     def assert_instance_of cls, obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to be an instance
of #{cls}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> expected to be an
instance of\n<#{cls}> but was\n<#{obj.class}>" }
       flip = (Module === obj) && ! (Module === cls) # HACK for specs
       obj, cls = cls, obj if flip
       assert cls === obj, msg
     end

     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}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> expected to be
kind_of?\n<#{cls}> but was\n<#{obj.class}>" }
       flip = (Module === obj) && ! (Module === cls) # HACK for specs
       obj, cls = cls, obj if flip
       assert obj.kind_of?(cls), msg
     end

     def assert_match exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(act)} to match #{mu_pp(exp)}" }
+      msg = message(msg) { "<#{mu_pp(act)}> expected to be
=~\n<#{mu_pp(exp)}>" }
       assert_respond_to act, :=~
       exp = /#{exp}/ if String === exp && String === act
       assert act =~ exp, msg
     end

     def assert_nil obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" }
+      msg = message(msg) {"<#{mu_pp(obj)}> expected to be nil" }
       assert obj.nil?, msg
     end

     def assert_operator o1, op, o2, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" }
+      msg = message(msg) { "<#{mu_pp(o1)}> expected to
be\n#{op}\n<#{mu_pp(o2)}>" }
       assert o1.__send__(op, o2), msg
     end

@@ -136,43 +153,42 @@
         yield
         should_raise = true
       rescue Exception => e
-        assert_includes exp, e.class
-        exception_details(e, "<#{mu_pp(exp)}> exception expected, not")
+        assert_includes exp, e.class, exception_details(e,
"<#{mu_pp(exp)}> exception expected but was\n")
         return e
       end

       exp = exp.first if exp.size == 1
-      fail "#{mu_pp(exp)} expected but nothing was raised." if should_raise
+      fail "<#{mu_pp(exp)}> exception expected but nothing was
raised." if should_raise
     end

     def assert_respond_to obj, meth, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to respond to #{meth}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> of type <#{obj.class}>
expected to respond_to?<#{meth}>" }
       flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
       obj, meth = meth, obj if flip
       assert obj.respond_to?(meth), msg
     end

     def assert_same exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(act)} to be the same as
#{mu_pp(exp)}" }
+      msg = message(msg) { "<#{mu_pp(exp)}> with id
<#{exp.object_id}> expected to be equal? to\n<#{mu_pp(act)}> with id
<#{act.object_id}>" }
       assert exp.equal?(act), msg
     end

     def assert_send send_ary, msg = nil
-      recv, msg, *args = send_ary
-      msg = message(msg) { "Expected ##{msg} on #{mu_pp(recv)} to
return true" }
-      assert recv.__send__(msg, *args), msg
+      recv, meth, *args = send_ary
+      msg = message(msg) { "#{mu_pp(recv)} expected to respond
to\n<#{meth}(#{mu_pp(args)})> with a true value" }
+      assert recv.__send__(meth, *args), msg
     end

     def assert_throws sym, msg = nil
-      default = "Expected #{mu_pp(sym)} to have been thrown"
+      default = "<#{mu_pp(sym)}> should have been thrown"
       caught = true
       catch(sym) do
         begin
           yield
         rescue ArgumentError => e     # 1.9 exception
-          default += ", not #{e.message.split(/ /).last}"
+          default += " but\n<#{e.message.split(/ /).last}> was thrown"
         rescue NameError => e         # 1.8 exception
-          default += ", not #{e.name.inspect}"
+          default += " but\n<#{e.name.inspect}> was thrown"
         end
         caught = false
       end
@@ -225,24 +241,25 @@
     end

     def refute test, msg = nil
-      msg ||= "Failed refutation, no message given"
+      msg ||= "failed refutation, no message given"
       not assert(! test, msg)
     end

     def refute_empty obj, msg = nil
-      msg = message(msg) { "Expected #{obj.inspect} to not be empty" }
+      msg = message(msg) { "empty not expected but was\n#{obj.inspect}" }
       assert_respond_to obj, :empty?
       refute obj.empty?, msg
     end

     def refute_equal exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(act)} to not be equal to
#{mu_pp(exp)}" }
+      msg = message(msg) { "<#{mu_pp(exp)}> not expected but
was\n<#{mu_pp(act)}>"  }
       refute exp == act, msg
     end

     def refute_in_delta exp, act, delta = 0.001, msg = nil
       n = (exp - act).abs
-      msg = message(msg) { "Expected #{exp} - #{act} (#{n}) to not be
< #{delta}" }
+      msg = message(msg) { "<#{exp}> and\n<#{act}> not expected to be
within\n<#{del
+      ta}> of each other" }
       refute delta > n, msg
     end

@@ -251,49 +268,49 @@
     end

     def refute_includes collection, obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(collection)} to not
include #{mu_pp(obj)}" }
+      msg = message(msg) { "<#{mu_pp(collection)}> not expected to
include\n<#{mu_pp(obj)}>" }
       assert_respond_to collection, :include?
       refute collection.include?(obj), msg
     end

     def refute_instance_of cls, obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to not be an
instance of #{cls}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> not expected to be an
instance of\n<#{cls}> but was\n<#{obj.class}>" }
       flip = (Module === obj) && ! (Module === cls) # HACK for specs
       obj, cls = cls, obj if flip
       refute cls === obj, msg
     end

     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}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> not expected to be
kind_of?\n<#{cls}> but was\n<#{obj.class}>" }
       flip = (Module === obj) && ! (Module === cls) # HACK for specs
       obj, cls = cls, obj if flip
       refute obj.kind_of?(cls), msg
     end

     def refute_match exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(act)} to not match
#{mu_pp(exp)}" }
+      msg = message(msg) { "<#{mu_pp(act)}> not expected to be
=~\n<#{mu_pp(exp)}>" }
       refute act =~ exp, msg
     end

     def refute_nil obj, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" }
+      msg = message(msg) {"<#{mu_pp(obj)}> not expected to be nil" }
       refute obj.nil?, msg
     end

     def refute_operator o1, op, o2, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}
#{mu_pp(o2)}" }
+      msg = message(msg) { "<#{mu_pp(o1)}> not expected to
be\n#{op}\n<#{mu_pp(o2)}>" }
       refute o1.__send__(op, o2), msg
     end

     def refute_respond_to obj, meth, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" }
+      msg = message(msg) { "<#{mu_pp(obj)}> of type <#{obj.class}>
not expected to respond_to?<#{meth}>" }
       flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs
       obj, meth = meth, obj if flip
       refute obj.respond_to?(meth), msg
     end

     def refute_same exp, act, msg = nil
-      msg = message(msg) { "Expected #{mu_pp(act)} to not be the same
as #{mu_pp(exp)}" }
+      msg = message(msg) { "<#{mu_pp(exp)}> with id
<#{exp.object_id}> not expected to be equal? to\n<#{mu_pp(act)}> with
id <#{act.object_id}>" }
       refute exp.equal?(act), msg
     end
   end
@@ -347,6 +364,7 @@

     def run args
       @verbose = args.delete('-v')
+      Assertions.use_pp = true if args.delete('-pp')

       filter = if args.first =~ /^(-n|--name)$/ then
                  args.shift

-- 
Yusuke ENDOH <mame / tsg.ne.jp>