diff -r bf8f3c788cad -r 763cef799c74 specky/ruby/specky_formatter.rb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/specky/ruby/specky_formatter.rb Sat Dec 18 00:56:09 2010 -0800 @@ -0,0 +1,147 @@ + +require 'rspec/core/formatters/base_text_formatter' + +### SpeckyFormatter: A basic RSpec 2.x text formatter, to be used +### with the 'Specky' vim plugin (or from the command line, if you +### dig it over the default 'documentation' format!) +### +### rspec -r /path/to/this/specky_formatter.rb -f SpeckyFormatter specs +### +class SpeckyFormatter < RSpec::Core::Formatters::BaseTextFormatter + + def initialize( *args ) + super + @indent_level = 0 + @failure_index = 0 + @failures = [] + end + + ######################################################################## + ### R S P E C H O O K S + ######################################################################## + + ### 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), '+' + @indent_level += 1 + end + + + ### Example group hook -- decrease indentation + ### + def example_group_finished( example_group ) + @indent_level -= 1 + end + + + ### Called on example success + ### + def example_passed( example ) + msg = self.format_example( example ) + msg << ')' + self.out msg + end + + + ### Called on a pending example + ### + def example_pending( example ) + msg = self.format_example( example ) + pending_msg = example.metadata[ :execution_result ][ :pending_message ] + msg << ", PENDING%s)" % [ ": #{pending_msg}" || '' ] + self.out msg + end + + + ### Called on example failure + ### + def example_failed( example ) + @failure_index += 1 + msg = self.format_example( example ) + msg << ", FAILED - #%d)" % [ @failure_index ] + self.out msg + + @failures << example + end + + + ### Called after all examples are run. Emit details for each failed example, + ### for Vim to fold. + ### + def dump_failures + self.out "\n\n\n" unless @failures.empty? + + @failures.each_with_index do |example, index| + desc = example.metadata[ :full_description ] + exception = example.execution_result[ :exception ] + + self.out "FAILURE - #%d)" % [ index + 1 ] + + if RSpec::Core::PendingExampleFixedError === exception + self.out "%s FIXED" % [ desc ] + self.out "Expected pending '%s' to fail. No error was raised." % [ + example.metadata[ :execution_result ][ :pending_message ] + ] + else + self.out desc + self.out "Failure/Error: %s" % [ read_failed_line( exception, example).strip ] + exception.message.split("\n").each {|l| self.out l} + + # logic taken from the base class + example.example_group.ancestors.push(example.example_group).each do |group| + if group.metadata[:shared_group_name] + self.out "Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " + + "#{backtrace_line(group.metadata[:example_group][:location])}" + break + end + end + end + self.out "\n" + end + 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 '+----------+-----------+--------+---------+-------+' + + self.out "| %7ss | %9s | %6s | %7s | %5s |" % [ + "%0.3f" % duration, succeeded, failure_count, + pending_count, example_count + ] + + self.out '+----------+-----------+--------+---------+-------+' + end + + + ######### + protected + ######### + + ### Send a string to the output IO object, after indentation. + ### + def out( *msg ) + msg = msg.join + output.puts "%s%s" % [ ' ' * @indent_level, msg ] + end + + ### Format the basic example information, along with the run duration. + ### + def format_example( example ) + metadata = example.metadata + duration = metadata[ :execution_result ][ :run_time ] + description = metadata[ :description ] + return "| %s (%0.3fs" % [ description, duration ] + end +end # SpeckyFormatter +