Files
node/test/parallel/test-vm-script-after-evaluate.js
Antoine du Hamel e50cbc1abd test: enforce better never-settling-promise detection
Tests should be explicit regarding whether a promise is expected to
settle, and the test should fail when the behavior does not meet
expectations.

PR-URL: https://github.com/nodejs/node/pull/60976
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Erick Wendel <erick.workspace@gmail.com>
2025-12-10 23:55:36 +00:00

67 lines
2.1 KiB
JavaScript

'use strict';
// https://github.com/nodejs/node/issues/59541
//
// Promises created in a context using microtaskMode: "aferEvaluate" (meaning
// it has its own microtask queue), when resolved in the surrounding context,
// will schedule a task back onto the inner context queue. This test checks that
// the async execution progresses normally.
const common = require('../common');
const vm = require('vm');
const microtaskMode = 'afterEvaluate';
(async () => {
const mustNotCall1 = common.mustNotCall();
await vm.runInNewContext(
`Promise.resolve()`,
{}, { microtaskMode });
// Expected behavior: resolving an promise created in the inner context, from
// the outer context results in the execution flow falling through, unless the
// inner context microtask queue is manually drained, which we don't do here.
mustNotCall1();
})().then(common.mustNotCall('never settling promise expected'));
(async () => {
const mustCall1 = common.mustCall();
const mustCall2 = common.mustCall();
const mustCall3 = common.mustCall();
// Create a new context.
const context = vm.createContext({}, { microtaskMode });
setImmediate(() => {
// This will drain the context microtask queue, after the `await` statement
// below, and allow the promise from the inner context, created below, to be
// resolved in the outer context.
vm.runInContext('', context);
mustCall2();
});
const inner_promise = vm.runInContext(
`Promise.resolve()`,
context);
mustCall1();
await inner_promise;
mustCall3();
})().then(common.mustCall());
{
const mustNotCall1 = common.mustNotCall();
const mustCall1 = common.mustCall();
const context = vm.createContext({ setImmediate, mustNotCall1 }, { microtaskMode });
// setImmediate() will be run after runInContext() returns, and since the
// anonymous function passed to `then` is defined in the inner context, the
// thenable job task will be enqueued on the inner context microtask queue,
// but at this point, it will not be drained automatically.
vm.runInContext(`new Promise(setImmediate).then(() => mustNotCall1())`, context);
mustCall1();
}