From 996360528f9e1c9d6b47a5cfdd5616cd3c2018b0 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 2 Jan 2023 14:43:21 +0100 Subject: [PATCH 1/2] test,esm: validate more edge cases for dynamic imports --- test/es-module/test-esm-loader-hooks.mjs | 86 ++++++++++++++++++- .../never-settling-resolve-step/loader.mjs | 10 +++ .../never-load.cjs | 7 ++ .../never-load.mjs | 5 ++ .../never-resolve.cjs | 7 ++ .../never-resolve.mjs | 5 ++ .../never-settling-resolve-step/race.cjs | 7 ++ .../never-settling-resolve-step/race.mjs | 7 ++ 8 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/loader.mjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.cjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.mjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.cjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.mjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/race.cjs create mode 100644 test/fixtures/es-module-loaders/never-settling-resolve-step/race.mjs diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs index 7cd967189ec1fc..fc448cfe072204 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -4,7 +4,7 @@ import assert from 'node:assert'; import { execPath } from 'node:process'; import { describe, it } from 'node:test'; -describe('Loader hooks', () => { +describe('Loader hooks', { concurrency: true }, () => { it('are called with all expected arguments', async () => { const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ '--no-warnings', @@ -23,4 +23,88 @@ describe('Loader hooks', () => { assert.match(lines[2], /{"url":"file:\/\/\/.*\/experimental\.json","format":"test","shortCircuit":true}/); assert.match(lines[3], /{"source":{"type":"Buffer","data":\[.*\]},"format":"json","shortCircuit":true}/); }); + + it('should be able to handle never resolving dynamic imports (ESM entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.mjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 13); + assert.strictEqual(signal, null); + }); + + it('should be able to handle never resolving dynamic imports (CJS entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.cjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); + + it('should be able to handle never loading dynamic imports (ESM entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.mjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 13); + assert.strictEqual(signal, null); + }); + + it('should be able to handle never loading dynamic imports (CJS entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.cjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); + + it('should be able to handle race of never settling dynamic imports (ESM entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/race.mjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^true\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); + + it('should be able to handle race of never settling dynamic imports (CJS entry point)', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/race.cjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^true\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); }); diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/loader.mjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/loader.mjs new file mode 100644 index 00000000000000..c180583b4c74db --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/loader.mjs @@ -0,0 +1,10 @@ +export function resolve(specifier, context, next) { + if (specifier === 'never-settle-resolve') return new Promise(() => {}); + if (specifier === 'never-settle-load') return { __proto__: null, shortCircuit: true, url: 'never-settle:///' }; + return next(specifier, context); +} + +export function load(url, context, next) { + if (url === 'never-settle:///') return new Promise(() => {}); + return next(url, context); +} diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.cjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.cjs new file mode 100644 index 00000000000000..cc81affe7d0dc6 --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.cjs @@ -0,0 +1,7 @@ +'use strict'; + +const neverSettlingDynamicImport = import('never-settle-load'); + +console.log('should be output'); + +neverSettlingDynamicImport.then(() => process.exit(1)); diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.mjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.mjs new file mode 100644 index 00000000000000..3dbf801c76051c --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-load.mjs @@ -0,0 +1,5 @@ +const neverSettlingDynamicImport = import('never-settle-load'); + +console.log('should be output'); + +await neverSettlingDynamicImport; diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.cjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.cjs new file mode 100644 index 00000000000000..bf6387560b4704 --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.cjs @@ -0,0 +1,7 @@ +'use strict'; + +const neverSettlingDynamicImport = import('never-settle-resolve'); + +console.log('should be output'); + +neverSettlingDynamicImport.then(() => process.exit(1)); diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.mjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.mjs new file mode 100644 index 00000000000000..806a131928c339 --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/never-resolve.mjs @@ -0,0 +1,5 @@ +const neverSettlingDynamicImport = import('never-settle-resolve'); + +console.log('should be output'); + +await neverSettlingDynamicImport; diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/race.cjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/race.cjs new file mode 100644 index 00000000000000..41884ab9d2e769 --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/race.cjs @@ -0,0 +1,7 @@ +'use strict'; + +Promise.race([ + import('never-settle-resolve'), + import('never-settle-load'), + import('node:process'), +]).then(result => console.log(result.default === process)); diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/race.mjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/race.mjs new file mode 100644 index 00000000000000..8213bbe59d4437 --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/race.mjs @@ -0,0 +1,7 @@ +const result = await Promise.race([ + import('never-settle-resolve'), + import('never-settle-load'), + import('node:process'), +]); + +console.log(result.default === process); From dc6182252620c04835ee848b779570f30f7876f3 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 2 Jan 2023 17:19:45 +0100 Subject: [PATCH 2/2] fixup! test,esm: validate more edge cases for dynamic imports --- test/es-module/test-esm-loader-hooks.mjs | 146 ++++++++++++----------- 1 file changed, 76 insertions(+), 70 deletions(-) diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs index fc448cfe072204..ce8085bbaf9d29 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -24,87 +24,93 @@ describe('Loader hooks', { concurrency: true }, () => { assert.match(lines[3], /{"source":{"type":"Buffer","data":\[.*\]},"format":"json","shortCircuit":true}/); }); - it('should be able to handle never resolving dynamic imports (ESM entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.mjs'), - ]); + describe('should handle never-settling hooks in ESM files', { concurrency: true }, () => { + it('top-level await of a never-settling resolve', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.mjs'), + ]); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^should be output\r?\n$/); - assert.strictEqual(code, 13); - assert.strictEqual(signal, null); - }); + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 13); + assert.strictEqual(signal, null); + }); - it('should be able to handle never resolving dynamic imports (CJS entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.cjs'), - ]); + it('top-level await of a never-settling load', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.mjs'), + ]); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^should be output\r?\n$/); - assert.strictEqual(code, 0); - assert.strictEqual(signal, null); - }); + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 13); + assert.strictEqual(signal, null); + }); - it('should be able to handle never loading dynamic imports (ESM entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.mjs'), - ]); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^should be output\r?\n$/); - assert.strictEqual(code, 13); - assert.strictEqual(signal, null); + it('top-level await of a race of never-settling hooks', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/race.mjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^true\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); }); - it('should be able to handle never loading dynamic imports (CJS entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.cjs'), - ]); + describe('should handle never-settling hooks in CJS files', { concurrency: true }, () => { + it('never-settling resolve', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-resolve.cjs'), + ]); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^should be output\r?\n$/); - assert.strictEqual(code, 0); - assert.strictEqual(signal, null); - }); + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); - it('should be able to handle race of never settling dynamic imports (ESM entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/race.mjs'), - ]); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^true\r?\n$/); - assert.strictEqual(code, 0); - assert.strictEqual(signal, null); - }); + it('never-settling load', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/never-load.cjs'), + ]); - it('should be able to handle race of never settling dynamic imports (CJS entry point)', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-loader', - fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), - fixtures.path('es-module-loaders/never-settling-resolve-step/race.cjs'), - ]); + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); - assert.strictEqual(stderr, ''); - assert.match(stdout, /^true\r?\n$/); - assert.strictEqual(code, 0); - assert.strictEqual(signal, null); + it('race of never-settling hooks', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/race.cjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^true\r?\n$/); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); }); });