diff --git a/test/es-module/test-esm-loader-thenable.mjs b/test/es-module/test-esm-loader-thenable.mjs new file mode 100644 index 00000000000000..c8c3ec2778e7e9 --- /dev/null +++ b/test/es-module/test-esm-loader-thenable.mjs @@ -0,0 +1,65 @@ +import { mustCall } from '../common/index.mjs'; +import { fileURL, path } from '../common/fixtures.mjs'; +import { match, ok, notStrictEqual, strictEqual } from 'assert'; +import { spawn } from 'child_process'; +import { execPath } from 'process'; + +{ + const child = spawn(execPath, [ + '--experimental-loader', + fileURL('es-module-loaders', 'thenable-load-hook.mjs').href, + path('es-modules', 'test-esm-ok.mjs'), + ]); + + let stderr = ''; + child.stderr.setEncoding('utf8'); + child.stderr.on('data', (data) => { + stderr += data; + }); + child.on('close', mustCall((code, _signal) => { + strictEqual(code, 0); + ok(!stderr.includes('must not call')); + })); +} + +{ + const child = spawn(execPath, [ + '--experimental-loader', + fileURL('es-module-loaders', 'thenable-load-hook-rejected.mjs').href, + path('es-modules', 'test-esm-ok.mjs'), + ]); + + let stderr = ''; + child.stderr.setEncoding('utf8'); + child.stderr.on('data', (data) => { + stderr += data; + }); + child.on('close', mustCall((code, _signal) => { + notStrictEqual(code, 0); + + match(stderr, /\sError: must crash the process\r?\n/); + + ok(!stderr.includes('must not call')); + })); +} + +{ + const child = spawn(execPath, [ + '--experimental-loader', + fileURL('es-module-loaders', 'thenable-load-hook-rejected-no-arguments.mjs').href, + path('es-modules', 'test-esm-ok.mjs'), + ]); + + let stderr = ''; + child.stderr.setEncoding('utf8'); + child.stderr.on('data', (data) => { + stderr += data; + }); + child.on('close', mustCall((code, _signal) => { + notStrictEqual(code, 0); + + match(stderr, /\sundefined\r?\n/); + + ok(!stderr.includes('must not call')); + })); +} diff --git a/test/fixtures/es-module-loaders/thenable-load-hook-rejected-no-arguments.mjs b/test/fixtures/es-module-loaders/thenable-load-hook-rejected-no-arguments.mjs new file mode 100644 index 00000000000000..5e008edecf7cf3 --- /dev/null +++ b/test/fixtures/es-module-loaders/thenable-load-hook-rejected-no-arguments.mjs @@ -0,0 +1,10 @@ +export function load () { + let thenAlreadyAccessed = false; + return { + get then() { + if (thenAlreadyAccessed) throw new Error('must not call'); + thenAlreadyAccessed = true; + return (_, reject) => reject(); + } + }; +} diff --git a/test/fixtures/es-module-loaders/thenable-load-hook-rejected.mjs b/test/fixtures/es-module-loaders/thenable-load-hook-rejected.mjs new file mode 100644 index 00000000000000..926f6d0bebd653 --- /dev/null +++ b/test/fixtures/es-module-loaders/thenable-load-hook-rejected.mjs @@ -0,0 +1,10 @@ +export function load () { + let thenAlreadyAccessed = false; + return { + get then() { + if (thenAlreadyAccessed) throw new Error('must not call'); + thenAlreadyAccessed = true; + return (_, reject) => reject(new Error('must crash the process')); + } + }; +} diff --git a/test/fixtures/es-module-loaders/thenable-load-hook.mjs b/test/fixtures/es-module-loaders/thenable-load-hook.mjs new file mode 100644 index 00000000000000..661f6e21ac69d3 --- /dev/null +++ b/test/fixtures/es-module-loaders/thenable-load-hook.mjs @@ -0,0 +1,10 @@ +export function load(url, context, next) { + let thenAlreadyAccessed = false; + return { + get then() { + if (thenAlreadyAccessed) throw new Error('must not call'); + thenAlreadyAccessed = true; + return (resolve) => resolve(next(url, context)); + } + }; +}