Commit d35c89e03dd for nodejs
commit d35c89e03dd17eb7a6433fbdb6b803147246c143
Author: Maya Lekova <maya@igalia.com>
Date: Sat Sep 26 21:53:05 2026 +0200
test: add smoke tests for defer importing synthetic modules
The tests added ensure that Node.js doesn't crash or produce
incorrect results when importing synthetic modules (i.e. JSON,
text or builtin modules) with the `defer` modifier.
Signed-off-by: Maya Lekova <maya@igalia.com>
PR-URL: https://github.com/nodejs/node/pull/65537
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
diff --git a/test/es-module/test-defer-import-builtin-module.mjs b/test/es-module/test-defer-import-builtin-module.mjs
new file mode 100644
index 00000000000..e63d19db77e
--- /dev/null
+++ b/test/es-module/test-defer-import-builtin-module.mjs
@@ -0,0 +1,29 @@
+// Flags: --js-defer-import-eval --expose-internals
+
+// Test that uses import.defer for a builtin module. Currently
+// defer importing of a synthetic module should be a no-op
+// in Node.js as they are born pre-evaluated, so the test
+// is mostly a smoke test that Node doesn't crash.
+
+// TODO: after deferring the evaluation of builtin modules
+// is implemented, accessing any property from it will
+// trigger the evaluation.
+
+import '../common/index.mjs';
+import * as assert from 'assert';
+
+// Check that there are no modules with 'http' in their name loaded yet.
+let modules = process.moduleLoadList.filter((item) => item.endsWith('http'));
+assert.strictEqual(modules.length, 0);
+
+const intermediate = await import('../fixtures/es-modules/import-builtin-module-intermediate.mjs');
+
+// Check that after dynamically importing the module with imports 'http'
+// itself, the builtin module is already present in the module list.
+modules = process.moduleLoadList.filter((item) => item.endsWith('http'));
+assert.partialDeepStrictEqual(modules, ['NativeModule http']);
+
+// Check that the imported module contains some known properties.
+assert.notStrictEqual(intermediate.http.STATUS_CODES, undefined);
+assert.notStrictEqual(intermediate.http.createServer, undefined);
+assert.strictEqual(typeof intermediate.http.createServer, 'function');
diff --git a/test/es-module/test-defer-import-json-module.mjs b/test/es-module/test-defer-import-json-module.mjs
new file mode 100644
index 00000000000..1b1d2b23353
--- /dev/null
+++ b/test/es-module/test-defer-import-json-module.mjs
@@ -0,0 +1,22 @@
+// Flags: --js-defer-import-eval
+
+// Test that uses import.defer for a JSON module. Currently
+// defer importing of a synthetic module should be a no-op
+// in Node.js, so the test is mostly a smoke test that Node
+// doesn't crash.
+
+import '../common/index.mjs';
+import * as assert from 'assert';
+
+import defer * as imported_json
+ from '../fixtures/json-with-directory-name-module/module-stub.json'
+ with { type: 'json' };
+
+// eslint-disable-next-line no-duplicate-imports
+import * as imported_json_eager
+ from '../fixtures/json-with-directory-name-module/module-stub.json'
+ with { type: 'json' };
+
+// Check that the imported object has the expected key/value.
+assert.strictEqual(imported_json.default.rocko, 'artischocko');
+assert.deepStrictEqual(imported_json_eager.default, imported_json.default);
diff --git a/test/es-module/test-defer-import-text-module.mjs b/test/es-module/test-defer-import-text-module.mjs
new file mode 100644
index 00000000000..e6710d72fd7
--- /dev/null
+++ b/test/es-module/test-defer-import-text-module.mjs
@@ -0,0 +1,18 @@
+// Flags: --js-defer-import-eval --experimental-import-text
+
+// Test that uses import.defer for a text module. Currently
+// defer importing of a synthetic module should be a no-op
+// in Node.js, so the test is mostly a smoke test that Node
+// doesn't crash.
+
+import '../common/index.mjs';
+import * as assert from 'assert';
+
+import defer * as imported_text
+ from '../fixtures/file-to-read-without-bom.txt'
+ with { type: 'text' };
+
+const expected_text = 'abc\ndef\nghi\n';
+
+// Check that the imported text has the expected value.
+assert.strictEqual(imported_text.default, expected_text);
diff --git a/test/fixtures/es-modules/import-builtin-module-intermediate.mjs b/test/fixtures/es-modules/import-builtin-module-intermediate.mjs
new file mode 100755
index 00000000000..5e5b4577098
--- /dev/null
+++ b/test/fixtures/es-modules/import-builtin-module-intermediate.mjs
@@ -0,0 +1,8 @@
+// This module uses import.defer to import the http builtin module.
+// It's dynamically imported by a test module, to ensure the HTTP
+// module is actually present in the module list after importing
+// this middle module.
+
+// Import the http builtin module and export all its properties.
+import defer * as http from 'node:http';
+export { http };