123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Core::Formatters::ExceptionPresenter Private

Do not use. This class is for internal use only.
Relationships & Source Files
Namespace Children
Classes:
Inherits: Object
Defined in: rspec-core/lib/rspec/core/formatters/exception_presenter.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#backtrace_formatter (readonly, private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#description (readonly)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#detail_formatter (readonly, private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#example (readonly)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#exception (readonly)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#extra_detail_formatter (readonly, private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

#message_color (readonly, private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 12

attr_reader :exception, :example, :description, :message_color,
            :detail_formatter, :extra_detail_formatter, :backtrace_formatter

Instance Method Details

#add_shared_group_lines(lines, colorizer) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 231

def add_shared_group_lines(lines, colorizer)
  return lines if @skip_shared_group_trace

  example.[:shared_group_inclusion_backtrace].each do |frame|
    lines << colorizer.wrap(frame.description, RSpec.configuration.default_color)
  end

  lines
end

#colorized_formatted_backtrace(colorizer = ::RSpec::Core::Formatters::ConsoleCodes)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 83

def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
  formatted_backtrace.map do |backtrace_info|
    colorizer.wrap "# #{backtrace_info}", RSpec.configuration.detail_color
  end
end

#colorized_message_lines(colorizer = ::RSpec::Core::Formatters::ConsoleCodes)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 38

def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
  add_shared_group_lines(failure_lines, colorizer).map do |line|
    colorizer.wrap line, message_color
  end
end

#encoded_description(description) (private)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 297

def encoded_description(description)
  return if description.nil?
  encoded_string(description)
end

#encoded_string(string) (private)

See additional method definition at line 125.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 133

def encoded_string(string)
  RSpec::Support::EncodedString.new(string, Encoding.default_external)
end

#encoding_of(_string) (private)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 130

def encoding_of(string)
  string.encoding
end

#exception_backtrace (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 303

def exception_backtrace
  exception.backtrace || []
end

#exception_class_name(exception = @exception) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 155

def exception_class_name(exception=@exception)
  name = exception.class.name.to_s
  name = "(anonymous error class)" if name == ''
  name
end

#exception_lines (private)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 209

def exception_lines
  @exception_lines ||= begin
    lines = []
    lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/
    encoded_string(exception_message_string(exception)).split("\n").each do |line|
      lines << (line.empty? ? line : "  #{line}")
    end
    lines
  end
end

#exception_message_string(exception) (private)

See additional method definition at line 190.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 200

def exception_message_string(exception)
  case exception
  when SyntaxError then exception.detailed_message.to_s
  else
    exception.message.to_s
  end
rescue Exception => other
  "A #{exception.class} for which `exception.message.to_s` raises #{other.class}."
end

#extra_failure_lines (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 220

def extra_failure_lines
  @extra_failure_lines ||= begin
    lines = Array(example.[:extra_failure_lines])
    unless lines.empty?
      lines.unshift('') unless lines.first == ''
      lines.push('') unless lines.last == ''
    end
    lines
  end
end

#failure_lines (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 161

def failure_lines
  @failure_lines ||= [].tap do |lines|
    lines.concat(failure_slash_error_lines)

    sections = [failure_slash_error_lines, exception_lines]
    if sections.any? { |section| section.size > 1 } && !exception_lines.first.empty?
      lines << ''
    end

    lines.concat(exception_lines)
    lines.concat(extra_failure_lines)
  end
end

#failure_slash_error_lines (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 175

