Skip to content

Commit

Permalink
test: isolate globalPreload tests
Browse files Browse the repository at this point in the history
PR-URL: #49545
Backport-PR-URL: #50669
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
  • Loading branch information
GeoffreyBooth authored and targos committed Nov 23, 2023
1 parent 9456094 commit 65201ab
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 132 deletions.
149 changes: 149 additions & 0 deletions test/es-module/test-esm-loader-globalpreload-hook.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { spawnPromisified } from '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import assert from 'node:assert';
import os from 'node:os';
import { execPath } from 'node:process';
import { describe, it } from 'node:test';

describe('globalPreload hook', () => {
it('should not emit deprecation warning when initialize is supplied', async () => {
const { stderr } = await spawnPromisified(execPath, [
'--experimental-loader',
'data:text/javascript,export function globalPreload(){}export function initialize(){}',
fixtures.path('empty.js'),
]);

assert.doesNotMatch(stderr, /`globalPreload` is an experimental feature/);
});

it('should handle globalPreload returning undefined', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout, '');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should handle loading node:test', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `getBuiltin("node:test")()`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.match(stdout, /\n# pass 1\r?\n/);
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should handle loading node:os with node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("node:os").arch())`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), os.arch());
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

// `os` is used here because it's simple and not mocked (the builtin module otherwise doesn't matter).
it('should handle loading builtin module without node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("os").arch())`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), os.arch());
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should throw when loading node:test without node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `getBuiltin("test")()`}',
fixtures.path('empty.js'),
]);

assert.match(stderr, /ERR_UNKNOWN_BUILTIN_MODULE/);
assert.strictEqual(stdout, '');
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
});

it('should register globals set from globalPreload', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return "this.myGlobal=4"}',
'--print', 'myGlobal',
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), '4');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should log console.log calls returned from globalPreload', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log("Hello from globalPreload")`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), 'Hello from globalPreload');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should crash if globalPreload returns code that throws', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `throw new Error("error from globalPreload")`}',
fixtures.path('empty.js'),
]);

assert.match(stderr, /error from globalPreload/);
assert.strictEqual(stdout, '');
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
});

it('should have a `this` value that is not bound to the loader instance', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
`data:text/javascript,export ${function globalPreload() {
if (this != null) {
throw new Error('hook function must not be bound to ESMLoader instance');
}
}}`,
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout, '');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});
});
126 changes: 1 addition & 125 deletions test/es-module/test-esm-loader-hooks.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { spawnPromisified } from '../common/index.mjs';
import * as fixtures from '../common/fixtures.mjs';
import assert from 'node:assert';
import os from 'node:os';
import { execPath } from 'node:process';
import { describe, it } from 'node:test';

Expand Down Expand Up @@ -371,7 +370,7 @@ describe('Loader hooks', { concurrency: true }, () => {
});

describe('globalPreload', () => {
it('should emit deprecation warning', async () => {
it('should emit warning', async () => {
const { stderr } = await spawnPromisified(execPath, [
'--experimental-loader',
'data:text/javascript,export function globalPreload(){}',
Expand All @@ -382,129 +381,6 @@ describe('Loader hooks', { concurrency: true }, () => {

assert.strictEqual(stderr.match(/`globalPreload` is an experimental feature/g).length, 1);
});

it('should not emit deprecation warning when initialize is supplied', async () => {
const { stderr } = await spawnPromisified(execPath, [
'--experimental-loader',
'data:text/javascript,export function globalPreload(){}export function initialize(){}',
fixtures.path('empty.js'),
]);

assert.doesNotMatch(stderr, /`globalPreload` is an experimental feature/);
});

it('should handle globalPreload returning undefined', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout, '');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should handle loading node:test', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `getBuiltin("node:test")()`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.match(stdout, /\n# pass 1\r?\n/);
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should handle loading node:os with node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("node:os").arch())`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), os.arch());
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

// `os` is used here because it's simple and not mocked (the builtin module otherwise doesn't matter).
it('should handle loading builtin module without node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("os").arch())`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), os.arch());
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should throw when loading node:test without node: prefix', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `getBuiltin("test")()`}',
fixtures.path('empty.js'),
]);

assert.match(stderr, /ERR_UNKNOWN_BUILTIN_MODULE/);
assert.strictEqual(stdout, '');
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
});

it('should register globals set from globalPreload', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return "this.myGlobal=4"}',
'--print', 'myGlobal',
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), '4');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should log console.log calls returned from globalPreload', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `console.log("Hello from globalPreload")`}',
fixtures.path('empty.js'),
]);

assert.strictEqual(stderr, '');
assert.strictEqual(stdout.trim(), 'Hello from globalPreload');
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});

it('should crash if globalPreload returns code that throws', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
'data:text/javascript,export function globalPreload(){return `throw new Error("error from globalPreload")`}',
fixtures.path('empty.js'),
]);

assert.match(stderr, /error from globalPreload/);
assert.strictEqual(stdout, '');
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
});
});

it('should be fine to call `process.removeAllListeners("beforeExit")` from the main thread', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
export function initialize() {
if (this != null) {
throw new Error('hook function must not be bound to loader instance');
}
}

export function resolve(url, _, next) {
if (this != null) throw new Error('hook function must not be bound to ESMLoader instance');
if (this != null) {
throw new Error('hook function must not be bound to loader instance');
}

return next(url);
}

export function load(url, _, next) {
if (this != null) throw new Error('hook function must not be bound to ESMLoader instance');
return next(url);
}
if (this != null) {
throw new Error('hook function must not be bound to loader instance');
}

export function globalPreload() {
if (this != null) throw new Error('hook function must not be bound to ESMLoader instance');
return "";
return next(url);
}

0 comments on commit 65201ab

Please sign in to comment.