]> git.openstreetmap.org Git - rails.git/blob - vendor/gems/rspec-1.1.2/lib/spec/runner/formatter/snippet_extractor.rb
Show whether a trace is public or private in the trace list, so that a user can easil...
[rails.git] / vendor / gems / rspec-1.1.2 / lib / spec / runner / formatter / snippet_extractor.rb
1 module Spec
2   module Runner
3     module Formatter
4       # This class extracts code snippets by looking at the backtrace of the passed error
5       class SnippetExtractor #:nodoc:
6         class NullConverter; def convert(code, pre); code; end; end #:nodoc:
7         begin; require 'rubygems'; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
8         
9         def snippet(error)
10           raw_code, line = snippet_for(error.backtrace[0])
11           highlighted = @@converter.convert(raw_code, false)
12           highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
13           post_process(highlighted, line)
14         end
15         
16         def snippet_for(error_line)
17           if error_line =~ /(.*):(\d+)/
18             file = $1
19             line = $2.to_i
20             [lines_around(file, line), line]
21           else
22             ["# Couldn't get snippet for #{error_line}", 1]
23           end
24         end
25         
26         def lines_around(file, line)
27           if File.file?(file)
28             lines = File.open(file).read.split("\n")
29             min = [0, line-3].max
30             max = [line+1, lines.length-1].min
31             selected_lines = []
32             selected_lines.join("\n")
33             lines[min..max].join("\n")
34           else
35             "# Couldn't get snippet for #{file}"
36           end
37         end
38         
39         def post_process(highlighted, offending_line)
40           new_lines = []
41           highlighted.split("\n").each_with_index do |line, i|
42             new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
43             new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
44             new_lines << new_line
45           end
46           new_lines.join("\n")
47         end
48         
49       end
50     end
51   end
52 end