Repository navigation
where(): a joint constraint over the whole argument list - #155
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #151
What
The one Mockery verb with no mapping here now has one:
withArgs(closure)→->where().Variant (2) of the issue — an invocation-level guard — as decided there: a constraint on the call, composing with per-position matchers instead of excluding them.
Shape decisions, and why
fn ($from, $to) => ...), not anInvocation. The guard must be evaluated everywhere matching is — and the by-reference slot walk (DoubleState::hasActionFor()) asksmatchesArguments()before any Invocation exists. AnInvocation-taking guard would either break the invariant that this walk agrees with dispatch, or require a synthetic Invocation with a fabricated sequence. Positional args keep every walk honest through the one choke point: dispatch,hasActionFor(), and averify()probe all go throughExpectation::matchesArguments().where()is refused withInvalidCallSpecificationwhere it is written, not silently replacing the first.description:names the guard in failure messages (theArg::satisfies()precedent); default renderswhere(…). When positions matched but the guard refused,describeAgainst()marks the guard itself —transfer(any(), any()) *where(…)*— rather than blaming a position that accepted. The guard is re-asked defensively while rendering, exactly like a matcher is.Notes for reviewers
verify()takes one through a new?callable $where = nullparameter (facade + free function) — an optional trailing parameter, additive per the compatibility policy.expect()/verify()forms, both renderings, the strict-refusal mark, the by-reference slot agreement (the guard refusing must look unconfigured to the slot walk), a zero-argument guard, and the variadic tail (fn (string $channel, int ...$values)).mutation-diff: 60 mutants, one survivor — theReturnRemovalon the zero-arg line, behaviorally equivalent (the fallthrough recomputes the same verdict); covered MSI 98%.stubbing/matchers.md,migrating-from-mockery.md, regeneratedMIGRATION.md),make docs-api,docs-claimsgreen; new self-checkingexamples/where-guard.phpin the build's@examplesscript.