Skip to content

Commit

Permalink
refactor: remove the v3 package and split into
Browse files Browse the repository at this point in the history
- consumer
- provider
- message
- models
- matchers
- version
- log
  • Loading branch information
mefellows committed Jun 6, 2021
1 parent 1c6a597 commit c11f5a8
Show file tree
Hide file tree
Showing 62 changed files with 1,346 additions and 1,489 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ TEST?=./...

.DEFAULT_GOAL := ci

# ci:: clean deps bin pactv3
ci:: docker deps clean bin test pact #goveralls

docker:
Expand All @@ -29,6 +28,7 @@ deps:
goveralls:
goveralls -service="travis-ci" -coverprofile=coverage.txt -repotoken $(COVERALLS_TOKEN)

cli:
@if [ ! -d pact/bin ]; then\
echo "--- 🐿 Installing Pact CLI dependencies"; \
curl -fsSL https://raw.githubusercontent.com/pact-foundation/pact-ruby-standalone/master/install.sh | bash -x; \
Expand All @@ -41,8 +41,8 @@ install: bin
pact: clean install #docker
@echo "--- 🔨 Running Pact examples"
mkdir -p ./examples/v3/pacts
go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/examples/v3/...
go test -v -timeout=10s -tags=provider -count=1 github.com/pact-foundation/pact-go/examples/v3/...
go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/examples/...
go test -v -timeout=10s -tags=provider -count=1 github.com/pact-foundation/pact-go/examples/...

release:
echo "--- 🚀 Releasing it"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ Pact Go runs as part of your regular Go tests.
We'll run through a simple example to get an understanding the concepts:

1. `go get github.com/pact-foundation/pact-go`
1. `cd $GOPATH/src/github.com/pact-foundation/pact-go/examples/v2/`
1. `cd $GOPATH/src/github.com/pact-foundation/pact-go/examples/`
1. `go test -v -run TestConsumer`.

The simple example looks like this:
Expand Down Expand Up @@ -222,7 +222,7 @@ func TestConsumer(t *testing.T) {
### Provider API Testing

1. `go get github.com/pact-foundation/pact-go`
1. `cd $GOPATH/src/github.com/pact-foundation/pact-go/examples/v2/`
1. `cd $GOPATH/src/github.com/pact-foundation/pact-go/examples/`
1. `go test -v -run TestProvider`.

Here is the Provider test process broker down:
Expand Down
2 changes: 1 addition & 1 deletion command/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"log"
"os"

"github.com/pact-foundation/pact-go/v3/installer"
"github.com/pact-foundation/pact-go/installer"

"github.com/spf13/cobra"
)
Expand Down
16 changes: 9 additions & 7 deletions v3/http.go → consumer/http.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Package v3 contains the main Pact DSL used in the Consumer
// package consumer contains the main Pact DSL used in the Consumer
// collaboration test cases, and Provider contract test verification.
package v3
package consumer

// TODO: setup a proper state machine to prevent actions
// Current issues
Expand All @@ -17,12 +17,14 @@ import (
"path/filepath"
"time"

native "github.com/pact-foundation/pact-go/internal/native/mockserver"
logging "github.com/pact-foundation/pact-go/log"
"github.com/pact-foundation/pact-go/models"
"github.com/pact-foundation/pact-go/utils"
native "github.com/pact-foundation/pact-go/v3/internal/native/mockserver"
)

func init() {
initLogging()
logging.InitLogging()
}

