README

GoDoc

oglematchers is a package for the Go programming language containing a set of matchers, useful in a testing or mocking framework, inspired by and mostly compatible with Google Test for C++ and Google JS Test. The package is used by the ogletest testing framework and oglemock mocking framework, which may be more directly useful to you, but can be generically used elsewhere as well.

A "matcher" is simply an object with a Matches method defining a set of golang values matched by the matcher, and a Description method describing that set. For example, here are some matchers:

// Numbers
Equals(17.13)
LessThan(19)

// Strings
Equals("taco")
HasSubstr("burrito")
MatchesRegex("t.*o")

// Combining matchers
AnyOf(LessThan(17), GreaterThan(19))

There are lots more; see here for a reference. You can also add your own simply by implementing the oglematchers.Matcher interface.

Installation

First, make sure you have installed Go 1.0.2 or newer. See here for instructions.

Use the following command to install oglematchers and keep it up to date:

go get -u github.com/jacobsa/oglematchers

Documentation

See here for documentation. Alternatively, you can install the package and then use godoc:

godoc github.com/jacobsa/oglematchers
Expand ▾ Collapse ▴

Documentation

Overview

    Package oglematchers provides a set of matchers useful in a testing or mocking framework. These matchers are inspired by and mostly compatible with Google Test for C++ and Google JS Test.

    This package is used by github.com/jacobsa/ogletest and github.com/jacobsa/oglemock, which may be more directly useful if you're not writing your own testing package or defining your own matchers.

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    This section is empty.

    Types

    type FatalError

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

      FatalError is an implementation of the error interface that may be returned from matchers, indicating the error should be propagated. Returning a *FatalError indicates that the matcher doesn't process values of the supplied type, or otherwise doesn't know how to handle the value.

      For example, if GreaterThan(17) returned false for the value "taco" without a fatal error, then Not(GreaterThan(17)) would return true. This is technically correct, but is surprising and may mask failures where the wrong sort of matcher is accidentally used. Instead, GreaterThan(17) can return a fatal error, which will be propagated by Not().

      func NewFatalError

      func NewFatalError(s string) *FatalError

        NewFatalError creates a FatalError struct with the supplied error text.

        func (*FatalError) Error

        func (e *FatalError) Error() string

        type Matcher

        type Matcher interface {
        	// Check whether the supplied value belongs to the the set defined by the
        	// matcher. Return a non-nil error if and only if it does not.
        	//
        	// The error describes why the value doesn't match. The error text is a
        	// relative clause that is suitable for being placed after the value. For
        	// example, a predicate that matches strings with a particular substring may,
        	// when presented with a numerical value, return the following error text:
        	//
        	//     "which is not a string"
        	//
        	// Then the failure message may look like:
        	//
        	//     Expected: has substring "taco"
        	//     Actual:   17, which is not a string
        	//
        	// If the error is self-apparent based on the description of the matcher, the
        	// error text may be empty (but the error still non-nil). For example:
        	//
        	//     Expected: 17
        	//     Actual:   19
        	//
        	// If you are implementing a new matcher, see also the documentation on
        	// FatalError.
        	Matches(candidate interface{}) error
        
        	// Description returns a string describing the property that values matching
        	// this matcher have, as a verb phrase where the subject is the value. For
        	// example, "is greather than 17" or "has substring "taco"".
        	Description() string
        }

          A Matcher is some predicate implicitly defining a set of values that it matches. For example, GreaterThan(17) matches all numeric values greater than 17, and HasSubstr("taco") matches all strings with the substring "taco".

          Matchers are typically exposed to tests via constructor functions like HasSubstr. In order to implement such a function you can either define your own matcher type or use NewMatcher.

          func AllOf

          func AllOf(matchers ...Matcher) Matcher

            AllOf accepts a set of matchers S and returns a matcher that follows the algorithm below when considering a candidate c:

            1. Return true if for every Matcher m in S, m matches c.
            
            2. Otherwise, if there is a matcher m in S such that m returns a fatal
               error for c, return that matcher's error message.
            
            3. Otherwise, return false with the error from some wrapped matcher.
            

            This is akin to a logical AND operation for matchers.

            func Any

            func Any() Matcher

              Any returns a matcher that matches any value.

              func AnyOf

              func AnyOf(vals ...interface{}) Matcher

                AnyOf accepts a set of values S and returns a matcher that follows the algorithm below when considering a candidate c:

                1. If there exists a value m in S such that m implements the Matcher
                   interface and m matches c, return true.
                
                2. Otherwise, if there exists a value v in S such that v does not implement
                   the Matcher interface and the matcher Equals(v) matches c, return true.
                
                3. Otherwise, if there is a value m in S such that m implements the Matcher
                   interface and m returns a fatal error for c, return that fatal error.
                
                4. Otherwise, return false.
                

                This is akin to a logical OR operation for matchers, with non-matchers x being treated as Equals(x).

                func Contains

                func Contains(x interface{}) Matcher

                  Return a matcher that matches arrays slices with at least one element that matches the supplied argument. If the argument x is not itself a Matcher, this is equivalent to Contains(Equals(x)).

                  func DeepEquals

                  func DeepEquals(x interface{}) Matcher

                    DeepEquals returns a matcher that matches based on 'deep equality', as defined by the reflect package. This matcher requires that values have identical types to x.

                    func ElementsAre

                    func ElementsAre(M ...interface{}) Matcher

                      Given a list of arguments M, ElementsAre returns a matcher that matches arrays and slices A where all of the following hold:

                      *  A is the same length as M.
                      
                      *  For each i < len(A) where M[i] is a matcher, A[i] matches M[i].
                      
                      *  For each i < len(A) where M[i] is not a matcher, A[i] matches
                         Equals(M[i]).
                      

                      func Equals

                      func Equals(x interface{}) Matcher

                        Equals(x) returns a matcher that matches values v such that v and x are equivalent. This includes the case when the comparison v == x using Go's built-in comparison operator is legal (except for structs, which this matcher does not support), but for convenience the following rules also apply:

                        *  Type checking is done based on underlying types rather than actual
                           types, so that e.g. two aliases for string can be compared:
                        
                               type stringAlias1 string
                               type stringAlias2 string
                        
                               a := "taco"
                               b := stringAlias1("taco")
                               c := stringAlias2("taco")
                        
                               ExpectTrue(a == b)  // Legal, passes
                               ExpectTrue(b == c)  // Illegal, doesn't compile
                        
                               ExpectThat(a, Equals(b))  // Passes
                               ExpectThat(b, Equals(c))  // Passes
                        
                        *  Values of numeric type are treated as if they were abstract numbers, and
                           compared accordingly. Therefore Equals(17) will match int(17),
                           int16(17), uint(17), float32(17), complex64(17), and so on.
                        

                        If you want a stricter matcher that contains no such cleverness, see IdenticalTo instead.

                        Arrays are supported by this matcher, but do not participate in the exceptions above. Two arrays compared with this matcher must have identical types, and their element type must itself be comparable according to Go's == operator.

                        func Error

                        func Error(m Matcher) Matcher

                          Error returns a matcher that matches non-nil values implementing the built-in error interface for whom the return value of Error() matches the supplied matcher.

                          For example:

                          err := errors.New("taco burrito")
                          
                          Error(Equals("taco burrito"))  // matches err
                          Error(HasSubstr("taco"))       // matches err
                          Error(HasSubstr("enchilada"))  // doesn't match err
                          

                          func GreaterOrEqual

                          func GreaterOrEqual(x interface{}) Matcher

                            GreaterOrEqual returns a matcher that matches integer, floating point, or strings values v such that v >= x. Comparison is not defined between numeric and string types, but is defined between all integer and floating point types.

                            x must itself be an integer, floating point, or string type; otherwise, GreaterOrEqual will panic.

                            func GreaterThan

                            func GreaterThan(x interface{}) Matcher

                              GreaterThan returns a matcher that matches integer, floating point, or strings values v such that v > x. Comparison is not defined between numeric and string types, but is defined between all integer and floating point types.

                              x must itself be an integer, floating point, or string type; otherwise, GreaterThan will panic.

                              func HasSameTypeAs

                              func HasSameTypeAs(p interface{}) Matcher

                                HasSameTypeAs returns a matcher that matches values with exactly the same type as the supplied prototype.

                                func HasSubstr

                                func HasSubstr(s string) Matcher

                                  HasSubstr returns a matcher that matches strings containing s as a substring.

                                  func IdenticalTo

                                  func IdenticalTo(x interface{}) Matcher

                                    IdenticalTo(x) returns a matcher that matches values v with type identical to x such that:

                                    1. If v and x are of a reference type (slice, map, function, channel), then
                                       they are either both nil or are references to the same object.
                                    
                                    2. Otherwise, if v and x are not of a reference type but have a valid type,
                                       then v == x.
                                    

                                    If v and x are both the invalid type (which results from the predeclared nil value, or from nil interface variables), then the matcher is satisfied.

                                    This function will panic if x is of a value type that is not comparable. For example, x cannot be an array of functions.

                                    func LessOrEqual

                                    func LessOrEqual(x interface{}) Matcher

                                      LessOrEqual returns a matcher that matches integer, floating point, or strings values v such that v <= x. Comparison is not defined between numeric and string types, but is defined between all integer and floating point types.

                                      x must itself be an integer, floating point, or string type; otherwise, LessOrEqual will panic.

                                      func LessThan

                                      func LessThan(x interface{}) Matcher

                                        LessThan returns a matcher that matches integer, floating point, or strings values v such that v < x. Comparison is not defined between numeric and string types, but is defined between all integer and floating point types.

                                        x must itself be an integer, floating point, or string type; otherwise, LessThan will panic.

                                        func MatchesRegexp

                                        func MatchesRegexp(pattern string) Matcher

                                          MatchesRegexp returns a matcher that matches strings and byte slices whose contents match the supplied regular expression. The semantics are those of regexp.Match. In particular, that means the match is not implicitly anchored to the ends of the string: MatchesRegexp("bar") will match "foo bar baz".

                                          func NewMatcher

                                          func NewMatcher(
                                          	predicate func(interface{}) error,
                                          	description string) Matcher

                                            Create a matcher with the given description and predicate function, which will be invoked to handle calls to Matchers.

                                            Using this constructor may be a convenience over defining your own type that implements Matcher if you do not need any logic in your Description method.

                                            func Not

                                            func Not(m Matcher) Matcher

                                              Not returns a matcher that inverts the set of values matched by the wrapped matcher. It does not transform the result for values for which the wrapped matcher returns a fatal error.

                                              func Panics

                                              func Panics(m Matcher) Matcher

                                                Panics matches zero-arg functions which, when invoked, panic with an error that matches the supplied matcher.

                                                NOTE(jacobsa): This matcher cannot detect the case where the function panics using panic(nil), by design of the language. See here for more info:

                                                http://goo.gl/9aIQL
                                                

                                                func Pointee

                                                func Pointee(m Matcher) Matcher

                                                  Return a matcher that matches non-nil pointers whose pointee matches the wrapped matcher.