Skip to content

Commit

Permalink
test: split promisified timers test for coverage purposes
Browse files Browse the repository at this point in the history
Because of lazy loading, running promisified timers tests for setTimeout
and setImmediate from the same file means that there is a piece of code
that doesn't get covered. Split into separate files to cover everything.

Refs: https://coverage.nodejs.org/coverage-290c158018ac0277/lib/timers.js.html#L269
  • Loading branch information
Trott committed Mar 28, 2021
1 parent 924238d commit 64e076e
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 160 deletions.
99 changes: 99 additions & 0 deletions test/parallel/test-timers-immediate-promisified.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Flags: --no-warnings --expose-internals
'use strict';
const common = require('../common');
const assert = require('assert');
const timers = require('timers');
const { promisify } = require('util');
const child_process = require('child_process');

// TODO(benjamingr) - refactor to use getEventListeners when #35991 lands
const { NodeEventTarget } = require('internal/event_target');

const timerPromises = require('timers/promises');

const setPromiseImmediate = promisify(timers.setImmediate);
const exec = promisify(child_process.exec);

assert.strictEqual(setPromiseImmediate, timerPromises.setImmediate);

process.on('multipleResolves', common.mustNotCall());

{
const promise = setPromiseImmediate();
promise.then(common.mustCall((value) => {
assert.strictEqual(value, undefined);
}));
}

{
const promise = setPromiseImmediate('foobar');
promise.then(common.mustCall((value) => {
assert.strictEqual(value, 'foobar');
}));
}

{
const ac = new AbortController();
const signal = ac.signal;
assert.rejects(setPromiseImmediate(10, { signal }), /AbortError/)
.then(common.mustCall());
ac.abort();
}

{
const signal = AbortSignal.abort(); // Abort in advance
assert.rejects(setPromiseImmediate(10, { signal }), /AbortError/)
.then(common.mustCall());
}

{
// Check that aborting after resolve will not reject.
const ac = new AbortController();
const signal = ac.signal;
setPromiseImmediate(10, { signal })
.then(common.mustCall(() => { ac.abort(); }))
.then(common.mustCall());
}

{
// Check that timer adding signals does not leak handlers
const signal = new NodeEventTarget();
signal.aborted = false;
setPromiseImmediate(0, { signal }).finally(common.mustCall(() => {
assert.strictEqual(signal.listenerCount('abort'), 0);
}));
}

