Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add snippet extractor

  • Loading branch information...
commit 9e5ab97044777c2ad5f01d113fd3026cd30add8d 1 parent bc80307
@dchelimsky dchelimsky authored
View
18 lib/rspec/core/formatters/html_formatter.rb
@@ -56,6 +56,7 @@ def start_dump(duration)
end
def example_started(example)
+ super
@example_number += 1
end
@@ -68,7 +69,7 @@ def example_passed(example)
def example_failed(example)
counter = 0
exception = example.metadata[:execution_result][:exception_encountered]
- # extra = extra_failure_content(failure)
+ extra = extra_failure_content(exception)
failure_style = 'failed'
failure_style = RSpec::Core::PendingExampleFixedError === exception ? 'pending_fixed' : 'failed'
@output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red
@@ -80,8 +81,8 @@ def example_failed(example)
@output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>"
@output.puts " <div class=\"failure\" id=\"failure_#{counter}\">"
@output.puts " <div class=\"message\"><pre>#{h(exception.message)}</pre></div>" unless exception.nil?
- @output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(exception.backtrace, example)}</pre></div>" if exception
- # @output.puts extra unless extra == ""
+ @output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(exception.backtrace, example).join("\n")}</pre></div>" if exception
+ @output.puts extra unless extra == ""
@output.puts " </div>"
@output.puts " </dd>"
@output.flush
@@ -99,10 +100,10 @@ def example_pending(example)
# Override this method if you wish to output extra HTML for a failed spec. For example, you
# could output links to images or other files produced during the specs.
#
- def extra_failure_content(failure)
- require 'spec/runner/formatter/snippet_extractor'
+ def extra_failure_content(exception)
+ require 'rspec/core/formatters/snippet_extractor'
@snippet_extractor ||= SnippetExtractor.new
- " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(failure.exception)}</code></pre>"
+ " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(exception)}</code></pre>"
end
def move_progress
@@ -118,7 +119,10 @@ def percent_done
result
end
- def dump_failure(counter, failure)
+ def dump_failures
+ end
+
+ def dump_pending
end
def dump_summary
View
52 lib/rspec/core/formatters/snippet_extractor.rb
@@ -0,0 +1,52 @@
+module RSpec
+ module Core
+ module Formatters
+ # This class extracts code snippets by looking at the backtrace of the passed error
+ class SnippetExtractor #:nodoc:
+ class NullConverter; def convert(code, pre); code; end; end #:nodoc:
+ begin; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
+
+ def snippet(error)
+ raw_code, line = snippet_for(error.backtrace[0])
+ highlighted = @@converter.convert(raw_code, false)
+ highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
+ post_process(highlighted, line)
+ end
+
+ def snippet_for(error_line)
+ if error_line =~ /(.*):(\d+)/
+ file = $1
+ line = $2.to_i
+ [lines_around(file, line), line]
+ else
+ ["# Couldn't get snippet for #{error_line}", 1]
+ end
+ end
+
+ def lines_around(file, line)
+ if File.file?(file)
+ lines = File.open(file).read.split("\n")
+ min = [0, line-3].max
+ max = [line+1, lines.length-1].min
+ selected_lines = []
+ selected_lines.join("\n")
+ lines[min..max].join("\n")
+ else
+ "# Couldn't get snippet for #{file}"
+ end
+ end
+
+ def post_process(highlighted, offending_line)
+ new_lines = []
+ highlighted.split("\n").each_with_index do |line, i|
+ new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
+ new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
+ new_lines << new_line
+ end
+ new_lines.join("\n")
+ end
+
+ end
+ end
+ end
+end

0 comments on commit 9e5ab97

Please sign in to comment.
Something went wrong with that request. Please try again.