Skip to content

Commit 320a8ad

Browse files
GeoffreyBoothdanielleadams
authored andcommitted
esm: misc test refactors
- add test specific to the event loop - move parallel tests into es-module folder - refactor fixture to add braces for if blocks - use 'os' instead of 'fs' as placeholder - spelling PR-URL: #46631 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent dd97b05 commit 320a8ad

9 files changed

Lines changed: 377 additions & 58 deletions

‎test/es-module/test-esm-import-meta-resolve.mjs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { mustCall } from '../common/index.mjs';
33
importassertfrom'assert';
44

55
constdirname=import.meta.url.slice(0,import.meta.url.lastIndexOf('/')+1);
6-
constfixtures=dirname.slice(0,dirname.lastIndexOf('/',dirname.length-2)+
7-
1)+'fixtures/';
6+
constfixtures=dirname.slice(0,dirname.lastIndexOf('/',dirname.length-2)+1)+'fixtures/';
87

98
(async()=>{
109
assert.strictEqual(awaitimport.meta.resolve('./test-esm-import-meta.mjs'),

‎test/es-module/test-esm-initialization.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { execPath } from 'node:process';
55
import{describe,it}from'node:test';
66

77

8-
describe('ESM: ensure initialisation happens only once',{concurrency: true},()=>{
8+
describe('ESM: ensure initialization happens only once',{concurrency: true},()=>{
99
it(async()=>{
1010
const{ code, stderr, stdout }=awaitspawnPromisified(execPath,[
1111
'--loader',

‎test/es-module/test-esm-loader-chaining.mjs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const setupArgs = [
1010
'--input-type=module',
1111
'--eval',
1212
];
13-
constcommonInput='import fs from "node:fs"; console.log(fs)';
13+
constcommonInput='import os from "node:os"; console.log(os)';
1414
constcommonArgs=[
1515
...setupArgs,
1616
commonInput,
@@ -115,11 +115,11 @@ describe('ESM: loader chaining', { concurrency: true }, () => {
115115
);
116116

117117
assert.match(stdout,/^resolveargcount:3$/m);
118-
assert.match(stdout,/specifier:'node:fs'/);
118+
assert.match(stdout,/specifier:'node:os'/);
119119
assert.match(stdout,/next:\[AsyncFunction:nextResolve\]/);
120120

121121
assert.match(stdout,/^loadargcount:3$/m);
122-
assert.match(stdout,/url:'node:fs'/);
122+
assert.match(stdout,/url:'node:os'/);
123123
assert.match(stdout,/next:\[AsyncFunction:nextLoad\]/);
124124
});
125125

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Flags: --experimental-loader ./test/fixtures/es-module-loaders/hooks-custom.mjs
2+
import{mustCall}from'../common/index.mjs';
3+
4+
constdone=mustCall();
5+
6+
7+
// Test that the process doesn't exit because of a caught exception thrown as part of dynamic import().
8+
for(leti=0;i<10;i++){
9+
awaitimport('nonexistent/file.mjs').catch(()=>{});
10+
}
11+
12+
done();
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
import{spawnPromisified}from'../common/index.mjs';
2+
import*asfixturesfrom'../common/fixtures.mjs';
3+
importassertfrom'node:assert';
4+
import{execPath}from'node:process';
5+
import{describe,it}from'node:test';
6+
7+
describe('Loader hooks throwing errors',{concurrency: true},()=>{
8+
it('throws on nonexistent modules',async()=>{
9+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
10+
'--no-warnings',
11+
'--experimental-loader',
12+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
13+
'--input-type=module',
14+
'--eval',
15+
'import "nonexistent/file.mjs"',
16+
]);
17+
18+
assert.match(stderr,/ERR_MODULE_NOT_FOUND/);
19+
assert.strictEqual(stdout,'');
20+
assert.strictEqual(code,1);
21+
assert.strictEqual(signal,null);
22+
});
23+
24+
it('throws on unknown extensions',async()=>{
25+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
26+
'--no-warnings',
27+
'--experimental-loader',
28+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
29+
'--input-type=module',
30+
'--eval',
31+
`import '${fixtures.fileURL('/es-modules/file.unknown')}'`,
32+
]);
33+
34+
assert.match(stderr,/ERR_UNKNOWN_FILE_EXTENSION/);
35+
assert.strictEqual(stdout,'');
36+
assert.strictEqual(code,1);
37+
assert.strictEqual(signal,null);
38+
});
39+
40+
it('throws on invalid return values',async()=>{
41+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
42+
'--no-warnings',
43+
'--experimental-loader',
44+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
45+
'--input-type=module',
46+
'--eval',
47+
'import "esmHook/badReturnVal.mjs"',
48+
]);
49+
50+
assert.match(stderr,/ERR_INVALID_RETURN_VALUE/);
51+
assert.strictEqual(stdout,'');
52+
assert.strictEqual(code,1);
53+
assert.strictEqual(signal,null);
54+
});
55+
56+
it('throws on boolean false',async()=>{
57+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
58+
'--no-warnings',
59+
'--experimental-loader',
60+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
61+
'--input-type=module',
62+
'--eval',
63+
'import "esmHook/format.false"',
64+
]);
65+
66+
assert.match(stderr,/ERR_INVALID_RETURN_PROPERTY_VALUE/);
67+
assert.strictEqual(stdout,'');
68+
assert.strictEqual(code,1);
69+
assert.strictEqual(signal,null);
70+
});
71+
it('throws on boolean true',async()=>{
72+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
73+
'--no-warnings',
74+
'--experimental-loader',
75+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
76+
'--input-type=module',
77+
'--eval',
78+
'import "esmHook/format.true"',
79+
]);
80+
81+
assert.match(stderr,/ERR_INVALID_RETURN_PROPERTY_VALUE/);
82+
assert.strictEqual(stdout,'');
83+
assert.strictEqual(code,1);
84+
assert.strictEqual(signal,null);
85+
});
86+
87+
it('throws on invalid returned object',async()=>{
88+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
89+
'--no-warnings',
90+
'--experimental-loader',
91+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
92+
'--input-type=module',
93+
'--eval',
94+
'import "esmHook/badReturnFormatVal.mjs"',
95+
]);
96+
97+
assert.match(stderr,/ERR_INVALID_RETURN_PROPERTY_VALUE/);
98+
assert.strictEqual(stdout,'');
99+
assert.strictEqual(code,1);
100+
assert.strictEqual(signal,null);
101+
});
102+
103+
it('throws on unsupported format',async()=>{
104+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
105+
'--no-warnings',
106+
'--experimental-loader',
107+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
108+
'--input-type=module',
109+
'--eval',
110+
'import "esmHook/unsupportedReturnFormatVal.mjs"',
111+
]);
112+
113+
assert.match(stderr,/ERR_UNKNOWN_MODULE_FORMAT/);
114+
assert.strictEqual(stdout,'');
115+
assert.strictEqual(code,1);
116+
assert.strictEqual(signal,null);
117+
});
118+
119+
it('throws on invalid format property type',async()=>{
120+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
121+
'--no-warnings',
122+
'--experimental-loader',
123+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
124+
'--input-type=module',
125+
'--eval',
126+
'import "esmHook/badReturnSourceVal.mjs"',
127+
]);
128+
129+
assert.match(stderr,/ERR_INVALID_RETURN_PROPERTY_VALUE/);
130+
assert.strictEqual(stdout,'');
131+
assert.strictEqual(code,1);
132+
assert.strictEqual(signal,null);
133+
});
134+
135+
it('rejects dynamic imports for all of the error cases checked above',async()=>{
136+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
137+
'--no-warnings',
138+
'--experimental-loader',
139+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
140+
'--input-type=module',
141+
'--eval',
142+
`import assert from 'node:assert';
143+
await Promise.allSettled([
144+
import('nonexistent/file.mjs'),
145+
import('${fixtures.fileURL('/es-modules/file.unknown')}'),
146+
import('esmHook/badReturnVal.mjs'),
147+
import('esmHook/format.false'),
148+
import('esmHook/format.true'),
149+
import('esmHook/badReturnFormatVal.mjs'),
150+
import('esmHook/unsupportedReturnFormatVal.mjs'),
151+
import('esmHook/badReturnSourceVal.mjs'),
152+
]).then((results) => {
153+
assert.strictEqual(results.every((result) => result.status === 'rejected'), true);
154+
})`,
155+
]);
156+
157+
assert.strictEqual(stderr,'');
158+
assert.strictEqual(stdout,'');
159+
assert.strictEqual(code,0);
160+
assert.strictEqual(signal,null);
161+
});
162+
});
163+
164+
describe('Loader hooks parsing modules',{concurrency: true},()=>{
165+
it('can parse .js files as ESM',async()=>{
166+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
167+
'--no-warnings',
168+
'--experimental-loader',
169+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
170+
'--input-type=module',
171+
'--eval',
172+
`import assert from 'node:assert';
173+
await import('${fixtures.fileURL('/es-module-loaders/js-as-esm.js')}')
174+
.then((parsedModule) => {
175+
assert.strictEqual(typeof parsedModule, 'object');
176+
assert.strictEqual(parsedModule.namedExport, 'named-export');
177+
})`,
178+
]);
179+
180+
assert.strictEqual(stderr,'');
181+
assert.strictEqual(stdout,'');
182+
assert.strictEqual(code,0);
183+
assert.strictEqual(signal,null);
184+
});
185+
186+
it('can define .ext files as ESM',async()=>{
187+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
188+
'--no-warnings',
189+
'--experimental-loader',
190+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
191+
'--input-type=module',
192+
'--eval',
193+
`import assert from 'node:assert';
194+
await import('${fixtures.fileURL('/es-modules/file.ext')}')
195+
.then((parsedModule) => {
196+
assert.strictEqual(typeof parsedModule, 'object');
197+
const { default: defaultExport } = parsedModule;
198+
assert.strictEqual(typeof defaultExport, 'function');
199+
assert.strictEqual(defaultExport.name, 'iAmReal');
200+
assert.strictEqual(defaultExport(), true);
201+
})`,
202+
]);
203+
204+
assert.strictEqual(stderr,'');
205+
assert.strictEqual(stdout,'');
206+
assert.strictEqual(code,0);
207+
assert.strictEqual(signal,null);
208+
});
209+
210+
it('can predetermine the format in the custom loader resolve hook',async()=>{
211+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
212+
'--no-warnings',
213+
'--experimental-loader',
214+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
215+
'--input-type=module',
216+
'--eval',
217+
`import assert from 'node:assert';
218+
await import('esmHook/preknownFormat.pre')
219+
.then((parsedModule) => {
220+
assert.strictEqual(typeof parsedModule, 'object');
221+
assert.strictEqual(parsedModule.default, 'hello world');
222+
})`,
223+
]);
224+
225+
assert.strictEqual(stderr,'');
226+
assert.strictEqual(stdout,'');
227+
assert.strictEqual(code,0);
228+
assert.strictEqual(signal,null);
229+
});
230+
231+
it('can provide source for a nonexistent file',async()=>{
232+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
233+
'--no-warnings',
234+
'--experimental-loader',
235+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
236+
'--input-type=module',
237+
'--eval',
238+
`import assert from 'node:assert';
239+
await import('esmHook/virtual.mjs')
240+
.then((parsedModule) => {
241+
assert.strictEqual(typeof parsedModule, 'object');
242+
assert.strictEqual(typeof parsedModule.default, 'undefined');
243+
assert.strictEqual(parsedModule.message, 'WOOHOO!');
244+
})`,
245+
]);
246+
247+
assert.strictEqual(stderr,'');
248+
assert.strictEqual(stdout,'');
249+
assert.strictEqual(code,0);
250+
assert.strictEqual(signal,null);
251+
});
252+
253+
it('ensures that loaders have a separate context from userland',async()=>{
254+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
255+
'--no-warnings',
256+
'--experimental-loader',
257+
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
258+
'--input-type=module',
259+
'--eval',
260+
`import assert from 'node:assert';
261+
await import('${fixtures.fileURL('/es-modules/stateful.mjs')}')
262+
.then(({ default: count }) => {
263+
assert.strictEqual(count(), 1);
264+
});`,
265+
]);
266+
267+
assert.strictEqual(stderr,'');
268+
assert.strictEqual(stdout,'');
269+
assert.strictEqual(code,0);
270+
assert.strictEqual(signal,null);
271+
});
272+
273+
it('ensures that user loaders are not bound to the internal loader',async()=>{
274+
const{ code, signal, stdout, stderr }=awaitspawnPromisified(execPath,[
275+
'--no-warnings',
276+
'--experimental-loader',
277+
fixtures.fileURL('/es-module-loaders/loader-this-value-inside-hook-functions.mjs'),
278+
'--input-type=module',
279+
'--eval',
280+
';',// Actual test is inside the loader module.
281+
]);
282+
283+
assert.strictEqual(stderr,'');
284+
assert.strictEqual(stdout,'');
285+
assert.strictEqual(code,0);
286+
assert.strictEqual(signal,null);
287+
});
288+
});
File renamed without changes.

test/parallel/test-loaders-unknown-builtin-module.mjs renamed to test/es-module/test-loaders-unknown-builtin-module.mjs

File renamed without changes.

0 commit comments

Comments
 (0)