1'use strict'; 2 3// Flags: --experimental-vm-modules 4 5const common = require('../common'); 6const assert = require('assert'); 7const { 8 Module, 9 SourceTextModule, 10 SyntheticModule, 11 createContext, 12 compileFunction, 13} = require('vm'); 14const util = require('util'); 15 16(async function test1() { 17 const context = createContext({ 18 foo: 'bar', 19 baz: undefined, 20 typeofProcess: undefined, 21 }); 22 const m = new SourceTextModule( 23 'baz = foo; typeofProcess = typeof process; typeof Object;', 24 { context } 25 ); 26 assert.strictEqual(m.status, 'unlinked'); 27 await m.link(common.mustNotCall()); 28 assert.strictEqual(m.status, 'linked'); 29 assert.strictEqual(await m.evaluate(), undefined); 30 assert.strictEqual(m.status, 'evaluated'); 31 assert.deepStrictEqual(context, { 32 foo: 'bar', 33 baz: 'bar', 34 typeofProcess: 'undefined' 35 }); 36}().then(common.mustCall())); 37 38(async () => { 39 const m = new SourceTextModule(` 40 global.vmResultFoo = "foo"; 41 global.vmResultTypeofProcess = Object.prototype.toString.call(process); 42 `); 43 await m.link(common.mustNotCall()); 44 await m.evaluate(); 45 assert.strictEqual(global.vmResultFoo, 'foo'); 46 assert.strictEqual(global.vmResultTypeofProcess, '[object process]'); 47 delete global.vmResultFoo; 48 delete global.vmResultTypeofProcess; 49})().then(common.mustCall()); 50 51(async () => { 52 const m = new SourceTextModule('while (true) {}'); 53 await m.link(common.mustNotCall()); 54 await m.evaluate({ timeout: 500 }) 55 .then(() => assert(false), () => {}); 56})().then(common.mustCall()); 57 58// Check the generated identifier for each module 59(async () => { 60 const context1 = createContext({ }); 61 const context2 = createContext({ }); 62 63 const m1 = new SourceTextModule('1', { context: context1 }); 64 assert.strictEqual(m1.identifier, 'vm:module(0)'); 65 const m2 = new SourceTextModule('2', { context: context1 }); 66 assert.strictEqual(m2.identifier, 'vm:module(1)'); 67 const m3 = new SourceTextModule('3', { context: context2 }); 68 assert.strictEqual(m3.identifier, 'vm:module(0)'); 69})().then(common.mustCall()); 70 71// Check inspection of the instance 72{ 73 const context = createContext({ foo: 'bar' }); 74 const m = new SourceTextModule('1', { context }); 75 76 assert.strictEqual( 77 util.inspect(m), 78 `SourceTextModule { 79 status: 'unlinked', 80 identifier: 'vm:module(0)', 81 context: { foo: 'bar' } 82}` 83 ); 84 85 assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]'); 86 87 assert.throws( 88 () => m[util.inspect.custom].call(Object.create(null)), 89 { 90 code: 'ERR_VM_MODULE_NOT_MODULE', 91 message: 'Provided module is not an instance of Module' 92 }, 93 ); 94} 95 96{ 97 const context = createContext({ foo: 'bar' }); 98 const m = new SyntheticModule([], () => {}, { context }); 99 100 assert.strictEqual( 101 util.inspect(m), 102 `SyntheticModule { 103 status: 'unlinked', 104 identifier: 'vm:module(0)', 105 context: { foo: 'bar' } 106}` 107 ); 108 109 assert.strictEqual(util.inspect(m, { depth: -1 }), '[SyntheticModule]'); 110} 111 112// Check dependencies getter returns same object every time 113{ 114 const m = new SourceTextModule(''); 115 const dep = m.dependencySpecifiers; 116 assert.notStrictEqual(dep, undefined); 117 assert.strictEqual(dep, m.dependencySpecifiers); 118} 119 120// Check the impossibility of creating an abstract instance of the Module. 121{ 122 assert.throws(() => new Module(), { 123 message: 'Module is not a constructor', 124 name: 'TypeError' 125 }); 126} 127 128// Check to throws invalid exportNames 129{ 130 assert.throws(() => new SyntheticModule(undefined, () => {}, {}), { 131 message: 'The "exportNames" argument must be an ' + 132 'Array of unique strings.' + 133 ' Received undefined', 134 name: 'TypeError' 135 }); 136} 137 138// Check to throws duplicated exportNames 139// https://github.com/nodejs/node/issues/32806 140{ 141 assert.throws(() => new SyntheticModule(['x', 'x'], () => {}, {}), { 142 message: 'The property \'exportNames.x\' is duplicated. Received \'x\'', 143 name: 'TypeError', 144 }); 145} 146 147// Check to throws invalid evaluateCallback 148{ 149 assert.throws(() => new SyntheticModule([], undefined, {}), { 150 message: 'The "evaluateCallback" argument must be of type function.' + 151 ' Received undefined', 152 name: 'TypeError' 153 }); 154} 155 156// Check to throws invalid options 157{ 158 assert.throws(() => new SyntheticModule([], () => {}, null), { 159 message: 'The "options" argument must be of type object.' + 160 ' Received null', 161 name: 'TypeError' 162 }); 163} 164 165// Test compileFunction importModuleDynamically 166{ 167 const module = new SyntheticModule([], () => {}); 168 module.link(() => {}); 169 const f = compileFunction('return import("x")', [], { 170 importModuleDynamically(specifier, referrer) { 171 assert.strictEqual(specifier, 'x'); 172 assert.strictEqual(referrer, f); 173 return module; 174 }, 175 }); 176 f().then((ns) => { 177 assert.strictEqual(ns, module.namespace); 178 }); 179} 180