class RSpec::Expectations::MultipleExpectationsNotMetError
Exception raised from ‘aggregate_failures` when multiple expectations fail.
@note The constant is defined here but the extensive logic of this class
is lazily defined when `FailureAggregator` is autoloaded, since we do not need to waste time defining that functionality unless `aggregate_failures` is used.
Exception raised from ‘aggregate_failures` when multiple expectations fail.
Attributes
@return [Array<Exception>] The list of expectation failures and other exceptions, combined.
Public Class Methods
# File lib/rspec/expectations/failure_aggregator.rb, line 136 def initialize(failure_aggregator) @failure_aggregator = failure_aggregator @all_exceptions = failures + other_errors end
Public Instance Methods
@return [String] The user-assigned label for the aggregation block.
# File lib/rspec/expectations/failure_aggregator.rb, line 111 def aggregation_block_label @failure_aggregator.block_label end
@return [Hash] The metadata hash passed to ‘aggregate_failures`.
# File lib/rspec/expectations/failure_aggregator.rb, line 116 def aggregation_metadata @failure_aggregator.metadata end
return [String] A description of the failure/error counts.
# File lib/rspec/expectations/failure_aggregator.rb, line 127 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
@return [Array<RSpec::Expectations::ExpectationNotMetError>] The list of expectation failures.
# File lib/rspec/expectations/failure_aggregator.rb, line 98 def failures @failure_aggregator.failures end
@return [String] The fully formatted exception message.
# File lib/rspec/expectations/failure_aggregator.rb, line 93 def message @message ||= (["#{summary}:"] + enumerated_failures + enumerated_errors).join("\n\n") end
@return [Array<Exception>] The list of other exceptions.
# File lib/rspec/expectations/failure_aggregator.rb, line 103 def other_errors @failure_aggregator.other_errors end
@return [String] A summary of the failure, including the block label and a count of failures.
# File lib/rspec/expectations/failure_aggregator.rb, line 121 def summary "Got #{exception_count_description} from failure aggregation " \ "block#{block_description}" end
Private Instance Methods
# File lib/rspec/expectations/failure_aggregator.rb, line 168 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
# File lib/rspec/expectations/failure_aggregator.rb, line 141 def block_description return "" unless aggregation_block_label " #{aggregation_block_label.inspect}" end
# File lib/rspec/expectations/failure_aggregator.rb, line 150 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
# File lib/rspec/expectations/failure_aggregator.rb, line 180 def enumerated_errors enumerated(other_errors, failures.size) do |error| "#{error.class}: #{error.message}" end end
# File lib/rspec/expectations/failure_aggregator.rb, line 176 def enumerated_failures enumerated(failures, 0, &:message) end
# File lib/rspec/expectations/failure_aggregator.rb, line 158 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
# File lib/rspec/expectations/failure_aggregator.rb, line 164 def format_backtrace(backtrace) backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? } end
# File lib/rspec/expectations/failure_aggregator.rb, line 195 def indentation @indentation ||= ' ' * longest_index_label_width end
# File lib/rspec/expectations/failure_aggregator.rb, line 186 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
# File lib/rspec/expectations/failure_aggregator.rb, line 207 def index_label(index) " #{index + 1}) " end
# File lib/rspec/expectations/failure_aggregator.rb, line 199 def longest_index_label_width @longest_index_label_width ||= width_of_label(failures.size) end
# File lib/rspec/expectations/failure_aggregator.rb, line 146 def pluralize(noun, count) "#{count} #{noun}#{'s' unless count == 1}" end
# File lib/rspec/expectations/failure_aggregator.rb, line 203 def width_of_label(index) index_label(index).chars.count end