-
Notifications
You must be signed in to change notification settings - Fork 28.2k
/
test-esm-imports.mjs
139 lines (122 loc) Β· 4.5 KB
/
test-esm-imports.mjs
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { mustCall } from '../common/index.mjs';
import { ok, deepStrictEqual, strictEqual } from 'assert';
import importer from '../fixtures/es-modules/pkgimports/importer.js';
import { requireFixture } from '../fixtures/pkgexports.mjs';
const { requireImport, importImport } = importer;
[requireImport, importImport].forEach((loadFixture) => {
const isRequire = loadFixture === requireImport;
const internalImports = new Map([
// Base case
['#test', { default: 'test' }],
// import / require conditions
['#branch', { default: isRequire ? 'requirebranch' : 'importbranch' }],
// Subpath imports
['#subpath/x.js', { default: 'xsubpath' }],
// External imports
['#external', { default: 'asdf' }],
// External subpath imports
['#external/subpath/asdf.js', { default: 'asdf' }],
// Trailing pattern imports
['#subpath/asdf.asdf', { default: 'test' }],
// Leading slash
['#subpath//asdf.asdf', { default: 'test' }],
// Double slash
['#subpath/as//df.asdf', { default: 'test' }],
]);
for (const [validSpecifier, expected] of internalImports) {
if (validSpecifier === null) continue;
loadFixture(validSpecifier)
.then(mustCall((actual) => {
deepStrictEqual({ ...actual }, expected);
}));
}
const invalidImportTargets = new Set([
// Target steps below the package base
['#belowbase', '#belowbase'],
// Target is a URL
['#url', '#url'],
]);
for (const [specifier, subpath] of invalidImportTargets) {
loadFixture(specifier).catch(mustCall((err) => {
strictEqual(err.code, 'ERR_INVALID_PACKAGE_TARGET');
assertStartsWith(err.message, 'Invalid "imports"');
assertIncludes(err.message, subpath);
assertNotIncludes(err.message, 'targets must start with');
}));
}
const invalidImportSpecifiers = new Map([
// Backtracking below the package base
['#subpath/sub/../../../belowbase', 'request is not a valid match in pattern'],
// Percent-encoded slash errors
['#external/subpath/x%2Fy', 'must not include encoded "/" or "\\"'],
['#external/subpath/x%5Cy', 'must not include encoded "/" or "\\"'],
// Target must have a name
['#', '#'],
// Initial slash target must have a leading name
['#/initialslash', '#/initialslash'],
// Percent-encoded target paths
['#encodedslash', 'must not include encoded "/" or "\\"'],
['#encodedbackslash', 'must not include encoded "/" or "\\"'],
]);
for (const [specifier, expected] of invalidImportSpecifiers) {
loadFixture(specifier).catch(mustCall((err) => {
strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER');
assertStartsWith(err.message, 'Invalid module');
assertIncludes(err.message, expected);
}));
}
const undefinedImports = new Set([
// EOL subpaths
'#external/invalidsubpath/x',
// Missing import
'#missing',
// Explicit null import
'#null',
'#subpath/null',
// No condition match import
'#nullcondition',
// Null subpath shadowing
'#subpath/nullshadow/x',
// Null pattern
'#subpath/internal/test',
'#subpath/internal//test',
]);
for (const specifier of undefinedImports) {
loadFixture(specifier).catch(mustCall((err) => {
strictEqual(err.code, 'ERR_PACKAGE_IMPORT_NOT_DEFINED');
assertStartsWith(err.message, 'Package import ');
assertIncludes(err.message, specifier);
}));
}
// Handle not found for the defined imports target not existing
const nonDefinedImports = new Set([
'#notfound',
'#subpath//null',
'#subpath/////null',
'#subpath//internal/test',
'#subpath//internal//test',
'#subpath/////internal/////test',
]);
for (const specifier of nonDefinedImports) {
loadFixture(specifier).catch(mustCall((err) => {
strictEqual(err.code,
isRequire ? 'MODULE_NOT_FOUND' : 'ERR_MODULE_NOT_FOUND');
}));
}
});
// CJS resolver must still support #package packages in node_modules
requireFixture('#cjs').then(mustCall((actual) => {
strictEqual(actual.default, 'cjs backcompat');
}));
function assertStartsWith(actual, expected) {
const start = actual.toString().substr(0, expected.length);
strictEqual(start, expected);
}
function assertIncludes(actual, expected) {
ok(actual.toString().indexOf(expected) !== -1,
`${JSON.stringify(actual)} includes ${JSON.stringify(expected)}`);
}
function assertNotIncludes(actual, expected) {
ok(actual.toString().indexOf(expected) === -1,
`${JSON.stringify(actual)} doesn't include ${JSON.stringify(expected)}`);
}