Skip to content

Commit b6fbd58

Browse files
committed
Make assertions throw
Fixes avajs#3201. Assertions now throw a `TestFailure` error when they fail. This error is not exported or documented and should not be used or thrown manually. You cannot catch this error in order to recover from a failure, use `t.try()` instead. All assertions except for `throws` and `throwsAsync` now return `true` when they pass. This is useful for some of the assertions in TypeScript where they can be used as a type guard. Committing a failed `t.try()` result now also throws.
1 parent c792f10 commit b6fbd58

25 files changed

+483
-533
lines changed

docs/03-assertions.md

+23-25
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ test('unicorns are truthy', t => {
2121

2222
If multiple assertion failures are encountered within a single test, AVA will only display the *first* one.
2323

24-
Assertions return a boolean indicating whether they passed. You can use this to return early from a test. Note that this does not apply to the "throws" and `snapshot()` assertions.
24+
In AVA 6, assertions return `true` if they've passed and throw otherwise. Catching this error does not cause the test to pass. The error value is undocumented.
25+
26+
In AVA 5, assertions return a boolean and do not throw. You can use this to return early from a test. The `snapshot()` assertion does not return a value.
27+
28+
If you use TypeScript you can use some assertions as type guards.
29+
30+
Note that the "throws" assertions return the error that was thrown (provided the assertion passed). In AVA 5, they return `undefined` if the assertion failed.
2531

2632
## Assertion planning
2733

@@ -95,47 +101,47 @@ test('custom assertion', t => {
95101

96102
### `.pass(message?)`
97103

98-
Passing assertion. Returns a boolean indicating whether the assertion passed.
104+
Passing assertion.
99105

100106
### `.fail(message?)`
101107

102-
Failing assertion. Returns a boolean indicating whether the assertion passed.
108+
Failing assertion.
103109

104110
### `.assert(actual, message?)`
105111

106-
Asserts that `actual` is truthy. Returns a boolean indicating whether the assertion passed.
112+
Asserts that `actual` is truthy.
107113

108114
### `.truthy(actual, message?)`
109115

110-
Assert that `actual` is truthy. Returns a boolean indicating whether the assertion passed.
116+
Assert that `actual` is truthy.
111117

112118
### `.falsy(actual, message?)`
113119

114-
Assert that `actual` is falsy. Returns a boolean indicating whether the assertion passed.
120+
Assert that `actual` is falsy.
115121

116122
### `.true(actual, message?)`
117123

118-
Assert that `actual` is `true`. Returns a boolean indicating whether the assertion passed.
124+
Assert that `actual` is `true`.
119125

120126
### `.false(actual, message?)`
121127

122-
Assert that `actual` is `false`. Returns a boolean indicating whether the assertion passed.
128+
Assert that `actual` is `false`.
123129

124130
### `.is(actual, expected, message?)`
125131

126-
Assert that `actual` is the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed.
132+
Assert that `actual` is the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
127133

128134
### `.not(actual, expected, message?)`
129135

130-
Assert that `actual` is not the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). Returns a boolean indicating whether the assertion passed.
136+
Assert that `actual` is not the same as `expected`. This is based on [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
131137

132138
### `.deepEqual(actual, expected, message?)`
133139

134140
Assert that `actual` is deeply equal to `expected`. See [Concordance](https://github.com/concordancejs/concordance) for details.
135141

136142
### `.notDeepEqual(actual, expected, message?)`
137143

138-
Assert that `actual` is not deeply equal to `expected`. The inverse of `.deepEqual()`. Returns a boolean indicating whether the assertion passed.
144+
Assert that `actual` is not deeply equal to `expected`. The inverse of `.deepEqual()`.
139145

140146
### `.like(actual, selector, message?)`
141147

@@ -168,12 +174,9 @@ You can also use arrays, but note that any indices in `actual` that are not in `
168174
t.like([1, 2, 3, 4], [1, , 3])
169175
```
170176

171-
Finally, this returns a boolean indicating whether the assertion passed.
172-
173177
### `.throws(fn, expectation?, message?)`
174178

175-
Assert that an error is thrown. `fn` must be a function which should throw. By default, the thrown value *must* be an error. It is returned so you can run more assertions against it. If the assertion fails then `undefined` is returned.
176-
179+
Assert that an error is thrown. `fn` must be a function which should throw. By default, the thrown value *must* be an error. It is returned so you can run more assertions against it.
177180
`expectation` can be an object with one or more of the following properties:
178181

179182
* `any`: a boolean only available in AVA 6, if `true` then the thrown value does not need to be an error. Defaults to `false`
@@ -208,8 +211,7 @@ test('throws', t => {
208211

209212
Assert that an error is thrown. `thrower` can be an async function which should throw, or a promise that should reject. This assertion must be awaited.
210213

211-
By default, the thrown value *must* be an error. It is returned so you can run more assertions against it. If the assertion fails then `undefined` is returned.
212-
214+
By default, the thrown value *must* be an error. It is returned so you can run more assertions against it.
213215
`expectation` can be an object with one or more of the following properties:
214216

215217
* `any`: a boolean only available in AVA 6, if `true` then the thrown value does not need to be an error. Defaults to `false`
@@ -245,7 +247,7 @@ test('rejects', async t => {
245247

246248
### `.notThrows(fn, message?)`
247249

248-
Assert that no error is thrown. `fn` must be a function which shouldn't throw. Does not return anything.
250+
Assert that no error is thrown. `fn` must be a function which shouldn't throw.
249251

250252
### `.notThrowsAsync(nonThrower, message?)`
251253

@@ -259,15 +261,13 @@ test('resolves', async t => {
259261
});
260262
```
261263

262-
Does not return anything.
263-
264264
### `.regex(contents, regex, message?)`
265265

266-
Assert that `contents` matches `regex`. Returns a boolean indicating whether the assertion passed.
266+
Assert that `contents` matches `regex`.
267267

268268
### `.notRegex(contents, regex, message?)`
269269

270-
Assert that `contents` does not match `regex`. Returns a boolean indicating whether the assertion passed.
270+
Assert that `contents` does not match `regex`.
271271

272272
### `.snapshot(expected, message?)`
273273

@@ -279,7 +279,7 @@ Compares the `expected` value with a previously recorded snapshot. Snapshots are
279279

280280
The implementation function behaves the same as any other test function. You can even use macros. The first title argument is always optional. Additional arguments are passed to the implementation or macro function.
281281

282-
`.try()` is an asynchronous function. You must `await` it. The result object has `commit()` and `discard()` methods. You must decide whether to commit or discard the result. If you commit a failed result, your test will fail.
282+
`.try()` is an asynchronous function. You must `await` it. The result object has `commit()` and `discard()` methods. You must decide whether to commit or discard the result. If you commit a failed result, your test will fail. In AVA 6, calling `commit()` on a failed result will throw an error.
283283

284284
You can check whether the attempt passed using the `passed` property. Any assertion errors are available through the `errors` property. The attempt title is available through the `title` property.
285285

@@ -318,5 +318,3 @@ test('flaky macro', async t => {
318318
secondTry.commit();
319319
});
320320
```
321-
322-
Returns a boolean indicating whether the assertion passed.

docs/recipes/typescript.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ Note that, despite the type cast above, when executing `t.context` is an empty o
177177

178178
## Typing `throws` assertions
179179

180-
The `t.throws()` and `t.throwsAsync()` assertions are typed to always return an Error. You can customize the error class using generics:
180+
In AVA 6, the `t.throws()` and `t.throwsAsync()` assertions are typed to always return an `Error`. You can customize the error class using generics:
181181

182182
```ts
183183
import test from 'ava';
@@ -206,6 +206,6 @@ test('throwsAsync', async t => {
206206
});
207207
```
208208

209-
Note that, despite the typing, the assertion returns `undefined` if it fails. Typing the assertions as returning `Error | undefined` didn't seem like the pragmatic choice.
209+
In AVA 5, the assertion is typed to return the `Error` if the assertion passes *or* `undefined` if it fails.
210210

211211
[`@ava/typescript`]: https://github.com/avajs/typescript

0 commit comments

Comments
 (0)