Passed
Push — main ( 220a40...bda11a )
by Tomáš
02:52
created

assert.go   A

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Test Coverage

Coverage 90.32%

Importance

Changes 0
Metric Value
cc 30
eloc 83
dl 0
loc 217
ccs 56
cts 62
cp 0.9032
crap 30.8163
rs 10
c 0
b 0
f 0
1
package assert
2
3
import (
4
	"encoding/json"
5
	"errors"
6
)
7
8
// Testing is an interface wrapper around *testing.T
9
type Testing interface {
10
	Helper()
11
	Errorf(format string, args ...any)
12
}
13
14
// Fail reports a failure message through
15
func Fail(t Testing, message string) bool {
16 2
	t.Helper()
17
18 2
	t.Errorf(message)
19
20 2
	return false
21
}
22
23
// Failf reports a failure formatted message through
24
func Failf(t Testing, format string, args ...any) bool {
25 65
	t.Helper()
26
27 65
	t.Errorf(format, args...)
28
29 65
	return false
30
}
31
32
// True asserts that the specified value is true.
33
func True(t Testing, condition bool) bool {
34 2
	t.Helper()
35
36 2
	if !condition {
37 1
		return Fail(t, "Should be true")
38
	}
39
40 1
	return true
41
}
42
43
// False asserts that the specified value is false.
44
func False(t Testing, condition bool) bool {
45 2
	t.Helper()
46
47 2
	if condition {
48 1
		return Fail(t, "Should be false")
49
	}
50
51 1
	return true
52
}
53
54
// Equal asserts that two objects are equal.
55
//
56
// Pointer variable equality is determined based on the equality of the
57
// referenced values (as opposed to the memory addresses).
58
func Equal[T Comparable](t Testing, actual, expected T) bool {
59 33
	t.Helper()
60
61 33
	if !equal(actual, expected) {
62 8
		return Failf(t, "Should be equal:\n  actual: %s\nexpected: %s", print(actual), print(expected))
63
	}
64
65 25
	return true
66
}
67
68
// NotEqual asserts that the specified values are NOT equal.
69
//
70
// Pointer variable equality is determined based on the equality of the
71
// referenced values (as opposed to the memory addresses).
72
func NotEqual[T Comparable](t Testing, actual, expected T) bool {
73 24
	t.Helper()
74
75 24
	if equal(actual, expected) {
76 18
		return Failf(t, "Should not be equal\n  actual: %s", print(actual))
77
	}
78
79 6
	return true
80
}
81
82
// EqualDelta asserts that two numeric values difference is less then delta.
83
//
84
// Method panics if delta value is not positive.
85
func EqualDelta[T Numeric](t Testing, actual, expected, delta T) bool {
86 14
	t.Helper()
87
88 14
	if !equalDelta(actual, expected, delta) {
89 6
		return Failf(t, "Should be equal in delta:\n  actual: %s\nexpected: %s", print(actual), print(expected))
90
	}
91
92 8
	return true
93
}
94
95
// Same asserts that two pointers reference the same object.
96
//
97
// Both arguments must be pointer variables. Pointer variable equality is
98
// determined based on the equality of both type and value.
99
func Same[T Reference](t Testing, actual, expected T) bool {
100 13
	t.Helper()
101
102 13
	if valid, ok := same[T](expected, actual); !ok {
103 3
		return Failf(t, "Should be pointers\n  actual: %s\nexpected: %s", print(actual), print(expected))
104 10
	} else if !valid {
105 4
		return Failf(t, "Should be same\n  actual: %s\nexpected: %s", print(actual), print(expected))
106
	}
107
108 6
	return true
109
}
110
111
// NotSame asserts that two pointers do NOT reference the same object.
112
//
113
// Both arguments must be pointer variables. Pointer variable equality is
114
// determined based on the equality of both type and value.
115
func NotSame[T Reference](t Testing, actual, expected T) bool {
116 13
	t.Helper()
117
118 13
	if valid, ok := same(expected, actual); !ok {
119 3
		Failf(t, "Should be pointers\n  actual: %s\nexpected: %s", print(actual), print(expected))
120 10
	} else if valid {
121 6
		return Failf(t, "Should not be same\n  actual: %s", print(actual))
122
	}
123
124 7
	return true
125
}
126
127
// Length asserts that object have given length.
128
func Length[S Iterable[any]](t Testing, object S, expected int) bool {
129 5
	t.Helper()
130
131 5
	if actual := length(object); actual != expected {
132 1
		return Failf(t, "Should have element length\n  object: %#v\n  actual: %d\nexpected: %d", object, actual, expected)
133
	}
134
135 4
	return true
136
}
137
138
// Contains asserts that object contains given element
139
//
140
// Works with strings, arrays, slices, maps values and channels
141
func Contains[S Iterable[E], E Comparable](t Testing, object S, element E) bool {
142 7
	t.Helper()
143
144 7
	if found, ok := contains(object, element); !ok {
145 1
		return Failf(t, "Should be iterable\n  object: %#v", object)
146 6
	} else if !found {
147 3
		return Failf(t, "Should contain element\n  object: %#v\n element: %#v", object, element)
148
	}
149
150 3
	return true
151
}
152
153
// NotContains asserts that object do NOT contains given element
154
//
155
// Works with strings, arrays, slices, maps values and channels
156
func NotContains[S Iterable[E], E Comparable](t Testing, object S, element E) bool {
157 7
	t.Helper()
158
159 7
	if found, ok := contains(object, element); !ok {
160 1
		Failf(t, "Should be iterable\n  object: %#v", object)
161 6
	} else if found {
162 3
		return Failf(t, "Should not contain element\n  object: %#v\n element: %#v", object, element)
163
	}
164
165 4
	return true
166
}
167
168
// Error asserts that error is NOT nil
169
func Error(t Testing, err error) bool {
170 2
	t.Helper()
171
172 2
	if err == nil {
173 1
		return Failf(t, "Should be error")
174
	}
175
176 1
	return true
177
}
178
179
// NoError asserts that error is nil
180
func NoError(t Testing, err error) bool {
181 5
	t.Helper()
182
183 5
	if err != nil {
184 1
		return Failf(t, "Should not be error\n   error: %#v", err)
185
	}
186
187 4
	return true
188
}
189
190
// ErrorIs asserts that error is unwrappable to given target
191
func ErrorIs(t Testing, err error, target error) bool {
192 4
	t.Helper()
193
194 4
	if !errors.Is(err, target) {
195 1
		return Failf(t, "Should be same error\n   error: %#v\n  target: %#v", err, target)
196
	}
197
198 3
	return true
199
}
200
201
// NotErrorIs asserts that error is NOT unwrappable to given target
202
func NotErrorIs(t Testing, err error, target error) bool {
203 4
	t.Helper()
204
205 4
	if errors.Is(err, target) {
206 3
		return Failf(t, "Should not be same error\n   error: %#v", err, target)
207
	}
208
209 1
	return true
210
}
211
212
// EqualJSON asserts that JSON strings are equal
213
func EqualJSON(t Testing, actual, expected string) bool {
214 11
	t.Helper()
215
216 11
	var actualJSON, expectedJSON any
217
218 11
	if err := json.Unmarshal([]byte(actual), &actualJSON); err != nil {
219 1
		return Failf(t, "Should be valid JSON\n  actual: %s\n     err: %v", expected, err)
220
	}
221
222 10
	if err := json.Unmarshal([]byte(expected), &expectedJSON); err != nil {
223 1
		return Failf(t, "Should be valid JSON\nexpected: %s\n     err: %v", expected, err)
224
	}
225
226 9
	return Equal(t, expectedJSON, actualJSON)
227
}
228
229
// JSON asserts that object can be marshall to expected JSON string
230
func JSON(t Testing, actual any, expected string) bool {
231 3
	t.Helper()
232
233 3
	s, err := json.Marshal(actual)
234
235 3
	return NoError(t, err) && EqualJSON(t, string(s), expected)
236
}
237