Skip to content

Commit

Permalink
test: ensure never settling promises are detected
Browse files Browse the repository at this point in the history
PR-URL: #50318
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
  • Loading branch information
aduh95 authored and UlisesGascon committed Dec 11, 2023
1 parent 11412e8 commit 6c59114
Show file tree
Hide file tree
Showing 40 changed files with 147 additions and 143 deletions.
2 changes: 2 additions & 0 deletions test/.eslintrc.yaml
Expand Up @@ -49,6 +49,8 @@ rules:
message: Use 'test' as debuglog value in tests.
- selector: CallExpression:matches([callee.object.name="common"][callee.property.name=/^must(Not)?Call/],[callee.name="mustCall"],[callee.name="mustCallAtLeast"],[callee.name="mustNotCall"])>:first-child[type=/FunctionExpression$/][body.body.length=0]
message: Do not use an empty function, omit the parameter altogether.
- selector: ExpressionStatement>CallExpression:matches([callee.name='rejects'], [callee.object.name='assert'][callee.property.name='rejects'])
message: Calling `assert.rejects` without `await` or `.then(common.mustCall())` will not detect never-settling promises.
- selector: Identifier[name='webcrypto']
message: Use `globalThis.crypto`.

Expand Down
16 changes: 8 additions & 8 deletions test/es-module/test-esm-cjs-named-error.mjs
Expand Up @@ -23,55 +23,55 @@ const expectedPackageHack =

