]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/gems/rspec-1.1.2/lib/spec/runner/formatter/snippet_extractor.rb
added RSpec and RSpec on Rails
[rails.git] / vendor / gems / rspec-1.1.2 / lib / spec / runner / formatter / snippet_extractor.rb
diff --git a/vendor/gems/rspec-1.1.2/lib/spec/runner/formatter/snippet_extractor.rb b/vendor/gems/rspec-1.1.2/lib/spec/runner/formatter/snippet_extractor.rb
new file mode 100644 (file)
index 0000000..41119fe
--- /dev/null
@@ -0,0 +1,52 @@
+module Spec
+  module Runner
+    module Formatter
+      # 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 'rubygems'; 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