-
Notifications
You must be signed in to change notification settings - Fork 32
/
assert.go
117 lines (104 loc) · 3.86 KB
/
assert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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 any, assert assertion, expected ...any) *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 any) 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 any, expected ...any) string