Skip to content

Commit 7f99aef

Browse files
committed
Remove legacy .throws() and .throwsAsync() interfaces
Fixes #2301.
1 parent 54ff130 commit 7f99aef

File tree

8 files changed

+96
-150
lines changed

8 files changed

+96
-150
lines changed

docs/03-assertions.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,19 @@ Assert that `value` is deeply equal to `expected`. See [Concordance](https://git
207207

208208
Assert that `value` is not deeply equal to `expected`. The inverse of `.deepEqual()`.
209209

210-
### `.throws(fn, [expected, [message]])`
210+
### `.throws(fn, [expectation, [message]])`
211211

212212
Assert that an error is thrown. `fn` must be a function which should throw. The thrown value *must* be an error. It is returned so you can run more assertions against it.
213213

214-
`expected` can be a constructor, in which case the thrown error must be an instance of the constructor. It can be a string, which is compared against the thrown error's message, or a regular expression which is matched against this message. You can also specify a matcher object with one or more of the following properties:
214+
`expectation` can be an object with one or more of the following properties:
215215

216216
* `instanceOf`: a constructor, the thrown error must be an instance of
217-
* `is`: the thrown error must be strictly equal to `expected.is`
217+
* `is`: the thrown error must be strictly equal to `expectation.is`
218218
* `message`: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this message
219219
* `name`: the expected `.name` value of the thrown error
220220
* `code`: the expected `.code` value of the thrown error
221221

222-
`expected` does not need to be specified. If you don't need it but do want to set an assertion message you have to specify `null`.
222+
`expectation` does not need to be specified. If you don't need it but do want to set an assertion message you have to specify `null`.
223223

224224
Example:
225225

@@ -231,27 +231,27 @@ const fn = () => {
231231
test('throws', t => {
232232
const error = t.throws(() => {
233233
fn();
234-
}, TypeError);
234+
}, {instanceOf: TypeError});
235235

236236
t.is(error.message, '🦄');
237237
});
238238
```
239239

240-
### `.throwsAsync(thrower, [expected, [message]])`
240+
### `.throwsAsync(thrower, [expectation, [message]])`
241241

242242
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.
243243

244244
The thrown value *must* be an error. It is returned so you can run more assertions against it.
245245

246-
`expected` can be a constructor, in which case the thrown error must be an instance of the constructor. It can be a string, which is compared against the thrown error's message, or a regular expression which is matched against this message. You can also specify a matcher object with one or more of the following properties:
246+
`expectation` can be an object with one or more of the following properties:
247247

248248
* `instanceOf`: a constructor, the thrown error must be an instance of
249-
* `is`: the thrown error must be strictly equal to `expected.is`
249+
* `is`: the thrown error must be strictly equal to `expectation.is`
250250
* `message`: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this message
251251
* `name`: the expected `.name` value of the thrown error
252252
* `code`: the expected `.code` value of the thrown error
253253

254-
`expected` does not need to be specified. If you don't need it but do want to set an assertion message you have to specify `null`.
254+
`expectation` does not need to be specified. If you don't need it but do want to set an assertion message you have to specify `null`.
255255

256256
Example:
257257

index.d.ts

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -252,24 +252,6 @@ export interface ThrowsAssertion {
252252
*/
253253
<ThrownError extends Error>(fn: () => any, expectations?: null, message?: string): ThrownError;
254254

255-
/**
256-
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
257-
* The error must be an instance of the given constructor.
258-
*/
259-
<ThrownError extends Error>(fn: () => any, constructor: Constructor, message?: string): ThrownError;
260-
261-
/**
262-
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
263-
* The error must have a message that matches the regular expression.
264-
*/
265-
<ThrownError extends Error>(fn: () => any, regex: RegExp, message?: string): ThrownError;
266-
267-
/**
268-
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
269-
* The error must have a message equal to `errorMessage`.
270-
*/
271-
<ThrownError extends Error>(fn: () => any, errorMessage: string, message?: string): ThrownError;
272-
273255
/**
274256
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
275257
* The error must satisfy all expectations.
@@ -287,24 +269,6 @@ export interface ThrowsAsyncAssertion {
287269
*/
288270
<ThrownError extends Error>(fn: () => PromiseLike<any>, expectations?: null, message?: string): Promise<ThrownError>;
289271

290-
/**
291-
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
292-
* value. You must await the result. The error must be an instance of the given constructor.
293-
*/
294-
<ThrownError extends Error>(fn: () => PromiseLike<any>, constructor: Constructor, message?: string): Promise<ThrownError>;
295-
296-
/**
297-
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
298-
* value. You must await the result. The error must have a message that matches the regular expression.
299-
*/
300-
<ThrownError extends Error>(fn: () => PromiseLike<any>, regex: RegExp, message?: string): Promise<ThrownError>;
301-
302-
/**
303-
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
304-
* value. You must await the result. The error must have a message equal to `errorMessage`.
305-
*/
306-
<ThrownError extends Error>(fn: () => PromiseLike<any>, errorMessage: string, message?: string): Promise<ThrownError>;
307-
308272
/**
309273
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
310274
* value. You must await the result. The error must satisfy all expectations.
@@ -317,24 +281,6 @@ export interface ThrowsAsyncAssertion {
317281
*/
318282
<ThrownError extends Error>(promise: PromiseLike<any>, expectations?: null, message?: string): Promise<ThrownError>;
319283

320-
/**
321-
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
322-
* rejection reason. You must await the result. The error must be an instance of the given constructor.
323-
*/
324-
<ThrownError extends Error>(promise: PromiseLike<any>, constructor: Constructor, message?: string): Promise<ThrownError>;
325-
326-
/**
327-
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
328-
* rejection reason. You must await the result. The error must have a message that matches the regular expression.
329-
*/
330-
<ThrownError extends Error>(promise: PromiseLike<any>, regex: RegExp, message?: string): Promise<ThrownError>;
331-
332-
/**
333-
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
334-
* rejection reason. You must await the result. The error must have a message equal to `errorMessage`.
335-
*/
336-
<ThrownError extends Error>(promise: PromiseLike<any>, errorMessage: string, message?: string): Promise<ThrownError>;
337-
338284
/**
339285
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
340286
* rejection reason. You must await the result. The error must satisfy all expectations.

lib/assert.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,19 @@ function getErrorWithLongStackTrace() {
7373
}
7474

7575
function validateExpectations(assertion, expectations, numArgs) { // eslint-disable-line complexity
76-
if (typeof expectations === 'function') {
77-
expectations = {instanceOf: expectations};
78-
} else if (typeof expectations === 'string' || expectations instanceof RegExp) {
79-
expectations = {message: expectations};
80-
} else if (numArgs === 1 || expectations === null) {
76+
if (numArgs === 1 || expectations === null) {
8177
expectations = {};
82-
} else if (typeof expectations !== 'object' || Array.isArray(expectations) || Object.keys(expectations).length === 0) {
78+
} else if (
79+
typeof expectations === 'function' ||
80+
typeof expectations === 'string' ||
81+
expectations instanceof RegExp ||
82+
typeof expectations !== 'object' ||
83+
Array.isArray(expectations) ||
84+
Object.keys(expectations).length === 0
85+
) {
8386
throw new AssertionError({
8487
assertion,
85-
message: `The second argument to \`t.${assertion}()\` must be a function, string, regular expression, expectation object or \`null\``,
88+
message: `The second argument to \`t.${assertion}()\` must be an expectation object or \`null\``,
8689
values: [formatWithLabel('Called with:', expectations)]
8790
});
8891
} else {

test/assert.js

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -835,44 +835,6 @@ test('.throws()', gather(t => {
835835
]
836836
});
837837

838-
// Fails because thrown error's message is not equal to 'bar'
839-
failsWith(t, () => {
840-
const err = new Error('foo');
841-
assertions.throws(() => {
842-
throw err;
843-
}, 'bar');
844-
}, {
845-
assertion: 'throws',
846-
message: '',
847-
values: [
848-
{label: 'Function threw unexpected exception:', formatted: /foo/},
849-
{label: 'Expected message to equal:', formatted: /bar/}
850-
]
851-
});
852-
853-
// Fails because thrown error is not the right instance
854-
failsWith(t, () => {
855-
const err = new Error('foo');
856-
assertions.throws(() => {
857-
throw err;
858-
}, class Foo {});
859-
}, {
860-
assertion: 'throws',
861-
message: '',
862-
values: [
863-
{label: 'Function threw unexpected exception:', formatted: /foo/},
864-
{label: 'Expected instance of:', formatted: /Foo/}
865-
]
866-
});
867-
868-
// Passes because thrown error's message is equal to 'bar'
869-
passes(t, () => {
870-
const err = new Error('foo');
871-
assertions.throws(() => {
872-
throw err;
873-
}, 'foo');
874-
});
875-
876838
// Passes because an error is thrown.
877839
passes(t, () => {
878840
assertions.throws(() => {
@@ -1043,19 +1005,6 @@ test('.throwsAsync()', gather(t => {
10431005
// Passes because the function returned a promise rejected with an error.
10441006
eventuallyPasses(t, () => assertions.throwsAsync(() => Promise.reject(new Error())));
10451007

1046-
// Passes because the error's message matches the regex
1047-
eventuallyPasses(t, () => assertions.throwsAsync(Promise.reject(new Error('abc')), /abc/));
1048-
1049-
// Fails because the error's message does not match the regex
1050-
eventuallyFailsWith(t, () => assertions.throwsAsync(Promise.reject(new Error('abc')), /def/), {
1051-
assertion: 'throwsAsync',
1052-
message: '',
1053-
values: [
1054-
{label: 'Promise rejected with unexpected exception:', formatted: /Error/},
1055-
{label: 'Expected message to match:', formatted: /\/def\//}
1056-
]
1057-
});
1058-
10591008
// Fails because the function throws synchronously
10601009
eventuallyFailsWith(t, () => assertions.throwsAsync(() => {
10611010
throw new Error('sync');
@@ -1136,23 +1085,47 @@ test('.throws() fails if passed a bad expectation', t => {
11361085
assertions.throws(() => {}, true);
11371086
}, {
11381087
assertion: 'throws',
1139-
message: 'The second argument to `t.throws()` must be a function, string, regular expression, expectation object or `null`',
1088+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
11401089
values: [{label: 'Called with:', formatted: /true/}]
11411090
});
11421091

1092+
failsWith(t, () => {
1093+
assertions.throws(() => {}, 'foo');
1094+
}, {
1095+
assertion: 'throws',
1096+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
1097+
values: [{label: 'Called with:', formatted: /foo/}]
1098+
});
1099+
1100+
failsWith(t, () => {
1101+
assertions.throws(() => {}, /baz/);
1102+
}, {
1103+
assertion: 'throws',
1104+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
1105+
values: [{label: 'Called with:', formatted: /baz/}]
1106+
});
1107+
1108+
failsWith(t, () => {
1109+
assertions.throws(() => {}, class Bar {});
1110+
}, {
1111+
assertion: 'throws',
1112+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
1113+
values: [{label: 'Called with:', formatted: /Bar/}]
1114+
});
1115+
11431116
failsWith(t, () => {
11441117
assertions.throws(() => {}, {});
11451118
}, {
11461119
assertion: 'throws',
1147-
message: 'The second argument to `t.throws()` must be a function, string, regular expression, expectation object or `null`',
1120+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
11481121
values: [{label: 'Called with:', formatted: /\{\}/}]
11491122
});
11501123

11511124
failsWith(t, () => {
11521125
assertions.throws(() => {}, []);
11531126
}, {
11541127
assertion: 'throws',
1155-
message: 'The second argument to `t.throws()` must be a function, string, regular expression, expectation object or `null`',
1128+
message: 'The second argument to `t.throws()` must be an expectation object or `null`',
11561129
values: [{label: 'Called with:', formatted: /\[\]/}]
11571130
});
11581131

@@ -1204,23 +1177,47 @@ test('.throwsAsync() fails if passed a bad expectation', t => {
12041177
assertions.throwsAsync(() => {}, true);
12051178
}, {
12061179
assertion: 'throwsAsync',
1207-
message: 'The second argument to `t.throwsAsync()` must be a function, string, regular expression, expectation object or `null`',
1180+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
12081181
values: [{label: 'Called with:', formatted: /true/}]
12091182
});
12101183

1184+
failsWith(t, () => {
1185+
assertions.throwsAsync(() => {}, 'foo');
1186+
}, {
1187+
assertion: 'throwsAsync',
1188+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
1189+
values: [{label: 'Called with:', formatted: /foo/}]
1190+
});
1191+
1192+
failsWith(t, () => {
1193+
assertions.throwsAsync(() => {}, /baz/);
1194+
}, {
1195+
assertion: 'throwsAsync',
1196+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
1197+
values: [{label: 'Called with:', formatted: /baz/}]
1198+
});
1199+
1200+
failsWith(t, () => {
1201+
assertions.throwsAsync(() => {}, class Bar {});
1202+
}, {
1203+
assertion: 'throwsAsync',
1204+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
1205+
values: [{label: 'Called with:', formatted: /Bar/}]
1206+
});
1207+
12111208
failsWith(t, () => {
12121209
assertions.throwsAsync(() => {}, {});
12131210
}, {
12141211
assertion: 'throwsAsync',
1215-
message: 'The second argument to `t.throwsAsync()` must be a function, string, regular expression, expectation object or `null`',
1212+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
12161213
values: [{label: 'Called with:', formatted: /\{\}/}]
12171214
});
12181215

12191216
failsWith(t, () => {
12201217
assertions.throwsAsync(() => {}, []);
12211218
}, {
12221219
assertion: 'throwsAsync',
1223-
message: 'The second argument to `t.throwsAsync()` must be a function, string, regular expression, expectation object or `null`',
1220+
message: 'The second argument to `t.throwsAsync()` must be an expectation object or `null`',
12241221
values: [{label: 'Called with:', formatted: /\[\]/}]
12251222
});
12261223

test/fixture/report/regular/traces-in-t-throws.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function returnRejectedPromise() {
99
}
1010

1111
test('throws', t => {
12-
t.throws(() => throwError(), TypeError);
12+
t.throws(() => throwError(), {instanceOf: TypeError});
1313
});
1414

1515
test('notThrows', t => {
@@ -21,9 +21,9 @@ test('notThrowsAsync', t => {
2121
});
2222

2323
test('throwsAsync', t => {
24-
t.throwsAsync(() => throwError(), TypeError);
24+
t.throwsAsync(() => throwError(), {instanceOf: TypeError});
2525
});
2626

2727
test('throwsAsync different error', t => {
28-
return t.throwsAsync(returnRejectedPromise, TypeError);
28+
return t.throwsAsync(returnRejectedPromise, {instanceOf: TypeError});
2929
});

test/reporters/mini.regular.log

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ stderr
331331

332332
traces-in-t-throws.js:12
333333

334-
11: test('throws', t => {
335-
 12: t.throws(() => throwError(), TypeError);
336-
13: });
334+
11: test('throws', t => {
335+
 12: t.throws(() => throwError(), {instanceOf: TypeError});
336+
13: });
337337

338338
Function threw unexpected exception:
339339

@@ -395,9 +395,9 @@ stderr
395395

396396
traces-in-t-throws.js:24
397397

398-
23: test('throwsAsync', t => {
399-
 24: t.throwsAsync(() => throwError(), TypeError);
400-
25: });
398+
23: test('throwsAsync', t => {
399+
 24: t.throwsAsync(() => throwError(), {instanceOf: TypeError});
400+
25: });
401401

402402
Function threw synchronously. Use `t.throws()` instead:
403403

@@ -415,9 +415,9 @@ stderr
415415

416416
traces-in-t-throws.js:28
417417

418-
27: test('throwsAsync different error', t => {
419-
 28: return t.throwsAsync(returnRejectedPromise, TypeError);
420-
29: });
418+
27: test('throwsAsync different error', t => {
419+
 28: return t.throwsAsync(returnRejectedPromise, {instanceOf: TypeError});
420+
29: });
421421

422422
Returned promise rejected with unexpected exception:
423423

0 commit comments

Comments
 (0)