summaryrefslogtreecommitdiff
path: root/test/es-module/test-esm-dynamic-import.js
blob: 91757172880f674721c873a6f22fec809644917a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Flags: --experimental-modules
'use strict';
const common = require('../common');
const assert = require('assert');
const { URL } = require('url');
const vm = require('vm');

common.crashOnUnhandledRejection();

const relativePath = '../fixtures/es-modules/test-esm-ok.mjs';
const absolutePath = require.resolve('../fixtures/es-modules/test-esm-ok.mjs');
const targetURL = new URL('file:///');
targetURL.pathname = absolutePath;

function expectErrorProperty(result, propertyKey, value) {
  Promise.resolve(result)
    .catch(common.mustCall(error => {
      assert.strictEqual(error[propertyKey], value);
    }));
}

function expectMissingModuleError(result) {
  expectErrorProperty(result, 'code', 'MODULE_NOT_FOUND');
}

function expectInvalidUrlError(result) {
  expectErrorProperty(result, 'code', 'ERR_INVALID_URL');
}

function expectInvalidReferrerError(result) {
  expectErrorProperty(result, 'code', 'ERR_INVALID_URL');
}

function expectInvalidProtocolError(result) {
  expectErrorProperty(result, 'code', 'ERR_INVALID_PROTOCOL');
}

function expectInvalidContextError(result) {
  expectErrorProperty(result,
    'message', 'import() called outside of main context');
}

function expectOkNamespace(result) {
  Promise.resolve(result)
    .then(common.mustCall(ns => {
      // Can't deepStrictEqual because ns isn't a normal object
      assert.deepEqual(ns, { default: true });
    }));
}

function expectFsNamespace(result) {
  Promise.resolve(result)
    .then(common.mustCall(ns => {
      assert.strictEqual(typeof ns.default.writeFile, 'function');
      assert.strictEqual(typeof ns.writeFile, 'function');
    }));
}

// For direct use of import expressions inside of CJS or ES modules, including
// via eval, all kinds of specifiers should work without issue.
(function testScriptOrModuleImport() {
  // Importing another file, both direct & via eval
  // expectOkNamespace(import(relativePath));
  expectOkNamespace(eval.call(null, `import("${relativePath}")`));
  expectOkNamespace(eval(`import("${relativePath}")`));
  expectOkNamespace(eval.call(null, `import("${targetURL}")`));

  // Importing a built-in, both direct & via eval
  expectFsNamespace(import("fs"));
  expectFsNamespace(eval('import("fs")'));
  expectFsNamespace(eval.call(null, 'import("fs")'));

  expectMissingModuleError(import("./not-an-existing-module.mjs"));
  // TODO(jkrems): Right now this doesn't hit a protocol error because the
  // module resolution step already rejects it. These arguably should be
  // protocol errors.
  expectMissingModuleError(import("node:fs"));
  expectMissingModuleError(import('http://example.com/foo.js'));
})();

// vm.runInThisContext:
// * Supports built-ins, always
// * Supports imports if the script has a known defined origin
(function testRunInThisContext() {
  // Succeeds because it's got an valid base url
  expectFsNamespace(vm.runInThisContext(`import("fs")`, {
    filename: __filename,
  }));
  expectOkNamespace(vm.runInThisContext(`import("${relativePath}")`, {
    filename: __filename,
  }));
  // Rejects because it's got an invalid referrer URL.
  // TODO(jkrems): Arguably the first two (built-in + absolute URL) could work
  // with some additional effort.
  expectInvalidReferrerError(vm.runInThisContext('import("fs")'));
  expectInvalidReferrerError(vm.runInThisContext(`import("${targetURL}")`));
  expectInvalidReferrerError(vm.runInThisContext(`import("${relativePath}")`));
})();

// vm.runInNewContext is currently completely unsupported, pending well-defined
// semantics for per-context/realm module maps in node.
(function testRunInNewContext() {
  // Rejects because it's running in the wrong context
  expectInvalidContextError(
    vm.runInNewContext(`import("${targetURL}")`, undefined, {
      filename: __filename,
    })
  );

  // Rejects because it's running in the wrong context
  expectInvalidContextError(vm.runInNewContext(`import("fs")`, undefined, {
    filename: __filename,
  }));
})();