node/test/es-module/test-vm-main-context-default-loader.js

143 lines
4.5 KiB
JavaScript
Raw Normal View History

'use strict';
const common = require('../common');
// Can't process.chdir() in worker.
common.skipIfWorker();
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');
const url = require('url');
const fs = require('fs');
const {
compileFunction,
Script,
createContext,
constants: { USE_MAIN_CONTEXT_DEFAULT_LOADER },
} = require('vm');
const assert = require('assert');
common.expectWarning('ExperimentalWarning',
'vm.USE_MAIN_CONTEXT_DEFAULT_LOADER is an experimental feature and might change at any time');
assert(
!process.execArgv.includes('--experimental-vm-modules'),
'This test must be run without --experimental-vm-modules');
assert.strictEqual(typeof USE_MAIN_CONTEXT_DEFAULT_LOADER, 'symbol');
async function testNotFoundErrors(options) {
// Import user modules.
const script = new Script('import("./message.mjs")', options);
// Use try-catch for better async stack traces in the logs.
await assert.rejects(script.runInThisContext(), { code: 'ERR_MODULE_NOT_FOUND' });
const imported = compileFunction('return import("./message.mjs")', [], options)();
// Use try-catch for better async stack traces in the logs.
await assert.rejects(imported, { code: 'ERR_MODULE_NOT_FOUND' });
}
async function testLoader(options) {
{
// Import built-in modules
const script = new Script('import("fs")', options);
let result = await script.runInThisContext();
assert.strictEqual(result.constants.F_OK, fs.constants.F_OK);
const imported = compileFunction('return import("fs")', [], options)();
result = await imported;
assert.strictEqual(result.constants.F_OK, fs.constants.F_OK);
}
const moduleUrl = fixtures.fileURL('es-modules', 'message.mjs');
fs.copyFileSync(moduleUrl, tmpdir.resolve('message.mjs'));
{
const namespace = await import(moduleUrl);
const script = new Script('import("./message.mjs")', options);
const result = await script.runInThisContext();
assert.deepStrictEqual(result, namespace);
}
{
const namespace = await import(moduleUrl);
const imported = compileFunction('return import("./message.mjs")', [], options)();
const result = await imported;
assert.deepStrictEqual(result, namespace);
}
}
async function main() {
{
// Importing with absolute path as filename.
tmpdir.refresh();
const filename = tmpdir.resolve('index.js');
const options = {
filename,
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER
};
await testNotFoundErrors(options);
await testLoader(options);
}
{
// Importing with file:// URL as filename.
tmpdir.refresh();
// We use a search parameter to bypass caching.
const filename = url.pathToFileURL(tmpdir.resolve('index.js')).href + '?t=1';
const options = {
filename,
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER
};
await testNotFoundErrors(options);
await testLoader(options);
}
{
// For undefined or non-path/URL filenames, import() should resolve to the cwd.
tmpdir.refresh();
process.chdir(tmpdir.path);
const undefinedOptions = {
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER
};
const nonPathOptions = {
filename: 'non-path',
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER
};
// Run the error tests first to avoid caching.
await testNotFoundErrors(undefinedOptions);
await testNotFoundErrors(nonPathOptions);
// createContext() with null referrer also resolves to cwd.
{
const options = {
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER,
};
const ctx = createContext({}, options);
const s = new Script('Promise.resolve("import(\'./message.mjs\')").then(eval)', {
importModuleDynamically: common.mustNotCall(),
});
await assert.rejects(s.runInContext(ctx), { code: 'ERR_MODULE_NOT_FOUND' });
}
await testLoader(undefinedOptions);
await testLoader(nonPathOptions);
{
const options = {
importModuleDynamically: USE_MAIN_CONTEXT_DEFAULT_LOADER,
};
const ctx = createContext({}, options);
const moduleUrl = fixtures.fileURL('es-modules', 'message.mjs');
const namespace = await import(moduleUrl.href);
const script = new Script('Promise.resolve("import(\'./message.mjs\')").then(eval)', {
importModuleDynamically: common.mustNotCall(),
});
const result = await script.runInContext(ctx);
assert.deepStrictEqual(result, namespace);
}
}
}
main().catch(common.mustNotCall());