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
|
require 'mocha/parameter_matchers/all_of'
require 'mocha/parameter_matchers/base'
module Mocha
module ParameterMatchers
# Matches any object that responds with +true+ to +include?(item)+
# for all items.
#
# @param [*Array] items expected items.
# @return [Includes] parameter matcher.
#
# @see Expectation#with
#
# @example Actual parameter includes all items.
# object = mock()
# object.expects(:method_1).with(includes('foo', 'bar'))
# object.method_1(['foo', 'bar', 'baz'])
# # no error raised
#
# @example Actual parameter does not include all items.
# object.method_1(['foo', 'baz'])
# # error raised, because ['foo', 'baz'] does not include 'bar'.
#
# @example Actual parameter includes item which matches nested matcher.
# object = mock()
# object.expects(:method_1).with(includes(has_key(:key)))
# object.method_1(['foo', 'bar', {key: 'baz'}])
# # no error raised
#
# @example Actual parameter does not include item matching nested matcher.
# object.method_1(['foo', 'bar', {:other_key => 'baz'}])
# # error raised, because no element matches `has_key(:key)` matcher
#
# @example Actual parameter is a String including substring.
# object = mock()
# object.expects(:method_1).with(includes('bar'))
# object.method_1('foobarbaz')
# # no error raised
#
# @example Actual parameter is a String not including substring.
# object.method_1('foobaz')
# # error raised, because 'foobaz' does not include 'bar'
#
# @example Actual parameter is a Hash including the given key.
# object = mock()
# object.expects(:method_1).with(includes(:bar))
# object.method_1({foo: 1, bar: 2})
# # no error raised
#
# @example Actual parameter is a Hash without the given key.
# object.method_1({foo: 1, baz: 2})
# # error raised, because hash does not include key 'bar'
#
# @example Actual parameter is a Hash with a key matching the given matcher.
# object = mock()
# object.expects(:method_1).with(includes(regexp_matches(/ar/)))
# object.method_1({'foo' => 1, 'bar' => 2})
# # no error raised
#
# @example Actual parameter is a Hash no key matching the given matcher.
# object.method_1({'foo' => 1, 'baz' => 3})
# # error raised, because hash does not include a key matching /ar/
def includes(*items)
Includes.new(*items)
end
# Parameter matcher which matches when actual parameter includes expected values.
class Includes < Base
# @private
def initialize(*items)
@items = items
end
# @private
# rubocop:disable Metrics/PerceivedComplexity
def matches?(available_parameters)
parameter = available_parameters.shift
return false unless parameter.respond_to?(:include?)
if @items.size == 1
# rubocop:disable Style/GuardClause
if parameter.respond_to?(:any?) && !parameter.is_a?(String)
parameter = parameter.keys if parameter.is_a?(Hash)
return parameter.any? { |p| @items.first.to_matcher.matches?([p]) }
else
return parameter.include?(@items.first)
end
# rubocop:enable Style/GuardClause
else
includes_matchers = @items.map { |item| Includes.new(item) }
AllOf.new(*includes_matchers).matches?([parameter])
end
end
# rubocop:enable Metrics/PerceivedComplexity
# @private
def mocha_inspect
item_descriptions = @items.map(&:mocha_inspect)
"includes(#{item_descriptions.join(', ')})"
end
end
end
end
|