File
Blob: src/workerd/api/node/tests/process-legacy-nodejs-test.js
| 1 | // Copyright (c) 2025 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 | import assert from 'node:assert'; |
| 5 | import * as processMod from 'node:process'; |
| 6 | |
| 7 | // Test that when enable_nodejs_process_v2 is disabled, the process module |
| 8 | // only exports the legacy subset of properties: nextTick, env, exit, |
| 9 | // getBuiltinModule, platform, and features |
| 10 | |
| 11 | const expectedLegacyKeys = [ |
| 12 | 'default', |
| 13 | 'env', |
| 14 | 'exit', |
| 15 | 'features', |
| 16 | 'getBuiltinModule', |
| 17 | 'nextTick', |
| 18 | 'platform', |
| 19 | ]; |
| 20 | |
| 21 | export const processLegacyNamedExports = { |
| 22 | test() { |
| 23 | // Test that named exports only include the legacy subset |
| 24 | const actualKeys = Object.keys(processMod).sort(); |
| 25 | assert.deepStrictEqual(actualKeys, expectedLegacyKeys); |
| 26 | }, |
| 27 | }; |
| 28 | |
| 29 | export const processLegacyDefaultExport = { |
| 30 | test() { |
| 31 | // Test that default export only includes the legacy subset |
| 32 | const actualKeys = Object.keys(processMod.default).sort(); |
| 33 | const expectedDefaultKeys = expectedLegacyKeys.filter( |
| 34 | (key) => key !== 'default' |
| 35 | ); |
| 36 | assert.deepStrictEqual(actualKeys, expectedDefaultKeys); |
| 37 | }, |
| 38 | }; |
| 39 | |
| 40 | export const processLegacyGlobalProcess = { |
| 41 | test() { |
| 42 | // Test that global process only includes the legacy subset |
| 43 | const actualKeys = Object.keys(process) |
| 44 | .filter((v) => v[0] !== '_') // Filter out private properties |
| 45 | .sort(); |
| 46 | const expectedDefaultKeys = expectedLegacyKeys.filter( |
| 47 | (key) => key !== 'default' |
| 48 | ); |
| 49 | assert.deepStrictEqual(actualKeys, expectedDefaultKeys); |
| 50 | }, |
| 51 | }; |
| 52 | |
| 53 | export const processLegacyFunctionality = { |
| 54 | async test() { |
| 55 | // Test that all legacy properties are functional |
| 56 | |
| 57 | // Test nextTick |
| 58 | let nextTickCalled = false; |
| 59 | process.nextTick(() => { |
| 60 | nextTickCalled = true; |
| 61 | }); |
| 62 | await scheduler.wait(0); |
| 63 | assert.ok(nextTickCalled); |
| 64 | |
| 65 | // Test env (should have FOO=BAR from binding) |
| 66 | assert.strictEqual(process.env.FOO, 'BAR'); |
| 67 | assert.strictEqual(typeof process.env, 'object'); |
| 68 | |
| 69 | // Test platform |
| 70 | assert.strictEqual(typeof process.platform, 'string'); |
| 71 | assert.ok(['darwin', 'win32', 'linux'].includes(process.platform)); |
| 72 | |
| 73 | // Test features |
| 74 | assert.strictEqual(typeof process.features, 'object'); |
| 75 | assert.ok(process.features !== null); |
| 76 | |
| 77 | // Test getBuiltinModule |
| 78 | assert.strictEqual(typeof process.getBuiltinModule, 'function'); |
| 79 | const processBuiltin = process.getBuiltinModule('node:process'); |
| 80 | assert.strictEqual(typeof processBuiltin, 'object'); |
| 81 | |
| 82 | // Test exit function exists (but don't call it) |
| 83 | assert.strictEqual(typeof process.exit, 'function'); |
| 84 | }, |
| 85 | }; |
| 86 | |
| 87 | export const processLegacyNoV2Properties = { |
| 88 | test() { |
| 89 | // Test that v2-only properties are NOT present |
| 90 | const v2OnlyProperties = [ |
| 91 | 'version', |
| 92 | 'versions', |
| 93 | 'title', |
| 94 | 'argv', |
| 95 | 'argv0', |
| 96 | 'execArgv', |
| 97 | 'arch', |
| 98 | 'config', |
| 99 | 'pid', |
| 100 | 'ppid', |
| 101 | 'hrtime', |
| 102 | 'emitWarning', |
| 103 | 'abort', |
| 104 | 'uptime', |
| 105 | 'loadEnvFile', |
| 106 | 'getegid', |
| 107 | 'geteuid', |
| 108 | 'getgid', |
| 109 | 'getgroups', |
| 110 | 'getuid', |
| 111 | 'setegid', |
| 112 | 'seteuid', |
| 113 | 'setgid', |
| 114 | 'setgroups', |
| 115 | 'setuid', |
| 116 | 'initgroups', |
| 117 | 'setSourceMapsEnabled', |
| 118 | 'getSourceMapsSupport', |
| 119 | 'allowedNodeEnvironmentFlags', |
| 120 | ]; |
| 121 | |
| 122 | for (const prop of v2OnlyProperties) { |
| 123 | assert.strictEqual( |
| 124 | process[prop], |
| 125 | undefined, |
| 126 | `process.${prop} should be undefined in legacy mode` |
| 127 | ); |
| 128 | assert.strictEqual( |
| 129 | processMod[prop], |
| 130 | undefined, |
| 131 | `processMod.${prop} should be undefined in legacy mode` |
| 132 | ); |
| 133 | assert.strictEqual( |
| 134 | processMod.default[prop], |
| 135 | undefined, |
| 136 | `processMod.default.${prop} should be undefined in legacy mode` |
| 137 | ); |
| 138 | } |
| 139 | }, |
| 140 | }; |
| 141 | |
| 142 | export const processLegacyConsistency = { |
| 143 | test() { |
| 144 | // Test that all three ways of accessing process are consistent |
| 145 | const processKeys = Object.keys(process) |
| 146 | .filter((k) => k[0] !== '_') |
| 147 | .sort(); |
| 148 | const processModKeys = Object.keys(processMod) |
| 149 | .filter((k) => k !== 'default') |
| 150 | .sort(); |
| 151 | const processDefaultKeys = Object.keys(processMod.default).sort(); |
| 152 | |
| 153 | assert.deepStrictEqual(processKeys, processDefaultKeys); |
| 154 | assert.deepStrictEqual(processModKeys, processDefaultKeys); |
| 155 | |
| 156 | // Test that function references are the same |
| 157 | assert.strictEqual(process.nextTick, processMod.nextTick); |
| 158 | assert.strictEqual(process.nextTick, processMod.default.nextTick); |
| 159 | assert.strictEqual(process.exit, processMod.exit); |
| 160 | assert.strictEqual(process.exit, processMod.default.exit); |
| 161 | assert.strictEqual(process.getBuiltinModule, processMod.getBuiltinModule); |
| 162 | assert.strictEqual( |
| 163 | process.getBuiltinModule, |
| 164 | processMod.default.getBuiltinModule |
| 165 | ); |
| 166 | }, |
| 167 | }; |