freerange / mocha

A mocking and stubbing library for Ruby
https://mocha.jamesmead.org
Other
1.23k stars 158 forks source link

Fix regression when matching Hash parameter #660

Closed floehopper closed 3 months ago

floehopper commented 4 months ago

In this commit which fixed https://github.com/freerange/mocha/issues/647 and which was released in v2.3.0, a top-level Hash argument passed into Expectation#with was implicitly converted into a HasEntries matcher in order to handle "nested" matchers used within the keys & values of the Hash.

This new behaviour makes particular sense for keyword arguments where the requirement to wrap such a Hash in a call to #has_entries was a bit surprising as described in https://github.com/freerange/mocha/issues/647.

However, that change inadvertently broke basic Hash parameter matching as described in https://github.com/freerange/mocha/issues/657, because the HasEntries matcher only needs to match each of the entries specified; it will still match if there are extra entries in the Hash it is matching against.

In order to fix this without breaking the "nested" matching behaviour added in 1, I've added an optional exact keyword argument to the HasEntries constructor and set this to true when it's called from PositionalOrKeywordHash#matches?. I haven't bothered to document the new exact argument, because currently it's only used internally.

I did consider introducing a new matcher more like the RSpec::Matchers#match matcher, but I decided that wouldn't provide as elegant a solution to https://github.com/freerange/mocha/issues/647 as the change in this PR.

I can imagine introducing something like #has_exact_entries to the public API, but it would probably make sense to add something similar for exact matching of array items at the same time, so I'm going to leave that for now.

I've added a few acceptance tests in this PR which would have caught the problem that I inadvertently introduced in this commit and a few that cover the "nested" matching behaviour that was introduced in that commit (previously I had only added a unit test).

I've also done a bit of tidying up in PositionalOrKeywordHashTest in preparatory commits.

Fixes #657.