bdd

package module
v0.0.0-...-3e71f58 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2016 License: MIT Imports: 8 Imported by: 0

README

bdd Build Status Coverage Status GoDoc

Go package for writing BDD-style tests.

Example

package bdd

import . "github.com/101loops/bdd"

var _ = Describe("User Service", func() {
	It("loads users by domain name", func() {
		users, err := service.loadUsersByDomain("acme.com")
		Check(err, IsNil)
		Check(users, HasLen, 2)
		Check(users[0].IsActive, IsTrue)
		Check(users[0].FirstName, Equals, "Roger")
		Check(users[0].Bio, Contains, "ACME").And("Roger").ButNot("fired")
	})
})

Install

go get github.com/stephanos/bdd`

Documentation

http://godoc.org/github.com/stephanos/bdd

Credit

Uses Ginkgo and Gomga internally (both MIT).

License

MIT (see LICENSE).

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Contains = &matcher{
	minArgs: 1,
	maxArgs: 1<<(31) - 1,
	name:    "Contains",
	apply: func(actual interface{}, expected []interface{}) (r Result) {

		var apply func(obtained interface{}, args []interface{}) Result
		switch actual.(type) {
		case string, fmt.Stringer:
			apply = HasSubstr.Apply
		case error:
			apply = ErrorContains.Apply
		default:
			apply = HasElem.Apply
		}

		for _, exp := range expected {
			r = apply(actual, []interface{}{exp})
			if !r.Success {
				return
			}
		}
		return
	},
}

Contains succeeds if actual contains all passed in substrings / elements. Actual must be an error, string, stringer, array, slice or map.

View Source
var Equals = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "Equals",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.Equal(expected[0]), actual)
	},
}

Equal uses reflect.DeepEqual to compare actual with expected. It's strict about types when performing comparisons. It is an error for both actual and expected to be nil. Use IsNil instead.

View Source
var EqualsNum = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "EqualsNum",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically("==", expected[0]), actual)
	},
}

EqualsNum succeeds if actual has the same numeric value as the passed-in number.

View Source
var ErrorContains = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "ErrorContains",
	apply: func(actual interface{}, expected []interface{}) Result {
		err, ok := actual.(error)
		if !ok {
			err := fmt.Errorf("expected an error, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}
		errStr := err.Error()

		substr, ok := toString(expected[0])
		if !ok {
			err := fmt.Errorf("expected a string, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if strings.Contains(errStr, substr) {
			r.Success = true
		} else {
			r.FailureMessage = fmt.Sprintf("Expected\n<error>: %s\n%s\n%s", errStr, " to contain ", format.Object(expected[0], 1))
			r.NegatedFailureMessage = fmt.Sprintf("Expected\n<error>: %s\n%s\n%s", errStr, " not to contain ", format.Object(expected[0], 1))
		}
		return r
	},
}

ErrorContains succeeds if actual is a non-nil error and contains the passed-in substring.

View Source
var HasElem = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasElem",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.ContainElement(expected[0]), actual)
	},
}

HasElem succeeds if actual contains the passed in element. Actual must be an array, slice or map. For maps, HasElem searches through the map's values.

View Source
var HasElems = &matcher{
	minArgs: 1,
	maxArgs: 1<<(31) - 1,
	name:    "HasElems",
	apply: func(actual interface{}, expected []interface{}) (r Result) {
		for _, val := range expected {
			r = resultFromGomega(gomega.ContainElement(val), actual)
			if !r.Success {
				return
			}
		}
		return
	},
}

HasElems succeeds if actual contains all passed in element. Actual must be an array, slice or map. For maps, HasElems searches through the map's values.

View Source
var HasKey = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasKey",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.HaveKey(expected[0]), actual)
	},
}

HasKey succeeds if actual is a map with the passed-in key.

View Source
var HasKeys = &matcher{
	minArgs: 1,
	maxArgs: 1<<(31) - 1,
	name:    "HasKeys",
	apply: func(actual interface{}, expected []interface{}) (r Result) {
		for _, key := range expected {
			r = resultFromGomega(gomega.HaveKey(key), actual)
			if !r.Success {
				return
			}
		}
		return
	},
}

HasKeys succeeds if actual is a map with all passed-in keys.

View Source
var HasLen = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasLen",
	apply: func(actual interface{}, expected []interface{}) Result {
		len, ok := expected[0].(int)
		if !ok {
			err := fmt.Errorf("expected length to be an int, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		return resultFromGomega(gomega.HaveLen(len), actual)
	},
}

HasLen succeeds if actual has the passed-in length. Actual must be of type string, array, map, chan, or slice.

View Source
var HasOccurred = &matcher{
	name: "HasOccurred",
	apply: func(actual interface{}, _ []interface{}) Result {
		if actual == nil {
			return Result{
				FailureMessage:        fmt.Sprintf("expected an error to have occured.  Got:\n%s", format.Object(actual, 1)),
				NegatedFailureMessage: fmt.Sprintf("expected an error to have occured. Got:\n%s", format.Object(actual, 1)),
			}
		}
		return resultFromGomega(gomega.HaveOccurred(), actual)
	},
}

HasOccurred succeeds if actual is a non-nil error.

View Source
var HasPrefix = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasSuffix",
	apply: func(actual interface{}, expected []interface{}) Result {
		str, ok := toString(actual)
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		prefix, ok := toString(expected[0])
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if strings.HasPrefix(str, prefix) {
			r.Success = true
		} else {
			r.FailureMessage = format.Message(actual, " to have prefix ", expected...)
			r.NegatedFailureMessage = format.Message(actual, " not to have prefix ", expected...)
		}
		return r
	},
}

Regexp succeeds if actual is a string or stringer that matches the has the passed-in prefix.

View Source
var HasSubstr = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasSubstr",
	apply: func(actual interface{}, expected []interface{}) Result {
		substr, ok := toString(expected[0])
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		return resultFromGomega(gomega.ContainSubstring(substr), actual)
	},
}

HasSubstr succeeds if actual is a string or stringer that contains the passed-in substring.

View Source
var HasSuffix = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "HasSuffix",
	apply: func(actual interface{}, expected []interface{}) Result {
		str, ok := toString(actual)
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		suffix, ok := toString(expected[0])
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if strings.HasSuffix(str, suffix) {
			r.Success = true
		} else {
			r.FailureMessage = format.Message(actual, " to have suffix ", expected...)
			r.NegatedFailureMessage = format.Message(actual, " not to have suffix ", expected...)
		}
		return r
	},
}

Regexp succeeds if actual is a string or stringer that matches the has the passed-in suffix.

View Source
var IsAfter = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsAfter",
	apply: func(actual interface{}, expected []interface{}) Result {
		after, ok := actual.(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		before, ok := expected[0].(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if after.After(before) {
			r.Success = true
		} else {
			r.FailureMessage = timeMismatch(after, " to be after ", before)
			r.NegatedFailureMessage = timeMismatch(after, " not to be after ", before)
		}
		return r
	},
}

IsAfter succeeds if actual is later than the passed-in time.

View Source
var IsAssignableTo = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsAssignableTo",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeAssignableToTypeOf(expected[0]), actual)
	},
}

IsAssignableTo succeeds if actual is assignable to the type of expected. It will return an error when one of the values is nil.

View Source
var IsBefore = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsBefore",
	apply: func(actual interface{}, expected []interface{}) Result {
		before, ok := actual.(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		after, ok := expected[0].(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if before.Before(after) {
			r.Success = true
		} else {
			r.FailureMessage = timeMismatch(before, " to be before ", after)
			r.NegatedFailureMessage = timeMismatch(before, " not to be before ", after)
		}
		return r
	},
}

IsBefore succeeds if actual is earlier than the passed-in time.

View Source
var IsClosed = &matcher{
	name: "IsClosed",
	apply: func(actual interface{}, _ []interface{}) Result {
		return resultFromGomega(gomega.BeClosed(), actual)
	},
}

IsClosed succeeds if actual is a closed channel.

In order to check whether or not the channel is closed, it is always necessary to read from the channel. You should keep this in mind if you wish to make subsequent assertions about values coming down the channel.

Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before asserting that it is closed.

View Source
var IsEmpty = &matcher{
	name: "IsEmpty",
	apply: func(actual interface{}, _ []interface{}) Result {
		return resultFromGomega(gomega.BeEmpty(), actual)
	},
}

IsEmpty succeeds if actual is empty. Actual must be of type string, array, map, chan, or slice.

View Source
var IsEquivalentTo = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsEquivalentTo",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeEquivalentTo(expected[0]), actual)
	},
}

IsEquivalentTo is more lax than Equal, allowing equality between different types. This is done by converting actual to have the type of expected before attempting equality with reflect.DeepEqual. It is an error for actual and expected to be nil. Use IsNil instead.

View Source
var IsFalse = &matcher{
	name: "IsFalse",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeFalse(), actual)
	},
}

IsFalse succeeds if actual is false

View Source
var IsGreaterThan = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsGreaterThan",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically(">", expected[0]), actual)
	},
}

IsGreaterThan succeeds if actual is a greater than the passed-in number.

View Source
var IsGreaterThanOrEqTo = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsGreaterThanOrEqTo",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically(">=", expected[0]), actual)
	},
}

IsGreaterThanOrEqTo succeeds if actual is a greater than or equal to the passed-in number.

View Source
var IsLessThan = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsLessThan",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically("<", expected[0]), actual)
	},
}

IsLessThan succeeds if actual is a smaller than the passed-in number.

View Source
var IsLessThanOrEqTo = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsLessThanOrEqTo",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically("<=", expected[0]), actual)
	},
}

IsLessThanOrEqTo succeeds if actual is a smaller than or equal to the passed-in number.

View Source
var IsNil = &matcher{
	name: "IsNil",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNil(), actual)
	},
}

IsNil succeeds if actual is nil

View Source
var IsOnOrAfter = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsOnOrAfter",
	apply: func(actual interface{}, expected []interface{}) Result {
		after, ok := actual.(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		before, ok := expected[0].(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if after.After(before) || after.Equal(before) {
			r.Success = true
		} else {
			r.FailureMessage = timeMismatch(after, " to be after or same time as ", before)
			r.NegatedFailureMessage = timeMismatch(after, " to be before ", before)
		}
		return r
	},
}

IsOnOrAfter succeeds if actual is the same time or later than the passed-in time.

View Source
var IsOnOrBefore = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsOnOrBefore",
	apply: func(actual interface{}, expected []interface{}) Result {
		before, ok := actual.(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		after, ok := expected[0].(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if before.Before(after) || before.Equal(after) {
			r.Success = true
		} else {
			r.FailureMessage = timeMismatch(before, " to be before or same time as ", after)
			r.NegatedFailureMessage = timeMismatch(before, " to be after ", after)
		}
		return r
	},
}

IsOnOrBefore succeeds if actual is the same time or earlier than the passed-in time.

View Source
var IsRoughly = &matcher{
	minArgs: 2,
	maxArgs: 2,
	name:    "IsRoughly",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeNumerically("~", expected[0], expected[1]), actual)
	},
}

IsRoughly succeeds if actual has about the same numeric value as the passed-in number. The second passed-in argument defines the threshold.

View Source
var IsSameTimeAs = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "IsSameTimeAs",
	apply: func(actual interface{}, expected []interface{}) Result {
		t1, ok := actual.(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		t2, ok := expected[0].(time.Time)
		if !ok {
			err := fmt.Errorf("expected a time.Time, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		var r Result
		if t1.Equal(t2) {
			r.Success = true
		} else {
			r.FailureMessage = timeMismatch(t1, " to be same time as ", t2)
			r.NegatedFailureMessage = timeMismatch(t1, " not to be same time as ", t2)
		}
		return r
	},
}

IsSameTimeAs succeeds if actual is the same time or later than the passed-in time.

View Source
var IsTrue = &matcher{
	name: "IsTrue",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeTrue(), actual)
	},
}

IsTrue succeeds if actual is true

View Source
var IsZero = &matcher{
	name: "IsZero",
	apply: func(actual interface{}, expected []interface{}) Result {
		return resultFromGomega(gomega.BeZero(), actual)
	},
}

IsZero succeeds if actual is the zero value for its type or if actual is nil.

View Source
var MatchesRegexp = &matcher{
	minArgs: 1,
	maxArgs: 1,
	name:    "MatchesRegexp",
	apply: func(actual interface{}, expected []interface{}) Result {
		regex, ok := toString(expected[0])
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(expected[0], 1))
			return Result{Error: err}
		}

		str, ok := toString(actual)
		if !ok {
			err := fmt.Errorf("expected a string or stringer, got: \n %s", format.Object(actual, 1))
			return Result{Error: err}
		}

		return resultFromGomega(gomega.MatchRegexp(regex), str)
	},
}

Regexp succeeds if actual is a string or stringer that matches the passed-in regexp.

View Source
var NotNil = Not(IsNil)

NotNil succeeds if actual is not nil

View Source
var Panics = &matcher{
	name: "Panics",
	apply: func(actual interface{}, _ []interface{}) Result {
		return resultFromGomega(gomega.Panic(), actual)
	},
}

Panics succeeds if actual is a function that, when invoked, panics. Actual must be a function that takes no arguments and returns no results.

Functions

func AfterEach

func AfterEach(body func(), timeout ...float64) bool

AfterEach blocks are run after It blocks. When multiple AfterEach blocks are defined in nested Describe and Context blocks the innermost AfterEach blocks are run first.

Like It blocks, AfterEach blocks can be made asynchronous by providing a body function that accepts a Done channel

func AfterSuite

func AfterSuite(body interface{}, timeout ...float64) bool

AfterSuite blocks are *always* run after all the specs regardless of whether specs have passed or failed. Moreover, if an interrupt signal (^C) is received it will attempt to run the AfterSuite before exiting.

AfterSuite blocks can be made asynchronous by providing a body function that accepts a Done channel

You may only register *one* AfterSuite handler per test suite.

func BeforeEach

func BeforeEach(body func(), timeout ...float64) bool

BeforeEach blocks are run before It blocks. When multiple BeforeEach blocks are defined in nested Describe and Context blocks the outermost BeforeEach blocks are run first.

Like It blocks, BeforeEach blocks can be made asynchronous by providing a body function that accepts a Done channel

func BeforeSuite

func BeforeSuite(body interface{}, timeout ...float64) bool

BeforeSuite blocks are run just once before any specs are run. When running in parallel, each parallel node process will call BeforeSuite.

BeforeSuite blocks can be made asynchronous by providing a body function that accepts a Done channel

You may only register *one* BeforeSuite handler per test suite.

func CheckFail

func CheckFail(msg string, args ...interface{})

CheckFail will record a failure for the current space and panic. This stops the current spec in its tracks - no subsequent assertions will be called.

func Context

func Context(text string, body func()) bool

Context blocks allow you to organize your specs. They can contain any number of BeforeEach, AfterEach, and It blocks.

Context blocks are usually used inside a Describe block to distinguish various scenarios.

func Describe

func Describe(text string, body func()) bool

Describe blocks allow you to organize your specs. They can contain any number of BeforeEach, AfterEach, and It blocks.

They are the root of every spec.

func It

func It(text string, body interface{}, timeout ...float64) bool

It blocks allow you to organize your specs. They can not contain other blocks, only assertions.

Normally It blocks are run synchronously. To perform asynchronous tests, pass a function that accepts a Done channel. When you do this, you can alsos provide an optional timeout.

func RunSpecs

func RunSpecs(t *testing.T, descr string)

RunSpecs is the entry point for the test runner. You must call this within a Golang testing TestX(t *testing.T) function.

func Scenario

func Scenario(text string, body func()) bool

Scenario blocks are an alias for With blocks.

func Should

func Should(text string, body interface{}, timeout ...float64) bool

Should blocks are an alias for It blocks.

func To

func To(text string, body interface{}, timeout ...float64) bool

To blocks are an alias for It blocks.

func When

func When(text string, body func()) bool

When blocks are an alias for With blocks.

func With

func With(text string, body func()) bool

With blocks are an alias for With blocks.

Types

type Checker

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

Checker makes assertions based on values and matchers.

func Assert

func Assert(obtained interface{}, matcher Matcher, args ...interface{}) *Checker

Assert wraps an actual value allowing assertions to be made on it:

Assert("foo", Equals, "foo")

func Check

func Check(obtained interface{}, matcher Matcher, args ...interface{}) *Checker

Check wraps an actual value allowing assertions to be made on it:

Check("foo", Equals, "foo")

func Expect

func Expect(obtained interface{}, matcher Matcher, args ...interface{}) *Checker

Expect wraps an actual value allowing assertions to be made on it:

Expect("foo", Equals, "foo")

func Ω

func Ω(obtained interface{}, matcher Matcher, args ...interface{}) *Checker

Ω wraps an actual value allowing assertions to be made on it:

Ω("foo", Equals, "foo")

func (*Checker) And

func (chk *Checker) And(args ...interface{}) *Checker

And runs an assertion after the previous one. The obtained value is taken from the previous one. It is only run when the previous assertion was successful.

func (*Checker) ButNot

func (chk *Checker) ButNot(args ...interface{}) *Checker

ButNot runs an assertion after a previous one. The obtained value is taken from the previous one, the previous matcher negated. It is only run when the previous assertion was successful.

type Matcher

type Matcher interface {

	// Apply applies the matcher to the passed-in data and returns a Result.
	Apply(obtained interface{}, args []interface{}) Result
}

Matcher can check if a passed-in value matches the matcher's expectations. Depending on the matcher arguments are required for the matching.

func Not

func Not(m Matcher) Matcher

Not negates a matcher.

type MatcherArgsLimiter

type MatcherArgsLimiter interface {

	// MinArgs is the maximum number of arguments for a matcher.
	MaxArgs() int
}

MatcherArgsLimiter can limit the amount of arguments for a matcher.

type MatcherArgsRequierer

type MatcherArgsRequierer interface {

	// MinArgs is the minimum number of arguments for a matcher.
	MinArgs() int
}

MatcherArgsRequierer can require a certain amount of arguments for a matcher.

type MatcherBuilder

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

func NewMatcherBuilder

func NewMatcherBuilder() *MatcherBuilder

func (*MatcherBuilder) Build

func (mb *MatcherBuilder) Build() Matcher

func (*MatcherBuilder) SetApply

func (mb *MatcherBuilder) SetApply(apply func(obtained interface{}, args []interface{}) Result) *MatcherBuilder

func (*MatcherBuilder) SetMaxArgs

func (mb *MatcherBuilder) SetMaxArgs(max int) *MatcherBuilder

func (*MatcherBuilder) SetMinArgs

func (mb *MatcherBuilder) SetMinArgs(min int) *MatcherBuilder

func (*MatcherBuilder) SetName

func (mb *MatcherBuilder) SetName(name string) *MatcherBuilder

type Result

type Result struct {

	// Success is whether a match was successful.
	Success bool

	// Error is an error that occurred during matching.
	Error error

	// FailureMessage is the message for an unsuccessful match.
	FailureMessage string

	// NegatedFailureMessage is the negated message for an unsuccessful match.
	NegatedFailureMessage string
}

Result is the result from applying a Matcher.

Jump to

Keyboard shortcuts

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