Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0bdf2db

Browse filesBrowse files
GeoffreyBoothjuanarbol
authored andcommitted
esm: rewrite loader hooks test
Rewrite the test that validates that custom loader hooks are called from being a test that depends on internals to one that spawns a child process and checks its output to confirm expected behavior. PR-URL: #46016 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Jacob Smith <jacob@frende.me>
1 parent c1cc1f9 commit 0bdf2db
Copy full SHA for 0bdf2db

File tree

Expand file treeCollapse file tree

2 files changed

+115
-81
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+115
-81
lines changed
Open diff view settings
Collapse file
+24-81Lines changed: 24 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,26 @@
1-
// Flags: --expose-internals
2-
import { mustCall } from '../common/index.mjs';
3-
import esmLoaderModule from 'internal/modules/esm/loader';
4-
import assert from 'assert';
5-
6-
const { ESMLoader } = esmLoaderModule;
7-
8-
/**
9-
* Verify custom hooks are called with appropriate arguments.
10-
*/
11-
{
12-
const esmLoader = new ESMLoader();
13-
14-
const originalSpecifier = 'foo/bar';
15-
const importAssertions = {
16-
__proto__: null,
17-
type: 'json',
18-
};
19-
const parentURL = 'file:///entrypoint.js';
20-
const resolvedURL = 'file:///foo/bar.js';
21-
const suggestedFormat = 'test';
22-
23-
function resolve(specifier, context, defaultResolve) {
24-
assert.strictEqual(specifier, originalSpecifier);
25-
// Ensure `context` has all and only the properties it's supposed to
26-
assert.deepStrictEqual(Object.keys(context), [
27-
'conditions',
28-
'importAssertions',
29-
'parentURL',
30-
]);
31-
assert.ok(Array.isArray(context.conditions));
32-
assert.deepStrictEqual(context.importAssertions, importAssertions);
33-
assert.strictEqual(context.parentURL, parentURL);
34-
assert.strictEqual(typeof defaultResolve, 'function');
35-
36-
return {
37-
format: suggestedFormat,
38-
shortCircuit: true,
39-
url: resolvedURL,
40-
};
41-
}
42-
43-
function load(resolvedURL, context, defaultLoad) {
44-
assert.strictEqual(resolvedURL, resolvedURL);
45-
assert.ok(new URL(resolvedURL));
46-
// Ensure `context` has all and only the properties it's supposed to
47-
assert.deepStrictEqual(Object.keys(context), [
48-
'format',
49-
'importAssertions',
1+
import { spawnPromisified } from '../common/index.mjs';
2+
import * as fixtures from '../common/fixtures.mjs';
3+
import assert from 'node:assert';
4+
import { execPath } from 'node:process';
5+
import { describe, it } from 'node:test';
6+
7+
describe('Loader hooks', () => {
8+
it('are called with all expected arguments', async () => {
9+
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
10+
'--no-warnings',
11+
'--experimental-loader',
12+
fixtures.fileURL('/es-module-loaders/hooks-input.mjs'),
13+
fixtures.path('/es-modules/json-modules.mjs'),
5014
]);
51-
assert.strictEqual(context.format, suggestedFormat);
52-
assert.deepStrictEqual(context.importAssertions, importAssertions);
53-
assert.strictEqual(typeof defaultLoad, 'function');
54-
55-
// This doesn't matter (just to avoid errors)
56-
return {
57-
format: 'module',
58-
shortCircuit: true,
59-
source: '',
60-
};
61-
}
62-
63-
const customLoader = [
64-
{
65-
exports: {
66-
// Ensure ESMLoader actually calls the custom hooks
67-
resolve: mustCall(resolve),
68-
load: mustCall(load),
69-
},
70-
url: import.meta.url,
71-
},
72-
];
73-
74-
esmLoader.addCustomLoaders(customLoader);
7515

76-
// Manually trigger hooks (since ESMLoader is not actually running)
77-
const job = await esmLoader.getModuleJob(
78-
originalSpecifier,
79-
parentURL,
80-
importAssertions,
81-
);
82-
await job.modulePromise;
83-
}
16+
assert.strictEqual(stderr, '');
17+
assert.strictEqual(code, 0);
18+
assert.strictEqual(signal, null);
19+
20+
const lines = stdout.split('\n');
21+
assert.match(lines[0], /{"url":"file:\/\/\/.*\/json-modules\.mjs","format":"test","shortCircuit":true}/);
22+
assert.match(lines[1], /{"source":{"type":"Buffer","data":\[.*\]},"format":"module","shortCircuit":true}/);
23+
assert.match(lines[2], /{"url":"file:\/\/\/.*\/experimental\.json","format":"test","shortCircuit":true}/);
24+
assert.match(lines[3], /{"source":{"type":"Buffer","data":\[.*\]},"format":"json","shortCircuit":true}/);
25+
});
26+
});
Collapse file
+91Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// This is expected to be used by test-esm-loader-hooks.mjs via:
2+
// node --loader ./test/fixtures/es-module-loaders/hooks-input.mjs ./test/fixtures/es-modules/json-modules.mjs
3+
4+
import assert from 'assert';
5+
import { readFile } from 'fs/promises';
6+
import { fileURLToPath } from 'url';
7+
8+
9+
let resolveCalls = 0;
10+
let loadCalls = 0;
11+
12+
export async function resolve(specifier, context, next) {
13+
resolveCalls++;
14+
let url;
15+
16+
if (resolveCalls === 1) {
17+
url = new URL(specifier).href;
18+
assert.match(specifier, /json-modules\.mjs$/);
19+
assert.strictEqual(context.parentURL, undefined);
20+
assert.deepStrictEqual(context.importAssertions, {
21+
__proto__: null,
22+
});
23+
} else if (resolveCalls === 2) {
24+
url = new URL(specifier, context.parentURL).href;
25+
assert.match(specifier, /experimental\.json$/);
26+
assert.match(context.parentURL, /json-modules\.mjs$/);
27+
assert.deepStrictEqual(context.importAssertions, {
28+
__proto__: null,
29+
type: 'json',
30+
});
31+
}
32+
33+
// Ensure `context` has all and only the properties it's supposed to
34+
assert.deepStrictEqual(Reflect.ownKeys(context), [
35+
'conditions',
36+
'importAssertions',
37+
'parentURL',
38+
]);
39+
assert.ok(Array.isArray(context.conditions));
40+
assert.strictEqual(typeof next, 'function');
41+
42+
const returnValue = {
43+
url,
44+
format: 'test',
45+
shortCircuit: true,
46+
}
47+
48+
console.log(JSON.stringify(returnValue)); // For the test to validate when it parses stdout
49+
50+
return returnValue;
51+
}
52+
53+
export async function load(url, context, next) {
54+
loadCalls++;
55+
const source = await readFile(fileURLToPath(url));
56+
let format;
57+
58+
if (loadCalls === 1) {
59+
assert.match(url, /json-modules\.mjs$/);
60+
assert.deepStrictEqual(context.importAssertions, {
61+
__proto__: null,
62+
});
63+
format = 'module';
64+
} else if (loadCalls === 2) {
65+
assert.match(url, /experimental\.json$/);
66+
assert.deepStrictEqual(context.importAssertions, {
67+
__proto__: null,
68+
type: 'json',
69+
});
70+
format = 'json';
71+
}
72+
73+
assert.ok(new URL(url));
74+
// Ensure `context` has all and only the properties it's supposed to
75+
assert.deepStrictEqual(Object.keys(context), [
76+
'format',
77+
'importAssertions',
78+
]);
79+
assert.strictEqual(context.format, 'test');
80+
assert.strictEqual(typeof next, 'function');
81+
82+
const returnValue = {
83+
source,
84+
format,
85+
shortCircuit: true,
86+
};
87+
88+
console.log(JSON.stringify(returnValue)); // For the test to validate when it parses stdout
89+
90+
return returnValue;
91+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.