const expectedBare = errTemplate('deep-fail', 'comeOn', '{ comeOn }');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/single-quote.mjs`);
}, {
name: 'SyntaxError',
message: expectedRelative
}, 'should support relative specifiers with single quotes');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/double-quote.mjs`);
}, {
name: 'SyntaxError',
message: expectedRelative
}, 'should support relative specifiers with double quotes');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/renamed-import.mjs`);
}, {
name: 'SyntaxError',
message: expectedRenamed
}, 'should correctly format named imports with renames');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/multi-line.mjs`);
}, {
name: 'SyntaxError',
message: expectedWithoutExample,
}, 'should correctly format named imports across multiple lines');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/json-hack.mjs`);
}, {
name: 'SyntaxError',
message: expectedPackageHack
}, 'should respect recursive package.json for module type');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/bare-import-single.mjs`);
}, {
name: 'SyntaxError',
message: expectedBare
}, 'should support bare specifiers with single quotes');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/bare-import-double.mjs`);
}, {
name: 'SyntaxError',
message: expectedBare
}, 'should support bare specifiers with double quotes');

rejects(async () => {
await rejects(async () => {
await import(`${fixtureBase}/escaped-single-quote.mjs`);
}, /import pkg from '\.\/oh'no\.cjs'/, 'should support relative specifiers with escaped single quote');
4 changes: 2 additions & 2 deletions test/internet/test-dns-lookup.js
Expand Up @@ -17,7 +17,7 @@ assert.rejects(
code: 'ENOTFOUND',
message: `getaddrinfo ENOTFOUND ${addresses.NOT_FOUND}`,
},
);
).then(common.mustCall());

assert.rejects(
dnsPromises.lookup(addresses.NOT_FOUND, {
Expand All @@ -29,7 +29,7 @@ assert.rejects(
code: 'ENOTFOUND',
message: `getaddrinfo ENOTFOUND ${addresses.NOT_FOUND}`,
},
);
).then(common.mustCall());

dns.lookup(addresses.NOT_FOUND, {
hints: 0,
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-blob.js
Expand Up @@ -409,10 +409,10 @@ assert.throws(() => new Blob({}), {
}

(async () => {
assert.rejects(async () => Blob.prototype.arrayBuffer.call(), {
await assert.rejects(async () => Blob.prototype.arrayBuffer.call(), {
code: 'ERR_INVALID_THIS',
});
assert.rejects(async () => Blob.prototype.text.call(), {
await assert.rejects(async () => Blob.prototype.text.call(), {
code: 'ERR_INVALID_THIS',
});
})().then(common.mustCall());
Expand Down
Expand Up @@ -16,7 +16,7 @@ subtle.importKey(
},
false,
[ 'encrypt', 'decrypt' ])
.then((k) => {
.then((k) =>
assert.rejects(() => {
return subtle.decrypt({
name: 'AES-GCM',
Expand All @@ -25,5 +25,5 @@ subtle.importKey(
}, {
name: 'OperationError',
message: /The provided data is too small/,
});
});
})
).then(common.mustCall());
6 changes: 3 additions & 3 deletions test/parallel/test-directory-import.js
@@ -1,14 +1,14 @@
'use strict';

require('../common');
const common = require('../common');
const fixtures = require('../common/fixtures');
const assert = require('assert');
const { pathToFileURL } = require('url');

{
assert.rejects(import('./'), /ERR_UNSUPPORTED_DIR_IMPORT/);
assert.rejects(import('./'), /ERR_UNSUPPORTED_DIR_IMPORT/).then(common.mustCall());
assert.rejects(
import(pathToFileURL(fixtures.path('packages', 'main'))),
/Did you mean/,
);
).then(common.mustCall());
}
2 changes: 1 addition & 1 deletion test/parallel/test-dns-lookup.js
Expand Up @@ -205,4 +205,4 @@ tickValue = 1;

// Should fail due to stub.
assert.rejects(dnsPromises.lookup('example.com'),
{ code: 'ENOMEM', hostname: 'example.com' });
{ code: 'ENOMEM', hostname: 'example.com' }).then(common.mustCall());
2 changes: 1 addition & 1 deletion test/parallel/test-dns-lookupService-promises.js
Expand Up @@ -16,4 +16,4 @@ dnsPromises.lookupService('127.0.0.1', 22).then(common.mustCall((result) => {
assert.rejects(
() => dnsPromises.lookupService('192.0.2.1', 22),
{ code: /^(?:ENOTFOUND|EAI_AGAIN)$/ }
);
).then(common.mustCall());
2 changes: 1 addition & 1 deletion test/parallel/test-dns-lookupService.js
Expand Up @@ -32,4 +32,4 @@ assert.rejects(
message: 'getnameinfo ENOENT 127.0.0.1',
syscall: 'getnameinfo'
}
);
).then(common.mustCall());
4 changes: 2 additions & 2 deletions test/parallel/test-dns-resolve-promises.js
@@ -1,6 +1,6 @@
// Flags: --expose-internals
'use strict';
require('../common');
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const cares = internalBinding('cares_wrap');
Expand All @@ -17,4 +17,4 @@ assert.rejects(
syscall: 'queryA',
hostname: 'example.org'
}
);
).then(common.mustCall());
2 changes: 1 addition & 1 deletion test/parallel/test-event-emitter-error-monitor.js
Expand Up @@ -25,7 +25,7 @@ EE.emit('error', theErr);

// Verify it works with once
process.nextTick(() => EE.emit('error', theErr));
assert.rejects(EventEmitter.once(EE, 'notTriggered'), theErr);
assert.rejects(EventEmitter.once(EE, 'notTriggered'), theErr).then(common.mustCall());

// Only error events trigger error monitor
EE.on('aEvent', common.mustCall());
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-file-validate-mode-flag.js
Expand Up @@ -33,8 +33,8 @@ assert.throws(() => openSync(__filename, 0, invalid), {

assert.rejects(openPromise(__filename, invalid), {
code: 'ERR_OUT_OF_RANGE'
});
}).then(common.mustCall());

assert.rejects(openPromise(__filename, 0, invalid), {
code: 'ERR_OUT_OF_RANGE'
});
}).then(common.mustCall());
2 changes: 1 addition & 1 deletion test/parallel/test-filehandle-close.js
Expand Up @@ -10,7 +10,7 @@ const fs = require('fs');
const fh = await fs.promises.open(__filename);
fs.closeSync(fh.fd);

assert.rejects(() => fh.close(), {
await assert.rejects(() => fh.close(), {
code: 'EBADF',
syscall: 'close'
});
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-fs-filehandle-use-after-close.js
Expand Up @@ -16,7 +16,7 @@ const fs = require('fs').promises;
// See https://github.com/nodejs/node/issues/31361 for more details.
const otherFilehandle = await fs.open(process.execPath);

assert.rejects(() => filehandle.stat(), {
await assert.rejects(() => filehandle.stat(), {
code: 'EBADF',
syscall: 'fstat'
});
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-fs-lchmod.js
Expand Up @@ -42,7 +42,7 @@ assert.throws(() => fs.lchmod(f, {}), { code: 'ERR_INVALID_ARG_TYPE' });
code: 'ERR_INVALID_ARG_TYPE',
};

assert.rejects(promises.lchmod(f, input, () => {}), errObj);
assert.rejects(promises.lchmod(f, input, () => {}), errObj).then(common.mustCall());
assert.throws(() => fs.lchmodSync(f, input), errObj);
});

Expand All @@ -61,6 +61,6 @@ assert.throws(() => fs.lchmodSync(f, '123x'), {
`4294967295. Received ${input}`
};

assert.rejects(promises.lchmod(f, input, () => {}), errObj);
assert.rejects(promises.lchmod(f, input, () => {}), errObj).then(common.mustCall());
assert.throws(() => fs.lchmodSync(f, input), errObj);
});
4 changes: 2 additions & 2 deletions test/parallel/test-fs-open.js
Expand Up @@ -94,7 +94,7 @@ for (const extra of [[], ['r'], ['r', 0], ['r', 0, 'bad callback']]) {
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
}
);
).then(common.mustCall());
});

// Check invalid modes.
Expand All @@ -116,5 +116,5 @@ for (const extra of [[], ['r'], ['r', 0], ['r', 0, 'bad callback']]) {
{
code: 'ERR_INVALID_ARG_TYPE'
}
);
).then(common.mustCall());
});
4 changes: 2 additions & 2 deletions test/parallel/test-fs-promises-readfile.js
Expand Up @@ -46,7 +46,7 @@ function validateReadFileAbortLogicBefore() {
const signal = AbortSignal.abort();
assert.rejects(readFile(fn, { signal }), {
name: 'AbortError'
});
}).then(common.mustCall());
}

function validateReadFileAbortLogicDuring() {
Expand All @@ -55,7 +55,7 @@ function validateReadFileAbortLogicDuring() {
process.nextTick(() => controller.abort());
assert.rejects(readFile(fn, { signal }), {
name: 'AbortError'
});
}).then(common.mustCall());
}

async function validateWrongSignalParam() {
Expand Down
12 changes: 6 additions & 6 deletions test/parallel/test-fs-promises-watch.js
Expand Up @@ -79,42 +79,42 @@ assert.rejects(
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch(1)) { }
},
{ code: 'ERR_INVALID_ARG_TYPE' });
{ code: 'ERR_INVALID_ARG_TYPE' }).then(common.mustCall());

assert.rejects(
async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch(__filename, 1)) { }
},
{ code: 'ERR_INVALID_ARG_TYPE' });
{ code: 'ERR_INVALID_ARG_TYPE' }).then(common.mustCall());

assert.rejects(
async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch('', { persistent: 1 })) { }
},
{ code: 'ERR_INVALID_ARG_TYPE' });
{ code: 'ERR_INVALID_ARG_TYPE' }).then(common.mustCall());

assert.rejects(
async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch('', { recursive: 1 })) { }
},
{ code: 'ERR_INVALID_ARG_TYPE' });
{ code: 'ERR_INVALID_ARG_TYPE' }).then(common.mustCall());

assert.rejects(
async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch('', { encoding: 1 })) { }
},
{ code: 'ERR_INVALID_ARG_VALUE' });
{ code: 'ERR_INVALID_ARG_VALUE' }).then(common.mustCall());

assert.rejects(
async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of watch('', { signal: 1 })) { }
},
{ code: 'ERR_INVALID_ARG_TYPE' });
{ code: 'ERR_INVALID_ARG_TYPE' }).then(common.mustCall());

(async () => {
const ac = new AbortController();
Expand Down
14 changes: 7 additions & 7 deletions test/parallel/test-fs-promises.js
Expand Up @@ -59,21 +59,21 @@ assert.strictEqual(
name: 'Error',
message: /^ENOENT: no such file or directory, access/
}
);
).then(common.mustCall());

assert.rejects(
access(__filename, 8),
{
code: 'ERR_OUT_OF_RANGE',
}
);
).then(common.mustCall());

assert.rejects(
access(__filename, { [Symbol.toPrimitive]() { return 5; } }),
{
code: 'ERR_INVALID_ARG_TYPE',
}
);
).then(common.mustCall());
}

function verifyStatObject(stat) {
Expand Down Expand Up @@ -407,7 +407,7 @@ async function executeOnHandle(dest, func) {
const dir = path.join(tmpDir, nextdir(), nextdir());
await mkdir(path.dirname(dir));
await writeFile(dir, '');
assert.rejects(
await assert.rejects(
mkdir(dir, { recursive: true }),
{
code: 'EEXIST',
Expand All @@ -424,7 +424,7 @@ async function executeOnHandle(dest, func) {
const dir = path.join(file, nextdir(), nextdir());
await mkdir(path.dirname(file));
await writeFile(file, '');
assert.rejects(
await assert.rejects(
mkdir(dir, { recursive: true }),
{
code: 'ENOTDIR',
Expand Down Expand Up @@ -463,14 +463,14 @@ async function executeOnHandle(dest, func) {
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
}
);
).then(common.mustCall());
});
}

// `mkdtemp` with invalid numeric prefix
{
await mkdtemp(path.resolve(tmpDir, 'FOO'));
assert.rejects(
await assert.rejects(
// mkdtemp() expects to get a string prefix.
async () => mkdtemp(1),
{
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-fs-read-empty-buffer.js
Expand Up @@ -37,5 +37,5 @@ assert.throws(
message: 'The argument \'buffer\' is empty and cannot be written. ' +
'Received Uint8Array(0) []'
}
);
).then(common.mustCall());
})().then(common.mustCall());

0 comments on commit 6c59114

Please sign in to comment.