type MockHTTPProviderConfig struct {
Expand Down Expand Up @@ -79,7 +81,7 @@ type MockHTTPProviderConfig struct {
// httpMockProvider is the entrypoint for http consumer tests
// This object is not thread safe
type httpMockProvider struct {
specificationVersion SpecificationVersion
specificationVersion models.SpecificationVersion
config MockHTTPProviderConfig
mockserver *native.MockServer
}
Expand Down Expand Up @@ -126,9 +128,9 @@ func (p *httpMockProvider) validateConfig() error {

p.mockserver = native.NewHTTPMockServer(p.config.Consumer, p.config.Provider)
switch p.specificationVersion {
case V2:
case models.V2:
p.mockserver.WithSpecificationVersion(native.SPECIFICATION_VERSION_V2)
case V3:
case models.V3:
p.mockserver.WithSpecificationVersion(native.SPECIFICATION_VERSION_V3)
}
native.Init()
Expand Down
8 changes: 5 additions & 3 deletions v3/http_v2.go → consumer/http_v2.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package v3
package consumer

import (
"log"

"github.com/pact-foundation/pact-go/models"
)

// HTTPMockProviderV2 is the entrypoint for V3 http consumer tests
Expand All @@ -16,7 +18,7 @@ func NewV2Pact(config MockHTTPProviderConfig) (*HTTPMockProviderV2, error) {
provider := &HTTPMockProviderV2{
httpMockProvider: &httpMockProvider{
config: config,
specificationVersion: V2,
specificationVersion: models.V2,
},
}
err := provider.validateConfig()
Expand All @@ -36,7 +38,7 @@ func (p *HTTPMockProviderV2) AddInteraction() *InteractionV2 {

i := &InteractionV2{
Interaction: Interaction{
specificationVersion: V2,
specificationVersion: models.V2,
interaction: interaction,
},
}
Expand Down
8 changes: 5 additions & 3 deletions v3/http_v3.go → consumer/http_v3.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package v3
package consumer

import (
"log"

"github.com/pact-foundation/pact-go/models"
)

// HTTPMockProviderV3 is the entrypoint for V3 http consumer tests
Expand All @@ -15,7 +17,7 @@ func NewV3Pact(config MockHTTPProviderConfig) (*HTTPMockProviderV3, error) {
provider := &HTTPMockProviderV3{
httpMockProvider: &httpMockProvider{
config: config,
specificationVersion: V3,
specificationVersion: models.V3,
},
}
err := provider.validateConfig()
Expand All @@ -35,7 +37,7 @@ func (p *HTTPMockProviderV3) AddInteraction() *InteractionV3 {

i := &InteractionV3{
Interaction: Interaction{
specificationVersion: V3,
specificationVersion: models.V3,
interaction: interaction,
},
}
Expand Down
33 changes: 18 additions & 15 deletions v3/interaction.go → consumer/interaction.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package v3
package consumer

import (
"encoding/json"
"fmt"
"log"
"strings"

"github.com/pact-foundation/pact-go/v3/internal/native/mockserver"
"github.com/pact-foundation/pact-go/internal/native/mockserver"
"github.com/pact-foundation/pact-go/matchers"
"github.com/pact-foundation/pact-go/models"
"github.com/pact-foundation/pact-go/utils"
)

// Interaction is the main implementation of the Pact interface.
type Interaction struct {
// Reference to the native rust handle
interaction *mockserver.Interaction
specificationVersion SpecificationVersion
specificationVersion models.SpecificationVersion
}

type InteractionRequest struct {
Expand All @@ -39,7 +42,7 @@ func (i *Interaction) UponReceiving(description string) *Interaction {
// WithRequest specifies the details of the HTTP request that will be used to
// confirm that the Provider provides an API listening on the given interface.
// Mandatory.
func (i *Interaction) WithRequest(method Method, path Matcher) *InteractionRequest {
func (i *Interaction) WithRequest(method models.Method, path matchers.Matcher) *InteractionRequest {
i.interaction.WithRequest(string(method), path)

return &InteractionRequest{
Expand All @@ -48,13 +51,13 @@ func (i *Interaction) WithRequest(method Method, path Matcher) *InteractionReque
}
}

func (i *InteractionRequest) WithQuery(key string, values ...Matcher) *InteractionRequest {
func (i *InteractionRequest) WithQuery(key string, values ...matchers.Matcher) *InteractionRequest {
i.interactionHandle.WithQuery(keyValuesToMapStringArrayInterface(key, values...))

return i
}

func (i *InteractionRequest) WithHeader(key string, values ...Matcher) *InteractionRequest {
func (i *InteractionRequest) WithHeader(key string, values ...matchers.Matcher) *InteractionRequest {
i.interactionHandle.WithRequestHeaders(keyValuesToMapStringArrayInterface(key, values...))

return i
Expand All @@ -70,7 +73,7 @@ func (i *InteractionRequest) WithJSONBody(body interface{}) *InteractionRequest
// Check if someone tried to add an object as a string representation
// as per original allowed implementation, e.g.
// { "foo": "bar", "baz": like("bat") }
if isJSONFormattedObject(string(s)) {
if utils.IsJSONFormattedObject(string(s)) {
log.Println("[WARN] request body appears to be a JSON formatted object, " +
"no matching will occur. Support for structured strings has been" +
"deprecated as of 0.13.0. Please use the JSON() method instead")
Expand All @@ -92,7 +95,7 @@ func (i *InteractionRequest) WithBody(contentType string, body []byte) *Interact
// Check if someone tried to add an object as a string representation
// as per original allowed implementation, e.g.
// { "foo": "bar", "baz": like("bat") }
if isJSONFormattedObject(string(body)) {
if utils.IsJSONFormattedObject(string(body)) {
log.Println("[WARN] request body appears to be a JSON formatted object, " +
"no matching will occur. Support for structured strings has been" +
"deprecated as of 0.13.0. Please use the JSON() method instead")
Expand All @@ -104,7 +107,7 @@ func (i *InteractionRequest) WithBody(contentType string, body []byte) *Interact
}

func (i *InteractionRequest) WithBodyMatch(body interface{}) *InteractionRequest {
i.interactionHandle.WithJSONRequestBody(MatchV2(body))
i.interactionHandle.WithJSONRequestBody(matchers.MatchV2(body))

return i
}
Expand All @@ -122,7 +125,7 @@ func (i *InteractionRequest) WillRespondWith(status int) *InteractionResponse {
}
}

func (i *InteractionResponse) WithHeader(key string, values ...Matcher) *InteractionResponse {
func (i *InteractionResponse) WithHeader(key string, values ...matchers.Matcher) *InteractionResponse {
i.interactionHandle.WithRequestHeaders(keyValuesToMapStringArrayInterface(key, values...))

return i
Expand All @@ -138,7 +141,7 @@ func (i *InteractionResponse) WithJSONBody(body interface{}) *InteractionRespons
// Check if someone tried to add an object as a string representation
// as per original allowed implementation, e.g.
// { "foo": "bar", "baz": like("bat") }
if isJSONFormattedObject(string(s)) {
if utils.IsJSONFormattedObject(string(s)) {
log.Println("[WARN] request body appears to be a JSON formatted object, " +
"no matching will occur. Support for structured strings has been" +
"deprecated as of 0.13.0. Please use the JSON() method instead")
Expand All @@ -162,12 +165,12 @@ func (i *InteractionResponse) WithBody(contentType string, body []byte) *Interac
}

func (i *InteractionResponse) WithBodyMatch(body interface{}) *InteractionResponse {
i.interactionHandle.WithJSONRequestBody(MatchV2(body))
i.interactionHandle.WithJSONRequestBody(matchers.MatchV2(body))

return i
}

func validateMatchers(version SpecificationVersion, obj interface{}) error {
func validateMatchers(version models.SpecificationVersion, obj interface{}) error {
if obj == nil {
return nil
}
Expand All @@ -193,7 +196,7 @@ func validateMatchers(version SpecificationVersion, obj interface{}) error {
return nil
}

func hasMatcherGreaterThanSpec(version SpecificationVersion, obj map[string]interface{}) []string {
func hasMatcherGreaterThanSpec(version models.SpecificationVersion, obj map[string]interface{}) []string {
results := make([]string, 0)

for k, v := range obj {
Expand Down Expand Up @@ -235,7 +238,7 @@ func hasMatcherGreaterThanSpec(version SpecificationVersion, obj map[string]inte
// return i
// }

func keyValuesToMapStringArrayInterface(key string, values ...Matcher) map[string][]interface{} {
func keyValuesToMapStringArrayInterface(key string, values ...matchers.Matcher) map[string][]interface{} {
q := make(map[string][]interface{})
for _, v := range values {
q[key] = append(q[key], v)
Expand Down
26 changes: 14 additions & 12 deletions v3/interaction_test.go → consumer/interaction_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package v3
package consumer

import (
"errors"
"testing"

"github.com/pact-foundation/pact-go/matchers"
"github.com/pact-foundation/pact-go/models"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -34,22 +36,22 @@ func TestInteraction(t *testing.T) {
{
description: "v3 matches should error",
test: map[string]interface{}{
"dateTime": Regex("2020-01-01", "[0-9\\-]+"),
"name": S("Billy"),
"superstring": Includes("foo"),
"nested": map[string]Matcher{
"val": Includes("val"),
"dateTime": matchers.Regex("2020-01-01", "[0-9\\-]+"),
"name": matchers.S("Billy"),
"superstring": matchers.Includes("foo"),
"nested": map[string]matchers.Matcher{
"val": matchers.Includes("val"),
},
},
want: errors.New("test error"),
},
{
description: "v2 matches should no terror",
test: map[string]interface{}{
"dateTime": Regex("2020-01-01", "[0-9\\-]+"),
"name": S("Billy"),
"nested": map[string]Matcher{
"val": Regex("val", ".*"),
"dateTime": matchers.Regex("2020-01-01", "[0-9\\-]+"),
"name": matchers.S("Billy"),
"nested": map[string]matchers.Matcher{
"val": matchers.Regex("val", ".*"),
},
},
want: nil,
Expand All @@ -58,9 +60,9 @@ func TestInteraction(t *testing.T) {

for _, test := range testCases {
if test.want != nil {
assert.Error(t, validateMatchers(V2, test.test), test.description)
assert.Error(t, validateMatchers(models.V2, test.test), test.description)
} else {
assert.NoError(t, validateMatchers(V2, test.test), test.description)
assert.NoError(t, validateMatchers(models.V2, test.test), test.description)
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion v3/interaction_v2.go → consumer/interaction_v2.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v3
package consumer

// InteractionV2 sets up an expected request/response on a mock server
// and is replayed on the provider side for verification
Expand Down
4 changes: 2 additions & 2 deletions v3/interaction_v2_test.go → consumer/interaction_v2_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v3
package consumer

// func TestInteraction_NewInteraction(t *testing.T) {
// i := &InteractionV2{}
Expand Down Expand Up @@ -120,7 +120,7 @@ package v3
// }

// for testCase, want := range testCases {
// if isJSONFormattedObject(testCase) != want {
// if utils.IsJSONFormattedObject(testCase) != want {
// t.Fatal("want", want, "got", !want, "for test case", testCase)
// }
// }
Expand Down
16 changes: 16 additions & 0 deletions consumer/interaction_v3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package consumer

import "github.com/pact-foundation/pact-go/models"

// InteractionV3 sets up an expected request/response on a mock server
// and is replayed on the provider side for verification
type InteractionV3 struct {
Interaction
}

// Given specifies a provider state. Optional.
func (i *InteractionV3) Given(state models.ProviderStateV3) *InteractionV3 {
i.Interaction.interaction.GivenWithParameter(state.Name, state.Parameters)

return i
}
Loading

0 comments on commit c11f5a8

Please sign in to comment.