/usr/lib/ruby/vendor_ruby/rspec/matchers/built_in/include.rb is in ruby-rspec-expectations 3.4.0c3e0m1s1-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | module RSpec
module Matchers
module BuiltIn
# @api private
# Provides the implementation for `include`.
# Not intended to be instantiated directly.
class Include < BaseMatcher
def initialize(*expected)
@expected = expected
end
# @api private
# @return [Boolean]
def matches?(actual)
perform_match(actual) { |v| v }
end
# @api private
# @return [Boolean]
def does_not_match?(actual)
perform_match(actual) { |v| !v }
end
# @api private
# @return [String]
def description
improve_hash_formatting("include#{readable_list_of(expected)}")
end
# @api private
# @return [String]
def failure_message
format_failure_message("to") { super }
end
# @api private
# @return [String]
def failure_message_when_negated
format_failure_message("not to") { super }
end
# @api private
# @return [Boolean]
def diffable?
!diff_would_wrongly_highlight_matched_item?
end
private
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
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
def perform_match(actual, &block)
@actual = actual
@divergent_items = excluded_from_actual(&block)
actual.respond_to?(:include?) && @divergent_items.empty?
end
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
def comparing_hash_to_a_subset?(expected_item)
actual.is_a?(Hash) && expected_item.is_a?(Hash)
end
def actual_hash_includes?(expected_key, expected_value)
actual_value = actual.fetch(expected_key) { return false }
values_match?(expected_value, actual_value)
end
def comparing_hash_keys?(expected_item)
actual.is_a?(Hash) && !expected_item.is_a?(Hash)
end
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
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
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
end
end
end
end
|