diff -r 09c4f575f627 -r cd1f3381c1ed specky/ruby/specky_formatter.rb --- a/specky/ruby/specky_formatter.rb Sat Dec 18 23:38:55 2010 -0800 +++ b/specky/ruby/specky_formatter.rb Fri Dec 24 20:01:10 2010 -0800 @@ -14,8 +14,11 @@ @indent_level = 0 @failure_index = 0 @failures = [] + @txt = '' + @summary = '' end + ######################################################################## ### R S P E C H O O K S ######################################################################## @@ -23,7 +26,6 @@ ### Example group hook -- increase indentation, emit description ### def example_group_started( example_group ) - output.puts self.out '+', '-' * (example_group.description.length + 2), '+' self.out '| ', example_group.description, ' |' self.out '+', '-' * (example_group.description.length + 2), '+' @@ -73,13 +75,18 @@ ### for Vim to fold. ### def dump_failures - self.out "\n\n\n" unless @failures.empty? + self.out "\n" unless @failures.empty? @failures.each_with_index do |example, index| desc = example.metadata[ :full_description ] exception = example.execution_result[ :exception ] + file = line = nil + if exception.backtrace.first =~ /(.*):(\d+)/ + file, line = $1, $2.to_i + end self.out "FAILURE - #%d)" % [ index + 1 ] + self.out "%s:%d" % [ file, line ] if RSpec::Core::PendingExampleFixedError === exception self.out "%s FIXED" % [ desc ] @@ -100,27 +107,55 @@ end end end - self.out "\n" + + self.out exception_source( file, line ) if file && line end end + ### Emit the source of the exception, with context lines. + ### + def exception_source( file, line ) + context = '' + low, high = line - 3, line + 3 + + File.open( file ).each_with_index do |cline, i| + cline.chomp!.rstrip! + next unless i >= low && i <= high + context << " %s%4d: %s\n" % [ ( i == line ? '>>' : ' |' ), i, cline ] + end + + return context + + rescue + 'Unable to parse exception context lines.' + end + + ### Emit summary data for all examples. ### def dump_summary( duration, example_count, failure_count, pending_count ) succeeded = example_count - failure_count - pending_count - self.out '+', '-' * 49, '+' - self.out '|', ' ' * 18, '-- Summary --', ' ' * 18, '|' - self.out '+----------+-----------+--------+---------+-------+' - self.out '| Duration | Succeeded | Failed | Pending | Total |' - self.out '+----------+-----------+--------+---------+-------+' + @summary << "+%s+\n" % [ '-' * 49 ] + @summary << "|%s-- Summary --%s|\n" % [ ' ' * 18, ' ' * 18 ] + @summary << "+----------+-----------+--------+---------+-------+\n" + @summary << "| Duration | Succeeded | Failed | Pending | Total |\n" + @summary << "+----------+-----------+--------+---------+-------+\n" - self.out "| %7ss | %9s | %6s | %7s | %5s |" % [ + @summary << "| %7ss | %9s | %6s | %7s | %5s |\n" % [ "%0.3f" % duration, succeeded, failure_count, pending_count, example_count ] - self.out '+----------+-----------+--------+---------+-------+' + @summary << "+----------+-----------+--------+---------+-------+\n\n" + end + + + ### End of run. Dump it all out! + ### + def close + output.puts @summary + output.puts @txt end @@ -132,7 +167,7 @@ ### def out( *msg ) msg = msg.join - output.puts "%s%s" % [ ' ' * @indent_level, msg ] + @txt << "%s%s\n" % [ ' ' * @indent_level, msg ] end ### Format the basic example information, along with the run duration.