-
Notifications
You must be signed in to change notification settings - Fork 0
/
assert.go
129 lines (110 loc) · 3.13 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
118
119
120
121
122
123
124
125
126
127
128
129
package snippets
import (
"encoding/json"
"fmt"
"math"
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
)
// ObjectsAreEqual checks two interfaces with reflect.DeepEqual.
func ObjectsAreEqual(expected, actual interface{}) bool {
if expected == nil || actual == nil {
return expected == actual
}
return reflect.DeepEqual(expected, actual)
}
// IsNil checks an interface{} with the reflect package.
func IsNil(object interface{}) bool {
if object == nil {
return true
}
value := reflect.ValueOf(object)
kind := value.Kind()
if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
return true
}
return false
}
// errorSingle fails and prints the single object
// along with the message.
func errorSingle(t testing.TB, msg string, obj interface{}) {
_, file, line, _ := runtime.Caller(2)
fmt.Printf("\033[31m\t%s:%d: %s\n\n\t\t%#v\033[39m\n\n", filepath.Base(file), line, msg, obj)
t.Fail()
}
// errorCompare fails and prints both the compared objects
// along with the message.
func errorCompare(t testing.TB, msg string, expected, actual interface{}) {
_, file, line, _ := runtime.Caller(2)
fmt.Printf("\033[31m\t%s:%d: %s\n\n\t\tgot: %#v\n\033[32m\t\texp: %#v\033[39m\n\n", filepath.Base(file), line, msg, actual, expected)
t.Fail()
}
// Assert wraps a testing.TB for convenient asserting calls.
type Assert struct {
t testing.TB
}
// True tests if the cond is true and prints the msg for failure.
func (a *Assert) True(cond bool, msg string) {
if !cond {
errorSingle(a.t, msg, cond)
}
}
// Equal tests if the two interfaces provided is equal
// and prints the msg for failure.
func (a *Assert) Equal(expected, actual interface{}, msg string) {
if !ObjectsAreEqual(expected, actual) {
errorCompare(a.t, msg, expected, actual)
}
}
func (a *Assert) noError(err error, msg string, fatal bool) {
if err != nil {
_, file, line, _ := runtime.Caller(2)
fmt.Printf("\033[31m\t%s:%d: %s\n\n\t\t%s\033[39m\n\n", filepath.Base(file), line, msg, err)
if fatal {
a.t.FailNow()
} else {
a.t.Fail()
}
}
}
// NoError fails the test and prints the msg if err != nil.
func (a *Assert) NoError(err error, msg string) {
a.noError(err, msg, false)
}
// MustNoError fails & stops the test if err != nil.
func (a *Assert) MustNoError(err error, msg string) {
a.noError(err, msg, true)
}
// NotNil fails the test and prints the msg if the obj is nil.
func (a *Assert) NotNil(obj interface{}, msg string) {
if IsNil(obj) {
errorSingle(a.t, msg, obj)
}
}
// FloatEqual compares two floats with an epsilon 1e-9.
func (a *Assert) FloatEqual(expected, actual float64, msg string) {
if math.Abs(expected-actual) > 1e-9 {
errorCompare(a.t, msg, expected, actual)
}
}
// RequireEnv checks if a specific env variable is set, and
// skip the test if it is not set.
func (a *Assert) RequireEnv(key string) string {
s := os.Getenv(key)
if s == "" {
a.t.Skip("set " + key + " to run this test")
}
return s
}
// JSON logs v in json-encoded form.
func (a *Assert) JSON(v interface{}) {
bs, _ := json.Marshal(v)
a.t.Log(string(bs))
}
// NewAssert provides an Assert instance.
func NewAssert(t testing.TB) *Assert {
return &Assert{t}
}