should

package
v0.0.0-...-5c28cf3 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2017 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package should gathers helpful tests (a.k.a. matchers, checks, assertions, /*predicates) for kindrid test libraries.

Design Philosophy

1. The matchers should play well with go's testing library and the `go test` command, but...

2. The matchers should also be usable without a `*testing.T` for use outside of Go's test framework.

3. Performance isn't top priority with the matchers, so reflection is okay.

4. We may import, facade, or duplicate code from other libraries within their licenses as needed to avoid re-implementation. Note code sources in the next section.

5. All exported functions will imply Should, Must, Expect, etc. We won't prefix names, but for readability it's best if function names conjugate well with such a prefix. For instance, `Equal` instead of `ShouldEqual` ().

Patterns

The base pattern we'll use is this:

satisfiesSomething(actual, expected ...interface{}) (passMessage, failMessage string)

And we'll call that type `Assertion`

1. Accept interface arguments.

2. Return one empty string and one non-empty string to signal success or failure.

3. That string should do terse reporting on one line, providing longer explanation after a singl `\n`. TODO: consider stack trace and other debug info after `\n\n\n` or something.

5. Wrappers for other test systems go in the root directory.

Thanks to https://github.com/smartystreets/assertions for their inspiration and excellent assertion library. Be sure to look at the Variables section (below) for those assertions aliased into this package.

Future

- [ ] Do we want to pass in options via flags, magic args ("option:save-golden"), or environment variables (SHOULD_SAVE_GOLDEN=1)?

Index

Constants

View Source
const (
	// ShortSeparator ends the failure message short portion (and begins the long
	// portion)
	ShortSeparator = "\n"

	// ShortLength is an arbitrary length used to shorten failure messages that
	// don't contain ShortSeparator
	ShortLength = 80

	// LongSeparator ends the failure message explanation section (and begins the
	// details)
	LongSeparator = "\n# DETAILS:"

	// DetailsSeparator ends the failure debugging portion (and begins details for
	// debugging asserts and test runner.)
	DetailsSeparator = "\n# INTERNALS:"

	// SectionSeparator separates the long, details, and internals sections.
	SectionSeparator = "\n~~~~~~~~~~\n"
)
View Source
const Ok = ""

Ok is what an Assertion returns when its condition is true.

Variables

View Source
var (
	// AlmostEqual is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	AlmostEqual = smarty.ShouldAlmostEqual
	// BeBetween is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeBetween = smarty.ShouldBeBetween
	// BeBetweenOrEqual is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeBetweenOrEqual = smarty.ShouldBeBetweenOrEqual
	// BeBlank is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeBlank = smarty.ShouldBeBlank
	// BeChronological is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeChronological = smarty.ShouldBeChronological
	// BeEmpty is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeEmpty = smarty.ShouldBeEmpty
	// BeFalse is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeFalse = smarty.ShouldBeFalse
	// BeGreaterThan is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeGreaterThan = smarty.ShouldBeGreaterThan
	// BeGreaterThanOrEqualTo is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeGreaterThanOrEqualTo = smarty.ShouldBeGreaterThanOrEqualTo
	// BeIn is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeIn = smarty.ShouldBeIn
	// BeLessThan is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeLessThan = smarty.ShouldBeLessThan
	// BeLessThanOrEqualTo is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeLessThanOrEqualTo = smarty.ShouldBeLessThanOrEqualTo
	// BeNil is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeNil = smarty.ShouldBeNil
	// BeTrue is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeTrue = smarty.ShouldBeTrue
	// BeZeroValue is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	BeZeroValue = smarty.ShouldBeZeroValue
	// Contain is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	Contain = smarty.ShouldContain
	// ContainKey is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	ContainKey = smarty.ShouldContainKey
	// ContainSubstring is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	ContainSubstring = smarty.ShouldContainSubstring
	// EndWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	EndWith = smarty.ShouldEndWith
	// Equal is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	Equal = smarty.ShouldEqual
	// EqualTrimSpace is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	EqualTrimSpace = smarty.ShouldEqualTrimSpace
	// EqualWithout is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	EqualWithout = smarty.ShouldEqualWithout
	// HappenAfter is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenAfter = smarty.ShouldHappenAfter
	// HappenBefore is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenBefore = smarty.ShouldHappenBefore
	// HappenBetween is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenBetween = smarty.ShouldHappenBetween
	// HappenOnOrAfter is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenOnOrAfter = smarty.ShouldHappenOnOrAfter
	// HappenOnOrBefore is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenOnOrBefore = smarty.ShouldHappenOnOrBefore
	// HappenOnOrBetween is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenOnOrBetween = smarty.ShouldHappenOnOrBetween
	// HappenWithin is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HappenWithin = smarty.ShouldHappenWithin
	// HaveLength is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HaveLength = smarty.ShouldHaveLength
	// HaveSameTypeAs is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	HaveSameTypeAs = smarty.ShouldHaveSameTypeAs
	// Implement is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	Implement = smarty.ShouldImplement
	// NotAlmostEqual is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotAlmostEqual = smarty.ShouldNotAlmostEqual
	// NotBeBetween is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeBetween = smarty.ShouldNotBeBetween
	// NotBeBetweenOrEqual is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeBetweenOrEqual = smarty.ShouldNotBeBetweenOrEqual
	// NotBeBlank is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeBlank = smarty.ShouldNotBeBlank
	// NotBeEmpty is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeEmpty = smarty.ShouldNotBeEmpty
	// NotBeIn is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeIn = smarty.ShouldNotBeIn
	// NotBeNil is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotBeNil = smarty.ShouldNotBeNil
	// NotContain is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotContain = smarty.ShouldNotContain
	// NotContainKey is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotContainKey = smarty.ShouldNotContainKey
	// NotContainSubstring is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotContainSubstring = smarty.ShouldNotContainSubstring
	// NotEndWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotEndWith = smarty.ShouldNotEndWith
	// NotEqual is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotEqual = smarty.ShouldNotEqual
	// NotHappenOnOrBetween is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotHappenOnOrBetween = smarty.ShouldNotHappenOnOrBetween
	// NotHappenWithin is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotHappenWithin = smarty.ShouldNotHappenWithin
	// NotHaveSameTypeAs is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotHaveSameTypeAs = smarty.ShouldNotHaveSameTypeAs
	// NotImplement is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotImplement = smarty.ShouldNotImplement
	// NotPanic is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotPanic = smarty.ShouldNotPanic
	// NotPanicWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotPanicWith = smarty.ShouldNotPanicWith
	// NotPointTo is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotPointTo = smarty.ShouldNotPointTo
	// NotResemble is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotResemble = smarty.ShouldNotResemble
	// NotStartWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	NotStartWith = smarty.ShouldNotStartWith
	// Panic is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	Panic = smarty.ShouldPanic
	// PanicWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	PanicWith = smarty.ShouldPanicWith
	// PointTo is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	PointTo = smarty.ShouldPointTo
	// Resemble is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	Resemble = smarty.ShouldResemble
	// StartWith is imported from smartystreets/assertions. See https://gowalker.org/github.com/smartystreets/assertions
	StartWith = smarty.ShouldStartWith
)

Functions

func AllowFields

func AllowFields(actual interface{}, expected ...interface{}) (fail string)

AllowFields passes if fields in the JSON container or string either don't exist or match expected types.

AllowFields(json, "id", reflect.String)  // assert that there is a field `id` with a  string value.
AllowFields(json, "count", reflect.Float64)  // assert that there is a field `count` with an numeric value.
AllowFields(json, "default", reflect.Interface)  // assert that there is a field `default` with any type of value.

func AlwaysFail

func AlwaysFail(actual interface{}, expected ...interface{}) (fail string)

AlwaysFail succeeds no matter what.

func AlwaysPass

func AlwaysPass(actual interface{}, expected ...interface{}) (fail string)

AlwaysPass succeeds no matter what.

func BeJSON

func BeJSON(actual interface{}, expected ...interface{}) (fail string)

BeJSON asserts that the first argument can be parsed as JSON.

func BeJSONAPI

func BeJSONAPI(actual interface{}, expected ...interface{}) (fail string)

BeJSONAPI passes if actual seems to be a complete JSONAPI-format response where response.data is a multi-object array or a single JSON object.

func BeJSONAPIArray

func BeJSONAPIArray(actual interface{}, expected ...interface{}) (fail string)

BeJSONAPIArray passes if actual seems to be a complete JSONAPI-format response where response.data is a multi-object array.

func BeJSONAPIRecord

func BeJSONAPIRecord(actual interface{}, expected ...interface{}) (fail string)

BeJSONAPIRecord passes if actual seems to be a complete JSONAPI-format response where response.data is a single JSON object.

func BeJSONAPIResourceIdentifier

func BeJSONAPIResourceIdentifier(actual interface{}, expected ...interface{}) (fail string)

BeJSONAPIResourceIdentifier passes if actual seems to be a JSONAPI resource typeentifier. Unlike a full JSONAPI resource object, it has no attributes but MUST refer to a resource in the included list.

func BeJsonapiError

func BeJsonapiError(actual interface{}, expected ...interface{}) (fail string)

func BeSortedByField

func BeSortedByField(actual interface{}, args ...interface{}) (fail string)

BeSortedByField passes if actual parses to JSON and has an element named args[0] in which every element has a field named arg[1] which is sorted, ascending by default, if arg[2] is true, the sort is descending.

func BeValidRecord

func BeValidRecord(json *gabs.Container) (fail string)

BeValidRecord returns a non-blank string if json doesn't comply with JSONAPI rules for a resource record

func BeValidRecordArray

func BeValidRecordArray(json *gabs.Container) (fail string)

BeValidRecordArray returns a non-blank string if json doesn't comply with JSONAPI rules for an array of resource records

func CountAtLeast

func CountAtLeast(actual interface{}, args ...interface{}) (fail string)

CountAtLeast passes if actual parses to a JSON and has an element named args[0] which is an array with >= arg[1] items

func DescribeRequest

func DescribeRequest(req *http.Request) (desc string)

DescribeRequest gives a short-ish report of a request.

func DescribeResponse

func DescribeResponse(rsp *http.Response) (desc string)

DescribeResponse gives a short-ish report of a response

func FailFirst

func FailFirst(msgs ...string) string

FailFirst returns the first non-blank failure string in a list of assertion returns.

func FormatFailure

func FormatFailure(short, long, details, meta string) (result string)

FormatFailure creates a failure message from its components

func HaveFields

func HaveFields(actual interface{}, expected ...interface{}) (fail string)

HaveFields passes if the JSON container or string has fields with certain values or types of values:

HaveFields(json, "id", reflect.String)  // assert that there is a field `id` with a  string value.
HaveFields(json, "count", reflect.Float64)  // assert that there is a field `count` with a numeric value.
HaveFields(json, "count", 100)  // assert that there is a field `count` with a numeric value equal to 100.
HaveFields(json, "default", reflect.Interface)  // assert that there is a field `default` with any type of value.

func HaveOnlyCamelcaseKeys

func HaveOnlyCamelcaseKeys(actual interface{}, ignored ...interface{}) (fail string)

HaveOnlyCamelcaseKeys passes if all the attributes within a JSON container or string contain only upper and lower case ASCII letters.

func HaveOnlyFields

func HaveOnlyFields(actual interface{}, allowed ...interface{}) (fail string)

HaveOnlyFields passes if the JSON container or string has fields with certain types of values:

HaveOnlyFields(json, "id", reflect.String)  // assert that there may a field `id` with a string value.
HaveOnlyFields(json, "count", reflect.Float64)  // assert that there may a field `count` with an numeric value.
HaveOnlyFields(json, "default", reflect.Interface)  // assert that there may a field `default` with any type of value.

func MatchHTTPStatusCode

func MatchHTTPStatusCode(actual interface{}, expected ...interface{}) (fail string)

MatchHTTPStatusCode asserts that the documented and actual HTTP status codes match

func NotJSONAPIError

func NotJSONAPIError(actual interface{}, expected ...interface{}) (fail string)

NotJSONAPIError returns a non-blank string if the JSON appears to be a JSONAPI error response

func ParseFailure

func ParseFailure(msg string) (short, long, details, meta string)

ParseFailure divides a failure message into parts that may be muted depending on verbosity levels

Types

type Assertion

type Assertion func(actual interface{}, expected ...interface{}) (failMessage string)

Assertion provides a generic assertion signature.

actual: value under test (if nil, failMessage CAN document the assertion) expected: optional matcher params

This concept defived from https://github.com/smartystreets/assertions

func Not

func Not(a Assertion) Assertion

Not negates the assertion it wraps. BUG: it doesn't properly rename the Function

type BodiedResponse

type BodiedResponse struct {
	Response *http.Response    // incorporate response
	Raw      string            // the raw body
	Parsed   StructureExplorer // parsed body
}

BodiedResponse holds a response with the Body already read and parsed

func ReadResponseBody

func ReadResponseBody(rsp *http.Response, parser StructureParser) (result *BodiedResponse, err error)

type GabsExplorer

type GabsExplorer gabs.Container

GabsExplorer wraps a StructureExplorer over a gabs.Container

func (*GabsExplorer) Data

func (ge *GabsExplorer) Data() interface{}

Data gets the datum stored within a StructureExplorer

func (*GabsExplorer) GetElement

func (ge *GabsExplorer) GetElement(i int) StructureExplorer

GetElement returns the the i-th element of an array structure (structure[i])

func (*GabsExplorer) GetPath

func (ge *GabsExplorer) GetPath(path string) StructureExplorer

GetPath returns the the element from an object structure by name. If the element isn't found, return's .Data() == nil

func (*GabsExplorer) GetPathCheck

func (ge *GabsExplorer) GetPathCheck(path string) (se StructureExplorer, ok bool)

GetPathCheck returns the the element from an object structure by name

func (*GabsExplorer) IsArray

func (ge *GabsExplorer) IsArray() bool

IsArray returns true if the Structure has ordered values

func (*GabsExplorer) IsObject

func (ge *GabsExplorer) IsObject() bool

IsObject returns true if the Structure explorer holds (possibly) unordered named values

func (*GabsExplorer) Keys

func (ge *GabsExplorer) Keys() (result []string)

Keys returns the names of the values within a structure

func (*GabsExplorer) Len

func (ge *GabsExplorer) Len() int

Len returns the number of items in an array structure

func (*GabsExplorer) PathExists

func (ge *GabsExplorer) PathExists(path string) bool

PathExists returns true if the path exists and its element is non-null element isn't found, return's .Data() == nil

func (*GabsExplorer) String

func (ge *GabsExplorer) String() string

String converts the explorer to a pretty string

type RESTExchange

type RESTExchange struct {
	Request  *http.Request   // The request
	Expected *BodiedResponse // The response we have got
	Actual   *BodiedResponse // The response we actually got
	Err      error           // any error running the request
}

RESTExchange holds one HTTP request, expected response, and actual response

type RESTHarness

type RESTHarness struct {
	API       rest.Describer
	Requester RequestMaker
	Parser    StructureParser
}

RESTHarness provides an engine that can construct requests, run them, and prepare the results for testing.

func (*RESTHarness) RunRequest

func (har *RESTHarness) RunRequest(requestID string, body string, params ...string) (result *RESTExchange)

RunRequest executes an HTTP request and returns the expected and actual response in a *RESTExchange. For the format of params, see rest.Describer's documentation, currently:

Params is a list of strings, [name1, value1, name2, value2, ...]. Keys have one of these prefixes:

	  ":" - indicates an html header as a string
   "&" - indicates a URL param as a string
   "=" - treated as a raw string in path and body templating, ADD QUOTES if you want quotes.

func (*RESTHarness) TestRequest

func (har *RESTHarness) TestRequest(t *testing.T, requestID string, body string, params ...string) (result *RESTExchange)

TestRequest works like RunRequest but makes some basic assertions about the return.

type RequestMaker

type RequestMaker func(*http.Request) (*http.Response, error)

RequesterMaker is a function that the tested code will use to simulate or actually perform a request.

type StructureExplorer

type StructureExplorer interface {
	// String prettyprints the structure.
	String() string

	// Data gets the datum stored within a StructureExplorer
	Data() interface{}

	// IsArray returns true if the Structure has ordered values
	IsArray() bool
	// Len returns the number of items in an array structure
	Len() int
	// GetElement returns the the i-th element of an array structure (structure[i])
	GetElement(i int) StructureExplorer

	// IsObject returns true if the Structure explorer holds (possibly) unordered named  values
	IsObject() bool
	// Has returns true if the key names an attribute in a structure
	Keys() []string
	// PathExists returns true if the structure has an element at path with a non-null value
	PathExists(path string) bool
	// GetPath returns the the element from an object structure by name if path exists and sets ok to true
	GetPath(path string) StructureExplorer
	// GetPathCheck returns (element, true) if path exists it's element has a
	// non-null value. Otherwise it returns (undefined, false.)
	GetPathCheck(path string) (result StructureExplorer, ok bool)
}

StructureExplorer considers generalizing *gabs.Container with the methods needed to test a complex data structure's content and schema.

func ParseJSON

func ParseJSON(actual interface{}) (StructureExplorer, error)

ParseJSON accepts JSON in various formats (including its output format) and returns traversable output.

func ParseJSONExplorer

func ParseJSONExplorer(body string) (StructureExplorer, error)

ParseJSONExplorer implements StructureParser, parsing a JSON string into a GabsExplorer

type StructureParser

type StructureParser func(rawBody string) (StructureExplorer, error)

Jump to

Keyboard shortcuts

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