Skip to content

Commit 1b2733f

Browse files
BridgeARrefack
authored andcommitted
test: common.expectsError should be a must call
Wrap expectsError in mustCall to make sure it's really called as expected. PR-URL: #14088 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent be20e9e commit 1b2733f

18 files changed

+49
-60
lines changed

test/common/README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Platform normalizes the `dd` command
5050

5151
Check if there is more than 1gb of total memory.
5252

53-
### expectsError([fn, ]settings)
53+
### expectsError([fn, ]settings[, exact])
5454
* `fn` [&lt;Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
5555
* `settings` [&lt;Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
5656
with the following optional properties:
@@ -63,9 +63,12 @@ Check if there is more than 1gb of total memory.
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
6565
regular expression must match the `message` property of the expected error
66+
* `exact` [&lt;Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1
6667

6768
* return function suitable for use as a validation function passed as the second
68-
argument to `assert.throws()`
69+
argument to e.g. `assert.throws()`. If the returned function has not been called
70+
exactly `exact` number of times when the test is complete, then the test will
71+
fail.
6972

7073
If `fn` is provided, it will be passed to `assert.throws` as first argument.
7174

@@ -217,7 +220,7 @@ Array of IPV6 hosts.
217220
* return [&lt;Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
218221

219222
Returns a function that calls `fn`. If the returned function has not been called
220-
exactly `expected` number of times when the test is complete, then the test will
223+
exactly `exact` number of times when the test is complete, then the test will
221224
fail.
222225

223226
If `fn` is not provided, an empty function will be used.

test/common/index.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -488,17 +488,15 @@ exports.mustCallAtLeast = function(fn, minimum) {
488488
return _mustCallInner(fn, minimum, 'minimum');
489489
};
490490

491-
function _mustCallInner(fn, criteria, field) {
491+
function _mustCallInner(fn, criteria = 1, field) {
492492
if (typeof fn === 'number') {
493493
criteria = fn;
494494
fn = noop;
495495
} else if (fn === undefined) {
496496
fn = noop;
497497
}
498498

499-
if (criteria === undefined)
500-
criteria = 1;
501-
else if (typeof criteria !== 'number')
499+
if (typeof criteria !== 'number')
502500
throw new TypeError(`Invalid ${field} value: ${criteria}`);
503501

504502
const context = {
@@ -702,13 +700,14 @@ Object.defineProperty(exports, 'hasSmallICU', {
702700
});
703701

704702
// Useful for testing expected internal/error objects
705-
exports.expectsError = function expectsError(fn, options) {
703+
exports.expectsError = function expectsError(fn, options, exact) {
706704
if (typeof fn !== 'function') {
705+
exact = options;
707706
options = fn;
708707
fn = undefined;
709708
}
710709
const { code, type, message } = options;
711-
function innerFn(error) {
710+
const innerFn = exports.mustCall(function(error) {
712711
assert.strictEqual(error.code, code);
713712
if (type !== undefined) {
714713
assert(error instanceof type,
@@ -721,7 +720,7 @@ exports.expectsError = function expectsError(fn, options) {
721720
assert.strictEqual(error.message, message);
722721
}
723722
return true;
724-
}
723+
}, exact);
725724
if (fn) {
726725
assert.throws(fn, innerFn);
727726
return;

test/parallel/test-assert.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,7 @@ assert.throws(makeBlock(a.deepEqual, /a/igm, /a/im),
153153
{
154154
const re1 = /a/g;
155155
re1.lastIndex = 3;
156-
assert.doesNotThrow(makeBlock(a.deepEqual, re1, /a/g),
157-
common.expectsError({
158-
code: 'ERR_ASSERTION',
159-
message: /^\/a\/g deepEqual \/a\/g$/
160-
}));
156+
assert.doesNotThrow(makeBlock(a.deepEqual, re1, /a/g));
161157
}
162158

163159
assert.doesNotThrow(makeBlock(a.deepEqual, 4, '4'), 'deepEqual(4, \'4\')');

test/parallel/test-buffer-compare-offset.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ assert.strictEqual(1, a.compare(b, Infinity, -Infinity));
5757
// zero length target because default for targetEnd <= targetSource
5858
assert.strictEqual(1, a.compare(b, '0xff'));
5959

60-
const oor = common.expectsError({code: 'ERR_INDEX_OUT_OF_RANGE'});
60+
const oor = common.expectsError({code: 'ERR_INDEX_OUT_OF_RANGE'}, 7);
6161

6262
assert.throws(() => a.compare(b, 0, 100, 0), oor);
6363
assert.throws(() => a.compare(b, 0, 1, 0, 100), oor);

test/parallel/test-child-process-send-after-close.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ child.on('close', common.mustCall((code, signal) => {
1414
type: Error,
1515
message: 'Channel closed',
1616
code: 'ERR_IPC_CHANNEL_CLOSED'
17-
});
17+
}, 2);
1818

19-
child.on('error', common.mustCall(testError));
19+
child.on('error', testError);
2020

2121
{
2222
const result = child.send('ping');
2323
assert.strictEqual(result, false);
2424
}
2525

2626
{
27-
const result = child.send('pong', common.mustCall(testError));
27+
const result = child.send('pong', testError);
2828
assert.strictEqual(result, false);
2929
}
3030
}));

test/parallel/test-child-process-spawnsync-validation-errors.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ if (!common.isWindows) {
186186
// Validate the killSignal option
187187
const typeErr = /^TypeError: "killSignal" must be a string or number$/;
188188
const unknownSignalErr =
189-
common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', type: TypeError });
189+
common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', type: TypeError }, 17);
190190

191191
pass('killSignal', undefined);
192192
pass('killSignal', null);

test/parallel/test-child-process-validate-stdio.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const assert = require('assert');
66
const _validateStdio = require('internal/child_process')._validateStdio;
77

88
const expectedError =
9-
common.expectsError({code: 'ERR_INVALID_OPT_VALUE', type: TypeError});
9+
common.expectsError({code: 'ERR_INVALID_OPT_VALUE', type: TypeError}, 2);
1010

1111
// should throw if string and not ignore, pipe, or inherit
1212
assert.throws(() => _validateStdio('foo'), expectedError);

test/parallel/test-fs-whatwg-url.js

+16-24
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@ fs.readFile(url, common.mustCall((err, data) => {
2828

2929
// Check that using a non file:// URL reports an error
3030
const httpUrl = new URL('http://example.org');
31-
fs.readFile(httpUrl, common.mustCall((err) => {
32-
common.expectsError({
33-
code: 'ERR_INVALID_URL_SCHEME',
34-
type: TypeError,
35-
message: 'The URL must be of scheme file'
36-
})(err);
31+
fs.readFile(httpUrl, common.expectsError({
32+
code: 'ERR_INVALID_URL_SCHEME',
33+
type: TypeError,
34+
message: 'The URL must be of scheme file'
3735
}));
3836

3937
// pct-encoded characters in the path will be decoded and checked
@@ -46,31 +44,25 @@ fs.readFile(new URL('file:///c:/tmp/%00test'), common.mustCall((err) => {
4644
if (common.isWindows) {
4745
// encoded back and forward slashes are not permitted on windows
4846
['%2f', '%2F', '%5c', '%5C'].forEach((i) => {
49-
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
50-
common.expectsError({
51-
code: 'ERR_INVALID_FILE_URL_PATH',
52-
type: TypeError,
53-
message: 'File URL path must not include encoded \\ or / characters'
54-
})(err);
47+
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.expectsError({
48+
code: 'ERR_INVALID_FILE_URL_PATH',
49+
type: TypeError,
50+
message: 'File URL path must not include encoded \\ or / characters'
5551
}));
5652
});
5753
} else {
5854
// encoded forward slashes are not permitted on other platforms
5955
['%2f', '%2F'].forEach((i) => {
60-
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.mustCall((err) => {
61-
common.expectsError({
62-
code: 'ERR_INVALID_FILE_URL_PATH',
63-
type: TypeError,
64-
message: 'File URL path must not include encoded / characters'
65-
})(err);
56+
fs.readFile(new URL(`file:///c:/tmp/${i}`), common.expectsError({
57+
code: 'ERR_INVALID_FILE_URL_PATH',
58+
type: TypeError,
59+
message: 'File URL path must not include encoded / characters'
6660
}));
6761
});
6862

69-
fs.readFile(new URL('file://hostname/a/b/c'), common.mustCall((err) => {
70-
common.expectsError({
71-
code: 'ERR_INVALID_FILE_URL_HOST',
72-
type: TypeError,
73-
message: `File URL host must be "localhost" or empty on ${os.platform()}`
74-
})(err);
63+
fs.readFile(new URL('file://hostname/a/b/c'), common.expectsError({
64+
code: 'ERR_INVALID_FILE_URL_HOST',
65+
type: TypeError,
66+
message: `File URL host must be "localhost" or empty on ${os.platform()}`
7567
}));
7668
}

test/parallel/test-internal-util-assertCrypto.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ const common = require('../common');
44
const assert = require('assert');
55
const util = require('internal/util');
66

7-
const expectedError = common.expectsError({
8-
code: 'ERR_NO_CRYPTO',
9-
type: Error
10-
});
11-
127
if (!process.versions.openssl) {
8+
const expectedError = common.expectsError({
9+
code: 'ERR_NO_CRYPTO',
10+
type: Error
11+
});
1312
assert.throws(() => util.assertCrypto(), expectedError);
1413
} else {
1514
assert.doesNotThrow(() => util.assertCrypto());

test/parallel/test-path-parse-format.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const unixSpecialCaseFormatTests = [
9191
const expectedMessage = common.expectsError({
9292
code: 'ERR_INVALID_ARG_TYPE',
9393
type: TypeError
94-
});
94+
}, 18);
9595

9696
const errors = [
9797
{method: 'parse', input: [null], message: expectedMessage},

test/parallel/test-process-cpuUsage.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ const invalidUserArgument = common.expectsError({
3535
code: 'ERR_INVALID_ARG_TYPE',
3636
type: TypeError,
3737
message: 'The "preValue.user" property must be of type Number'
38-
});
38+
}, 8);
3939

4040
const invalidSystemArgument = common.expectsError({
4141
code: 'ERR_INVALID_ARG_TYPE',
4242
type: TypeError,
4343
message: 'The "preValue.system" property must be of type Number'
44-
});
44+
}, 2);
4545

4646

4747
// Ensure that an invalid shape for the previous value argument throws an error.

test/parallel/test-process-emitwarning.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ warningThrowToString.toString = function() {
5858
process.emitWarning(warningThrowToString);
5959

6060
const expectedError =
61-
common.expectsError({code: 'ERR_INVALID_ARG_TYPE', type: TypeError});
61+
common.expectsError({code: 'ERR_INVALID_ARG_TYPE', type: TypeError}, 11);
6262

6363
// TypeError is thrown on invalid input
6464
assert.throws(() => process.emitWarning(1), expectedError);

test/parallel/test-process-kill-pid.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const invalidPidArgument = common.expectsError({
4242
code: 'ERR_INVALID_ARG_TYPE',
4343
type: TypeError,
4444
message: 'The "pid" argument must be of type Number'
45-
});
45+
}, 6);
4646

4747
assert.throws(function() { process.kill('SIGTERM'); },
4848
invalidPidArgument);

test/parallel/test-url-format-whatwg.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ assert.strictEqual(
2525
code: 'ERR_INVALID_ARG_TYPE',
2626
type: TypeError,
2727
message: 'The "options" argument must be of type object'
28-
});
28+
}, 4);
2929
assert.throws(() => url.format(myURL, true), expectedErr);
3030
assert.throws(() => url.format(myURL, 1), expectedErr);
3131
assert.throws(() => url.format(myURL, 'test'), expectedErr);

test/parallel/test-whatwg-url-domainto.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const wptToASCIITests = require('../fixtures/url-toascii.js');
1313

1414
{
1515
const expectedError = common.expectsError(
16-
{ code: 'ERR_MISSING_ARGS', type: TypeError });
16+
{ code: 'ERR_MISSING_ARGS', type: TypeError }, 2);
1717
assert.throws(() => domainToASCII(), expectedError);
1818
assert.throws(() => domainToUnicode(), expectedError);
1919
assert.strictEqual(domainToASCII(undefined), 'undefined');

test/parallel/test-whatwg-url-parsing.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const failureTests = tests.filter((test) => test.failure).concat([
2626
]);
2727

2828
const expectedError = common.expectsError(
29-
{ code: 'ERR_INVALID_URL', type: TypeError });
29+
{ code: 'ERR_INVALID_URL', type: TypeError }, 102);
3030

3131
for (const test of failureTests) {
3232
assert.throws(

test/parallel/test-whatwg-url-searchparams-constructor.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ function makeIterableFunc(array) {
209209
code: 'ERR_INVALID_TUPLE',
210210
type: TypeError,
211211
message: 'Each query pair must be an iterable [name, value] tuple'
212-
});
212+
}, 6);
213213

214214
let params;
215215
params = new URLSearchParams(undefined);

test/parallel/test-whatwg-url-searchparams.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ sp.forEach(function() {
7676
const callbackErr = common.expectsError({
7777
code: 'ERR_INVALID_CALLBACK',
7878
type: TypeError
79-
});
79+
}, 2);
8080
assert.throws(() => sp.forEach(), callbackErr);
8181
assert.throws(() => sp.forEach(1), callbackErr);
8282
}

0 commit comments

Comments
 (0)