class RSpec::Matchers::BuiltIn::ContainExactly
rubocop:disable Metrics/ClassLength @api private Provides the implementation for ‘contain_exactly` and `match_array`. Not intended to be instantiated directly.
Public Instance Methods
description()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 29 def description list = EnglishPhrasing.list(surface_descriptions_in(expected)) "contain exactly#{list}" end
failure_message()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 11 def failure_message if Array === actual generate_failure_message else "expected a collection that can be converted to an array with " \ "`#to_ary` or `#to_a`, but got #{actual_formatted}" end end
failure_message_when_negated()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 22 def failure_message_when_negated list = EnglishPhrasing.list(surface_descriptions_in(expected)) "expected #{actual_formatted} not to contain exactly#{list}" end
matches?(actual)
click to toggle source
Calls superclass method
RSpec::Matchers::BuiltIn::BaseMatcher#matches?
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 34 def matches?(actual) @pairings_maximizer = nil @best_solution = nil @extra_items = nil @missing_items = nil super(actual) end
Private Instance Methods
actual_collection_line()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 56 def actual_collection_line message_line('actual collection contained', actual) end
best_solution()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 137 def best_solution @best_solution ||= pairings_maximizer.find_best_solution end
convert_actual_to_an_array()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 94 def convert_actual_to_an_array if actual.respond_to?(:to_ary) @actual = actual.to_ary elsif actual.respond_to?(:to_a) && !to_a_disallowed?(actual) @actual = actual.to_a else false end end
describe_collection(collection, surface_descriptions=false)
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 68 def describe_collection(collection, surface_descriptions=false) if surface_descriptions "#{description_of(safe_sort(surface_descriptions_in collection))}\n" else "#{description_of(safe_sort(collection))}\n" end end
expected_collection_line()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 52 def expected_collection_line message_line('expected collection contained', expected, true) end
extra_elements_line()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 64 def extra_elements_line message_line('the extra elements were', extra_items) end
extra_items()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 131 def extra_items @extra_items ||= best_solution.unmatched_actual_indexes.map do |index| actual[index] end end
generate_failure_message()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 44 def generate_failure_message message = expected_collection_line message += actual_collection_line message += missing_elements_line unless missing_items.empty? message += extra_elements_line unless extra_items.empty? message end
match(_expected, _actual)
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 81 def match(_expected, _actual) return false unless convert_actual_to_an_array match_when_sorted? || (extra_items.empty? && missing_items.empty?) end
match_when_sorted?()
click to toggle source
This cannot always work (e.g. when dealing with unsortable items, or matchers as expected items), but it’s practically free compared to the slowness of the full matching algorithm, and in common cases this works, so it’s worth a try.
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 90 def match_when_sorted? values_match?(safe_sort(expected), safe_sort(actual)) end
message_line(prefix, collection, surface_descriptions=false)
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 76 def message_line(prefix, collection, surface_descriptions=false) "%-32s%s" % [prefix + ':', describe_collection(collection, surface_descriptions)] end
missing_elements_line()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 60 def missing_elements_line message_line('the missing elements were', missing_items, true) end
missing_items()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 125 def missing_items @missing_items ||= best_solution.unmatched_expected_indexes.map do |index| expected[index] end end
pairings_maximizer()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 141 def pairings_maximizer @pairings_maximizer ||= begin expected_matches = Hash[Array.new(expected.size) { |i| [i, []] }] actual_matches = Hash[Array.new(actual.size) { |i| [i, []] }] expected.each_with_index do |e, ei| actual.each_with_index do |a, ai| next unless values_match?(e, a) expected_matches[ei] << ai actual_matches[ai] << ei end end PairingsMaximizer.new(expected_matches, actual_matches) end end
safe_sort(array)
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 104 def safe_sort(array) array.sort rescue Support::AllExceptionsExceptOnesWeMustNotRescue array end
to_a_disallowed?(object)
click to toggle source
:nocov:
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 112 def to_a_disallowed?(object) case object when NilClass, String then true else Kernel == RSpec::Support.method_handle_for(object, :to_a).owner end end