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 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.
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 intoExpectation#with
was implicitly converted into aHasEntries
matcher in order to handle "nested" matchers used within the keys & values of theHash
.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 theHasEntries
matcher only needs to match each of the entries specified; it will still match if there are extra entries in theHash
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 theHasEntries
constructor and set this totrue
when it's called fromPositionalOrKeywordHash#matches?
. I haven't bothered to document the newexact
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.