123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Package assertions contains the implementations for all assertions which
- // are referenced in goconvey's `convey` package
- // (github.com/smartystreets/goconvey/convey) and gunit (github.com/smartystreets/gunit)
- // for use with the So(...) method.
- // They can also be used in traditional Go test functions and even in
- // applications.
- //
- // Many of the assertions lean heavily on work done by Aaron Jacobs in his excellent oglematchers library.
- // (https://github.com/jacobsa/oglematchers)
- // The ShouldResemble assertion leans heavily on work done by Daniel Jacques in his very helpful go-render library.
- // (https://github.com/luci/go-render)
- package assertions
- import (
- "fmt"
- "runtime"
- )
- // By default we use a no-op serializer. The actual Serializer provides a JSON
- // representation of failure results on selected assertions so the goconvey
- // web UI can display a convenient diff.
- var serializer Serializer = new(noopSerializer)
- // GoConveyMode provides control over JSON serialization of failures. When
- // using the assertions in this package from the convey package JSON results
- // are very helpful and can be rendered in a DIFF view. In that case, this function
- // will be called with a true value to enable the JSON serialization. By default,
- // the assertions in this package will not serializer a JSON result, making
- // standalone ussage more convenient.
- func GoConveyMode(yes bool) {
- if yes {
- serializer = newSerializer()
- } else {
- serializer = new(noopSerializer)
- }
- }
- type testingT interface {
- Error(args ...interface{})
- }
- type Assertion struct {
- t testingT
- failed bool
- }
- // New swallows the *testing.T struct and prints failed assertions using t.Error.
- // Example: assertions.New(t).So(1, should.Equal, 1)
- func New(t testingT) *Assertion {
- return &Assertion{t: t}
- }
- // Failed reports whether any calls to So (on this Assertion instance) have failed.
- func (this *Assertion) Failed() bool {
- return this.failed
- }
- // So calls the standalone So function and additionally, calls t.Error in failure scenarios.
- func (this *Assertion) So(actual interface{}, assert assertion, expected ...interface{}) bool {
- ok, result := So(actual, assert, expected...)
- if !ok {
- this.failed = true
- _, file, line, _ := runtime.Caller(1)
- this.t.Error(fmt.Sprintf("\n%s:%d\n%s", file, line, result))
- }
- return ok
- }
- // So is a convenience function (as opposed to an inconvenience function?)
- // for running assertions on arbitrary arguments in any context, be it for testing or even
- // application logging. It allows you to perform assertion-like behavior (and get nicely
- // formatted messages detailing discrepancies) but without the program blowing up or panicking.
- // All that is required is to import this package and call `So` with one of the assertions
- // exported by this package as the second parameter.
- // The first return parameter is a boolean indicating if the assertion was true. The second
- // return parameter is the well-formatted message showing why an assertion was incorrect, or
- // blank if the assertion was correct.
- //
- // Example:
- //
- // if ok, message := So(x, ShouldBeGreaterThan, y); !ok {
- // log.Println(message)
- // }
- //
- func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) {
- if result := so(actual, assert, expected...); len(result) == 0 {
- return true, result
- } else {
- return false, result
- }
- }
- // so is like So, except that it only returns the string message, which is blank if the
- // assertion passed. Used to facilitate testing.
- func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string {
- return assert(actual, expected...)
- }
- // assertion is an alias for a function with a signature that the So()
- // function can handle. Any future or custom assertions should conform to this
- // method signature. The return value should be an empty string if the assertion
- // passes and a well-formed failure message if not.
- type assertion func(actual interface{}, expected ...interface{}) string
- ////////////////////////////////////////////////////////////////////////////
|