11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --experimental-vm-modules
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst {
81cb0ef41Sopenharmony_ci  Module,
91cb0ef41Sopenharmony_ci  SourceTextModule,
101cb0ef41Sopenharmony_ci  SyntheticModule,
111cb0ef41Sopenharmony_ci  createContext,
121cb0ef41Sopenharmony_ci  compileFunction,
131cb0ef41Sopenharmony_ci} = require('vm');
141cb0ef41Sopenharmony_ciconst util = require('util');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci(async function test1() {
171cb0ef41Sopenharmony_ci  const context = createContext({
181cb0ef41Sopenharmony_ci    foo: 'bar',
191cb0ef41Sopenharmony_ci    baz: undefined,
201cb0ef41Sopenharmony_ci    typeofProcess: undefined,
211cb0ef41Sopenharmony_ci  });
221cb0ef41Sopenharmony_ci  const m = new SourceTextModule(
231cb0ef41Sopenharmony_ci    'baz = foo; typeofProcess = typeof process; typeof Object;',
241cb0ef41Sopenharmony_ci    { context }
251cb0ef41Sopenharmony_ci  );
261cb0ef41Sopenharmony_ci  assert.strictEqual(m.status, 'unlinked');
271cb0ef41Sopenharmony_ci  await m.link(common.mustNotCall());
281cb0ef41Sopenharmony_ci  assert.strictEqual(m.status, 'linked');
291cb0ef41Sopenharmony_ci  assert.strictEqual(await m.evaluate(), undefined);
301cb0ef41Sopenharmony_ci  assert.strictEqual(m.status, 'evaluated');
311cb0ef41Sopenharmony_ci  assert.deepStrictEqual(context, {
321cb0ef41Sopenharmony_ci    foo: 'bar',
331cb0ef41Sopenharmony_ci    baz: 'bar',
341cb0ef41Sopenharmony_ci    typeofProcess: 'undefined'
351cb0ef41Sopenharmony_ci  });
361cb0ef41Sopenharmony_ci}().then(common.mustCall()));
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci(async () => {
391cb0ef41Sopenharmony_ci  const m = new SourceTextModule(`
401cb0ef41Sopenharmony_ci    global.vmResultFoo = "foo";
411cb0ef41Sopenharmony_ci    global.vmResultTypeofProcess = Object.prototype.toString.call(process);
421cb0ef41Sopenharmony_ci  `);
431cb0ef41Sopenharmony_ci  await m.link(common.mustNotCall());
441cb0ef41Sopenharmony_ci  await m.evaluate();
451cb0ef41Sopenharmony_ci  assert.strictEqual(global.vmResultFoo, 'foo');
461cb0ef41Sopenharmony_ci  assert.strictEqual(global.vmResultTypeofProcess, '[object process]');
471cb0ef41Sopenharmony_ci  delete global.vmResultFoo;
481cb0ef41Sopenharmony_ci  delete global.vmResultTypeofProcess;
491cb0ef41Sopenharmony_ci})().then(common.mustCall());
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci(async () => {
521cb0ef41Sopenharmony_ci  const m = new SourceTextModule('while (true) {}');
531cb0ef41Sopenharmony_ci  await m.link(common.mustNotCall());
541cb0ef41Sopenharmony_ci  await m.evaluate({ timeout: 500 })
551cb0ef41Sopenharmony_ci    .then(() => assert(false), () => {});
561cb0ef41Sopenharmony_ci})().then(common.mustCall());
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci// Check the generated identifier for each module
591cb0ef41Sopenharmony_ci(async () => {
601cb0ef41Sopenharmony_ci  const context1 = createContext({ });
611cb0ef41Sopenharmony_ci  const context2 = createContext({ });
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  const m1 = new SourceTextModule('1', { context: context1 });
641cb0ef41Sopenharmony_ci  assert.strictEqual(m1.identifier, 'vm:module(0)');
651cb0ef41Sopenharmony_ci  const m2 = new SourceTextModule('2', { context: context1 });
661cb0ef41Sopenharmony_ci  assert.strictEqual(m2.identifier, 'vm:module(1)');
671cb0ef41Sopenharmony_ci  const m3 = new SourceTextModule('3', { context: context2 });
681cb0ef41Sopenharmony_ci  assert.strictEqual(m3.identifier, 'vm:module(0)');
691cb0ef41Sopenharmony_ci})().then(common.mustCall());
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci// Check inspection of the instance
721cb0ef41Sopenharmony_ci{
731cb0ef41Sopenharmony_ci  const context = createContext({ foo: 'bar' });
741cb0ef41Sopenharmony_ci  const m = new SourceTextModule('1', { context });
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  assert.strictEqual(
771cb0ef41Sopenharmony_ci    util.inspect(m),
781cb0ef41Sopenharmony_ci    `SourceTextModule {
791cb0ef41Sopenharmony_ci  status: 'unlinked',
801cb0ef41Sopenharmony_ci  identifier: 'vm:module(0)',
811cb0ef41Sopenharmony_ci  context: { foo: 'bar' }
821cb0ef41Sopenharmony_ci}`
831cb0ef41Sopenharmony_ci  );
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]');
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  assert.throws(
881cb0ef41Sopenharmony_ci    () => m[util.inspect.custom].call(Object.create(null)),
891cb0ef41Sopenharmony_ci    {
901cb0ef41Sopenharmony_ci      code: 'ERR_VM_MODULE_NOT_MODULE',
911cb0ef41Sopenharmony_ci      message: 'Provided module is not an instance of Module'
921cb0ef41Sopenharmony_ci    },
931cb0ef41Sopenharmony_ci  );
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci{
971cb0ef41Sopenharmony_ci  const context = createContext({ foo: 'bar' });
981cb0ef41Sopenharmony_ci  const m = new SyntheticModule([], () => {}, { context });
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  assert.strictEqual(
1011cb0ef41Sopenharmony_ci    util.inspect(m),
1021cb0ef41Sopenharmony_ci    `SyntheticModule {
1031cb0ef41Sopenharmony_ci  status: 'unlinked',
1041cb0ef41Sopenharmony_ci  identifier: 'vm:module(0)',
1051cb0ef41Sopenharmony_ci  context: { foo: 'bar' }
1061cb0ef41Sopenharmony_ci}`
1071cb0ef41Sopenharmony_ci  );
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  assert.strictEqual(util.inspect(m, { depth: -1 }), '[SyntheticModule]');
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci// Check dependencies getter returns same object every time
1131cb0ef41Sopenharmony_ci{
1141cb0ef41Sopenharmony_ci  const m = new SourceTextModule('');
1151cb0ef41Sopenharmony_ci  const dep = m.dependencySpecifiers;
1161cb0ef41Sopenharmony_ci  assert.notStrictEqual(dep, undefined);
1171cb0ef41Sopenharmony_ci  assert.strictEqual(dep, m.dependencySpecifiers);
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci// Check the impossibility of creating an abstract instance of the Module.
1211cb0ef41Sopenharmony_ci{
1221cb0ef41Sopenharmony_ci  assert.throws(() => new Module(), {
1231cb0ef41Sopenharmony_ci    message: 'Module is not a constructor',
1241cb0ef41Sopenharmony_ci    name: 'TypeError'
1251cb0ef41Sopenharmony_ci  });
1261cb0ef41Sopenharmony_ci}
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci// Check to throws invalid exportNames
1291cb0ef41Sopenharmony_ci{
1301cb0ef41Sopenharmony_ci  assert.throws(() => new SyntheticModule(undefined, () => {}, {}), {
1311cb0ef41Sopenharmony_ci    message: 'The "exportNames" argument must be an ' +
1321cb0ef41Sopenharmony_ci        'Array of unique strings.' +
1331cb0ef41Sopenharmony_ci        ' Received undefined',
1341cb0ef41Sopenharmony_ci    name: 'TypeError'
1351cb0ef41Sopenharmony_ci  });
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci// Check to throws duplicated exportNames
1391cb0ef41Sopenharmony_ci// https://github.com/nodejs/node/issues/32806
1401cb0ef41Sopenharmony_ci{
1411cb0ef41Sopenharmony_ci  assert.throws(() => new SyntheticModule(['x', 'x'], () => {}, {}), {
1421cb0ef41Sopenharmony_ci    message: 'The property \'exportNames.x\' is duplicated. Received \'x\'',
1431cb0ef41Sopenharmony_ci    name: 'TypeError',
1441cb0ef41Sopenharmony_ci  });
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci// Check to throws invalid evaluateCallback
1481cb0ef41Sopenharmony_ci{
1491cb0ef41Sopenharmony_ci  assert.throws(() => new SyntheticModule([], undefined, {}), {
1501cb0ef41Sopenharmony_ci    message: 'The "evaluateCallback" argument must be of type function.' +
1511cb0ef41Sopenharmony_ci      ' Received undefined',
1521cb0ef41Sopenharmony_ci    name: 'TypeError'
1531cb0ef41Sopenharmony_ci  });
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci// Check to throws invalid options
1571cb0ef41Sopenharmony_ci{
1581cb0ef41Sopenharmony_ci  assert.throws(() => new SyntheticModule([], () => {}, null), {
1591cb0ef41Sopenharmony_ci    message: 'The "options" argument must be of type object.' +
1601cb0ef41Sopenharmony_ci      ' Received null',
1611cb0ef41Sopenharmony_ci    name: 'TypeError'
1621cb0ef41Sopenharmony_ci  });
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci// Test compileFunction importModuleDynamically
1661cb0ef41Sopenharmony_ci{
1671cb0ef41Sopenharmony_ci  const module = new SyntheticModule([], () => {});
1681cb0ef41Sopenharmony_ci  module.link(() => {});
1691cb0ef41Sopenharmony_ci  const f = compileFunction('return import("x")', [], {
1701cb0ef41Sopenharmony_ci    importModuleDynamically(specifier, referrer) {
1711cb0ef41Sopenharmony_ci      assert.strictEqual(specifier, 'x');
1721cb0ef41Sopenharmony_ci      assert.strictEqual(referrer, f);
1731cb0ef41Sopenharmony_ci      return module;
1741cb0ef41Sopenharmony_ci    },
1751cb0ef41Sopenharmony_ci  });
1761cb0ef41Sopenharmony_ci  f().then((ns) => {
1771cb0ef41Sopenharmony_ci    assert.strictEqual(ns, module.namespace);
1781cb0ef41Sopenharmony_ci  });
1791cb0ef41Sopenharmony_ci}
180