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
- Variables
- func AllowFields(actual interface{}, expected ...interface{}) (fail string)
- func AlwaysFail(actual interface{}, expected ...interface{}) (fail string)
- func AlwaysPass(actual interface{}, expected ...interface{}) (fail string)
- func BeJSON(actual interface{}, expected ...interface{}) (fail string)
- func BeJSONAPI(actual interface{}, expected ...interface{}) (fail string)
- func BeJSONAPIArray(actual interface{}, expected ...interface{}) (fail string)
- func BeJSONAPIRecord(actual interface{}, expected ...interface{}) (fail string)
- func BeJSONAPIResourceIdentifier(actual interface{}, expected ...interface{}) (fail string)
- func BeJsonapiError(actual interface{}, expected ...interface{}) (fail string)
- func BeSortedByField(actual interface{}, args ...interface{}) (fail string)
- func BeValidRecord(json *gabs.Container) (fail string)
- func BeValidRecordArray(json *gabs.Container) (fail string)
- func CountAtLeast(actual interface{}, args ...interface{}) (fail string)
- func DescribeRequest(req *http.Request) (desc string)
- func DescribeResponse(rsp *http.Response) (desc string)
- func FailFirst(msgs ...string) string
- func FormatFailure(short, long, details, meta string) (result string)
- func HaveFields(actual interface{}, expected ...interface{}) (fail string)
- func HaveOnlyCamelcaseKeys(actual interface{}, ignored ...interface{}) (fail string)
- func HaveOnlyFields(actual interface{}, allowed ...interface{}) (fail string)
- func MatchHTTPStatusCode(actual interface{}, expected ...interface{}) (fail string)
- func NotJSONAPIError(actual interface{}, expected ...interface{}) (fail string)
- func ParseFailure(msg string) (short, long, details, meta string)
- type Assertion
- type BodiedResponse
- type GabsExplorer
- func (ge *GabsExplorer) Data() interface{}
- func (ge *GabsExplorer) GetElement(i int) StructureExplorer
- func (ge *GabsExplorer) GetPath(path string) StructureExplorer
- func (ge *GabsExplorer) GetPathCheck(path string) (se StructureExplorer, ok bool)
- func (ge *GabsExplorer) IsArray() bool
- func (ge *GabsExplorer) IsObject() bool
- func (ge *GabsExplorer) Keys() (result []string)
- func (ge *GabsExplorer) Len() int
- func (ge *GabsExplorer) PathExists(path string) bool
- func (ge *GabsExplorer) String() string
- type RESTExchange
- type RESTHarness
- type RequestMaker
- type StructureExplorer
- type StructureParser
Constants ¶
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" )
const Ok = ""
Ok is what an Assertion returns when its condition is true.
Variables ¶
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 ¶
BeValidRecord returns a non-blank string if json doesn't comply with JSONAPI rules for a resource record
func BeValidRecordArray ¶
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 ¶
DescribeRequest gives a short-ish report of a request.
func DescribeResponse ¶
DescribeResponse gives a short-ish report of a response
func FailFirst ¶
FailFirst returns the first non-blank failure string in a list of assertion returns.
func FormatFailure ¶
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 ¶
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
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 ¶
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 ¶
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)