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