forked from gavv/httpexpect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
assertion.go
289 lines (234 loc) · 8.17 KB
/
assertion.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
package httpexpect
// AssertionType defines type of performed assertion.
type AssertionType uint
//go:generate stringer -type=AssertionType
const (
// Check if the invocation is correct
AssertUsage AssertionType = iota
// Check if the operation succeeded
AssertOperation
// Check expression: [Actual] has appropriate type
AssertType
AssertNotType
// Check expression: [Actual] has valid value
AssertValid
AssertNotValid
// Check expression: [Actual] is nil
AssertNil
AssertNotNil
// Check expression: [Actual] is empty
AssertEmpty
AssertNotEmpty
// Check expression: [Actual] is equal to [Expected]
// If [Delta] is set, it specifies allowed difference between values
AssertEqual
AssertNotEqual
// Check expression: [Actual] < [Expected]
AssertLt
// Check expression: [Actual] <= [Expected]
AssertLe
// Check expression: [Actual] > [Expected]
AssertGt
// Check expression: [Actual] >= [Expected]
AssertGe
// Check expression: [Actual] belongs to inclusive range [Expected]
// [Expected] stores AssertionRange with Min and Max values
AssertInRange
AssertNotInRange
// Check expression: [Actual] matches json schema [Expected]
// [Expected] stores map with parsed schema or string with schema uri
AssertMatchSchema
AssertNotMatchSchema
// Check expression: [Actual] matches json path [Expected]
// [Expected] stores a string with json path
AssertMatchPath
AssertNotMatchPath
// Check expression: [Actual] matches regex [Expected]
// [Expected] stores a string with regular expression
AssertMatchRegexp
AssertNotMatchRegexp
// Check expression: [Actual] matches format [Expected]
// [Expected] stores expected format or format list (AssertionList)
AssertMatchFormat
AssertNotMatchFormat
// Check expression: [Actual] contains key [Expected]
AssertContainsKey
AssertNotContainsKey
// Check expression: [Actual] contains element [Expected]
AssertContainsElement
AssertNotContainsElement
// Check expression: [Actual] contains subset [Expected]
AssertContainsSubset
AssertNotContainsSubset
// Check expression: [Actual] belongs to list [Expected]
// [Expected] stores AssertionList with allowed values
AssertBelongs
AssertNotBelongs
)
// AssertionSeverity defines how assertion failure should be treated.
type AssertionSeverity uint
//go:generate stringer -type=AssertionSeverity
const (
// This assertion failure should mark current test as failed.
// Typically handler will call t.Errorf().
// This severity is used for most assertions.
SeverityError AssertionSeverity = iota
// This assertion failure is informational only, it can be logged,
// but should not cause test failure.
// Typically handler will call t.Logf(), or just ignore assertion.
// This severity is used for assertions issued inside predicate functions,
// e.g. in Array.Filter and Object.Filter.
SeverityLog
)
// AssertionContext provides context where the assetion happened.
type AssertionContext struct {
// Name of the running test
// Usually comes from testing.T
TestName string
// Name of request being sent
// Comes from Request.WithName()
RequestName string
// Chain of nested assertion names
// Example value:
// {`Request("GET")`, `Expect()`, `JSON()`, `NotNull()`}
Path []string
// Chain of nested assertion names starting from alias
// When alias is not set, AliasedPath has the same value as Path
// Example value:
// {`foo`, `NotNull()`} // alias named foo
AliasedPath []string
// Request being sent
// May be nil if request was not yet sent
Request *Request
// Response being matched
// May be nil if response was not yet received
Response *Response
// Environment shared between tests
// Comes from Expect instance
Environment *Environment
// Whether reporter is known to output to testing.TB
// For example, true when reporter is testing.T or testify-based reporter.
TestingTB bool
}
// AssertionFailure provides detailed information about failed assertion.
//
// [Type] and [Errors] fields are set for all assertions.
// [Actual], [Expected], [Reference], and [Delta] fields are set only for
// certain assertion types.
//
// The value itself is stored in [Actual.Value], [Expected.Value], etc.
// It allows to distinguish whether the value is not present at all,
// or is present but is nil.
//
// [Actual] stores the value being examined.
//
// Exact meaning of [Expected] depends on assertion type. It may be the value
// to which [Actual] was compared, or range to which [Actual] should belong,
// or pattern with which [Actual] should match, or element which [Actual]
// should contain, and so on.
//
// If [Reference] is set, it stores the value from which the check originated.
// For example, the user asked to check for unordered equality of arrays
// A and B. During comparison, a check failed that array A contains element E
// from array B. In this case [Actual] will be set to A (actually observed array),
// [Expected] will be set to E (expected but missing element), and [Reference]
// will be set to B (reference array that originated the check).
//
// If [Delta] is set, it stores maximum allowed difference between [Actual]
// and [Expected] values.
//
// For further details, see comments for corresponding AssertionType constant.
type AssertionFailure struct {
// Type of failed assertion
Type AssertionType
// Severity of failure
Severity AssertionSeverity
// Deprecated: use Severity
IsFatal bool
// List of error messages
Errors []error
// Actually observed value
Actual *AssertionValue
// Expected value
Expected *AssertionValue
// Reference value
Reference *AssertionValue
// Allowed delta between actual and expected
Delta *AssertionValue
// Stacktrace of the failure
Stacktrace []StacktraceEntry
}
// AssertionValue holds expected or actual value
type AssertionValue struct {
Value interface{}
}
// AssertionRange holds inclusive range for allowed values
type AssertionRange struct {
Min interface{}
Max interface{}
}
// AssertionList holds list of allowed values
type AssertionList []interface{}
// AssertionHandler takes care of formatting and reporting test Failure or Success.
//
// You can log every performed assertion, or report only failures. You can implement
// custom formatting, for example, provide a JSON output for ulterior processing.
//
// Usually you don't need to implement AssertionHandler; instead you can implement
// Reporter, which is much simpler, and use it with DefaultAssertionHandler.
type AssertionHandler interface {
// Invoked every time when an assertion succeeded.
// May ignore failure, or log it, e.g. using t.Logf().
Success(*AssertionContext)
// Invoked every time when an assertion failed.
// Handling depends on Failure.Severity field:
// - for SeverityError, reports failure to testing suite, e.g. using t.Errorf()
// - for SeverityLog, ignores failure, or logs it, e.g. using t.Logf()
Failure(*AssertionContext, *AssertionFailure)
}
// DefaultAssertionHandler is default implementation for AssertionHandler.
//
// - Formatter is used to format success and failure messages
// - Reporter is used to report formatted fatal failure messages
// - Logger is used to print formatted success and non-fatal failure messages
//
// Formatter and Reporter are required. Logger is optional.
// By default httpexpect creates DefaultAssertionHandler without Logger.
type DefaultAssertionHandler struct {
Formatter Formatter
Reporter Reporter
Logger Logger
}
// Success implements AssertionHandler.Success.
func (h *DefaultAssertionHandler) Success(ctx *AssertionContext) {
if h.Formatter == nil {
panic("DefaultAssertionHandler.Formatter is nil")
}
if h.Logger == nil {
return
}
msg := h.Formatter.FormatSuccess(ctx)
h.Logger.Logf("%s", msg)
}
// Failure implements AssertionHandler.Failure.
func (h *DefaultAssertionHandler) Failure(
ctx *AssertionContext, failure *AssertionFailure,
) {
if h.Formatter == nil {
panic("DefaultAssertionHandler.Formatter is nil")
}
switch failure.Severity {
case SeverityError:
if h.Reporter == nil {
panic("DefaultAssertionHandler.Reporter is nil")
}
msg := h.Formatter.FormatFailure(ctx, failure)
h.Reporter.Errorf("%s", msg)
case SeverityLog:
if h.Logger == nil {
return
}
msg := h.Formatter.FormatFailure(ctx, failure)
h.Logger.Logf("%s", msg)
}
}