From fab126c8c19e2375cc6c4ef997bda08324e9c3e0 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sun, 29 Sep 2013 18:27:01 +0800 Subject: [PATCH] Introduce customizable error descriptions. The original one is the default, which is InlineErrorDescription. In the command line, use -i, or --inline. The second one would try to put the expected result and actual result with newlines, which is much easier to tell the difference with human eyes when the inspected string is quite long. For example, try to test a markdown formatter with a long text. In the command line, use -l, or --newline. The last one tries to put this further with external diff command. Which might not be as portable as the one in minitest, but could be already useful on most of the platforms other than Windows. In the command line, use -f, or --diff. Just try to be consistent with formatter argument, we also provide --error which you could specify Inline, Newline, or Diff, or even user provided error descriptors. However I failed to find a letter for this argument. I guess providing --error might be good enough. --- bin/bacon | 18 ++++++++++++++++++ lib/bacon.rb | 42 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/bin/bacon b/bin/bacon index bff060a..82bc39d 100755 --- a/bin/bacon +++ b/bin/bacon @@ -7,6 +7,7 @@ module Bacon; end automatic = false output = 'SpecDoxOutput' +error = 'InlineErrorDescription' options = OptionParser.new("", 24, ' ') { |opts| opts.banner = "Usage: bacon [options] [files | -a] [-- untouched arguments]" @@ -57,6 +58,22 @@ options = OptionParser.new("", 24, ' ') { |opts| "do FORMAT (SpecDox/TestUnit/Tap) output") { |format| output = format + "Output" } + + opts.on("-i", "--inline", "show errors inlined (default)") { + error = 'InlineErrorDescription' + } + opts.on("-l", "--newline", "show errors with newlines") { + error = 'NewlineErrorDescription' + } + opts.on("-f", "--diff", "show errors with diff command") { + error = 'DiffErrorDescription' + } + + opts.on("--error DESCRIPTOR", + "show errors with DESCRIPTOR (Inline/Newline/Diff)") { |descriptor| + error = descriptor + "ErrorDescription" + } + opts.on("-Q", "--no-backtrace", "don't print backtraces") { Bacon.const_set :Backtraces, false } @@ -110,6 +127,7 @@ end require 'bacon' Bacon.extend Bacon.const_get(output) rescue abort "No such formatter: #{output}" +Bacon.extend Bacon.const_get(error) rescue abort "No such error descriptor: #{error}" Bacon.summary_on_exit files.each { |file| diff --git a/lib/bacon.rb b/lib/bacon.rb index 771c6d6..d061eff 100644 --- a/lib/bacon.rb +++ b/lib/bacon.rb @@ -121,6 +121,42 @@ def handle_summary; end extend SpecDoxOutput # default + module InlineErrorDescription + def handle_error_description negated, object, name, args + desc = negated ? "not " : "" + desc << object.inspect << "." << name + desc << "(" << args.map{|x|x.inspect}.join(", ") << ") failed" + end + end + + module NewlineErrorDescription + def handle_error_description negated, object, name, args + desc = negated ? "not " : "" + desc << "\n#{object.inspect}\n.#{name}(\n" + desc << args.map{|x|x.inspect}.join(",\n") << "\n) failed" + end + end + + module DiffErrorDescription + def handle_error_description negated, object, name, args + require 'tempfile' + desc = negated ? "not " : "" + Tempfile.open('expect') do |expect| + Tempfile.open('was') do |was| + expect.puts(object.to_s) + expect.close + was.puts(args.map{|x|x.to_s}.join(",\n")) + was.close + desc << "#{object.class}##{name}(\n" + desc << `diff #{expect.path} #{was.path}` + end + end + desc << ") failed" + end + end + + extend InlineErrorDescription # default + class Error < RuntimeError attr_accessor :count_as @@ -334,11 +370,7 @@ def satisfy(description="", &block) def method_missing(name, *args, &block) name = "#{name}?" if name.to_s =~ /\w[^?]\z/ - - desc = @negated ? "not " : "" - desc << @object.inspect << "." << name.to_s - desc << "(" << args.map{|x|x.inspect}.join(", ") << ") failed" - + desc = Bacon.handle_error_description(@negated, @object, name.to_s, args) satisfy(desc) { |x| x.__send__(name, *args, &block) } end