class RSpec::Expectations::MultipleExpectationsNotMetError

‘aggregate_failures` is used.
not need to waste time defining that functionality unless
is lazily defined when `FailureAggregator` is autoloaded, since we do
@note The constant is defined here but the extensive logic of this class
Exception raised from `aggregate_failures` when multiple expectations fail.

def aggregation_block_label

Returns:
  • (String) - The user-assigned label for the aggregation block.
def aggregation_block_label
  @failure_aggregator.block_label
end

def aggregation_metadata

Returns:
  • (Hash) - The metadata hash passed to `aggregate_failures`.
def aggregation_metadata
  @failure_aggregator.metadata
end

def backtrace_line(line)

def backtrace_line(line)
  return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p }
  # It changes the current path that is relative to
  # system root to be relative to the project root.
  line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze)
end

def block_description

def block_description
  return "" unless aggregation_block_label
  " #{aggregation_block_label.inspect}"
end

def enumerated(exceptions, index_offset)

def enumerated(exceptions, index_offset)
  exceptions.each_with_index.map do |exception, index|
    index += index_offset
    formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}"
    "#{index_label index}#{indented formatted_message, index}"
  end
end

def enumerated_errors

def enumerated_errors
  enumerated(other_errors, failures.size) do |error|
    "#{error.class}: #{error.message}"
  end
end

def enumerated_failures

def enumerated_failures
  enumerated(failures, 0, &:message)
end

def exception_count_description

return [String] A description of the failure/error counts.
def exception_count_description
  failure_count = pluralize("failure", failures.size)
  return failure_count if other_errors.empty?
  error_count = pluralize("other error", other_errors.size)
  "#{failure_count} and #{error_count}"
end

def exclusion_patterns

def exclusion_patterns
  patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:]
  patterns << "org/jruby/" if RSpec::Support::Ruby.jruby?
  patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) }
end

def failures

Returns:
  • (Array) - The list of expectation failures.
def failures
  @failure_aggregator.failures
end

def format_backtrace(backtrace)

def format_backtrace(backtrace)
  backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? }
end

def indentation

def indentation
  @indentation ||= ' ' * longest_index_label_width
end

def indented(failure_message, index)

def indented(failure_message, index)
  line_1, *rest = failure_message.strip.lines.to_a
  first_line_indentation = ' ' * (longest_index_label_width - width_of_label(index))
  first_line_indentation + line_1 + rest.map do |line|
    line =~ /\S/ ? indentation + line : line
  end.join
end

def index_label(index)

def index_label(index)
  "  #{index + 1}) "
end

def initialize(failure_aggregator)

def initialize(failure_aggregator)
  @failure_aggregator = failure_aggregator
  @all_exceptions = failures + other_errors
end

def longest_index_label_width

def longest_index_label_width
  @longest_index_label_width ||= width_of_label(failures.size)
end

def message

Returns:
  • (String) - The fully formatted exception message.
def message
  @message ||= (["#{summary}:"] + enumerated_failures + enumerated_errors).join("\n\n")
end

def other_errors

Returns:
  • (Array) - The list of other exceptions.
def other_errors
  @failure_aggregator.other_errors
end

def pluralize(noun, count)

def pluralize(noun, count)
  "#{count} #{noun}#{'s' unless count == 1}"
end

def summary

Returns:
  • (String) - A summary of the failure, including the block label and a count of failures.
def summary
  "Got #{exception_count_description} from failure aggregation " \
  "block#{block_description}"
end

def width_of_label(index)

def width_of_label(index)
  index_label(index).chars.count
end