| 'use strict'; |
| |
| // Flags: --experimental-vm-modules --js-source-phase-imports |
| |
| require('../common'); |
| |
| const assert = require('assert'); |
| |
| const { SourceTextModule } = require('vm'); |
| const test = require('node:test'); |
| |
| test('basic circular linking', async function circular() { |
| const foo = new SourceTextModule(` |
| import getFoo from 'bar'; |
| export let foo = 42; |
| export default getFoo(); |
| `); |
| const bar = new SourceTextModule(` |
| import { foo } from 'foo'; |
| export default function getFoo() { |
| return foo; |
| } |
| `); |
| foo.linkRequests([bar]); |
| bar.linkRequests([foo]); |
| |
| foo.instantiate(); |
| assert.strictEqual(foo.status, 'linked'); |
| assert.strictEqual(bar.status, 'linked'); |
| |
| await foo.evaluate(); |
| assert.strictEqual(foo.namespace.default, 42); |
| }); |
| |
| test('circular linking graph', async function circular2() { |
| const sourceMap = { |
| 'root': ` |
| import * as a from './a.mjs'; |
| import * as b from './b.mjs'; |
| if (!('fromA' in a)) |
| throw new Error(); |
| if (!('fromB' in a)) |
| throw new Error(); |
| if (!('fromA' in b)) |
| throw new Error(); |
| if (!('fromB' in b)) |
| throw new Error(); |
| `, |
| './a.mjs': ` |
| export * from './b.mjs'; |
| export let fromA; |
| `, |
| './b.mjs': ` |
| export * from './a.mjs'; |
| export let fromB; |
| ` |
| }; |
| const moduleMap = new Map(); |
| for (const [specifier, source] of Object.entries(sourceMap)) { |
| moduleMap.set(specifier, new SourceTextModule(source, { |
| identifier: new URL(specifier, 'file:///').href, |
| })); |
| } |
| for (const mod of moduleMap.values()) { |
| mod.linkRequests(mod.moduleRequests.map((request) => { |
| return moduleMap.get(request.specifier); |
| })); |
| } |
| const rootModule = moduleMap.get('root'); |
| rootModule.instantiate(); |
| await rootModule.evaluate(); |
| }); |