class RSpec::Core::Formatters::ExceptionPresenter

Constants

RESET_CODE

UPDATE: Copy from SyntaxHighlighter::CodeRayImplementation

Public Class Methods

new(exception, example, options={}) click to toggle source
# File lib/super_diff/rspec/monkey_patches.rb, line 89
def initialize(exception, example, options={})
  @exception               = exception
  @example                 = example
  @message_color           = options.fetch(:message_color)          { RSpec.configuration.failure_color }
  @description             = options.fetch(:description)            { example.full_description }
  @detail_formatter        = options.fetch(:detail_formatter)       { Proc.new {} }
  @extra_detail_formatter  = options.fetch(:extra_detail_formatter) { Proc.new {} }
  @backtrace_formatter     = options.fetch(:backtrace_formatter)    { RSpec.configuration.backtrace_formatter }
  @indentation             = options.fetch(:indentation, 2)
  @skip_shared_group_trace = options.fetch(:skip_shared_group_trace, false)
  # Patch to convert options[:failure_lines] to groups
  if options.include?(:failure_lines)
    @failure_line_groups = [
      {
        lines: options[:failure_lines],
        already_colorized: false
      }
    ]
  end
end

Public Instance Methods

add_shared_group_lines(lines, colorizer) click to toggle source
# File lib/super_diff/rspec/monkey_patches.rb, line 139
def add_shared_group_lines(lines, colorizer)
  return lines if @skip_shared_group_trace

  example.metadata[:shared_group_inclusion_backtrace].each do |frame|
    # Use red instead of the default color
    lines << colorizer.wrap(frame.description, :failure)
  end

  lines
end
colorized_message_lines(colorizer = ::RSpec::Core::Formatters::ConsoleCodes) click to toggle source

Override to only color uncolored lines in red and to not color empty lines

# File lib/super_diff/rspec/monkey_patches.rb, line 112
def colorized_message_lines(colorizer = ::RSpec::Core::Formatters::ConsoleCodes)
  lines = failure_line_groups.flat_map do |group|
    if group[:already_colorized]
      group[:lines]
    else
      group[:lines].map do |line|
        if line.strip.empty?
          line
        else
          indentation = line[/^[ ]+/]
          rest = colorizer.wrap(line.sub(/^[ ]+/, ''), message_color)

          if indentation
            indentation + rest
          else
            rest
          end
        end
      end
    end
  end

  add_shared_group_lines(lines, colorizer)
end
failure_line_groups() click to toggle source

Considering that `failure_slash_error_lines` is already colored, extract this from the other lines so that they, too, can be colored, later

TODO: Refactor this somehow

# File lib/super_diff/rspec/monkey_patches.rb, line 156
def failure_line_groups
  if defined?(@failure_line_groups)
    @failure_line_groups
  else
    @failure_line_groups = [
      {
        lines: failure_slash_error_lines,
        already_colorized: true
      }
    ]

    sections = [failure_slash_error_lines, exception_lines]
    separate_groups = (
      sections.any? { |section| section.size > 1 } &&
      !exception_lines.first.empty?
    )

    if separate_groups
      @failure_line_groups << { lines: [''], already_colorized: true }
    end

    already_colorized = exception_lines.any? do |line|
      SuperDiff::Csi.already_colorized?(line)
    end

    if already_colorized
      @failure_line_groups << {
        lines: exception_lines,
        already_colorized: true
      }
    else
      locatable_exception_lines =
        exception_lines.each_with_index.map do |line, index|
          { text: line, index: index }
        end

      boundary_line =
        locatable_exception_lines.find do |line, index|
          line[:text].strip.empty? || line[:text].match?(/^    /)
        end

      if boundary_line
        @failure_line_groups << {
          lines: exception_lines[0..boundary_line[:index] - 1],
          already_colorized: false
        }
        @failure_line_groups << {
          lines: exception_lines[boundary_line[:index]..-1],
          already_colorized: true
        }
      else
        @failure_line_groups << {
          lines: exception_lines,
          already_colorized: false
        }
      end
    end

    @failure_line_groups
  end
end
failure_slash_error_lines() click to toggle source

Style the first part in white and don't style the snippet of the line

# File lib/super_diff/rspec/monkey_patches.rb, line 219
def failure_slash_error_lines
  lines = read_failed_lines

  failure_slash_error = ConsoleCodes.wrap("Failure/Error: ", :bold)

  if lines.count == 1
    lines[0] = failure_slash_error + lines[0].strip
  else
    least_indentation = SnippetExtractor.least_indentation_from(lines)
    lines = lines.map do |line|
      line.sub(/^#{least_indentation}/, '  ')
    end
    lines.unshift(failure_slash_error)
  end

  lines
end
find_failed_line() click to toggle source

Exclude this file from being included in backtraces, so that the SnippetExtractor prints the right thing

# File lib/super_diff/rspec/monkey_patches.rb, line 239
def find_failed_line
  line_regex = RSpec.configuration.in_project_source_dir_regex
  loaded_spec_files = RSpec.configuration.loaded_spec_files

  exception_backtrace.find do |line|
    next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
    path = File.expand_path(line_path)
    path != __FILE__ && (loaded_spec_files.include?(path) || path =~ line_regex)
  end || exception_backtrace.first
end