Skip to content
File

Blob: src/workerd/api/node/tests/node-compat-v2-test.js

javascript120 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4//
5 
6// Imports of Node.js built-ins should work both with and without
7// the 'node:' prefix.
8import { default as assert } from 'node:assert';
9import { default as assert2 } from 'assert';
10import { AsyncLocalStorage } from 'async_hooks';
11 
12const assert3 = (await import('node:assert')).default;
13const assert4 = (await import('assert')).default;
14 
15assert.strictEqual(assert, assert2);
16assert.strictEqual(assert, assert3);
17assert.strictEqual(assert, assert4);
18 
19export const nodeJsExpectedGlobals = {
20 async test() {
21 // Expected Node.js globals Buffer, process, and global should be present.
22 const { Buffer } = await import('node:buffer');
23 assert.strictEqual(Buffer, globalThis.Buffer);
24 
25 const { default: process } = await import('node:process');
26 assert.strictEqual(process, globalThis.process);
27 
28 assert.strictEqual(global, globalThis);
29 },
30};
31 
32export const nodeJsGetBuiltins = {
33 async test() {
34 // node:* modules in the worker bundle should override the built-in modules...
35 const { default: fs } = await import('node:fs');
36 const { default: path } = await import('node:path');
37 
38 await import('node:path');
39 
40 // But process.getBuiltinModule should always return the built-in module.
41 const builtInPath = process.getBuiltinModule('node:path');
42 const builtInVm = process.getBuiltinModule('node:vm');
43 
44 // The built-in node:vm module is not available in workers, so this should
45 // return undefined.
46 assert.strictEqual(builtInVm, undefined);
47 
48 // These are from the worker bundle....
49 assert.strictEqual(fs, 1);
50 assert.strictEqual(path, 2);
51 
52 // node:path is implemented tho...
53 assert.notStrictEqual(path, builtInPath);
54 assert.strictEqual(typeof builtInPath, 'object');
55 assert.strictEqual(typeof builtInPath.join, 'function');
56 
57 // While process.getBuiltinModule(...) in Node.js only returns Node.js
58 // built-ins, our impl will return cloudflare: and workerd: built-ins
59 // also, for completeness. A key difference, however, is that for non-Node.js
60 // built-ins, the return value is the module namespace rather than the default
61 // export.
62 
63 const socket = await import('cloudflare:sockets');
64 assert.strictEqual(process.getBuiltinModule('cloudflare:sockets'), socket);
65 },
66};
67 
68export const nodeJsEventsExports = {
69 async test() {
70 // Expected node:events exports should be present
71 const { EventEmitter, getMaxListeners, usingDomains } =
72 await import('node:events');
73 assert.notEqual(getMaxListeners, undefined);
74 assert.strictEqual(getMaxListeners, EventEmitter.getMaxListeners);
75 assert.notEqual(usingDomains, undefined);
76 assert.strictEqual(usingDomains, EventEmitter.usingDomains);
77 },
78};
79 
80export const nodeJsBufferExports = {
81 async test() {
82 // Expected node:buffer exports should be present
83 const { atob, btoa, Blob } = await import('node:buffer');
84 assert.notEqual(atob, undefined);
85 assert.notEqual(btoa, undefined);
86 // We cannot do strictEqual with atob and globalThis.atob
87 // since, buffer module exports them with `.bind(globalThis)`
88 assert.strictEqual(typeof atob, 'function');
89 assert.strictEqual(typeof btoa, 'function');
90 assert.notEqual(Blob, undefined);
91 assert.strictEqual(Blob, globalThis.Blob);
92 },
93};
94 
95export const nodeJsSetImmediate = {
96 async test() {
97 const als = new AsyncLocalStorage();
98 const { promise, resolve } = Promise.withResolvers();
99 als.run('abc', () =>
100 setImmediate((a) => {
101 assert.strictEqual(als.getStore(), 'abc');
102 resolve(a);
103 }, 1)
104 );
105 assert.strictEqual(await promise, 1);
106 
107 const i = setImmediate(() => {
108 throw new Error('should not have fired');
109 });
110 i[Symbol.dispose](); // Calls clear immediate
111 i[Symbol.dispose](); // Should be a no-op
112 
113 const i2 = setImmediate(() => {
114 throw new Error('should not have fired');
115 });
116 clearImmediate(i2);
117 clearImmediate(i2); // clearing twice works fine
118 },
119};