def failure_slash_error_lines
  lines = read_failed_lines
  if lines.count == 1
    lines[0] = "Failure/Error: #{lines[0].strip}"
  else
    least_indentation = SnippetExtractor.least_indentation_from(lines)
    lines = lines.map { |line| line.sub(/^#{least_indentation}/, '  ') }
    lines.unshift('Failure/Error:')
  end
  lines
end

#final_exception(exception, previous = []) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 109

def final_exception(exception, previous=[])
  cause = exception.cause

  if cause && Exception === cause && !previous.include?(cause)
    previous << cause
    final_exception(cause, previous)
  else
    exception
  end
end

#find_failed_line (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 267

def find_failed_line
  line_regex = RSpec.configuration.in_project_source_dir_regex
  loaded_spec_files = RSpec.configuration.loaded_spec_files

  exception_backtrace.reject! do |line|
    line.start_with?("<internal:")
  end

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

#formatted_backtrace(exception = @exception)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 44

def formatted_backtrace(exception=@exception)
  backtrace_formatter.format_backtrace(exception.backtrace, example.) +
    formatted_cause(exception)
end

#formatted_cause(_)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 77

def formatted_cause(exception)
  last_cause = final_exception(exception, [exception])
  cause = []

  if exception.cause
    cause << '------------------'
    cause << '--- Caused by: ---'
    cause << "#{exception_class_name(last_cause)}:" unless exception_class_name(last_cause) =~ /RSpec/

    encoded_string(exception_message_string(last_cause)).split("\n").each do |line|
      cause << "  #{line}"
    end

    unless last_cause.backtrace.nil? || last_cause.backtrace.empty?
      lines = backtrace_formatter.format_backtrace(last_cause.backtrace, example.)
      lines = [lines[0]] unless RSpec.configuration.full_cause_backtrace # rubocop:disable Metrics/BlockNesting

      lines.each do |line|
        cause << ("  #{line}")
      end
    end
  end

  cause
end

#formatted_message_and_backtrace(colorizer) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 282

def formatted_message_and_backtrace(colorizer)
  lines = colorized_message_lines(colorizer) + colorized_formatted_backtrace(colorizer)
  encoding = encoding_of("")
  lines.map do |line|
    RSpec::Support::EncodedString.new(line, encoding)
  end
end

#fully_formatted(failure_number, colorizer = ::RSpec::Core::Formatters::ConsoleCodes)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 89

def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
  lines = fully_formatted_lines(failure_number, colorizer)
  lines.join("\n") << "\n"
end

#fully_formatted_lines(failure_number, colorizer)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 94

def fully_formatted_lines(failure_number, colorizer)
  lines = [
    encoded_description(description),
    detail_formatter.call(example, colorizer),
    formatted_message_and_backtrace(colorizer),
    extra_detail_formatter.call(failure_number, colorizer),
  ].compact.flatten

  lines = indent_lines(lines, failure_number)
  lines.unshift("")
  lines
end

#indent_lines(lines, failure_number) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 139

def indent_lines(lines, failure_number)
  alignment_basis = ' ' * @indentation
  alignment_basis <<  "#{failure_number}) " if failure_number
  indentation = ' ' * alignment_basis.length

  lines.each_with_index.map do |line, index|
    if index == 0
      "#{alignment_basis}#{line}"
    elsif line.empty?
      line
    else
      "#{indentation}#{line}"
    end
  end
end

#message_lines

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 34

def message_lines
  add_shared_group_lines(failure_lines, Notifications::NullColorizer)
end

#read_failed_lines (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/formatters/exception_presenter.rb', line 241

def read_failed_lines
  matching_line = find_failed_line
  unless matching_line
    return ["Unable to find matching line from backtrace"]
  end

  file_and_line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)

  unless file_and_line_number
    return ["Unable to infer file and line number from backtrace"]
  end

  file_path, line_number = file_and_line_number[1..2]
  max_line_count = RSpec.configuration.max_displayed_failure_line_count
  lines = SnippetExtractor.extract_expression_lines_at(file_path, line_number.to_i, max_line_count)
  RSpec.world.syntax_highlighter.highlight(lines)
rescue SnippetExtractor::NoSuchFileError
  ["Unable to find #{file_path} to read failed line"]
rescue SnippetExtractor::NoSuchLineError
  ["Unable to find matching line in #{file_path}"]
rescue SecurityError
  # :nocov: - SecurityError is no longer produced starting in ruby 2.7
  ["Unable to read failed line"]
  # :nocov:
end