class RSpec::Matchers::BuiltIn::Include

@api private Provides the implementation for `include`. Not intended to be instantiated directly.

Public Class Methods

new(*expected) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 8
def initialize(*expected)
  @expected = expected
end

Public Instance Methods

description() click to toggle source

@api private @return [String]

# File lib/rspec/matchers/built_in/include.rb, line 26
def description
  improve_hash_formatting("include#{readable_list_of(expected)}")
end
diffable?() click to toggle source

@api private @return [Boolean]

# File lib/rspec/matchers/built_in/include.rb, line 44
def diffable?
  !diff_would_wrongly_highlight_matched_item?
end
does_not_match?(actual) click to toggle source

@api private @return [Boolean]

# File lib/rspec/matchers/built_in/include.rb, line 20
def does_not_match?(actual)
  perform_match(actual) { |v| !v }
end
failure_message() click to toggle source

@api private @return [String]

# File lib/rspec/matchers/built_in/include.rb, line 32
def failure_message
  format_failure_message("to") { super }
end
failure_message_when_negated() click to toggle source

@api private @return [String]

# File lib/rspec/matchers/built_in/include.rb, line 38
def failure_message_when_negated
  format_failure_message("not to") { super }
end
matches?(actual) click to toggle source

@api private @return [Boolean]

# File lib/rspec/matchers/built_in/include.rb, line 14
def matches?(actual)
  perform_match(actual) { |v| v }
end

Private Instance Methods

actual_collection_includes?(expected_item) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 110
def actual_collection_includes?(expected_item)
  return true if actual.include?(expected_item)

  # String lacks an `any?` method...
  return false unless actual.respond_to?(:any?)

  actual.any? { |value| values_match?(expected_item, value) }
end
actual_hash_has_key?(expected_key) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 103
def actual_hash_has_key?(expected_key)
  # We check `key?` first for perf:
  # `key?` is O(1), but `any?` is O(N).
  actual.key?(expected_key) ||
  actual.keys.any? { |key| values_match?(expected_key, key) }
end
actual_hash_includes?(expected_key, expected_value) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 94
def actual_hash_includes?(expected_key, expected_value)
  actual_value = actual.fetch(expected_key) { return false }
  values_match?(expected_value, actual_value)
end
comparing_hash_keys?(expected_item) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 99
def comparing_hash_keys?(expected_item)
  actual.is_a?(Hash) && !expected_item.is_a?(Hash)
end
comparing_hash_to_a_subset?(expected_item) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 90
def comparing_hash_to_a_subset?(expected_item)
  actual.is_a?(Hash) && expected_item.is_a?(Hash)
end
diff_would_wrongly_highlight_matched_item?() click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 119
def diff_would_wrongly_highlight_matched_item?
  return false unless actual.is_a?(String) && expected.is_a?(Array)

  lines = actual.split("\n")
  expected.any? do |str|
    actual.include?(str) && lines.none? { |line| line == str }
  end
end
excluded_from_actual() { |actual_hash_includes?(key, value)| ... } click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 73
def excluded_from_actual
  return [] unless @actual.respond_to?(:include?)

  expected.inject([]) do |memo, expected_item|
    if comparing_hash_to_a_subset?(expected_item)
      expected_item.each do |(key, value)|
        memo << { key => value } unless yield actual_hash_includes?(key, value)
      end
    elsif comparing_hash_keys?(expected_item)
      memo << expected_item unless yield actual_hash_has_key?(expected_item)
    else
      memo << expected_item unless yield actual_collection_includes?(expected_item)
    end
    memo
  end
end
format_failure_message(preposition) { || ... } click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 50
def format_failure_message(preposition)
  if actual.respond_to?(:include?)
    improve_hash_formatting("expected #{description_of @actual} #{preposition} include#{readable_list_of @divergent_items}")
  else
    improve_hash_formatting(yield) + ", but it does not respond to `include?`"
  end
end
perform_match(actual, &block) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 67
def perform_match(actual, &block)
  @actual = actual
  @divergent_items = excluded_from_actual(&block)
  actual.respond_to?(:include?) && @divergent_items.empty?
end
readable_list_of(items) click to toggle source
# File lib/rspec/matchers/built_in/include.rb, line 58
def readable_list_of(items)
  described_items = surface_descriptions_in(items)
  if described_items.all? { |item| item.is_a?(Hash) }
    " #{described_items.inject(:merge).inspect}"
  else
    EnglishPhrasing.list(described_items)
  end
end