copper

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2024 License: MPL-2.0 Imports: 14 Imported by: 0

README

Copper

Copper

Copper keeps REST APIs honest

Introduction

Copper is a test library intended to verify that API contracts are upheld when exercising a REST API from a test. This is very useful for verifying that all paths and functionality that is declared in an API spec is in fact tested.

Why?

Implementing these checks in tests will allow your application to check API correctness and backwards compatibility before the code ever hits production. As long as the specification and application is not edited in the same change set, breaking changes will also be prevented. Since the verification runs during builds only, there is no overhead during production use, nor does Copper impose any sort of requirements on the implementation other than that it needs to conform to its own specification.

Usage

Copper is used from integration style tests. Wrap the HTTP client being used in copper and then use that client for performing the API calls in your test case. This works best from a single main test for a single spec, and then subtest for the specific endpoints/use cases.

func TestVersion1(t *testing.T) {
	f, err := os.Open("spec.yaml")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	client, err := copper.WrapClient(http.DefaultClient, f)
	if err != nil {
		t.Fatal(err)
	}

	t.Run("ping", func(t *testing.T) {
		testPingEndpoints(t, client)
	}
	t.Run("other use case that I have", func(t *testing.T) {
		testMyOtherThing(t, client)
	}
	
	// Verifying at the end checks that all paths, methods and responses are covered and that no extra paths have been hit.
	client.Verify(t)
}

See the examples for complete examples.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotChecked      = errors.New("endpoint not checked")
	ErrNotPartOfSpec   = errors.New("response is not part of spec")
	ErrResponseInvalid = errors.New("response invalid")
	ErrRequestInvalid  = errors.New("request invalid")
)

Functions

This section is empty.

Types

type Option

type Option func(c *config)

func WithBasePath

func WithBasePath(path string) Option

WithBasePath is a functional Option for setting the base path of the validator.

type ValidatingClient

type ValidatingClient struct {
	*Verifier
	// contains filtered or unexported fields
}

ValidatingClient provides an HTTP client, and wraps the main methods, recording any and all paths that are being called.

func WrapClient

func WrapClient(c *http.Client, spec io.Reader, opts ...Option) (*ValidatingClient, error)

WrapClient takes an HTTP client and io.Reader for the OpenAPI spec. The spec is parsed, and wraps the client so that the outbound calls are now recorded when made.

func (*ValidatingClient) Delete

func (v *ValidatingClient) Delete(url string) (resp *http.Response, err error)

Delete records response for HTTP DELETE requests

func (*ValidatingClient) Do

Do takes any http.Request, sends it to the server it and then records the result.

func (*ValidatingClient) Get

func (v *ValidatingClient) Get(url string) (resp *http.Response, err error)

Get is a convenience method for recording responses for HTTP GET requests

func (*ValidatingClient) Head

func (v *ValidatingClient) Head(url string) (resp *http.Response, err error)

Head is a convenience method for recording responses for HTTP HEAD requests

func (*ValidatingClient) Post

func (v *ValidatingClient) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error)

Post is a convenience method for recording responses for HTTP POST requests

func (*ValidatingClient) Put

func (v *ValidatingClient) Put(url string, contentType string, body io.Reader) (resp *http.Response, err error)

Put is a convenience method for recording responses for HTTP PUT requests

func (*ValidatingClient) WithClient

func (v *ValidatingClient) WithClient(c *http.Client) (*ValidatingClient, error)

WithClient returns a new client using the same validator, but a new client. This can be useful to change transport or authorization settings, while still contributing to the same spec validation.

type Verifier

type Verifier struct {
	// contains filtered or unexported fields
}

func NewVerifier

func NewVerifier(specBytes []byte, basePath string) (*Verifier, error)

NewVerifier takes bytes for an OpenAPI spec and a base path, and then returns a new Verifier that contains the declared paths.

func (*Verifier) Error

func (v *Verifier) Error() error

Error return the current collection of errors in the verifier.

func (*Verifier) Record

func (v *Verifier) Record(res *http.Response)

func (*Verifier) Verify

func (v *Verifier) Verify(t *testing.T)

Verify will cause the given test context to fail with an error if Error returns a non-nil error.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL