| package assert |
| |
| import ( |
| "fmt" |
| "io" |
| "os" |
| "reflect" |
| "runtime" |
| "strings" |
| ) |
| |
| // Result contains a single assertion failure as an error. |
| // You should not create a Result directly, use So instead. |
| // Once created, a Result is read-only and only allows |
| // queries using the provided methods. |
| type Result struct { |
| invocation string |
| err error |
| |
| stdout io.Writer |
| logger *logger |
| } |
| |
| // So is a convenience function (as opposed to an inconvenience function?) |
| // for running assertions on arbitrary arguments in any context. It allows you to perform |
| // assertion-like behavior and decide what happens in the event of a failure. |
| // It is a variant of assertions.So in every respect except its return value. |
| // In this case, the return value is a *Result which possesses several of its |
| // own convenience methods: |
| // |
| // fmt.Println(assert.So(1, should.Equal, 1)) // Calls String() and prints the representation of the assertion. |
| // assert.So(1, should.Equal, 1).Println() // Calls fmt.Print with the failure message and file:line header. |
| // assert.So(1, should.Equal, 1).Log() // Calls log.Print with the failure message and file:line header. |
| // assert.So(1, should.Equal, 1).Panic() // Calls log.Panic with the failure message and file:line header. |
| // assert.So(1, should.Equal, 1).Fatal() // Calls log.Fatal with the failure message and file:line header. |
| // if err := assert.So(1, should.Equal, 1).Error(); err != nil { |
| // // Allows custom handling of the error, which will include the failure message and file:line header. |
| // } |
| func So(actual interface{}, assert assertion, expected ...interface{}) *Result { |
| result := new(Result) |
| result.stdout = os.Stdout |
| result.invocation = fmt.Sprintf("So(actual: %v, %v, expected: %v)", actual, assertionName(assert), expected) |
| if failure := assert(actual, expected...); len(failure) > 0 { |
| _, file, line, _ := runtime.Caller(1) |
| result.err = fmt.Errorf("Assertion failure at %s:%d\n%s", file, line, failure) |
| } |
| return result |
| } |
| func assertionName(i interface{}) string { |
| functionAddress := runtime.FuncForPC(reflect.ValueOf(i).Pointer()) |
| fullNameStartingWithPackage := functionAddress.Name() |
| parts := strings.Split(fullNameStartingWithPackage, "/") |
| baseName := parts[len(parts)-1] |
| return strings.Replace(baseName, "assertions.Should", "should.", 1) |
| } |
| |
| // Failed returns true if the assertion failed, false if it passed. |
| func (this *Result) Failed() bool { |
| return !this.Passed() |
| } |
| |
| // Passed returns true if the assertion passed, false if it failed. |
| func (this *Result) Passed() bool { |
| return this.err == nil |
| } |
| |
| // Error returns the error representing an assertion failure, which is nil in the case of a passed assertion. |
| func (this *Result) Error() error { |
| return this.err |
| } |
| |
| // String implements fmt.Stringer. |
| // It returns the error as a string in the case of an assertion failure. |
| // Unlike other methods defined herein, if returns a non-empty |
| // representation of the assertion as confirmation of success. |
| func (this *Result) String() string { |
| if this.Passed() { |
| return fmt.Sprintf("✔ %s", this.invocation) |
| } else { |
| return fmt.Sprintf("✘ %s\n%v", this.invocation, this.Error()) |
| } |
| } |
| |
| // Println calls fmt.Println in the case of an assertion failure. |
| func (this *Result) Println() *Result { |
| if this.Failed() { |
| fmt.Fprintln(this.stdout, this) |
| } |
| return this |
| } |
| |
| // Log calls log.Print in the case of an assertion failure. |
| func (this *Result) Log() *Result { |
| if this.Failed() { |
| this.logger.Print(this) |
| } |
| return this |
| } |
| |
| // Panic calls log.Panic in the case of an assertion failure. |
| func (this *Result) Panic() *Result { |
| if this.Failed() { |
| this.logger.Panic(this) |
| } |
| return this |
| } |
| |
| // Fatal calls log.Fatal in the case of an assertion failure. |
| func (this *Result) Fatal() *Result { |
| if this.Failed() { |
| this.logger.Fatal(this) |
| } |
| return this |
| } |
| |
| // assertion is a copy of github.com/smartystreets/assertions.assertion. |
| type assertion func(actual interface{}, expected ...interface{}) string |