Skip to content
This repository was archived by the owner on Jul 7, 2026. It is now read-only.

Support for Pact v3 - #569

Merged
marcingrzejszczak merged 26 commits into
spring-attic:masterfrom
TYsewyn:feature/gh406-upgrade-pact
Apr 2, 2018
Merged

marcingrzejszczak merged 26 commits into
spring-attic:masterfrom
TYsewyn:feature/gh406-upgrade-pact

Conversation

@TYsewyn

@TYsewyn TYsewyn commented Mar 7, 2018 •

Copy link
Copy Markdown
Contributor

PR to track the Pact v3 support.

❗️This is currently a work in progress❗️

Tasks

Notes on implementation:

  • Only supports the AND rule logic to combine multiple matchers for the same json path
  • Only the body and header matchers are currently supported, path and query matchers will be added in a future release.

Introduces breaking changes:

  • Returns a collection of Pact contracts instead of one (see d942bfd#diff-3c9a6ccf897ca28d932eb2bef60dc2e9R27)
  • The testMatchers and stubMatchers have been changed to be able to add path, query and header matchers This has been reverted in favor of a non-invasive change using deprecation

Closes #583
Fixes #595

@TYsewyn TYsewyn mentioned this pull request Mar 7, 2018
@codecov-io

codecov-io commented Mar 7, 2018 •

Copy link
Copy Markdown

Codecov Report

Merging #569 into master will increase coverage by 0.41%.
The diff coverage is 63.45%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #569      +/-   ##
============================================
+ Coverage     61.06%   61.48%   +0.41%     
- Complexity     1834     1935     +101     
============================================
  Files           210      217       +7     
  Lines          7534     7918     +384     
  Branches       1125     1234     +109     
============================================
+ Hits           4601     4868     +267     
- Misses         2291     2373      +82     
- Partials        642      677      +35
Impacted Files Coverage Δ Complexity Δ
...ud/contract/verifier/converter/YamlContract.groovy 100% <ø> (ø) 0 <0> (ø) ⬇️
...k/cloud/contract/spec/internal/BodyMatchers.groovy 18.51% <ø> (+18.51%) 5 <0> (+5) ⬆️
.../cloud/contract/spec/internal/OutputMessage.groovy 29.16% <0%> (-2.66%) 3 <0> (ø)
...contract/spec/internal/ResponseBodyMatchers.groovy 0% <0%> (ø) 0 <0> (ø) ⬇️
...tract/spec/internal/PatternValueDslProperty.groovy 26.31% <0%> (-3.99%) 6 <0> (ø)
...k/cloud/contract/spec/internal/MatchingType.groovy 66.66% <0%> (-33.34%) 7 <7> (+1)
...ramework/cloud/contract/spec/internal/Input.groovy 33.33% <0%> (-2.67%) 3 <0> (ø)
...ework/cloud/contract/spec/internal/Response.groovy 50% <100%> (+20%) 9 <2> (+3) ⬆️
...saging/stream/StubRunnerStreamMessageSelector.java 91.11% <100%> (ø) 11 <0> (ø) ⬇️
...verifier/builder/MessagingMethodBodyBuilder.groovy 81.81% <100%> (ø) 10 <0> (ø) ⬇️
... and 32 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ff8fd0a...009aa9e. Read the comment docs.

@marcingrzejszczak

Copy link
Copy Markdown
Contributor

Apparently in Pact 2.0 support, I haven't noticed that in the Pact matchers section you could do $.body and pass a regular expression, or $.headers and match a header. I haven't noticed the headers part :/

@marcingrzejszczak

Copy link
Copy Markdown
Contributor

Related - #583

@marcingrzejszczak marcingrzejszczak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WOW, this is absolutely fantastic work, so, first of all, congratulations! I gave my feedback which is, generally speaking, mostly about some minor tweaks and changes. As far as the very conversion is concerned, I guess you know more about Pact then I do, so I can provide little feedback. In general, it looks great and I would be more than happy to merge it once you feel that it's pretty stable :)

<groupId>au.com.dius</groupId>
<artifactId>pact-jvm-model</artifactId>
<optional>true</optional>
<artifactId>pact-jvm-consumer-java8_2.12</artifactId>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not optional? Do we want to force that particular version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, that wasn't supposed to happen. Then again, I won't know if it will work with future versions.
(except when somebody files an issue)

private static DslPart traverse(Object value, DslPart parent, Closure dslPropertyValueExtractor) {
boolean isRoot = parent == null
Object v = value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a matter of preference, but could you get rid of all of those separations between blocks? If not, then I'll do it later

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider it done

}
}

p

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add return ? I prefer to always explicitly define return, otherwise you can accidentally return sth you didn't want to return, and also it's more comprehensible for others. Also if you refactor from a method that returns sth to void, your code will still compile even though it shouldn't :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider it done

})
}

private static void processMap(Map<String, Object> values, PactDslJsonBody jsonObject, Closure dslPropertyValueExtractor) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't iterating JSON a fantastic experience? :D

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, really fantastic! I'm glad I can mention this on my resume now :D

class MatchingRulesConverter {

static Category matchingRulesForBody(BodyMatchers bodyMatchers) {
matchingRulesFor("body", bodyMatchers)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return please

}
} else {
ruleGroup.rules.each { MatchingRule rule ->
if (rule instanceof RegexMatcher) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically, you could rewrite this to call jsonPath only once and just pass different value basing on the instance of rule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! But then you would need to explain me how I could pass the current closure context to another method.
Closures, they're possibly great when you understand it completely. :D

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, so just ignore it.

return dsl.request.url.queryParameters
}
throw new IllegalStateException("No url provided")
pactContracts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing return (I wasn't adding this comment everywhere since it doesn't make much sense to repeat myself)

@PackageScope
class RequestResponsePactCreator {

static final Closure requestDslPropertyValueExtractor = { DslProperty property -> property.serverValue }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha! you have to add a modifier e.g. protected if you want this to be a constant field. Otherwise if you check out the MOP, you'll see that a private static final field was created with a public static getter method :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Both should be private indeed!

},
"$.body.something": {
"match": "equality"
"body": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should check for the headers matchers too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's for some time later. They also introduced path & query matchers.
See https://github.com/pact-foundation/pact-specification/tree/version-3#drop-the-jsonpath-notation-for-matchers

})
jsonPath('$.id', byType())

// TODO: CURRENTLY NOT SUPPORTED

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't it supported? That should work I guess OOB ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it wasn't. They added new matchers to v3, check https://github.com/pact-foundation/pact-specification/tree/version-3#add-an-equality-matcher until the generators

@spencergibb spencergibb modified the milestones: 2.0.0.M9, 2.0.0.RC1 Apr 2, 2018
@marcingrzejszczak
marcingrzejszczak merged commit de529e2 into spring-attic:master Apr 2, 2018
@TYsewyn
TYsewyn deleted the feature/gh406-upgrade-pact branch May 6, 2018 09:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Development

Successfully merging this pull request may close these issues.

4 participants