Skip to content

Commit

Permalink
Fix nested parameter matching for keyword arguments
Browse files Browse the repository at this point in the history
Previously, parameter matching for keyword arguments only worked when
the matchers specified the exact value of each argument. This change
means that we make use of the `HasEntries` matcher to ensure that any
matchers for each of the keyword arguments are also taken into account.

Fixes #647.
  • Loading branch information
floehopper committed May 17, 2024
1 parent 5324009 commit f94e250
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/mocha/parameter_matchers/positional_or_keyword_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def initialize(value, expectation)

def matches?(available_parameters)
parameter, is_last_parameter = extract_parameter(available_parameters)
return false unless parameter == @value

return false unless HasEntries.new(@value).matches?([parameter])

if is_last_parameter && !same_type_of_hash?(parameter, @value)
return false if Mocha.configuration.strict_keyword_argument_matching?
Expand Down
9 changes: 9 additions & 0 deletions test/acceptance/keyword_argument_matching_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ def test_should_match_positional_and_keyword_args_with_hash_matcher
assert_passed(test_result)
end

def test_should_match_keyword_args_with_nested_matcher
test_result = run_as_test do
mock = mock()
mock.expects(:method).with(key: is_a(Integer))
mock.method(key: 42)
end
assert_passed(test_result)
end

def test_should_match_last_positional_hash_with_hash_matcher
test_result = run_as_test do
mock = mock()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def test_should_match_keyword_args_with_keyword_args
assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters
end

def test_should_match_keyword_args_with_matchers_using_keyword_args
matcher = Hash.ruby2_keywords_hash({ key_1: is_a(String), key_2: is_a(Integer) }).to_matcher # rubocop:disable Style/BracesAroundHashParameters
assert matcher.matches?([Hash.ruby2_keywords_hash({ key_1: 'foo', key_2: 2 })]) # rubocop:disable Style/BracesAroundHashParameters
end

def test_should_match_hash_arg_with_keyword_args_but_display_deprecation_warning_if_appropriate
expectation = Mocha::Expectation.new(self, :foo); execution_point = ExecutionPoint.current
matcher = Hash.ruby2_keywords_hash({ key_1: 1, key_2: 2 }).to_matcher(expectation) # rubocop:disable Style/BracesAroundHashParameters
Expand Down

0 comments on commit f94e250

Please sign in to comment.