Class: RSpec::Core::Formatters::SnippetExtractor Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec/legacy_formatters/snippet_extractor.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Extracts code snippets by looking at the backtrace of the passed error and applies synax highlighting and line numbers using html.

Defined Under Namespace

Modules: LegacyNullConverter

Instance Method Summary collapse

Constructor Details

#initialize(source = nil, beginning_line_number = nil, max_line_count = nil) ⇒ SnippetExtractor

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copied from the 3.4 version, but with default overrides to cope with our usage



32
33
34
35
36
# File 'lib/rspec/legacy_formatters/snippet_extractor.rb', line 32

def initialize(source=nil, beginning_line_number=nil, max_line_count=nil)
  @source = source
  @beginning_line_number = beginning_line_number
  @max_line_count = max_line_count
end

Instance Method Details

#lines_around(file, line) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Extract lines of code centered around a particular line within a source file.

Parameters:

  • file (String)

    filename

  • line (Fixnum)

    line number

Returns:

  • (String)

    lines around the target line within the file (2 above and 1 below).



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rspec/legacy_formatters/snippet_extractor.rb', line 80

def lines_around(file, line)
  if File.file?(file)
    lines = File.read(file).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
rescue SecurityError
  "# Couldn't get snippet for #{file}"
end

#post_process(highlighted, offending_line) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Adds line numbers to all lines and highlights the line where the failure occurred using html span tags.

Parameters:

  • highlighted (String)

    syntax-highlighted snippet surrounding the offending line of code

  • offending_line (Fixnum)

    line where failure occured

Returns:

  • (String)

    completed snippet



102
103
104
105
106
107
108
109
110
# File 'lib/rspec/legacy_formatters/snippet_extractor.rb', line 102

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

#snippet(backtrace) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Extract lines of code corresponding to a backtrace.

Parameters:

  • backtrace (String)

    the backtrace from a test failure

Returns:

  • (String)

    highlighted code snippet indicating where the test failure occured

See Also:



46
47
48
49
50
51
52
53
# File 'lib/rspec/legacy_formatters/snippet_extractor.rb', line 46

def snippet(backtrace)
  raw_code, line = snippet_for(backtrace[0])
  highlighted = @@converter.convert(raw_code)
  if LegacyNullConverter == @@converter || (defined?(NullConverter) && @@converter.is_a?(NullConverter))
    highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>"
  end
  post_process(highlighted, line)
end

#snippet_for(error_line) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a snippet from a line of code.

Parameters:

  • error_line (String)

    file name with line number (i.e. 'foo_spec.rb:12')

Returns:

  • (String)

    lines around the target line within the file

See Also:



63
64
65
66
67
68
69
70
71
# File 'lib/rspec/legacy_formatters/snippet_extractor.rb', line 63

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