{
Promise.all(
[1, '', false, Infinity].map(
(i) => assert.rejects(setPromiseImmediate(10, i), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', false, Infinity, null, {}].map(
(signal) => assert.rejects(setPromiseImmediate(10, { signal }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', Infinity, null, {}].map(
(ref) => assert.rejects(setPromiseImmediate(10, { ref }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());
}

{
exec(`${process.execPath} -pe "const assert = require('assert');` +
'require(\'timers/promises\').setImmediate(null, { ref: false }).' +
'then(assert.fail)"').then(common.mustCall(({ stderr }) => {
assert.strictEqual(stderr, '');
}));
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,12 @@ const { NodeEventTarget } = require('internal/event_target');
const timerPromises = require('timers/promises');

const setPromiseTimeout = promisify(timers.setTimeout);
const setPromiseImmediate = promisify(timers.setImmediate);
const exec = promisify(child_process.exec);

assert.strictEqual(setPromiseTimeout, timerPromises.setTimeout);
assert.strictEqual(setPromiseImmediate, timerPromises.setImmediate);
const { setInterval } = timerPromises;

process.on('multipleResolves', common.mustNotCall());

{
const promise = setPromiseTimeout(1);
promise.then(common.mustCall((value) => {
assert.strictEqual(value, undefined);
}));
}

{
const promise = setPromiseTimeout(1, 'foobar');
promise.then(common.mustCall((value) => {
assert.strictEqual(value, 'foobar');
}));
}

{
const promise = setPromiseImmediate();
promise.then(common.mustCall((value) => {
assert.strictEqual(value, undefined);
}));
}

{
const promise = setPromiseImmediate('foobar');
promise.then(common.mustCall((value) => {
assert.strictEqual(value, 'foobar');
}));
}

{
const iterable = setInterval(1, undefined);
const iterator = iterable[Symbol.asyncIterator]();
Expand Down Expand Up @@ -89,34 +58,6 @@ process.on('multipleResolves', common.mustNotCall());
.then(common.mustCall());
}

{
const ac = new AbortController();
const signal = ac.signal;
assert.rejects(setPromiseTimeout(10, undefined, { signal }), /AbortError/)
.then(common.mustCall());
ac.abort();
}

{
const signal = AbortSignal.abort(); // Abort in advance
assert.rejects(setPromiseTimeout(10, undefined, { signal }), /AbortError/)
.then(common.mustCall());
}

{
const ac = new AbortController();
const signal = ac.signal;
assert.rejects(setPromiseImmediate(10, { signal }), /AbortError/)
.then(common.mustCall());
ac.abort();
}

{
const signal = AbortSignal.abort(); // Abort in advance
assert.rejects(setPromiseImmediate(10, { signal }), /AbortError/)
.then(common.mustCall());
}

{
const signal = AbortSignal.abort(); // Abort in advance

Expand Down Expand Up @@ -155,23 +96,6 @@ process.on('multipleResolves', common.mustNotCall());
assert.rejects(abortPromise, /AbortError/).then(common.mustCall());
}

{
// Check that aborting after resolve will not reject.
const ac = new AbortController();
const signal = ac.signal;
setPromiseTimeout(10, undefined, { signal })
.then(common.mustCall(() => { ac.abort(); }))
.then(common.mustCall());
}
{
// Check that aborting after resolve will not reject.
const ac = new AbortController();
const signal = ac.signal;
setPromiseImmediate(10, { signal })
.then(common.mustCall(() => { ac.abort(); }))
.then(common.mustCall());
}

{
[1, '', Infinity, null, {}].forEach((ref) => {
const iterable = setInterval(10, undefined, { ref });
Expand All @@ -192,24 +116,6 @@ process.on('multipleResolves', common.mustNotCall());
});
}

{
// Check that timer adding signals does not leak handlers
const signal = new NodeEventTarget();
signal.aborted = false;
setPromiseTimeout(0, null, { signal }).finally(common.mustCall(() => {
assert.strictEqual(signal.listenerCount('abort'), 0);
}));
}

{
// Check that timer adding signals does not leak handlers
const signal = new NodeEventTarget();
signal.aborted = false;
setPromiseImmediate(0, { signal }).finally(common.mustCall(() => {
assert.strictEqual(signal.listenerCount('abort'), 0);
}));
}

{
// Check that timer adding signals does not leak handlers
const signal = new NodeEventTarget();
Expand Down Expand Up @@ -247,72 +153,6 @@ process.on('multipleResolves', common.mustNotCall());
tryBreak().then(common.mustCall());
}

{
Promise.all(
[1, '', false, Infinity].map(
(i) => assert.rejects(setPromiseImmediate(10, i), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', false, Infinity, null, {}].map(
(signal) => assert.rejects(setPromiseImmediate(10, { signal }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', Infinity, null, {}].map(
(ref) => assert.rejects(setPromiseImmediate(10, { ref }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', false, Infinity].map(
(i) => assert.rejects(setPromiseTimeout(10, null, i), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', false, Infinity, null, {}].map(
(signal) => assert.rejects(setPromiseTimeout(10, null, { signal }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());

Promise.all(
[1, '', Infinity, null, {}].map(
(ref) => assert.rejects(setPromiseTimeout(10, null, { ref }), {
code: 'ERR_INVALID_ARG_TYPE'
})
)
).then(common.mustCall());
}

{
exec(`${process.execPath} -pe "const assert = require('assert');` +
'require(\'timers/promises\').setTimeout(1000, null, { ref: false }).' +
'then(assert.fail)"').then(common.mustCall(({ stderr }) => {
assert.strictEqual(stderr, '');
}));
}

{
exec(`${process.execPath} -pe "const assert = require('assert');` +
'require(\'timers/promises\').setImmediate(null, { ref: false }).' +
'then(assert.fail)"').then(common.mustCall(({ stderr }) => {
assert.strictEqual(stderr, '');
}));
}

{
exec(`${process.execPath} -pe "const assert = require('assert');` +
'const interval = require(\'timers/promises\')' +
Expand Down
Loading

0 comments on commit 64e076e

Please sign in to comment.