Skip to content

Commit

Permalink
feat: add new v3 matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Aug 23, 2020
1 parent 1269271 commit 2b0b5d6
Show file tree
Hide file tree
Showing 9 changed files with 527 additions and 115 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pact: install docker

pactv3: clean
@echo "--- 🔨 Running Pact examples"
go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/examples/v3/... -run TestConsumerV2
go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/examples/v3/... -run TestConsumerV3

release:
echo "--- 🚀 Releasing it"
Expand Down
12 changes: 9 additions & 3 deletions examples/v3/consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,15 @@ func TestConsumerV3(t *testing.T) {
Headers: v3.MapMatcher{"Content-Type": s("application/json")},
// Body: v3.Match(&User{}),
Body: v3.MapMatcher{
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"superstring": v3.Includes("foo"),
"id": v3.Integer(12),
"accountBalance": v3.Decimal(123.76),
"itemsMinMax": v3.ArrayMinMaxLike(27, 3, 5),
"itemsMin": v3.ArrayMinLike("min", 3),
"equality": v3.Equality("a thing"),
},
})

Expand Down
234 changes: 234 additions & 0 deletions examples/v3/pacts/consumer-provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
{
"consumer": {
"name": "consumer"
},
"interactions": [
{
"description": "A request to do a foo",
"providerStates": [
{
"name": "User foo exists",
"params": {
"id": "foo"
}
}
],
"request": {
"body": {
"name": "billy"
},
"headers": {
"Authorization": "Bearer 1234",
"Content-Type": "application/json"
},
"matchingRules": {
"body": {
"$.name": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
},
"headers": {
"$.Authorization": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.Content-Type": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
},
"path": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "\\/foo.*"
}
]
},
"query": {
"$.baz[0]": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "[a-z]+"
}
]
},
"$.baz[1]": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "[a-z]+"
}
]
},
"$.baz[2]": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "[a-z]+"
}
]
}
}
},
"method": "POST",
"path": "/foobar",
"query": {
"baz": [
"bar",
"bat",
"baz"
]
}
},
"response": {
"body": {
"accountBalance": 123.76,
"dateTime": "2020-01-01",
"equality": "a thing",
"id": 12,
"itemsMin": [
"min",
"min",
"min"
],
"itemsMinMax": [
27,
27,
27,
27,
27
],
"lastName": "LastName",
"name": "FirstName",
"superstring": "foo"
},
"headers": {
"Content-Type": "application/json"
},
"matchingRules": {
"body": {
"$.accountBalance": {
"combine": "AND",
"matchers": [
{
"match": "decimal"
}
]
},
"$.dateTime": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "[0-9\\-]+"
}
]
},
"$.equality": {
"combine": "AND",
"matchers": [
{
"match": "equality"
}
]
},
"$.id": {
"combine": "AND",
"matchers": [
{
"match": "integer"
}
]
},
"$.itemsMin": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.itemsMinMax": {
"combine": "AND",
"matchers": [
{
"match": "type",
"max": 5
}
]
},
"$.lastName": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.name": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.superstring": {
"combine": "AND",
"matchers": [
{
"match": "include",
"value": "foo"
}
]
}
},
"headers": {
"$.Content-Type": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
}
},
"status": 200
}
}
],
"metadata": {
"pactGo": {
"version": "v1.4.3"
},
"pactRust": {
"version": "0.6.3"
},
"pactSpecification": {
"version": "3.0.0"
}
},
"provider": {
"name": "provider"
}
}
61 changes: 61 additions & 0 deletions v3/matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package v3

import "time"

// Term Matcher regexes
const (
hexadecimal = `[0-9a-fA-F]+`
ipAddress = `(\d{1,3}\.)+\d{1,3}`
ipv6Address = `(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)`
uuid = `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`
timestamp = `^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$`
date = `^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))?)`
timeRegex = `^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$`
)

var timeExample = time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)

// MatcherClass is used to differentiate the various matchers when serialising
type MatcherClass string

// Matcher Types used to discriminate when serialising the rules
const (
// likeMatcher is the ID for the Like Matcher
likeMatcher MatcherClass = "likeMatcher"

// regexMatcher is the ID for the Term Matcher
regexMatcher = "regexMatcher"

// arrayMinLikeMatcher is the ID for the ArrayMinLike Matcher
arrayMinLikeMatcher = "arrayMinLikeMatcher"

// arrayMaxLikeMatcher is the ID for the arrayMaxLikeMatcher Matcher
// arrayMaxLikeMatcher = "arrayMaxLikeMatcher"

// arrayMinMaxLikeMatcher sets lower and upper bounds on the array size
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-a-minmax-type-matcher
arrayMinMaxLikeMatcher = "arrayMinMaxLikeMatcher"

// Matches map[string]interface{} types is basically a container for other matchers
structTypeMatcher = "structTypeMatcher"

// Matches integers
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-more-specific-type-matchers
integerMatcher = "intMatcher"

// Matches decimals
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-more-specific-type-matchers
decimalMatcher = "decimalMatcher"

// Matches nulls
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-more-specific-type-matchers
nullMatcher = "nullMatcher"

// Equality matcher
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-an-equality-matcher
equalityMatcher = "equalityMatcher"

// includes matcher
// https://github.com/pact-foundation/pact-specification/tree/version-3#add-an-include-matcher
includesMatcher = "includesMatcher"
)

0 comments on commit 2b0b5d6

Please sign in to comment.