Support message testing function in throws & throwsAsync assertions
This commit is contained in:
parent
f5caa8fb82
commit
e387cba63c
4 changed files with 103 additions and 7 deletions
|
|
@ -172,7 +172,10 @@ Assert that an error is thrown. `fn` must be a function which should throw. The
|
|||
|
||||
* `instanceOf`: a constructor, the thrown error must be an instance of
|
||||
* `is`: the thrown error must be strictly equal to `expectation.is`
|
||||
* `message`: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this message
|
||||
* `message`: the following types are valid:
|
||||
* *string* - it is compared against the thrown error's message
|
||||
* *regular expression* - it is matched against this message
|
||||
* *function* - it is passed the thrown error message and must return a boolean for whether the assertion passed
|
||||
* `name`: the expected `.name` value of the thrown error
|
||||
* `code`: the expected `.code` value of the thrown error
|
||||
|
||||
|
|
@ -204,7 +207,10 @@ The thrown value *must* be an error. It is returned so you can run more assertio
|
|||
|
||||
* `instanceOf`: a constructor, the thrown error must be an instance of
|
||||
* `is`: the thrown error must be strictly equal to `expectation.is`
|
||||
* `message`: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this message
|
||||
* `message`: the following types are valid:
|
||||
* *string* - it is compared against the thrown error's message
|
||||
* *regular expression* - it is matched against this message
|
||||
* *function* - it is passed the thrown error message and must return a boolean for whether the assertion passed
|
||||
* `name`: the expected `.name` value of the thrown error
|
||||
* `code`: the expected `.code` value of the thrown error
|
||||
|
||||
|
|
|
|||
|
|
@ -106,10 +106,15 @@ function validateExpectations(assertion, expectations, numberArgs) { // eslint-d
|
|||
});
|
||||
}
|
||||
|
||||
if (hasOwnProperty(expectations, 'message') && typeof expectations.message !== 'string' && !(expectations.message instanceof RegExp)) {
|
||||
if (
|
||||
hasOwnProperty(expectations, 'message')
|
||||
&& typeof expectations.message !== 'string'
|
||||
&& !(expectations.message instanceof RegExp)
|
||||
&& !(typeof expectations.message === 'function')
|
||||
) {
|
||||
throw new AssertionError({
|
||||
assertion,
|
||||
message: `The \`message\` property of the second argument to \`t.${assertion}()\` must be a string or regular expression`,
|
||||
message: `The \`message\` property of the second argument to \`t.${assertion}()\` must be a string, regular expression or a function`,
|
||||
values: [formatWithLabel('Called with:', expectations)],
|
||||
});
|
||||
}
|
||||
|
|
@ -230,6 +235,19 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
|
|||
});
|
||||
}
|
||||
|
||||
if (typeof expectations.message === 'function' && expectations.message(actual.message) === false) {
|
||||
throw new AssertionError({
|
||||
assertion,
|
||||
message,
|
||||
savedError,
|
||||
actualStack,
|
||||
values: [
|
||||
formatWithLabel(`${prefix} unexpected exception:`, actual),
|
||||
formatWithLabel('Expected message to return true:', expectations.message),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof expectations.code !== 'undefined' && actual.code !== expectations.code) {
|
||||
throw new AssertionError({
|
||||
assertion,
|
||||
|
|
|
|||
|
|
@ -899,6 +899,78 @@ test('.throws()', gather(t => {
|
|||
formatted: /null/,
|
||||
}],
|
||||
});
|
||||
|
||||
// Fails because the string in the message is incorrect
|
||||
failsWith(
|
||||
t,
|
||||
() =>
|
||||
assertions.throws(
|
||||
() => {
|
||||
throw new Error('error');
|
||||
},
|
||||
{message: 'my error'},
|
||||
),
|
||||
{
|
||||
assertion: 'throws',
|
||||
message: '',
|
||||
values: [
|
||||
{label: 'Function threw unexpected exception:', formatted: /error/},
|
||||
{label: 'Expected message to equal:', formatted: /my error/},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
passes(t, () => assertions.throws(() => {
|
||||
throw new Error('error');
|
||||
}, {message: 'error'}));
|
||||
|
||||
// Fails because the regular expression in the message is incorrect
|
||||
failsWith(
|
||||
t,
|
||||
() =>
|
||||
assertions.throws(
|
||||
() => {
|
||||
throw new Error('error');
|
||||
},
|
||||
{message: /my error/},
|
||||
),
|
||||
{
|
||||
assertion: 'throws',
|
||||
message: '',
|
||||
values: [
|
||||
{label: 'Function threw unexpected exception:', formatted: /error/},
|
||||
{label: 'Expected message to match:', formatted: /my error/},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
passes(t, () => assertions.throws(() => {
|
||||
throw new Error('error');
|
||||
}, {message: /error/}));
|
||||
|
||||
// Fails because the function in the message returns false
|
||||
failsWith(
|
||||
t,
|
||||
() =>
|
||||
assertions.throws(
|
||||
() => {
|
||||
throw new Error('error');
|
||||
},
|
||||
{message: () => false},
|
||||
),
|
||||
{
|
||||
assertion: 'throws',
|
||||
message: '',
|
||||
values: [
|
||||
{label: 'Function threw unexpected exception:', formatted: /error/},
|
||||
{label: 'Expected message to return true:', formatted: /Function/},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
passes(t, () => assertions.throws(() => {
|
||||
throw new Error('error');
|
||||
}, {message: () => true}));
|
||||
}));
|
||||
|
||||
test('.throws() returns the thrown error', t => {
|
||||
|
|
@ -1066,7 +1138,7 @@ test('.throws() fails if passed a bad expectation', t => {
|
|||
|
||||
failsWith(t, () => assertions.throws(() => {}, {message: null}), {
|
||||
assertion: 'throws',
|
||||
message: 'The `message` property of the second argument to `t.throws()` must be a string or regular expression',
|
||||
message: 'The `message` property of the second argument to `t.throws()` must be a string, regular expression or a function',
|
||||
values: [{label: 'Called with:', formatted: /message: null/}],
|
||||
});
|
||||
|
||||
|
|
@ -1136,7 +1208,7 @@ test('.throwsAsync() fails if passed a bad expectation', t => {
|
|||
|
||||
failsWith(t, () => assertions.throwsAsync(() => {}, {message: null}), {
|
||||
assertion: 'throwsAsync',
|
||||
message: 'The `message` property of the second argument to `t.throwsAsync()` must be a string or regular expression',
|
||||
message: 'The `message` property of the second argument to `t.throwsAsync()` must be a string, regular expression or a function',
|
||||
values: [{label: 'Called with:', formatted: /message: null/}],
|
||||
}, {expectBoolean: false});
|
||||
|
||||
|
|
|
|||
2
types/assertions.d.ts
vendored
2
types/assertions.d.ts
vendored
|
|
@ -12,7 +12,7 @@ export type ThrowsExpectation = {
|
|||
is?: Error;
|
||||
|
||||
/** The thrown error must have a message that equals the given string, or matches the regular expression. */
|
||||
message?: string | RegExp;
|
||||
message?: string | RegExp | ((message: string) => boolean);
|
||||
|
||||
/** The thrown error must have a name that equals the given string. */
|
||||
name?: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue