Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: ensure never settling promises are detected #50318

Merged
merged 2 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions test/.eslintrc.yaml
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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());
Loading