• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { spawnPromisified } from '../common/index.mjs';
2import * as fixtures from '../common/fixtures.mjs';
3import assert from 'node:assert';
4import os from 'node:os';
5import { execPath } from 'node:process';
6import { describe, it } from 'node:test';
7
8describe('globalPreload hook', () => {
9  it('should not emit deprecation warning when initialize is supplied', async () => {
10    const { stderr } = await spawnPromisified(execPath, [
11      '--experimental-loader',
12      'data:text/javascript,export function globalPreload(){}export function initialize(){}',
13      fixtures.path('empty.js'),
14    ]);
15
16    assert.doesNotMatch(stderr, /`globalPreload` is an experimental feature/);
17  });
18
19  it('should handle globalPreload returning undefined', async () => {
20    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
21      '--no-warnings',
22      '--experimental-loader',
23      'data:text/javascript,export function globalPreload(){}',
24      fixtures.path('empty.js'),
25    ]);
26
27    assert.strictEqual(stderr, '');
28    assert.strictEqual(stdout, '');
29    assert.strictEqual(code, 0);
30    assert.strictEqual(signal, null);
31  });
32
33  it('should handle loading node:test', async () => {
34    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
35      '--no-warnings',
36      '--experimental-loader',
37      'data:text/javascript,export function globalPreload(){return `getBuiltin("node:test")()`}',
38      fixtures.path('empty.js'),
39    ]);
40
41    assert.strictEqual(stderr, '');
42    assert.match(stdout, /\n# pass 1\r?\n/);
43    assert.strictEqual(code, 0);
44    assert.strictEqual(signal, null);
45  });
46
47  it('should handle loading node:os with node: prefix', async () => {
48    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
49      '--no-warnings',
50      '--experimental-loader',
51      'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("node:os").arch())`}',
52      fixtures.path('empty.js'),
53    ]);
54
55    assert.strictEqual(stderr, '');
56    assert.strictEqual(stdout.trim(), os.arch());
57    assert.strictEqual(code, 0);
58    assert.strictEqual(signal, null);
59  });
60
61  // `os` is used here because it's simple and not mocked (the builtin module otherwise doesn't matter).
62  it('should handle loading builtin module without node: prefix', async () => {
63    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
64      '--no-warnings',
65      '--experimental-loader',
66      'data:text/javascript,export function globalPreload(){return `console.log(getBuiltin("os").arch())`}',
67      fixtures.path('empty.js'),
68    ]);
69
70    assert.strictEqual(stderr, '');
71    assert.strictEqual(stdout.trim(), os.arch());
72    assert.strictEqual(code, 0);
73    assert.strictEqual(signal, null);
74  });
75
76  it('should throw when loading node:test without node: prefix', async () => {
77    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
78      '--no-warnings',
79      '--experimental-loader',
80      'data:text/javascript,export function globalPreload(){return `getBuiltin("test")()`}',
81      fixtures.path('empty.js'),
82    ]);
83
84    assert.match(stderr, /ERR_UNKNOWN_BUILTIN_MODULE/);
85    assert.strictEqual(stdout, '');
86    assert.strictEqual(code, 1);
87    assert.strictEqual(signal, null);
88  });
89
90  it('should register globals set from globalPreload', async () => {
91    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
92      '--no-warnings',
93      '--experimental-loader',
94      'data:text/javascript,export function globalPreload(){return "this.myGlobal=4"}',
95      '--print', 'myGlobal',
96    ]);
97
98    assert.strictEqual(stderr, '');
99    assert.strictEqual(stdout.trim(), '4');
100    assert.strictEqual(code, 0);
101    assert.strictEqual(signal, null);
102  });
103
104  it('should log console.log calls returned from globalPreload', async () => {
105    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
106      '--no-warnings',
107      '--experimental-loader',
108      'data:text/javascript,export function globalPreload(){return `console.log("Hello from globalPreload")`}',
109      fixtures.path('empty.js'),
110    ]);
111
112    assert.strictEqual(stderr, '');
113    assert.strictEqual(stdout.trim(), 'Hello from globalPreload');
114    assert.strictEqual(code, 0);
115    assert.strictEqual(signal, null);
116  });
117
118  it('should crash if globalPreload returns code that throws', async () => {
119    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
120      '--no-warnings',
121      '--experimental-loader',
122      'data:text/javascript,export function globalPreload(){return `throw new Error("error from globalPreload")`}',
123      fixtures.path('empty.js'),
124    ]);
125
126    assert.match(stderr, /error from globalPreload/);
127    assert.strictEqual(stdout, '');
128    assert.strictEqual(code, 1);
129    assert.strictEqual(signal, null);
130  });
131
132  it('should have a `this` value that is not bound to the loader instance', async () => {
133    const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
134      '--no-warnings',
135      '--experimental-loader',
136      `data:text/javascript,export ${function globalPreload() {
137        if (this != null) {
138          throw new Error('hook function must not be bound to ESMLoader instance');
139        }
140      }}`,
141      fixtures.path('empty.js'),
142    ]);
143
144    assert.strictEqual(stderr, '');
145    assert.strictEqual(stdout, '');
146    assert.strictEqual(code, 0);
147    assert.strictEqual(signal, null);
148  });
149});
150