11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --experimental-vm-modules
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst { SourceTextModule } = require('vm');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciasync function simple() {
121cb0ef41Sopenharmony_ci  const foo = new SourceTextModule('export default 5;');
131cb0ef41Sopenharmony_ci  await foo.link(common.mustNotCall());
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci  globalThis.fiveResult = undefined;
161cb0ef41Sopenharmony_ci  const bar = new SourceTextModule('import five from "foo"; fiveResult = five');
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci  assert.deepStrictEqual(bar.dependencySpecifiers, ['foo']);
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  await bar.link(common.mustCall((specifier, module) => {
211cb0ef41Sopenharmony_ci    assert.strictEqual(module, bar);
221cb0ef41Sopenharmony_ci    assert.strictEqual(specifier, 'foo');
231cb0ef41Sopenharmony_ci    return foo;
241cb0ef41Sopenharmony_ci  }));
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  await bar.evaluate();
271cb0ef41Sopenharmony_ci  assert.strictEqual(globalThis.fiveResult, 5);
281cb0ef41Sopenharmony_ci  delete globalThis.fiveResult;
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciasync function depth() {
321cb0ef41Sopenharmony_ci  const foo = new SourceTextModule('export default 5');
331cb0ef41Sopenharmony_ci  await foo.link(common.mustNotCall());
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  async function getProxy(parentName, parentModule) {
361cb0ef41Sopenharmony_ci    const mod = new SourceTextModule(`
371cb0ef41Sopenharmony_ci      import ${parentName} from '${parentName}';
381cb0ef41Sopenharmony_ci      export default ${parentName};
391cb0ef41Sopenharmony_ci    `);
401cb0ef41Sopenharmony_ci    await mod.link(common.mustCall((specifier, module) => {
411cb0ef41Sopenharmony_ci      assert.strictEqual(module, mod);
421cb0ef41Sopenharmony_ci      assert.strictEqual(specifier, parentName);
431cb0ef41Sopenharmony_ci      return parentModule;
441cb0ef41Sopenharmony_ci    }));
451cb0ef41Sopenharmony_ci    return mod;
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  const bar = await getProxy('foo', foo);
491cb0ef41Sopenharmony_ci  const baz = await getProxy('bar', bar);
501cb0ef41Sopenharmony_ci  const barz = await getProxy('baz', baz);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  await barz.evaluate();
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  assert.strictEqual(barz.namespace.default, 5);
551cb0ef41Sopenharmony_ci}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ciasync function circular() {
581cb0ef41Sopenharmony_ci  const foo = new SourceTextModule(`
591cb0ef41Sopenharmony_ci    import getFoo from 'bar';
601cb0ef41Sopenharmony_ci    export let foo = 42;
611cb0ef41Sopenharmony_ci    export default getFoo();
621cb0ef41Sopenharmony_ci  `);
631cb0ef41Sopenharmony_ci  const bar = new SourceTextModule(`
641cb0ef41Sopenharmony_ci    import { foo } from 'foo';
651cb0ef41Sopenharmony_ci    export default function getFoo() {
661cb0ef41Sopenharmony_ci      return foo;
671cb0ef41Sopenharmony_ci    }
681cb0ef41Sopenharmony_ci  `);
691cb0ef41Sopenharmony_ci  await foo.link(common.mustCall(async (specifier, module) => {
701cb0ef41Sopenharmony_ci    if (specifier === 'bar') {
711cb0ef41Sopenharmony_ci      assert.strictEqual(module, foo);
721cb0ef41Sopenharmony_ci      return bar;
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci    assert.strictEqual(specifier, 'foo');
751cb0ef41Sopenharmony_ci    assert.strictEqual(module, bar);
761cb0ef41Sopenharmony_ci    assert.strictEqual(foo.status, 'linking');
771cb0ef41Sopenharmony_ci    return foo;
781cb0ef41Sopenharmony_ci  }, 2));
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  assert.strictEqual(bar.status, 'linked');
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  await foo.evaluate();
831cb0ef41Sopenharmony_ci  assert.strictEqual(foo.namespace.default, 42);
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciasync function circular2() {
871cb0ef41Sopenharmony_ci  const sourceMap = {
881cb0ef41Sopenharmony_ci    'root': `
891cb0ef41Sopenharmony_ci      import * as a from './a.mjs';
901cb0ef41Sopenharmony_ci      import * as b from './b.mjs';
911cb0ef41Sopenharmony_ci      if (!('fromA' in a))
921cb0ef41Sopenharmony_ci        throw new Error();
931cb0ef41Sopenharmony_ci      if (!('fromB' in a))
941cb0ef41Sopenharmony_ci        throw new Error();
951cb0ef41Sopenharmony_ci      if (!('fromA' in b))
961cb0ef41Sopenharmony_ci        throw new Error();
971cb0ef41Sopenharmony_ci      if (!('fromB' in b))
981cb0ef41Sopenharmony_ci        throw new Error();
991cb0ef41Sopenharmony_ci    `,
1001cb0ef41Sopenharmony_ci    './a.mjs': `
1011cb0ef41Sopenharmony_ci      export * from './b.mjs';
1021cb0ef41Sopenharmony_ci      export let fromA;
1031cb0ef41Sopenharmony_ci    `,
1041cb0ef41Sopenharmony_ci    './b.mjs': `
1051cb0ef41Sopenharmony_ci      export * from './a.mjs';
1061cb0ef41Sopenharmony_ci      export let fromB;
1071cb0ef41Sopenharmony_ci    `
1081cb0ef41Sopenharmony_ci  };
1091cb0ef41Sopenharmony_ci  const moduleMap = new Map();
1101cb0ef41Sopenharmony_ci  const rootModule = new SourceTextModule(sourceMap.root, {
1111cb0ef41Sopenharmony_ci    identifier: 'vm:root',
1121cb0ef41Sopenharmony_ci  });
1131cb0ef41Sopenharmony_ci  async function link(specifier, referencingModule) {
1141cb0ef41Sopenharmony_ci    if (moduleMap.has(specifier)) {
1151cb0ef41Sopenharmony_ci      return moduleMap.get(specifier);
1161cb0ef41Sopenharmony_ci    }
1171cb0ef41Sopenharmony_ci    const mod = new SourceTextModule(sourceMap[specifier], {
1181cb0ef41Sopenharmony_ci      identifier: new URL(specifier, 'file:///').href,
1191cb0ef41Sopenharmony_ci    });
1201cb0ef41Sopenharmony_ci    moduleMap.set(specifier, mod);
1211cb0ef41Sopenharmony_ci    return mod;
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci  await rootModule.link(link);
1241cb0ef41Sopenharmony_ci  await rootModule.evaluate();
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciasync function asserts() {
1281cb0ef41Sopenharmony_ci  const m = new SourceTextModule(`
1291cb0ef41Sopenharmony_ci  import "foo" assert { n1: 'v1', n2: 'v2' };
1301cb0ef41Sopenharmony_ci  `, { identifier: 'm' });
1311cb0ef41Sopenharmony_ci  await m.link((s, r, p) => {
1321cb0ef41Sopenharmony_ci    assert.strictEqual(s, 'foo');
1331cb0ef41Sopenharmony_ci    assert.strictEqual(r.identifier, 'm');
1341cb0ef41Sopenharmony_ci    assert.strictEqual(p.attributes.n1, 'v1');
1351cb0ef41Sopenharmony_ci    assert.strictEqual(p.assert.n1, 'v1');
1361cb0ef41Sopenharmony_ci    assert.strictEqual(p.attributes.n2, 'v2');
1371cb0ef41Sopenharmony_ci    assert.strictEqual(p.assert.n2, 'v2');
1381cb0ef41Sopenharmony_ci    return new SourceTextModule('');
1391cb0ef41Sopenharmony_ci  });
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciconst finished = common.mustCall();
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci(async function main() {
1451cb0ef41Sopenharmony_ci  await simple();
1461cb0ef41Sopenharmony_ci  await depth();
1471cb0ef41Sopenharmony_ci  await circular();
1481cb0ef41Sopenharmony_ci  await circular2();
1491cb0ef41Sopenharmony_ci  await asserts();
1501cb0ef41Sopenharmony_ci  finished();
1511cb0ef41Sopenharmony_ci})().then(common.mustCall());
152