feat(plugins): Register the standard matching rules and generators as core plugin capabilities - #548
Merged
Merged
Conversation
… core plugin capabilities
Proposal 009: let a plugin delegate a standard Pact rule to the host it is
running under, instead of reimplementing it. The mechanism has been in the
plugin driver since 006; nothing registered anything behind it, so a plugin
naming a standard rule resolved the catalogue entry and then failed with
"No core field matcher registered for 'type'".
Catalogue entries:
- the matcher entries are re-keyed by the name the rule carries in a
request (`MatchingRule::name()`, the same string the driver puts in
`MatchFieldRequest.rule.type`) rather than the specification version
prefixed to the name, which moves to a `spec-version` value on the entry;
- generator entries are added - there were none at all, so `find_field_
generator("Uuid")` failed at the catalogue step and no `generator/*`
capability was ever advertised;
- both lists are now exactly the rules and generators this crate
implements, pinned by a test that compares them against the enum
variants, with an exhaustive match so a new variant fails to compile
until it has an entry.
Handlers:
- `CoreFieldRuleMatcher` answers for the 16 rules that act on a single
value, and `CoreFieldValueGenerator` for the 12 generators that are a
pure function of their configuration and the test context;
- the collection-wide rules (`min-type`, `values`, `array-contains`,
`each-key`/`each-value`) and the `ArrayContains` generator are
registered too, but answer with why they can not be applied one value at
a time - they stay host-only per 006's non-goals, and a plugin naming one
should be told that rather than that nothing is registered;
- a rule or generator name this crate does not provide is an error, not a
call back out: an unrecognised name parses into the `Plugin` carrier
variant, which would send the callback straight back to a plugin.
Two bugs this turned up:
- `MatchingRule::Equality` on `&Bytes` built its mismatch message with
`split_at(10)`, which panics for any value shorter than 10 bytes;
- rule and generator configuration crosses the plugin interface as a
`google.protobuf.Struct`, which has one number type, so a plugin's
`min: 2` arrives as `2.0` and the integer accessors reading it fall back
to the attribute's default - a `RandomInt(5, 5)` from a plugin generated
from `0..10`. Whole floats are put back to integers on the way in.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Proposal 009: let a plugin delegate a standard Pact rule to the host it is running under, instead of reimplementing it. The mechanism has been in the plugin driver since 006; nothing registered anything behind it, so a plugin naming a standard rule resolved the catalogue entry and then failed with "No core field matcher registered for 'type'".
Catalogue entries:
MatchingRule::name(), the same string the driver puts inMatchFieldRequest.rule.type) rather than the specification version prefixed to the name, which moves to aspec-versionvalue on the entry;find_field_ generator("Uuid")failed at the catalogue step and nogenerator/*capability was ever advertised;Handlers:
CoreFieldRuleMatcheranswers for the 16 rules that act on a single value, andCoreFieldValueGeneratorfor the 12 generators that are a pure function of their configuration and the test context;min-type,values,array-contains,each-key/each-value) and theArrayContainsgenerator are registered too, but answer with why they can not be applied one value at a time - they stay host-only per 006's non-goals, and a plugin naming one should be told that rather than that nothing is registered;Plugincarrier variant, which would send the callback straight back to a plugin.Two bugs this turned up:
MatchingRule::Equalityon&Bytesbuilt its mismatch message withsplit_at(10), which panics for any value shorter than 10 bytes;google.protobuf.Struct, which has one number type, so a plugin'smin: 2arrives as2.0and the integer accessors reading it fall back to the attribute's default - aRandomInt(5, 5)from a plugin generated from0..10. Whole floats are put back to integers on the way in.