Skip to content

Commit 2a621d4

Browse files
BridgeARrefack
authored andcommitted
test: validate more properties in expectsError
PR-URL: #14058 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Gibson Fahnestock <[email protected]>
1 parent b55ab01 commit 2a621d4

File tree

3 files changed

+60
-28
lines changed

3 files changed

+60
-28
lines changed

test/common/README.md

+28-15
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,41 @@ Platform normalizes the `dd` command
5151
Check if there is more than 1gb of total memory.
5252

5353
### expectsError([fn, ]settings[, exact])
54-
* `fn` [&lt;Function>]
54+
* `fn` [&lt;Function>] a function that should throw.
5555
* `settings` [&lt;Object>]
56-
with the following optional properties:
56+
that must contain the `code` property plus any of the other following
57+
properties (some properties only apply for `AssertionError`):
5758
* `code` [&lt;String>]
58-
expected error must have this value for its `code` property
59+
expected error must have this value for its `code` property.
5960
* `type` [&lt;Function>]
60-
expected error must be an instance of `type`
61-
* `message` [&lt;String>]
62-
or [&lt;RegExp>]
61+
expected error must be an instance of `type` and must be an Error subclass.
62+
* `message` [&lt;String>] or [&lt;RegExp>]
6363
if a string is provided for `message`, expected error must have it for its
6464
`message` property; if a regular expression is provided for `message`, the
65-
regular expression must match the `message` property of the expected error
65+
regular expression must match the `message` property of the expected error.
66+
* `name` [&lt;String>]
67+
expected error must have this value for its `name` property.
68+
* `generatedMessage` [&lt;String>]
69+
(`AssertionError` only) expected error must have this value for its
70+
`generatedMessage` property.
71+
* `actual` &lt;any>
72+
(`AssertionError` only) expected error must have this value for its
73+
`actual` property.
74+
* `expected` &lt;any>
75+
(`AssertionError` only) expected error must have this value for its
76+
`expected` property.
77+
* `operator` &lt;any>
78+
(`AssertionError` only) expected error must have this value for its
79+
`operator` property.
6680
* `exact` [&lt;Number>] default = 1
81+
* return [&lt;Function>]
6782

68-
* return function suitable for use as a validation function passed as the second
69-
argument to e.g. `assert.throws()`. If the returned function has not been
70-
called exactly `exact` number of times when the test is complete, then the
71-
test will fail.
72-
73-
If `fn` is provided, it will be passed to `assert.throws` as first argument.
74-
75-
The expected error should be [subclassed by the `internal/errors` module](https://github.com/nodejs/node/blob/master/doc/guides/using-internal-errors.md#api).
83+
If `fn` is provided, it will be passed to `assert.throws` as first argument
84+
and `undefined` will be returned.
85+
Otherwise a function suitable as callback or for use as a validation function
86+
passed as the second argument to `assert.throws()` will be returned. If the
87+
returned function has not been called exactly `exact` number of times when the
88+
test is complete, then the test will fail.
7689

7790
### expectWarning(name, expected)
7891
* `name` [&lt;String>]

test/common/index.js

+31-12
Original file line numberDiff line numberDiff line change
@@ -696,24 +696,43 @@ Object.defineProperty(exports, 'hasSmallICU', {
696696
});
697697

698698
// Useful for testing expected internal/error objects
699-
exports.expectsError = function expectsError(fn, options, exact) {
699+
exports.expectsError = function expectsError(fn, settings, exact) {
700700
if (typeof fn !== 'function') {
701-
exact = options;
702-
options = fn;
701+
exact = settings;
702+
settings = fn;
703703
fn = undefined;
704704
}
705-
const { code, type, message } = options;
706705
const innerFn = exports.mustCall(function(error) {
707-
assert.strictEqual(error.code, code);
708-
if (type !== undefined) {
706+
assert.strictEqual(error.code, settings.code);
707+
if ('type' in settings) {
708+
const type = settings.type;
709+
if (type !== Error && !Error.isPrototypeOf(type)) {
710+
throw new TypeError('`settings.type` must inherit from `Error`');
711+
}
709712
assert(error instanceof type,
710-
`${error} is not the expected type ${type}`);
713+
`${error.name} is not instance of ${type.name}`);
714+
}
715+
if ('message' in settings) {
716+
const message = settings.message;
717+
if (typeof message === 'string') {
718+
assert.strictEqual(error.message, message);
719+
} else {
720+
assert(message.test(error.message),
721+
`${error.message} does not match ${message}`);
722+
}
711723
}
712-
if (message instanceof RegExp) {
713-
assert(message.test(error.message),
714-
`${error.message} does not match ${message}`);
715-
} else if (typeof message === 'string') {
716-
assert.strictEqual(error.message, message);
724+
if ('name' in settings) {
725+
assert.strictEqual(error.name, settings.name);
726+
}
727+
if (error.constructor.name === 'AssertionError') {
728+
['generatedMessage', 'actual', 'expected', 'operator'].forEach((key) => {
729+
if (key in settings) {
730+
const actual = error[key];
731+
const expected = settings[key];
732+
assert.strictEqual(actual, expected,
733+
`${key}: expected ${expected}, not ${actual}`);
734+
}
735+
});
717736
}
718737
return true;
719738
}, exact);

test/parallel/test-internal-errors.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ assert.throws(() => {
166166
}, common.expectsError({ code: 'TEST_ERROR_1', type: RangeError }));
167167
}, common.expectsError({
168168
code: 'ERR_ASSERTION',
169-
message: /^.+ is not the expected type \S/
169+
message: /^.+ is not instance of \S/
170170
}));
171171

172172
assert.throws(() => {

0 commit comments

Comments
 (0)