Files
node/test/parallel/test-vm-module-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

72 lines
1.9 KiB
JavaScript

// Flags: --experimental-vm-modules
'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.
const common = require('../common');
const vm = require('vm');
const microtaskMode = 'afterEvaluate';
(async () => {
const mustNotCall1 = common.mustNotCall();
const mustNotCall2 = common.mustNotCall();
const mustCall1 = common.mustCall();
const inner = {};
const context = vm.createContext({ inner }, { microtaskMode });
const module = new vm.SourceTextModule(
'inner.promise = Promise.resolve();',
{ context },
);
await module.link(mustNotCall1);
await module.evaluate();
// Prior to the fix for Issue 59541, the next statement was never executed.
mustCall1();
await inner.promise;
// This is expected: the await statement above enqueues a (thenable job) task
// onto the inner context microtask queue, but it will not be checkpointed,
// therefore we never make progress.
mustNotCall2();
})().then(common.mustNotCall('never settling promise expected'));
(async () => {
const mustNotCall1 = common.mustNotCall();
const mustCall1 = common.mustCall();
const mustCall2 = common.mustCall();
const mustCall3 = common.mustCall();
const inner = {};
const context = vm.createContext({ inner }, { microtaskMode });
const module = new vm.SourceTextModule(
'inner.promise = Promise.resolve();',
{ context },
);
await module.link(mustNotCall1);
await module.evaluate();
mustCall1();
setImmediate(() => {
mustCall2();
// This will checkpoint the inner context microtask queue, and allow the
// promise from the inner context to be resolved in the outer context.
module.evaluate();
});
await inner.promise;
mustCall3();
})().then(common.mustCall());