-
-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
3 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'mocha/parameter_matchers/base' | ||
|
||
module Mocha | ||
module ParameterMatchers | ||
# Matches +Hash+ containing +keys+. | ||
# | ||
# @param [*Array<Object>] keys expected keys. | ||
# @return [HasKeys] parameter matcher. | ||
# | ||
# @see Expectation#with | ||
# | ||
# @example Actual parameter contains entry with expected keys. | ||
# object = mock() | ||
# object.expects(:method_1).with(has_keys(:key_1, :key_2)) | ||
# object.method_1(:key_1 => 1, :key_2 => 2, :key_3 => 3) | ||
# # no error raised | ||
# | ||
# @example Actual parameter does not contain all expected keys. | ||
# object = mock() | ||
# object.expects(:method_1).with(has_keys(:key_1, :key_2)) | ||
# object.method_1(:key_2 => 2) | ||
# # error raised, because method_1 was not called with Hash containing key: :key_1 | ||
# | ||
def has_keys(*keys) # rubocop:disable Naming/PredicateName | ||
HasKeys.new(*keys) | ||
end | ||
|
||
# Parameter matcher which matches when actual parameter contains +Hash+ with all expected keys. | ||
class HasKeys < Base | ||
# @private | ||
def initialize(*keys) | ||
raise ArgumentError, 'No arguments. Expecting at least one.' if keys.empty? | ||
|
||
@keys = keys | ||
end | ||
|
||
# @private | ||
def matches?(available_parameters) | ||
parameter = available_parameters.shift | ||
return false unless parameter.respond_to?(:keys) | ||
|
||
@keys.map(&:to_matcher).all? do |matcher| | ||
parameter.keys.any? { |key| matcher.matches?([key]) } | ||
end | ||
end | ||
|
||
# @private | ||
def mocha_inspect | ||
"has_keys(#{@keys.mocha_inspect(false)})" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require File.expand_path('../../../test_helper', __FILE__) | ||
|
||
require 'mocha/parameter_matchers/has_keys' | ||
require 'mocha/parameter_matchers/instance_methods' | ||
require 'mocha/inspect' | ||
|
||
class HasKeysTest < Mocha::TestCase | ||
include Mocha::ParameterMatchers | ||
|
||
def test_should_match_hash_including_specified_keys | ||
matcher = has_keys(:key_1, :key_2) | ||
assert matcher.matches?([{ :key_1 => 1, :key_2 => 2, :key_3 => 3 }]) | ||
end | ||
|
||
def test_should_not_match_hash_not_including_specified_keys | ||
matcher = has_keys(:key_1, :key_2) | ||
assert !matcher.matches?([{ :key_3 => 3 }]) | ||
end | ||
|
||
def test_should_not_match_hash_not_including_all_keys | ||
matcher = has_keys(:key_1, :key_2) | ||
assert !matcher.matches?([{ :key_1 => 1, :key_3 => 3 }]) | ||
end | ||
|
||
def test_should_describe_matcher | ||
matcher = has_keys(:key_1, :key_2) | ||
assert_equal 'has_keys(:key_1, :key_2)', matcher.mocha_inspect | ||
end | ||
|
||
def test_should_match_hash_including_specified_key_with_nested_key_matcher | ||
matcher = has_keys(equals(:key_1), equals(:key_2)) | ||
assert matcher.matches?([{ :key_1 => 1, :key_2 => 2 }]) | ||
end | ||
|
||
def test_should_not_match_hash_not_including_specified_keys_with_nested_key_matchers | ||
matcher = has_keys(equals(:key_1), equals(:key2)) | ||
assert !matcher.matches?([{ :key_2 => 2 }]) | ||
end | ||
|
||
def test_should_not_raise_error_on_empty_arguments | ||
matcher = has_keys(:key_1, :key_2) | ||
assert_nothing_raised { matcher.matches?([]) } | ||
end | ||
|
||
def test_should_not_match_on_empty_arguments | ||
matcher = has_keys(:key_1, :key_2) | ||
assert !matcher.matches?([]) | ||
end | ||
|
||
def test_should_not_raise_error_on_argument_that_does_not_respond_to_keys | ||
matcher = has_keys(:key_1, :key_2) | ||
assert_nothing_raised { matcher.matches?([:key_1]) } | ||
end | ||
|
||
def test_should_not_match_on_argument_that_does_not_respond_to_keys | ||
matcher = has_keys(:key_1, :key_2) | ||
assert !matcher.matches?([:key_1]) | ||
end | ||
|
||
def test_should_raise_argument_error_if_no_keys_are_supplied | ||
e = assert_raises(ArgumentError) { has_keys } | ||
assert_equal 'No arguments. Expecting at least one.', e.message | ||
end | ||
end |