mirror of
https://github.com/nodejs/node.git
synced 2025-04-29 06:19:07 +00:00

Some checks are pending
Coverage Linux (without intl) / coverage-linux-without-intl (push) Waiting to run
Coverage Linux / coverage-linux (push) Waiting to run
Coverage Windows / coverage-windows (push) Waiting to run
Test and upload documentation to artifacts / build-docs (push) Waiting to run
Linters / lint-addon-docs (push) Waiting to run
Linters / lint-cpp (push) Waiting to run
Linters / format-cpp (push) Waiting to run
Linters / lint-js-and-md (push) Waiting to run
Linters / lint-py (push) Waiting to run
Linters / lint-yaml (push) Waiting to run
Linters / lint-sh (push) Waiting to run
Linters / lint-codeowners (push) Waiting to run
Linters / lint-pr-url (push) Waiting to run
Linters / lint-readme (push) Waiting to run
Notify on Push / Notify on Force Push on `main` (push) Waiting to run
Notify on Push / Notify on Push on `main` that lacks metadata (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
PR-URL: https://github.com/nodejs/node/pull/57171 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
353 lines
12 KiB
JavaScript
353 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
const { spawnPromisified } = require('../common');
|
|
const fixtures = require('../common/fixtures');
|
|
const { match, strictEqual } = require('node:assert');
|
|
const { test } = require('node:test');
|
|
const { chmodSync, constants } = require('node:fs');
|
|
const common = require('../common');
|
|
|
|
test('should handle non existing json', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--experimental-config-file',
|
|
'i-do-not-exist.json',
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Cannot read configuration from i-do-not-exist\.json: no such file or directory/);
|
|
match(result.stderr, /i-do-not-exist\.json: not found/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should handle empty json', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/empty.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Can't parse/);
|
|
match(result.stderr, /empty\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should handle empty object json', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/empty-object.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
match(result.stdout, /Hello, World!/);
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should parse boolean flag', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/transform-types.json'),
|
|
fixtures.path('typescript/ts/transformation/test-enum.ts'),
|
|
]);
|
|
match(result.stderr, /--experimental-config-file is an experimental feature and might change at any time/);
|
|
match(result.stdout, /Hello, TypeScript!/);
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should not override a flag declared twice', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/override-property.json'),
|
|
fixtures.path('typescript/ts/transformation/test-enum.ts'),
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, 'Hello, TypeScript!\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should override env-file', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/transform-types.json'),
|
|
'--env-file', fixtures.path('dotenv/node-options-no-tranform.env'),
|
|
fixtures.path('typescript/ts/transformation/test-enum.ts'),
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
match(result.stdout, /Hello, TypeScript!/);
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should not override NODE_OPTIONS', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/transform-types.json'),
|
|
fixtures.path('typescript/ts/transformation/test-enum.ts'),
|
|
], {
|
|
env: {
|
|
...process.env,
|
|
NODE_OPTIONS: '--no-experimental-transform-types',
|
|
},
|
|
});
|
|
match(result.stderr, /ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 1);
|
|
});
|
|
|
|
test('should not ovverride CLI flags', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--no-experimental-transform-types',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/transform-types.json'),
|
|
fixtures.path('typescript/ts/transformation/test-enum.ts'),
|
|
]);
|
|
match(result.stderr, /ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 1);
|
|
});
|
|
|
|
test('should parse array flag correctly', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/import.json'),
|
|
'--eval', 'setTimeout(() => console.log("D"),99)',
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, 'A\nB\nC\nD\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should validate invalid array flag', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/invalid-import.json'),
|
|
'--eval', 'setTimeout(() => console.log("D"),99)',
|
|
]);
|
|
match(result.stderr, /invalid-import\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should validate array flag as string', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/import-as-string.json'),
|
|
'--eval', 'setTimeout(() => console.log("B"),99)',
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, 'A\nB\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should throw at unknown flag', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/unknown-flag.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Unknown or not allowed option some-unknown-flag/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should throw at flag not available in NODE_OPTIONS', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/not-node-options-flag.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Unknown or not allowed option test/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('unsigned flag should be parsed correctly', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/numeric.json'),
|
|
'-p', 'http.maxHeaderSize',
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, '4294967295\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('numeric flag should not allow negative values', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/negative-numeric.json'),
|
|
'-p', 'http.maxHeaderSize',
|
|
]);
|
|
match(result.stderr, /Invalid value for --max-http-header-size/);
|
|
match(result.stderr, /negative-numeric\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('v8 flag should not be allowed in config file', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/v8-flag.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /V8 flag --abort-on-uncaught-exception is currently not supported/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('string flag should be parsed correctly', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--test',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/string.json'),
|
|
fixtures.path('rc/test.js'),
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, '.\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('host port flag should be parsed correctly', { skip: !process.features.inspector }, async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--expose-internals',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/host-port.json'),
|
|
'-p', 'require("internal/options").getOptionValue("--inspect-port").port',
|
|
]);
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, '65535\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('no op flag should throw', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/no-op.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /No-op flag --http-parser is currently not supported/);
|
|
match(result.stderr, /no-op\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should not allow users to sneak in a flag', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/sneaky-flag.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /The number of NODE_OPTIONS doesn't match the number of flags in the config file/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('non object root', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/non-object-root.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Root value unexpected not an object for/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('non object node options', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/non-object-node-options.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /"nodeOptions" value unexpected for/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should throw correct error when a json is broken', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/broken.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Can't parse/);
|
|
match(result.stderr, /broken\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('broken value in node_options', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/broken-node-options.json'),
|
|
'-p', '"Hello, World!"',
|
|
]);
|
|
match(result.stderr, /Can't parse/);
|
|
match(result.stderr, /broken-node-options\.json: invalid content/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
});
|
|
|
|
test('should use node.config.json as default', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-default-config-file',
|
|
'-p', 'http.maxHeaderSize',
|
|
], {
|
|
cwd: fixtures.path('rc/default'),
|
|
});
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, '10\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
|
|
test('should override node.config.json when specificied', async () => {
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-default-config-file',
|
|
'--experimental-config-file',
|
|
fixtures.path('rc/default/override.json'),
|
|
'-p', 'http.maxHeaderSize',
|
|
], {
|
|
cwd: fixtures.path('rc/default'),
|
|
});
|
|
strictEqual(result.stderr, '');
|
|
strictEqual(result.stdout, '20\n');
|
|
strictEqual(result.code, 0);
|
|
});
|
|
// Skip on windows because it doesn't support chmod changing read permissions
|
|
test('should throw an error when the file is non readable', { skip: common.isWindows }, async () => {
|
|
chmodSync(fixtures.path('rc/non-readable/node.config.json'), constants.O_RDONLY);
|
|
const result = await spawnPromisified(process.execPath, [
|
|
'--no-warnings',
|
|
'--experimental-default-config-file',
|
|
'-p', 'http.maxHeaderSize',
|
|
], {
|
|
cwd: fixtures.path('rc/non-readable'),
|
|
});
|
|
match(result.stderr, /Cannot read configuration from node\.config\.json: permission denied/);
|
|
strictEqual(result.stdout, '');
|
|
strictEqual(result.code, 9);
|
|
chmodSync(fixtures.path('rc/non-readable/node.config.json'),
|
|
constants.S_IRWXU | constants.S_IRWXG | constants.S_IRWXO);
|
|
});
|