// Flags: --experimental-vm-modules 'use strict'; const common = require('../common'); const assert = require('assert'); const { createContext, Script, SourceTextModule } = require('vm'); // Verifies that a `import` call returns a promise created in the context // where the `import` was called, not the context of `importModuleDynamically` // callback. async function testScript() { const ctx = createContext(); const mod1 = new SourceTextModule('export const a = 1;', { context: ctx, }); // No import statements, so must not link statically. await mod1.link(common.mustNotCall()); const script2 = new Script(` const promise = import("mod1"); if (Object.getPrototypeOf(promise) !== Promise.prototype) { throw new Error('Expected promise to be created in the current context'); } globalThis.__result = promise; `, { importModuleDynamically: common.mustCall((specifier, referrer) => { assert.strictEqual(specifier, 'mod1'); assert.strictEqual(referrer, script2); return mod1; }), }); script2.runInContext(ctx); // Wait for the promise to resolve. await ctx.__result; } async function testScriptImportFailed() { const ctx = createContext(); const mod1 = new SourceTextModule('export const a = 1;', { context: ctx, }); // No import statements, so must not link statically. await mod1.link(common.mustNotCall()); const err = new Error('import failed'); const script2 = new Script(` const promise = import("mod1"); if (Object.getPrototypeOf(promise) !== Promise.prototype) { throw new Error('Expected promise to be created in the current context'); } globalThis.__result = promise; `, { importModuleDynamically: common.mustCall((specifier, referrer) => { throw err; }), }); script2.runInContext(ctx); // Wait for the promise to reject. await assert.rejects(ctx.__result, err); } async function testModule() { const ctx = createContext(); const mod1 = new SourceTextModule('export const a = 1;', { context: ctx, }); // No import statements, so must not link statically. await mod1.link(common.mustNotCall()); const mod2 = new SourceTextModule(` const promise = import("mod1"); if (Object.getPrototypeOf(promise) !== Promise.prototype) { throw new Error('Expected promise to be created in the current context'); } await promise; `, { context: ctx, importModuleDynamically: common.mustCall((specifier, referrer) => { assert.strictEqual(specifier, 'mod1'); assert.strictEqual(referrer, mod2); return mod1; }), }); // No import statements, so must not link statically. await mod2.link(common.mustNotCall()); await mod2.evaluate(); } async function testModuleImportFailed() { const ctx = createContext(); const mod1 = new SourceTextModule('export const a = 1;', { context: ctx, }); // No import statements, so must not link statically. await mod1.link(common.mustNotCall()); const err = new Error('import failed'); ctx.__err = err; const mod2 = new SourceTextModule(` const promise = import("mod1"); if (Object.getPrototypeOf(promise) !== Promise.prototype) { throw new Error('Expected promise to be created in the current context'); } await promise.then(() => { throw new Error('Expected promise to be rejected'); }, (e) => { if (e !== globalThis.__err) { throw new Error('Expected promise to be rejected with "import failed"'); } }); `, { context: ctx, importModuleDynamically: common.mustCall((specifier, referrer) => { throw err; }), }); // No import statements, so must not link statically. await mod2.link(common.mustNotCall()); await mod2.evaluate(); } Promise.all([ testScript(), testScriptImportFailed(), testModule(), testModuleImportFailed(), ]).then(common.mustCall());