class RSpec::Matchers::BuiltIn::ContainExactly
@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 31 def description "contain exactly#{to_sentence(surface_descriptions_in expected)}" end
failure_message()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 10 def failure_message if Array === actual message = "expected collection contained: #{safe_sort(surface_descriptions_in expected).inspect}\n" message += "actual collection contained: #{safe_sort(actual).inspect}\n" message += "the missing elements were: #{safe_sort(surface_descriptions_in missing_items).inspect}\n" unless missing_items.empty? message += "the extra elements were: #{safe_sort(extra_items).inspect}\n" unless extra_items.empty? message else "expected a collection that can be converted to an array with " "`#to_ary` or `#to_a`, but got #{actual.inspect}" end end
failure_message_when_negated()
click to toggle source
@api private @return [String]
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 25 def failure_message_when_negated "expected #{actual.inspect} not to contain exactly#{to_sentence(surface_descriptions_in expected)}" end
Private Instance Methods
best_solution()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 76 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 50 def convert_actual_to_an_array if actual.respond_to?(:to_ary) @actual = actual.to_ary elsif should_enumerate?(actual) && actual.respond_to?(:to_a) @actual = actual.to_a else return false end end
extra_items()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 70 def extra_items @extra_items ||= best_solution.unmatched_actual_indexes.map do |index| actual[index] end end
match(_expected, _actual)
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 37 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 46 def match_when_sorted? values_match?(safe_sort(expected), safe_sort(actual)) end
missing_items()
click to toggle source
# File lib/rspec/matchers/built_in/contain_exactly.rb, line 64 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 80 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 60 def safe_sort(array) array.sort rescue array end