Remove vows from tests.#854
Conversation
|
Warning Rate limit exceeded@jdmarshall has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 13 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (32)
WalkthroughAll test files were migrated from the Vows framework to Node's built-in test runner ( Changes
Sequence Diagram(s)(omitted — changes are test-harness migrations across many files; no single control-flow diagram applies) Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Assessment against linked issues
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Oh goodie. Node 22.18 breaks my tests. looks like node --test is the problem Known issue: nodejs/node#59364 |
There was a problem hiding this comment.
Actionable comments posted: 15
🔭 Outside diff range comments (2)
test/6-strict-mode.js (1)
106-107: Remove vows-specific assertionThe
assert.instanceOfmethod is from the vows framework and doesn't exist in Node's built-in assert module.- assert.instanceOf(error,Error); + assert(error instanceof Error);test/2-config-test.js (1)
31-33: Avoid polluting process.argv across tests.Using push accumulates flags over multiple tests and can leak state into later suites. Set argv explicitly per test to avoid order-dependent failures.
- process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'); + process.argv = ['node', 'test.js', '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'];
🧹 Nitpick comments (44)
test/4-array-merging.js (2)
28-38: Prefer deepStrictEqual for exact structural comparisonUsing assert.deepStrictEqual avoids loose equality and is the recommended assert variant for arrays/objects.
Apply this diff:
- assert.deepEqual(CONFIG.arrayMerging.emptyArray, ['not empty anymore']); + assert.deepStrictEqual(CONFIG.arrayMerging.emptyArray, ['not empty anymore']); @@ - assert.deepEqual(CONFIG.arrayMerging.oneItem, ['replaced']); + assert.deepStrictEqual(CONFIG.arrayMerging.oneItem, ['replaced']); @@ - assert.deepEqual(CONFIG.arrayMerging.removeMe, []); + assert.deepStrictEqual(CONFIG.arrayMerging.removeMe, []);
27-27: Minor wording nit: duplicated “Tests” in suite titleTighten the description string.
- describe('Array merging tests Tests', function() { + describe('Array merging tests', function() {test/17-toml.js (1)
6-6: Clarify parser import as a side-effect (or avoid unused binding)If this require is for side effects (registering TOML support), avoid the unused variable and document the intent.
-const Parser = require('../parser'); +// Register TOML parser via module side effects. +require('../parser');test/8-config-extending.js (1)
25-31: Tidy up: path.join, const naming, and leaner assertion functionNon-functional cleanup that improves readability and consistency.
- process.env.NODE_CONFIG_DIR = __dirname + '/8-config'; - var base_config = require(process.env.NODE_CONFIG_DIR + path.sep + 'base-config.json'); - CONFIG.util.attachProtoDeep(base_config); - - assert.doesNotThrow(function () { - let result = Util.extendDeep(base_config, CONFIG); - }, 'Extending a configuration with another configuration has an error'); + process.env.NODE_CONFIG_DIR = __dirname + '/8-config'; + const baseConfig = require(path.join(process.env.NODE_CONFIG_DIR, 'base-config.json')); + CONFIG.util.attachProtoDeep(baseConfig); + + assert.doesNotThrow(() => { + Util.extendDeep(baseConfig, CONFIG); + }, 'Extending a configuration with another configuration has an error');test/22-binary.js (1)
28-36: Use deepStrictEqual for Buffer comparisonBuffers should be compared strictly; deepStrictEqual avoids edge cases and aligns with modern assert usage.
- assert.deepEqual(expectedBuffer, actualBuffer); + assert.deepStrictEqual(expectedBuffer, actualBuffer);test/23-serialize.js (1)
11-11: Nit: Rename inner describe from “Binary tests” to reflect serializationMinor naming mismatch; this suite isn’t testing binary data.
Apply this diff:
- describe('Binary tests', function() { + describe('Serialization tests', function() {test/11-regexp.js (5)
14-14: Nit: Typo in suite name (“Regexp tests Tests”)Drop the duplicate “Tests” for readability.
- describe('Regexp tests Tests', function() { + describe('Regexp tests', function() {
15-15: Prefer const for immutable aliasconfig isn’t reassigned; const communicates intent and prevents accidental reassignments.
- let config = CONFIG; + const config = CONFIG;
25-30: Clarify exec() call with an explicit test stringCalling RegExp#exec with no argument implicitly coerces undefined to 'undefined'. Passing a literal string removes ambiguity.
- regExp.exec(); + regExp.exec('some input');
41-46: Use strict assertions for exact string matchesassert.strictEqual avoids type coercion and aligns with modern assert usage.
- assert.equal(config.SomeMore.regexp1.source, /This is a Regexp/g.source); + assert.strictEqual(config.SomeMore.regexp1.source, /This is a Regexp/g.source); @@ - assert.equal(config.SomeMore.regexp2.source, /This is the replaced/g.source); + assert.strictEqual(config.SomeMore.regexp2.source, /This is the replaced/g.source);
11-11: Nit: Prefer const over var for CONFIGCONFIG isn’t reassigned; const is safer and idiomatic.
-var CONFIG = requireUncached(__dirname + '/../lib/config'); +const CONFIG = requireUncached(__dirname + '/../lib/config');test/14-node_env-load-multiple-files.js (4)
29-29: Mismatch between suite title and setupThe description says NODE_ENV includes 'cloud' and 'bare-metal', but setup uses 'development,bare-metal'. Align the title to the setup.
- describe('When there is \'cloud\' and \'bare-metal\' values in NODE_ENV and HOST is \'test\'', function() { + describe('When there is \'development\' and \'bare-metal\' values in NODE_ENV and HOST is \'test\'', function() {
18-26: Prefer strict equality in assertionsUse assert.strictEqual to avoid coercion and match best practices (also aligns with the objective to correct assert usage).
- assert.equal(config.get('db.name'), 'development-config-env-provided'); - assert.equal(config.get('db.port'), 3000); + assert.strictEqual(config.get('db.name'), 'development-config-env-provided'); + assert.strictEqual(config.get('db.port'), 3000); @@ - assert.equal(config.get('app.context'), 'local cloud'); - assert.equal(config.get('app.message'), 'local development'); + assert.strictEqual(config.get('app.context'), 'local cloud'); + assert.strictEqual(config.get('app.message'), 'local development');
40-43: Prefer strict equality in assertionsSame reasoning as above.
- assert.equal(config.get('host.os'), 'linux'); - assert.equal(config.get('host.arch'), 'x86_64'); + assert.strictEqual(config.get('host.os'), 'linux'); + assert.strictEqual(config.get('host.arch'), 'x86_64');
55-57: Prefer strict equality in assertionsSame reasoning as above.
- assert.equal(config.get('db.name'), 'bare-metal-config-env-provided'); + assert.strictEqual(config.get('db.name'), 'bare-metal-config-env-provided');test/x-config-js-test-transpiled.js (1)
21-21: Nit: Assign env vars as stringsprocess.env values are strings; being explicit avoids accidental toString surprises and is consistent with other env assignments.
- process.env.NODE_CONFIG_STRICT_MODE = false; + process.env.NODE_CONFIG_STRICT_MODE = 'false';test/21-date.js (1)
10-10: Nit: Prefer const for CONFIGCONFIG is never reassigned; const is clearer and safer.
-var CONFIG = requireUncached(__dirname + '/../lib/config'); +const CONFIG = requireUncached(__dirname + '/../lib/config');test/16-custom-parser.js (3)
20-24: Prefer assert.strictEqual over assert.equal for precise comparisonsUse strict equality to avoid coercion and align with Node’s assert best practices.
- assert.equal(config.get('file.type'), 'yaml'); - assert.equal(config.get('file.name'), 'local.yml'); - assert.equal(config.get('parser'), 'js-yaml'); - assert.equal(config.has('custom.key'), false); + assert.strictEqual(config.get('file.type'), 'yaml'); + assert.strictEqual(config.get('file.name'), 'local.yml'); + assert.strictEqual(config.get('parser'), 'js-yaml'); + assert.strictEqual(config.has('custom.key'), false);- assert.equal(config.get('file.type'), 'custom'); - assert.equal(config.get('file.name'), 'local.yml'); + assert.strictEqual(config.get('file.type'), 'custom'); + assert.strictEqual(config.get('file.name'), 'local.yml'); // assert.equal(config.get('file.name'), 'my-custom-awesome-dsl'); - assert.equal(config.get('parser'), 'custom-awesomeness'); - assert.equal(config.get('custom.key'), 'wow!'); + assert.strictEqual(config.get('parser'), 'custom-awesomeness'); + assert.strictEqual(config.get('custom.key'), 'wow!');- assert.equal(config.get('file.type'), 'json'); - assert.equal(config.get('file.name'), 'local.yml'); - assert.equal(config.get('parser'), 'json'); - assert.equal(config.get('custom.key'), 'wow!'); + assert.strictEqual(config.get('file.type'), 'json'); + assert.strictEqual(config.get('file.name'), 'local.yml'); + assert.strictEqual(config.get('parser'), 'json'); + assert.strictEqual(config.get('custom.key'), 'wow!');- assert.equal(config.get('file.type'), 'yaml'); - assert.equal(config.get('file.name'), 'local.yml'); - assert.equal(config.get('parser'), 'json5'); - assert.equal(config.get('custom.key'), 'json5 rules!'); + assert.strictEqual(config.get('file.type'), 'yaml'); + assert.strictEqual(config.get('file.name'), 'local.yml'); + assert.strictEqual(config.get('parser'), 'json5'); + assert.strictEqual(config.get('custom.key'), 'json5 rules!');Also applies to: 38-43, 56-61, 75-79
82-85: Tighten teardown: remove unused parameter and clean NODE_CONFIG_DIRThe after hook doesn’t need a parameter and should also clear NODE_CONFIG_DIR to avoid side effects across files.
- after(function (topic) { - delete process.env.NODE_CONFIG_PARSER; - requireUncached(__dirname + '/../parser'); - }); + after(function () { + delete process.env.NODE_CONFIG_PARSER; + delete process.env.NODE_CONFIG_DIR; + requireUncached(__dirname + '/../parser'); + });
40-41: Remove or update stale commented assertionThis commented-out assertion contradicts the active assertion above. Either delete it or rework the scenario to assert the intended value.
- // assert.equal(config.get('file.name'), 'my-custom-awesome-dsl'); + // If needed, assert the intended custom filename here once behavior is defined.test/13-node_env-hostname.js (2)
35-37: Use strict equality for HOSTNAME testSafer and consistent with the rest of the suite.
- it('HOSTNAME env variable is the winner', function() { - assert.equal(config.util.getEnv('HOSTNAME'), 'some.machine'); - }); + it('HOSTNAME env variable is the winner', function() { + assert.strictEqual(config.util.getEnv('HOSTNAME'), 'some.machine'); + });
4-4: Add teardown to avoid env leakage across testsClean up HOST and HOSTNAME to reduce cross-file coupling. Requires importing after.
-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it, before, beforeEach, after } = require('node:test');}); -}); + after(() => { + delete process.env.HOST; + delete process.env.HOSTNAME; + }); +});Also applies to: 55-55
test/10-gitcrypt-test.js (2)
4-4: Add teardown for environment variablesMinor hygiene to prevent env leakage to other files. Requires importing after.
-const { describe, it, beforeEach } = require('node:test'); +const { describe, it, beforeEach, after } = require('node:test');-}); + after(() => { + delete process.env.CONFIG_SKIP_GITCRYPT; + delete process.env.NODE_ENV; + delete process.env.NODE_CONFIG_STRICT_MODE; + delete process.env.NODE_CONFIG; + delete process.env.CUSTOM_JSON_ENVIRONMENT_VAR; + }); +});Also applies to: 57-57
18-25: Optional: assign string values to process.env for clarityprocess.env values are strings; using booleans/numbers relies on implicit coercion. Assign string values for intent.
- process.env.NODE_CONFIG_STRICT_MODE = false; + process.env.NODE_CONFIG_STRICT_MODE = 'false'; @@ - process.env.CONFIG_SKIP_GITCRYPT = 1; + process.env.CONFIG_SKIP_GITCRYPT = '1'; @@ - process.env.CONFIG_SKIP_GITCRYPT = 0; + process.env.CONFIG_SKIP_GITCRYPT = '0';Also applies to: 46-47
test/x-config-test-ts.js (3)
21-27: Delete env vars instead of setting empty stringsAssigning '' keeps the variable defined; delete provides a true “unset” state and mirrors behavior in other tests.
- process.env.NODE_APP_INSTANCE = ''; - process.env.NODE_ENV = ''; - process.env.NODE_CONFIG = ''; + delete process.env.NODE_APP_INSTANCE; + delete process.env.NODE_ENV; + delete process.env.NODE_CONFIG;
41-43: Use strict equality for string comparisonAvoids coercion and keeps assert usage consistent.
- assert.equal(config.siteTitle, 'New Instance!'); + assert.strictEqual(config.siteTitle, 'New Instance!');
51-52: Avoid variable shadowing in last testNo need to re-declare config; it isn’t used. This avoids shadowing the outer variable and reduces lint noise.
- let config = requireUncached(__dirname + '/../lib/config'); + requireUncached(__dirname + '/../lib/config');test/12-node_env-override.js (3)
41-43: Prefer strict equality in env and config assertionsUse assert.strictEqual to avoid coercion and keep consistent with Node’s assert best practices.
- assert.equal(config.util.getEnv('NODE_ENV'), 'development'); - assert.equal(config.get('deploymentUsed'), 'default'); + assert.strictEqual(config.util.getEnv('NODE_ENV'), 'development'); + assert.strictEqual(config.get('deploymentUsed'), 'default');- assert.equal(config.util.getEnv('NODE_CONFIG_ENV'), 'apollo'); - assert.equal(config.get('deploymentUsed'), 'node-config-env-provided'); + assert.strictEqual(config.util.getEnv('NODE_CONFIG_ENV'), 'apollo'); + assert.strictEqual(config.get('deploymentUsed'), 'node-config-env-provided');- assert.equal(config.util.getEnv('NODE_CONFIG_ENV'), 'mercury'); - assert.equal(config.get('deploymentUsed'), 'node-env-provided'); + assert.strictEqual(config.util.getEnv('NODE_CONFIG_ENV'), 'mercury'); + assert.strictEqual(config.get('deploymentUsed'), 'node-env-provided');- assert.equal(config.get('deploymentUsed'), 'node-config-env-provided'); + assert.strictEqual(config.get('deploymentUsed'), 'node-config-env-provided');Also applies to: 56-58, 75-77, 95-96
46-59: Clarify test title to match behaviorThe test description says “NODE_CONFIG_ENV by itself should be used,” but the setup defines only NODE_ENV. Consider rewording to avoid confusion.
- it('NODE_CONFIG_ENV by itself should be used', function () { + it('NODE_ENV by itself should be used (reflected via NODE_CONFIG_ENV lookup)', function () {
65-82: Symmetry: cleanup correct variable and wordingThis suite sets only NODE_CONFIG_ENV. The after hook should clean that var; message also mentions NODE_ENV. See prior fix; ensure wording matches setup.
test/0-util.js (3)
51-73: Improve variable naming consistencyLine 71 has an arithmetic expression split across lines which appears to be unintentional.
- 1.1 - - 1, + 1.1 - 1,
134-144: Use strictEqual for consistencySeveral assertions use
assert.equalwhenassert.strictEqualwould be more appropriate for type-safe comparisons.- assert.equal(util.getOption(options, "item1"), 23); + assert.strictEqual(util.getOption(options, "item1"), 23);- assert.equal(util.getOption(options, "missing", "orange"), "orange"); + assert.strictEqual(util.getOption(options, "missing", "orange"), "orange");- assert.equal(util.getOption(options, "item2", "orange"), 0); + assert.strictEqual(util.getOption(options, "item2", "orange"), 0);
152-156: Use strictEqual for consistency in locateMatchingFiles test- assert.equal(Path.basename(results[0]), "default.json"); - assert.equal(Path.basename(results[1]), "default.mjs"); + assert.strictEqual(Path.basename(results[0]), "default.json"); + assert.strictEqual(Path.basename(results[1]), "default.mjs");test/20-multiple-config.js (1)
8-65: Consider extracting common test logicAll test cases follow the same pattern of setting NODE_CONFIG_DIR and asserting that CONFIG loads without error. Consider extracting this into a helper function to reduce duplication.
Add a helper function at the top of the describe block:
describe('Tests for multiple config', function() { function testConfigDirSetup(description, configDirs) { it(description, function() { process.env.NODE_CONFIG_DIR = configDirs.join(path.delimiter); assert.doesNotThrow(function () { const CONFIG = requireUncached(__dirname + '/../lib/config'); }, description.replace('should work without error', 'has an error')); }); } testConfigDirSetup('Adding multiple relative configuration paths should work without error', ['./test/20-config', './test/20-extra-config']); testConfigDirSetup('Adding multiple absolute configuration paths should work without error', [__dirname + '/20-config', __dirname + '/20-extra-config']); // ... etc });test/6-strict-mode.js (1)
3-5: Clean migration to Node.js built-in test frameworkThe imports are properly updated. Note that
beforeandbeforeEachare imported but not used - consider removing them to keep imports clean.-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it } = require('node:test');test/9-raw-configs.js (2)
8-8: Remove unused test hooks (before, beforeEach).They're not used in this file. Trimming these keeps the import clean and avoids lints.
-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it } = require('node:test');
16-29: Prefer strict assertions to avoid coercion.Use strictEqual/deepStrictEqual to eliminate any risk of type coercion in tests.
- assert.equal(CONFIG.get('circularReference'), process.stdout); - assert.deepEqual(CONFIG.get('testObj'), { foo: 'bar' }); + assert.strictEqual(CONFIG.get('circularReference'), process.stdout); + assert.deepStrictEqual(CONFIG.get('testObj'), { foo: 'bar' }); assert.strictEqual(typeof CONFIG.get('yell'), 'function');- assert.equal(CONFIG.get('innerRaw').innerCircularReference, process.stdout); - assert.equal(CONFIG.get('innerRaw.innerCircularReference'), process.stdout); + assert.strictEqual(CONFIG.get('innerRaw').innerCircularReference, process.stdout); + assert.strictEqual(CONFIG.get('innerRaw.innerCircularReference'), process.stdout);- assert.equal(CONFIG.get('nestedRaw').nested.test, process.stdout); - assert.equal(CONFIG.get('nestedRaw.nested').test, process.stdout); - assert.equal(CONFIG.get('nestedRaw.nested.test'), process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw').nested.test, process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw.nested').test, process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw.nested.test'), process.stdout);test/util.js (2)
21-25: Isolate process.argv mutations within the test.Mutating
process.argvwithout restoring can leak into subsequent tests. Use a local save/restore.- process.env.BOTH = 'in-the-env'; - process.argv = ['ignore', 'ignore', '--BOTH=in-the-argv']; - assert.equal(initParam('BOTH', 'mydefault'), 'in-the-argv'); + process.env.BOTH = 'in-the-env'; + const prevArgv = process.argv.slice(); + try { + process.argv = ['ignore', 'ignore', '--BOTH=in-the-argv']; + assert.equal(initParam('BOTH', 'mydefault'), 'in-the-argv'); + } finally { + process.argv = prevArgv; + }Apply the same pattern to other tests that modify
process.argv.
63-69: Restore NODE_CONFIG safely to avoid setting the string 'undefined'.If
previsundefined, assigning it back will set the env var to the string'undefined'. Delete instead.- process.env.NODE_CONFIG = prev; + if (prev === undefined) { + delete process.env.NODE_CONFIG; + } else { + process.env.NODE_CONFIG = prev; + }test/3-deferred-configs.js (1)
28-29: Optional: adopt strict asserts for consistency.Not required, but switching to
strictEqual/deepStrictEqualacross this file aligns with modern assert usage and avoids accidental coercion.Example:
- assert.equal(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!'); + assert.strictEqual(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!');Also applies to: 33-34, 38-39, 46-47, 50-51, 54-56, 59-61
test/5-getConfigSources.js (3)
27-29: Align the test description with the expectation.The description says “four entries” but the assertion expects 6. Either adjust the description or the expectation; given the multi-directory setup + env + CLI, 6 is plausible.
Suggested minimal edit:
- it('Two files plus NODE_CONFIG in env and as command line args should result in four entries', function() { - assert.equal(sources.length,6); + it('Two directories + NODE_CONFIG in env + CLI should result in six entries', function() { + assert.equal(sources.length, 6);
105-107: Fix test title to reflect the actual expectation (4 entries).The body asserts 4 entries, but the title says 3.
- it('Three files should result in 3 entries', function() { - assert.equal(sources.length,4); + it('Empty-returning file is still included, resulting in 4 entries', function() { + assert.equal(sources.length, 4);
5-6: Prefer strict assertions to avoid type coercion.Using assert.strictEqual and assert.deepStrictEqual improves correctness in cases where types matter (numbers/booleans/strings).
Example:
- assert.equal(sources.length, 6); + assert.strictEqual(sources.length, 6);test/2-config-test.js (1)
5-5: Prefer strict assertions across the suite.Using assert.strictEqual/deepStrictEqual instead of equal/deepEqual prevents type coercion and false positives, especially for booleans and numbers used throughout this file.
Example:
-assert.equal(config.EnvOverride.parm6, 101); +assert.strictEqual(config.EnvOverride.parm6, 101);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (32)
package.json(1 hunks)test/0-util.js(1 hunks)test/1-protected-test.js(8 hunks)test/10-gitcrypt-test.js(3 hunks)test/11-regexp.js(1 hunks)test/12-node_env-override.js(1 hunks)test/13-node_env-hostname.js(1 hunks)test/14-node_env-load-multiple-files.js(1 hunks)test/15-async-configs.js(2 hunks)test/16-custom-parser.js(1 hunks)test/17-toml.js(2 hunks)test/18-skipConfigSources.js(1 hunks)test/19-custom-environment-variables.js(1 hunks)test/2-config-test.js(4 hunks)test/20-multiple-config.js(6 hunks)test/21-date.js(1 hunks)test/22-binary.js(1 hunks)test/22-files-order.js(3 hunks)test/23-serialize.js(1 hunks)test/3-deferred-configs.js(2 hunks)test/4-array-merging.js(2 hunks)test/5-getConfigSources.js(3 hunks)test/6-strict-mode.js(2 hunks)test/7-unicode-situations.js(2 hunks)test/8-config-extending.js(2 hunks)test/9-raw-configs.js(1 hunks)test/makeImmutable-shared-refs.js(1 hunks)test/util.js(1 hunks)test/x-config-js-test-transpiled.js(2 hunks)test/x-config-test-ts-module-exports.js(2 hunks)test/x-config-test-ts.js(2 hunks)test/x-deferred-configs-ts.js(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (27)
test/21-date.js (4)
test/11-regexp.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (3)
requireUncached(5-5)require(6-6)assert(7-7)
test/19-custom-environment-variables.js (3)
test/5-getConfigSources.js (6)
Path(3-3)require(5-5)requireUncached(4-4)config(22-22)config(76-76)config(101-101)test/12-node_env-override.js (7)
require(4-4)requireUncached(3-3)config(11-11)config(31-31)config(47-47)config(66-66)config(85-85)test/makeImmutable-shared-refs.js (1)
require(3-3)
test/x-config-test-ts-module-exports.js (1)
lib/config.js (1)
config(1030-1030)
test/18-skipConfigSources.js (3)
lib/config.js (5)
Path(9-9)require(8-8)config(1030-1030)value(142-142)value(336-336)lib/util.js (1)
Path(8-8)test/6-strict-mode.js (3)
require(4-4)requireUncached(3-3)assert(5-5)
test/x-config-js-test-transpiled.js (7)
test/22-binary.js (4)
requireUncached(7-7)require(8-8)require(11-11)assert(9-9)test/17-toml.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/22-files-order.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)test/9-raw-configs.js (4)
requireUncached(7-7)require(8-8)assert(9-9)CONFIG(11-11)test/23-serialize.js (4)
requireUncached(5-5)require(6-6)assert(7-7)CONFIG(8-8)
test/1-protected-test.js (2)
test/8-config-extending.js (1)
result(30-30)lib/config.js (2)
config(1030-1030)diff(815-815)
test/17-toml.js (7)
test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/22-files-order.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(18-18)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (3)
requireUncached(5-5)require(6-6)assert(7-7)lib/config.js (2)
require(8-8)config(1030-1030)
test/14-node_env-load-multiple-files.js (3)
test/6-strict-mode.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/15-async-configs.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(26-26)test/x-config-test-ts-module-exports.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(17-17)
test/makeImmutable-shared-refs.js (2)
test/19-custom-environment-variables.js (2)
require(5-5)assert(6-6)lib/config.js (2)
require(8-8)util(114-114)
test/13-node_env-hostname.js (1)
lib/config.js (2)
require(8-8)config(1030-1030)
test/22-binary.js (9)
test/11-regexp.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(15-15)test/17-toml.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(10-10)test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/22-files-order.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(18-18)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (3)
requireUncached(5-5)require(6-6)assert(7-7)lib/config.js (2)
require(8-8)config(1030-1030)
test/4-array-merging.js (1)
lib/config.js (1)
require(8-8)
test/8-config-extending.js (2)
test/2-config-test.js (2)
require(4-4)requireUncached(3-3)test/13-node_env-hostname.js (1)
requireUncached(3-3)
test/x-config-test-ts.js (9)
test/6-strict-mode.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/20-multiple-config.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/5-getConfigSources.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/10-gitcrypt-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-config-test-ts-module-exports.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(17-17)test/4-array-merging.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/7-unicode-situations.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/9-raw-configs.js (2)
requireUncached(7-7)assert(9-9)
test/2-config-test.js (1)
lib/config.js (3)
require(8-8)config(1030-1030)moduleConfig(214-214)
test/16-custom-parser.js (4)
test/20-multiple-config.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-config-test-ts.js (5)
requireUncached(3-3)require(4-4)assert(5-5)config(17-17)config(51-51)lib/config.js (2)
require(8-8)config(1030-1030)
test/6-strict-mode.js (1)
test/18-skipConfigSources.js (1)
require(5-5)
test/5-getConfigSources.js (9)
test/19-custom-environment-variables.js (2)
require(5-5)requireUncached(4-4)lib/config.js (3)
require(8-8)sources(978-978)config(1030-1030)test/1-protected-test.js (3)
require(4-4)requireUncached(3-3)config(30-30)test/12-node_env-override.js (3)
require(4-4)requireUncached(3-3)config(11-11)test/makeImmutable-shared-refs.js (1)
require(3-3)test/3-deferred-configs.js (2)
require(4-4)requireUncached(3-3)test/10-gitcrypt-test.js (2)
require(4-4)requireUncached(3-3)test/x-config-test-ts.js (2)
require(4-4)requireUncached(3-3)test/9-raw-configs.js (2)
require(8-8)requireUncached(7-7)
test/0-util.js (2)
test/8-config-extending.js (2)
require(5-5)require(7-7)test/util.js (1)
testCases(94-116)
test/x-deferred-configs-ts.js (4)
test/6-strict-mode.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-config-test-ts.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/15-async-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/9-raw-configs.js (3)
requireUncached(7-7)assert(9-9)CONFIG(11-11)
test/11-regexp.js (1)
lib/config.js (2)
require(8-8)config(1030-1030)
test/9-raw-configs.js (4)
test/6-strict-mode.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (4)
requireUncached(5-5)require(6-6)assert(7-7)CONFIG(8-8)lib/config.js (1)
require(8-8)
test/util.js (3)
lib/config.js (3)
require(8-8)config(1030-1030)util(114-114)test/1-protected-test.js (4)
require(4-4)requireUncached(3-3)assert(5-5)config(30-30)test/2-config-test.js (16)
require(4-4)requireUncached(3-3)assert(5-5)config(18-18)config(61-61)config(138-138)config(181-181)config(197-197)config(213-213)config(261-261)config(294-294)config(316-316)config(344-344)config(418-418)config(467-467)config(565-565)
test/22-files-order.js (7)
test/22-binary.js (5)
requireUncached(7-7)require(8-8)require(11-11)assert(9-9)config(15-15)test/17-toml.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(10-10)test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (3)
requireUncached(5-5)require(6-6)assert(7-7)
test/3-deferred-configs.js (1)
lib/config.js (1)
require(8-8)
test/23-serialize.js (7)
test/11-regexp.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/22-binary.js (4)
requireUncached(7-7)require(8-8)require(11-11)assert(9-9)test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/22-files-order.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/9-raw-configs.js (4)
requireUncached(7-7)require(8-8)assert(9-9)CONFIG(11-11)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)lib/config.js (1)
require(8-8)
test/12-node_env-override.js (4)
test/19-custom-environment-variables.js (6)
requireUncached(4-4)require(5-5)assert(6-6)config(10-10)config(30-30)config(50-50)test/5-getConfigSources.js (6)
requireUncached(4-4)require(5-5)assert(6-6)config(22-22)config(76-76)config(101-101)test/makeImmutable-shared-refs.js (2)
require(3-3)assert(4-4)lib/config.js (2)
require(8-8)config(1030-1030)
🔇 Additional comments (57)
package.json (1)
60-60: Switch to node:test runner via c8 node --test looks goodUsing Node’s built-in test harness aligns with the PR objective and modernizes the test execution path.
test/17-toml.js (1)
16-27: LGTM: per-test setup and strict structural assertionbeforeEach reloading of config provides isolation, and deepStrictEqual is the right choice for object arrays here.
test/8-config-extending.js (1)
22-34: LGTM: behavior preserved while migrating off VowsThe test intent (“does not throw on deep extend after attachProtoDeep”) remains intact under node:test.
test/22-binary.js (1)
13-27: LGTM: immutability enforcement verified cleanlyThe throws assertion correctly validates that binary config values are immutable.
test/23-serialize.js (1)
12-17: LGTM: Serialization smoke test is correct and resilientUsing assert.doesNotThrow around JSON.stringify(CONFIG.get('level1')) is appropriate here. The migration to node:test looks clean.
test/x-config-js-test-transpiled.js (1)
26-34: LGTM: Initialization and basic assertions look goodClearing env, loading via requireUncached, and verifying CONFIG availability and expected title are sound.
test/21-date.js (1)
21-27: LGTM: Date method invocation guarded properlyUsing assert.doesNotThrow to validate toISOString() on the loaded Date object is appropriate.
test/1-protected-test.js (16)
1-6: LGTM!The migration to Node's built-in test runner is clean and follows standard patterns.
14-14: Good preservation of test state isolationStoring the original argv to restore later is essential for preventing test interference. This approach correctly ensures test isolation.
25-50: Well-structured test initialization with proper isolationThe beforeEach hook properly resets environment variables and reloads the config module uncached, ensuring each test runs with a clean state. This is particularly important given the singleton nature of the config module.
52-56: LGTM - Clear and focused testThe assertion correctly validates the library is loaded as an object.
58-75: Comprehensive isObject() test coverageGood coverage of edge cases including null, undefined, arrays, and primitives. The assertions correctly validate the behavior of the isObject utility.
77-144: Thorough deep cloning tests with proper edge case coverageExcellent test coverage for the cloneDeep functionality including:
- Deep equality checks
- Reference vs value copying for arrays and objects
- Special object preservation (Date, RegExp)
- Mutation isolation verification
The tests properly validate that modifications to cloned objects don't affect originals.
146-224: Comprehensive extendDeep() test coverageThe test suite thoroughly validates deep merging behavior including:
- Normal extension
- Non-object replacement
- Deep object merging
- Date handling
- Partial object creation when mixing types
- Array type preservation
- Prototype method preservation
All assertions correctly test the expected merge semantics.
226-296: Well-structured equalsDeep() testsGood coverage of equality comparison scenarios including:
- Empty objects
- Arrays
- Object property order independence
- Deep nested objects
- Null/undefined edge cases
- Size mismatches
- Value differences
The tests properly validate deep equality semantics.
298-340: Thorough diffDeep() validationTests properly validate diff generation including:
- Empty diff for identical objects
- Deep comparison ignoring property order
- Shallow diff extraction
- Deep nested diff extraction
The assertions correctly check both the structure and values of generated diffs.
342-592: Comprehensive substituteDeep() test suite with excellent error handlingThis test suite provides extensive coverage of variable substitution including:
- Empty mappings
- Non-existent variables
- JSON content handling
- Edge cases with undefined, null, empty strings
- Type validation with proper error assertions for invalid leaf types (Array, Boolean, Number, null, undefined, NaN)
- Parser error handling with descriptive error messages
The error cases are particularly well-tested using assert.throws with proper validation.
594-641: Good setPath() test coverageTests properly validate path setting behavior including:
- Null value handling (ignored)
- Top-level key creation
- Sub-key creation
- Parent object creation
- Value overwriting
All assertions correctly validate the expected behavior.
643-716: Comprehensive parseFile() tests across multiple formatsExcellent coverage of file parsing for YAML, CSON, and .properties formats. Tests validate:
- Correct object structure
- Property values
- Array types
- Variable replacements in .properties files
- Section support
The assertions properly validate parsing behavior for each format.
718-738: Basic but sufficient loadFileConfigs() testTests validate that the function exists, returns an object, and loads configuration correctly.
740-784: Thorough attachProtoDeep() validationTests properly validate:
- Function existence
- Original object preservation
- Prototype method attachment at all levels (including sub-objects)
- Prototype methods are hidden from JSON serialization
The JSON serialization test is particularly important to ensure prototype pollution doesn't affect object iteration.
786-824: Well-structured getCmdLineArg() tests with proper cleanupTests comprehensively validate command-line argument parsing including:
- Basic argument retrieval
- Missing argument handling
- Alternative syntax support
- First-match precedence
- Proper restoration of original argv
The cleanup in line 819-823 properly restores the original process.argv state.
826-854: Good toObject() serialization testsTests validate:
- Function existence
- POJO conversion (not an instance of Config)
- Serialization of current instance
- Serialization of provided arguments
The assertions correctly validate the serialization behavior.
test/x-config-test-ts-module-exports.js (3)
1-5: LGTM - Consistent test framework migrationThe migration to Node's built-in test runner follows the same pattern as other test files in this PR.
16-32: Well-structured test setup with proper environment isolationThe beforeEach hook properly:
- Clears environment variables from previous tests
- Sets the TypeScript config directory
- Disables strict mode
- Loads config uncached for test isolation
This ensures clean state between tests when working with TypeScript config files using module.exports.
34-44: Clear and focused TypeScript configuration testsThe tests validate:
- Library availability as an object
- Correct loading of TypeScript configuration values
Simple but sufficient for validating TypeScript config support with module.exports.
test/19-custom-environment-variables.js (5)
1-7: LGTM - Consistent test framework migrationThe migration follows the established pattern with proper imports.
8-27: Good test for unset environment variablesThe test properly validates that configuration values remain unchanged when environment variables are not set.
29-47: Important edge case: empty string environment variablesGood coverage of the edge case where environment variables are set to empty strings. The test correctly validates that empty strings don't override configuration values.
49-71: Comprehensive test for environment variable overridesTests properly validate that:
- String environment variables override config values
- JSON environment variables are parsed correctly
The JSON parsing test is particularly important for complex configuration overrides.
73-97: Good test coverage for getCustomEnvVars() utilityThe test validates the utility function for retrieving custom environment variable overrides from a specific directory. Properly sets up environment and validates both string and JSON values.
test/15-async-configs.js (4)
1-5: LGTM - Clean migration to node:testThe test file properly migrates to Node's built-in test runner.
24-30: Proper async test setupThe beforeEach correctly uses async/await to resolve async configurations before each test, ensuring the config is ready for assertions.
32-44: Comprehensive async config validationTests properly validate:
- AsyncConfig values are resolved by resolveAsyncConfigs
- Regular functions remain untouched
thiscontext binding in async functionsGood coverage of the async configuration feature.
46-60: Thorough testing of complex async scenariosTests validate:
- Objects returned from promises are treated as single values
- Original values are preserved
- Local promise values override originals
- Deferred functionality works with AsyncConfig
Excellent coverage of edge cases in async configuration resolution.
test/22-files-order.js (3)
1-5: LGTM - Consistent test framework migrationThe migration follows the established pattern across the test suite.
16-31: Well-structured test setup for file order validationThe beforeEach properly sets up the multi-file configuration scenario with:
- Custom config directory
- NODE_ENV=test
- NODE_APP_INSTANCE=instance
This setup allows testing the correct loading order of configuration files.
33-37: Clear validation of configuration file precedenceThe test correctly validates that configuration files are loaded in the expected order:
- prop1 from default config
- prop2 from JSON instance config (overrides)
- prop3 from YML instance config (overrides)
This ensures the file precedence system works as intended.
test/10-gitcrypt-test.js (1)
7-38: LGTM: Migration and core assertions look solidThe rewrite to node:test is clear, with per-test isolation via requireUncached and correct positive/negative paths for CONFIG_SKIP_GITCRYPT. Assertions are precise.
test/7-unicode-situations.js (3)
1-1: Good addition of 'use strict'This brings the test file in line with modern JavaScript best practices.
3-6: Successful migration to Node.js built-in test frameworkThe imports have been properly updated to use the Node.js built-in test framework (
node:test). The migration from vows to the native test runner is clean and follows the consistent pattern used across the PR.
22-42: Well-structured test organizationThe migration to nested
describeblocks with focusedittests improves readability and follows standard testing conventions. The test logic remains intact while adopting the more modern structure.test/0-util.js (1)
7-7: Clean migration to Node.js built-in test frameworkThe imports have been properly updated from vows to the Node.js built-in test framework. Good job maintaining consistency across the test suite migration.
test/20-multiple-config.js (2)
1-2: Good addition of 'use strict'Adding strict mode improves code quality and helps catch potential errors.
5-6: Successful migration to Node.js built-in test frameworkThe migration from vows to Node.js built-in test runner is clean and consistent with the overall PR objectives.
test/x-deferred-configs-ts.js (3)
1-1: Good addition of 'use strict'This aligns with best practices and the pattern used across all migrated test files.
5-7: Clean migration to Node.js built-in test frameworkThe imports are properly updated from vows to Node.js built-in test runner, maintaining consistency with the PR-wide migration.
22-53: Well-structured test migrationThe test structure has been successfully migrated to use nested
describeblocks with individualittests. The test logic and assertions remain unchanged, preserving the original test coverage.test/6-strict-mode.js (1)
1-1: Good addition of 'use strict'Consistent with the modernization effort across all test files.
test/9-raw-configs.js (1)
13-37: Migration looks good and preserves behavior.The switch to node:test, uncached load, and assertions for raw values look correct and consistent with the suite.
test/util.js (1)
77-91: Promise detection tests are solid.Good coverage for created, resolved, and rejected promises (with catch to avoid unhandled rejections).
test/makeImmutable-shared-refs.js (2)
73-81: Idempotency test is appropriate and valuable.Verifies no “Cannot redefine property” on the second call—good guard against regressions.
57-60: Assertion is correct — keep the existing "Can not" messageThe code in lib/config.js throws the exact message using "Can not ... runtime configuration property" so the test's regex is valid.
- lib/config.js:381-384 — throw Error(
Can not ${message} runtime configuration property: "${name}". Configuration objects are immutable unless ALLOW_CONFIG_MUTATIONS is set.)- test/makeImmutable-shared-refs.js:57-60 — assertion uses /Can not update runtime configuration property/ and matches the thrown message.
No change required; ignore the original suggestion.
Likely an incorrect or invalid review comment.
test/18-skipConfigSources.js (1)
8-12: Conversion to node:test and structure LGTM.The migration reads well and keeps the semantics of the original vows tests intact.
test/3-deferred-configs.js (1)
22-62: Migration preserves deferred-config semantics.Good use of requireUncached and environment setup; the assertions map 1:1 with prior behavior.
test/5-getConfigSources.js (1)
8-35: Good migration from Vows to node:test with isolated setup per scenario.Use of requireUncached and per-scenario beforeEach improves test isolation. Path.delimiter for multi-dir config is also a nice cross-platform touch.
test/2-config-test.js (1)
4-5: Nice migration to node:test and requireUncached harness.Test structure is much clearer than the old Vows topics/batches and isolates lib loads well. Solid coverage retained across formats and features.
Also workaround for nodejs/node#59364
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (2)
test/1-protected-test.js (1)
839-853: This test doesn’t call toObject; assert the serialization of the provided argument.The test name implies validating
toObjecton an input, but it only comparesconfig.get('Customers')to a literal. CalltoObjectand compare against a canonical POJO to exercise the code under test.-it('Returns a serialized version of whatever argument is provided', function() { - assert.notDeepStrictEqual(config.get('Customers'), { - dbHost: 'base', - dbName: 'from_default_json', - dbPort: 5999, - dbString: 'from_default_json:5999', - random: 0.08624527123827352, - dbPassword: 'real password', - dbPassword2: 'another password', - lang: ['en','de','es'], - altDbPort: 4400, - altDbPort1: 2209, - emptySub: null - }); - }); +it('Returns a serialized version of whatever argument is provided', function() { + const customers = config.get('Customers'); + const expected = JSON.parse(JSON.stringify(customers)); + assert.deepStrictEqual(config.util.toObject(customers), expected); + });test/10-gitcrypt-test.js (1)
41-56: Ensure the error-path test uses the encrypted fixtures (missing NODE_CONFIG_DIR).This block doesn’t set
NODE_CONFIG_DIR, so it may load default configs and not exercise the encrypted files. Set the directory and clear interfering overrides before requiring config.describe('initialization with encrypted files without CONFIG_SKIP_GITCRYPT', function() { it('An exception is thrown if CONFIG_SKIP_GITCRYPT is not set', function() { // Hard-code $NODE_ENV=encrypted for testing process.env.NODE_ENV='encrypted'; + // Ensure we use the encrypted test fixtures and no other overrides interfere + process.env.NODE_CONFIG_DIR = __dirname + '/10-config'; + delete process.env.NODE_APP_INSTANCE; + delete process.env["NODE_CONFIG"]; + process.argv = []; + // Test Environment Variable Substitution process.env.CONFIG_SKIP_GITCRYPT = 0; delete process.env["CONFIG_SKIP_GITCRYPT"]; assert.throws( function () { let config = requireUncached(__dirname + '/../lib/config'); }, /Cannot parse config file/ ); }); });
♻️ Duplicate comments (9)
test/5-getConfigSources.js (2)
20-20: Fix CLI argument quoting for --NODE_CONFIG (currently a parse error).Passing
'{}'preserves quotes and will cause JSON parsing to fail. This means the CLI override isn’t actually being tested.- process.argv = ["node","path/to/some.js","--NODE_CONFIG='{}'"]; //TODO: This is a parse error so not testing the right thing + process.argv = ["node", "path/to/some.js", "--NODE_CONFIG={}"];
31-34: Indexing bug: verify the last two overrides instead of fixed positions.The env/CLI entries should be at the end, not at fixed indices. Using tail indices is more robust.
- it("The environment variable and command line args are the last two overrides", function () { - assert.equal(sources[2].name,'$NODE_CONFIG'); - assert.equal(sources[3].name,"--NODE_CONFIG argument"); - }); + it("The environment variable and command line args are the last two overrides", function () { + assert.equal(sources[sources.length - 2].name, '$NODE_CONFIG'); + assert.equal(sources[sources.length - 1].name, '--NODE_CONFIG argument'); + });test/2-config-test.js (5)
183-185: Initialize $NODE_CONFIG explicitly in this suite to remove cross-suite dependency.This suite currently relies on env state set elsewhere. Set NODE_CONFIG and clear argv locally before requiring config.
- config = requireUncached(__dirname + '/../lib/config'); + process.env.NODE_CONFIG = '{"EnvOverride":{"parm3":"overridden from $NODE_CONFIG","parm4":100}}'; + process.argv = []; + config = requireUncached(__dirname + '/../lib/config');
199-201: Initialize --NODE_CONFIG via argv explicitly and clear conflicting env.Provide the CLI arg directly and ensure $NODE_CONFIG isn’t also set for deterministic behavior.
- config = requireUncached(__dirname + '/../lib/config'); + delete process.env.NODE_CONFIG; + process.argv = ['node', 'test.js', '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}']; + config = requireUncached(__dirname + '/../lib/config');
215-217: Set custom env vars locally in this suite for determinism.Avoid depending on env set by other suites. Define required vars here so the suite is order-independent.
- config = requireUncached(__dirname + '/../lib/config'); + process.env.CUSTOM_JSON_ENVIRONMENT_VAR = 'CUSTOM VALUE FROM JSON ENV MAPPING'; + process.env.CUSTOM_BOOLEAN_TRUE_ENVIRONMENT_VAR = 'true'; + process.env.CUSTOM_BOOLEAN_FALSE_ENVIRONMENT_VAR = 'false'; + process.env.CUSTOM_BOOLEAN_ERROR_ENVIRONMENT_VAR = 'notProperBoolean'; + process.env.CUSTOM_NUMBER_INTEGER_ENVIRONMENT_VAR = '1001'; + process.env.CUSTOM_NUMBER_FLOAT_ENVIRONMENT_VAR = '3.14'; + process.env.CUSTOM_NUMBER_EMPTY_ENVIRONMENT_VAR = ''; + process.env.CUSTOM_NUMBER_STRING_ENVIRONMENT_VAR = 'String'; + process.argv = []; + config = requireUncached(__dirname + '/../lib/config');
578-580: Same argv pollution here: assign argv instead of pushing.Mirror the earlier fix to avoid accumulating CLI flags across tests.
- process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'); + process.argv = ['node', 'test.js', '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'];
569-570: Windows compatibility: use path.delimiter when composing NODE_CONFIG_DIR.Hardcoding “:” breaks on Windows. Use the platform delimiter.
- process.env.NODE_CONFIG_DIR = __dirname + '/config:' + __dirname + '/x-config'; + process.env.NODE_CONFIG_DIR = [__dirname + '/config', __dirname + '/x-config'].join(require('path').delimiter);test/12-node_env-override.js (2)
25-27: Fix test bug: parameter shadows suite’s config variable (asserting the TestContext).The parameter named config shadows the suite variable; the assertion is not validating the loaded config.
- it('Library is available', function (config) { - assert.strictEqual(typeof config, 'object'); - }); + it('Library is available', function () { + assert.strictEqual(typeof config, 'object'); + });
79-82: Fix teardown: delete NODE_CONFIG_ENV, not NODE_ENV.This suite sets NODE_CONFIG_ENV only. Deleting NODE_ENV here is a no-op and leaks NODE_CONFIG_ENV into following tests.
- after(function () { - delete process.env.NODE_ENV; - }); + after(function () { + delete process.env.NODE_CONFIG_ENV; + });
🧹 Nitpick comments (22)
test/8-config-extending.js (3)
5-5: Remove unusedbeforeEachimport
beforeEachisn’t used in this file.-const { describe, it, beforeEach } = require('node:test'); +const { describe, it } = require('node:test');
25-26: Avoid redundant env reassignment and usepath.joinfor portability
- The reassignment of
NODE_CONFIG_DIRinside the test is redundant given the top-level setup.- Prefer
path.joinover manual concatenation for cross-platform correctness.- process.env.NODE_CONFIG_DIR = __dirname + '/8-config'; - var base_config = require(process.env.NODE_CONFIG_DIR + path.sep + 'base-config.json'); + const base_config = require(path.join(process.env.NODE_CONFIG_DIR, 'base-config.json'));
29-31: Remove unused variable in assertion block
resultis unused. Just invokeUtil.extendDeepto assert it doesn’t throw.- assert.doesNotThrow(function () { - let result = Util.extendDeep(base_config, CONFIG); - }, 'Extending a configuration with another configuration has an error'); + assert.doesNotThrow(function () { + Util.extendDeep(base_config, CONFIG); + }, 'Extending a configuration with another configuration has an error');test/20-multiple-config.js (2)
5-5: ImportafterEachand use the hooks to restoreNODE_CONFIG_DIRYou already import
beforeEachbut don’t use it. AddafterEachand use both to snapshot/restoreNODE_CONFIG_DIRto minimize cross-file interference during parallel execution.-const { describe, it, beforeEach } = require('node:test'); +const { describe, it, beforeEach, afterEach } = require('node:test');
8-9: Snapshot/restore env per scenario to reduce flakinessWrap scenarios with
beforeEach/afterEachto restoreNODE_CONFIG_DIRafter each test run.describe('Tests for multiple config', function() { + let originalConfigDir; + beforeEach(() => { + originalConfigDir = process.env.NODE_CONFIG_DIR; + }); + afterEach(() => { + process.env.NODE_CONFIG_DIR = originalConfigDir; + });test/4-array-merging.js (3)
4-4: Remove unusedbefore/beforeEachimportsThey’re not used in this file.
-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it } = require('node:test');
27-27: Tighten the suite titleMinor wording cleanup.
- describe('Array merging tests Tests', function() { + describe('Array merging tests', function() {
29-29: PreferdeepStrictEqualoverdeepEqualUse the strict variant for clearer intent in assertions.
- assert.deepEqual(CONFIG.arrayMerging.emptyArray, ['not empty anymore']); + assert.deepStrictEqual(CONFIG.arrayMerging.emptyArray, ['not empty anymore']);- assert.deepEqual(CONFIG.arrayMerging.oneItem, ['replaced']); + assert.deepStrictEqual(CONFIG.arrayMerging.oneItem, ['replaced']);- assert.deepEqual(CONFIG.arrayMerging.removeMe, []); + assert.deepStrictEqual(CONFIG.arrayMerging.removeMe, []);Also applies to: 33-33, 37-37
test/9-raw-configs.js (3)
8-8: Remove unusedbefore/beforeEachimportsThey’re not used in this file.
-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it } = require('node:test');
16-16: UsestrictEqualfor reference equality checksFor object/stream identity checks,
strictEqualcommunicates the intent explicitly. While==and===behave the same for objects,strictEqualis clearer.- assert.equal(CONFIG.get('circularReference'), process.stdout); + assert.strictEqual(CONFIG.get('circularReference'), process.stdout);- assert.equal(CONFIG.get('innerRaw').innerCircularReference, process.stdout); - assert.equal(CONFIG.get('innerRaw.innerCircularReference'), process.stdout); + assert.strictEqual(CONFIG.get('innerRaw').innerCircularReference, process.stdout); + assert.strictEqual(CONFIG.get('innerRaw.innerCircularReference'), process.stdout);- assert.equal(CONFIG.get('nestedRaw').nested.test, process.stdout); - assert.equal(CONFIG.get('nestedRaw.nested').test, process.stdout); - assert.equal(CONFIG.get('nestedRaw.nested.test'), process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw').nested.test, process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw.nested').test, process.stdout); + assert.strictEqual(CONFIG.get('nestedRaw.nested.test'), process.stdout);Also applies to: 22-23, 27-29
11-12: Note on top-level load and env mutationsCONFIG is loaded at module import time based on top-level env setup. This can interact poorly with parallel test execution in Node’s test runner. If you see flakiness on Node 22.18+, consider moving env setup +
requireUncachedinto abeforeEachand restoring afterward.test/x-config-test-ts-module-exports.js (1)
21-24: Clear env by deleting keys rather than setting empty stringsUsing empty strings can carry ambiguous semantics in downstream code. Deleting is closer to “unset.”
- process.env.NODE_APP_INSTANCE = ''; - process.env.NODE_ENV = ''; - process.env.NODE_CONFIG = ''; + delete process.env.NODE_APP_INSTANCE; + delete process.env.NODE_ENV; + delete process.env.NODE_CONFIG;test/1-protected-test.js (2)
14-14: Avoid mutating the saved argv reference; copy it instead to prevent coupling.Storing
process.argvby reference means later mutations (push/assign) also mutateargvOrg. Save a shallow copy so you can reliably restore it later.-const argvOrg = process.argv; +const argvOrg = process.argv.slice();
819-823: Restore argv robustly using deep equality and a fresh copy.This test currently checks identity and assigns the same array reference back. Prefer deepStrictEqual and assign a copy to avoid reusing the same array object.
-it('Revert original process arguments', function() { - assert.notEqual(process.argv, argvOrg); - process.argv = argvOrg; - assert.equal(process.argv, argvOrg); - }); +it('Revert original process arguments', function() { + assert.notDeepStrictEqual(process.argv, argvOrg); + process.argv = argvOrg.slice(); + assert.deepStrictEqual(process.argv, argvOrg); + });test/13-node_env-hostname.js (2)
35-37: Prefer strict assertions for string equality.Use
strictEqualto avoid type coercion in assertions.- it('HOSTNAME env variable is the winner', function() { - assert.equal(config.util.getEnv('HOSTNAME'), 'some.machine'); - }); + it('HOSTNAME env variable is the winner', function() { + assert.strictEqual(config.util.getEnv('HOSTNAME'), 'some.machine'); + });
51-53: Prefer strict assertions for string equality.Use
strictEqualto avoid type coercion in assertions.- it('HOST env variable is the winner', function() { - assert.strictEqual(config.util.getEnv('HOSTNAME'), 'other.machine'); - }); + it('HOST env variable is the winner', function() { + assert.strictEqual(config.util.getEnv('HOSTNAME'), 'other.machine'); + });test/x-deferred-configs-ts.js (2)
20-20: Use const instead of var for module-level CONFIG.The reference isn’t reassigned; prefer
const.-var CONFIG = requireUncached(__dirname + '/../lib/config'); +const CONFIG = requireUncached(__dirname + '/../lib/config');
49-51: Prefer strict equality against undefined.Use
strictEqualto avoid coercion.- it("second defer function return original value.", function () { - assert.equal(CONFIG.original.deferredOriginal, undefined); - }); + it("second defer function return original value.", function () { + assert.strictEqual(CONFIG.original.deferredOriginal, undefined); + });test/5-getConfigSources.js (2)
27-29: Update test description to match the expected count.The assertion expects 6 entries; fix the description to avoid confusion.
- it('Two files plus NODE_CONFIG in env and as command line args should result in four entries', function() { + it('Two config dirs plus NODE_CONFIG in env and as command line args should result in six entries', function() { assert.equal(sources.length,6); });
105-107: Update test description to match the expected count.The test asserts 4 entries; fix the description to say four.
- it('Three files should result in 3 entries', function() { + it('Four files should result in 4 entries', function() { assert.equal(sources.length,4); });test/2-config-test.js (2)
31-33: Avoid argv pollution: assign argv instead of pushing.Pushing accumulates flags across tests and can create order-dependent failures. Set argv deterministically for this suite.
- process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'); + process.argv = ['node', 'test.js', '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'];
43-45: Prefer string literals for process.env values for clarity.process.env coerces non-strings to strings anyway. Using strings makes the intent explicit and avoids surprises with type coercion.
- process.env.CUSTOM_NUMBER_INTEGER_ENVIRONMENT_VAR = 1001; - process.env.CUSTOM_NUMBER_FLOAT_ENVIRONMENT_VAR = 3.14; + process.env.CUSTOM_NUMBER_INTEGER_ENVIRONMENT_VAR = '1001'; + process.env.CUSTOM_NUMBER_FLOAT_ENVIRONMENT_VAR = '3.14';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (32)
package.json(1 hunks)test/0-util.js(1 hunks)test/1-protected-test.js(8 hunks)test/10-gitcrypt-test.js(3 hunks)test/11-regexp.js(1 hunks)test/12-node_env-override.js(1 hunks)test/13-node_env-hostname.js(1 hunks)test/14-node_env-load-multiple-files.js(1 hunks)test/15-async-configs.js(2 hunks)test/16-custom-parser.js(1 hunks)test/17-toml.js(2 hunks)test/18-skipConfigSources.js(1 hunks)test/19-custom-environment-variables.js(1 hunks)test/2-config-test.js(4 hunks)test/20-multiple-config.js(6 hunks)test/21-date.js(1 hunks)test/22-binary.js(1 hunks)test/22-files-order.js(3 hunks)test/23-serialize.js(1 hunks)test/3-deferred-configs.js(2 hunks)test/4-array-merging.js(2 hunks)test/5-getConfigSources.js(3 hunks)test/6-strict-mode.js(2 hunks)test/7-unicode-situations.js(2 hunks)test/8-config-extending.js(2 hunks)test/9-raw-configs.js(1 hunks)test/makeImmutable-shared-refs.js(1 hunks)test/util.js(1 hunks)test/x-config-js-test-transpiled.js(2 hunks)test/x-config-test-ts-module-exports.js(2 hunks)test/x-config-test-ts.js(2 hunks)test/x-deferred-configs-ts.js(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (20)
- test/23-serialize.js
- test/19-custom-environment-variables.js
- test/17-toml.js
- test/16-custom-parser.js
- package.json
- test/0-util.js
- test/18-skipConfigSources.js
- test/6-strict-mode.js
- test/x-config-js-test-transpiled.js
- test/7-unicode-situations.js
- test/3-deferred-configs.js
- test/makeImmutable-shared-refs.js
- test/x-config-test-ts.js
- test/14-node_env-load-multiple-files.js
- test/22-files-order.js
- test/15-async-configs.js
- test/11-regexp.js
- test/util.js
- test/21-date.js
- test/22-binary.js
🧰 Additional context used
🧬 Code Graph Analysis (10)
test/13-node_env-hostname.js (4)
test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/1-protected-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)lib/config.js (2)
require(8-8)config(1030-1030)
test/8-config-extending.js (2)
lib/config.js (2)
path(213-213)require(8-8)test/0-util.js (5)
require(7-7)result(413-413)result(418-418)result(500-500)result(510-510)
test/4-array-merging.js (3)
test/6-strict-mode.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/2-config-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/9-raw-configs.js (4)
requireUncached(7-7)require(8-8)assert(9-9)CONFIG(11-11)
test/1-protected-test.js (2)
test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)lib/config.js (3)
require(8-8)config(1030-1030)diff(815-815)
test/20-multiple-config.js (1)
test/16-custom-parser.js (3)
require(4-4)requireUncached(3-3)assert(5-5)
test/5-getConfigSources.js (15)
test/19-custom-environment-variables.js (4)
Path(3-3)require(5-5)requireUncached(4-4)assert(6-6)lib/config.js (4)
Path(9-9)require(8-8)sources(978-978)config(1030-1030)test/6-strict-mode.js (3)
require(4-4)requireUncached(3-3)assert(5-5)test/12-node_env-override.js (4)
require(4-4)requireUncached(3-3)assert(5-5)config(11-11)test/2-config-test.js (16)
require(4-4)requireUncached(3-3)assert(5-5)config(18-18)config(61-61)config(138-138)config(181-181)config(197-197)config(213-213)config(261-261)config(294-294)config(316-316)config(344-344)config(418-418)config(467-467)config(565-565)test/makeImmutable-shared-refs.js (2)
require(3-3)assert(4-4)test/3-deferred-configs.js (3)
require(4-4)requireUncached(3-3)assert(5-5)test/10-gitcrypt-test.js (3)
require(4-4)requireUncached(3-3)assert(5-5)test/1-protected-test.js (4)
require(4-4)requireUncached(3-3)assert(5-5)config(30-30)test/x-config-test-ts.js (3)
require(4-4)requireUncached(3-3)assert(5-5)test/4-array-merging.js (3)
require(4-4)requireUncached(3-3)assert(5-5)test/7-unicode-situations.js (3)
require(5-5)requireUncached(4-4)assert(6-6)test/x-deferred-configs-ts.js (3)
require(6-6)requireUncached(5-5)assert(7-7)test/8-config-extending.js (4)
require(5-5)require(7-7)requireUncached(4-4)assert(6-6)test/9-raw-configs.js (3)
require(8-8)requireUncached(7-7)assert(9-9)
test/2-config-test.js (1)
test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)
test/12-node_env-override.js (4)
test/5-getConfigSources.js (6)
requireUncached(4-4)require(5-5)assert(6-6)config(22-22)config(76-76)config(101-101)test/19-custom-environment-variables.js (6)
requireUncached(4-4)require(5-5)assert(6-6)config(10-10)config(30-30)config(50-50)test/makeImmutable-shared-refs.js (2)
require(3-3)assert(4-4)lib/config.js (2)
require(8-8)config(1030-1030)
test/x-config-test-ts-module-exports.js (6)
test/10-gitcrypt-test.js (5)
requireUncached(3-3)require(4-4)assert(5-5)config(9-9)config(51-51)test/14-node_env-load-multiple-files.js (6)
requireUncached(3-3)require(4-4)assert(5-5)config(9-9)config(30-30)config(47-47)test/x-config-test-ts.js (5)
requireUncached(3-3)require(4-4)assert(5-5)config(17-17)config(51-51)test/15-async-configs.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(26-26)test/x-deferred-configs-ts.js (3)
requireUncached(5-5)require(6-6)assert(7-7)lib/config.js (2)
require(8-8)config(1030-1030)
test/x-deferred-configs-ts.js (2)
test/2-config-test.js (1)
require(4-4)lib/config.js (1)
require(8-8)
🔇 Additional comments (4)
test/20-multiple-config.js (1)
9-19: LGTM on the migration and scenariosThe scenarios (relative, absolute, mixed, and empty string) correctly cover the previous Vows intent, and
requireUncachedusage withinassert.doesNotThrowis appropriate.Also applies to: 21-31, 33-42, 44-53, 55-65
test/x-config-test-ts-module-exports.js (1)
16-45: Overall migration looks solidGood use of
beforeEachfor per-test setup,requireUncachedfor isolation, and strict assertions. This aligns with the suite-wide move off Vows.test/12-node_env-override.js (2)
3-5: LGTM on harness migration.Switch to node:test and requireUncached is clean and consistent with the rest of the PR.
104-108: LGTM on final teardown.Cleaning NODE_CONFIG_DIR, NODE_CONFIG_ENV, and NODE_ENV at the end is good hygiene.
423555a to
d7203e2
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🔭 Outside diff range comments (5)
test/20-multiple-config.js (5)
8-19: Assertions run during describe() registration instead of in testsThe assert.doesNotThrow call runs at suite definition time, not inside an it(), so it won't be reported as a proper test. Wrap it in an it() and restore env after.
describe('Adding multiple relative configuration paths should work without error', function () { - process.env.NODE_CONFIG_DIR = [ - './test/20-config', - './test/20-extra-config', - ].join(path.delimiter) - - assert.doesNotThrow(function () { - const CONFIG = requireUncached(__dirname + '/../lib/config'); - }, 'Adding multiple relative configuration paths has an error'); + it('does not throw when using multiple relative paths', function () { + const prev = process.env.NODE_CONFIG_DIR; + try { + process.env.NODE_CONFIG_DIR = [ + './test/20-config', + './test/20-extra-config', + ].join(path.delimiter); + assert.doesNotThrow(function () { + const CONFIG = requireUncached(__dirname + '/../lib/config'); + }, 'Adding multiple relative configuration paths has an error'); + } finally { + if (prev === undefined) delete process.env.NODE_CONFIG_DIR; + else process.env.NODE_CONFIG_DIR = prev; + } + }); });
21-31: Same issue: wrap in it() and restore env (absolute paths case)This block has the same problem as above.
describe('Adding multiple absolute configuration paths should work without error', function () { - process.env.NODE_CONFIG_DIR = [ - __dirname + '/20-config', - __dirname + '/20-extra-config', - ].join(path.delimiter) - - assert.doesNotThrow(function () { - const CONFIG = requireUncached(__dirname + '/../lib/config'); - }, 'Adding multiple absolute configuration paths has an error'); + it('does not throw when using multiple absolute paths', function () { + const prev = process.env.NODE_CONFIG_DIR; + try { + process.env.NODE_CONFIG_DIR = [ + __dirname + '/20-config', + __dirname + '/20-extra-config', + ].join(path.delimiter); + assert.doesNotThrow(function () { + const CONFIG = requireUncached(__dirname + '/../lib/config'); + }, 'Adding multiple absolute configuration paths has an error'); + } finally { + if (prev === undefined) delete process.env.NODE_CONFIG_DIR; + else process.env.NODE_CONFIG_DIR = prev; + } + }); });
33-42: Same issue: wrap in it() and restore env (absolute + relative paths)This block has the same problem as above.
describe('Adding one absolute and one relative configuration paths should work without error', function () { - process.env.NODE_CONFIG_DIR = [ - __dirname + '/20-config', - './test/20-extra-config', - ].join(path.delimiter) - - assert.doesNotThrow(function () { - const CONFIG = requireUncached(__dirname + '/../lib/config'); - }, 'Adding one absolute and one relative configuration paths has an error'); + it('does not throw when using absolute + relative paths', function () { + const prev = process.env.NODE_CONFIG_DIR; + try { + process.env.NODE_CONFIG_DIR = [ + __dirname + '/20-config', + './test/20-extra-config', + ].join(path.delimiter); + assert.doesNotThrow(function () { + const CONFIG = requireUncached(__dirname + '/../lib/config'); + }, 'Adding one absolute and one relative configuration paths has an error'); + } finally { + if (prev === undefined) delete process.env.NODE_CONFIG_DIR; + else process.env.NODE_CONFIG_DIR = prev; + } + }); });
44-53: Same issue: wrap in it() and restore env (relative + absolute paths)This block has the same problem as above.
describe('Adding one relative and one absolute configuration paths should work without error', function () { - process.env.NODE_CONFIG_DIR = [ - './test/20-config', - __dirname + '/20-extra-config', - ].join(path.delimiter) - - assert.doesNotThrow(function () { - const CONFIG = requireUncached(__dirname + '/../lib/config'); - }, 'Adding one relative and one absolute configuration paths has an error'); + it('does not throw when using relative + absolute paths', function () { + const prev = process.env.NODE_CONFIG_DIR; + try { + process.env.NODE_CONFIG_DIR = [ + './test/20-config', + __dirname + '/20-extra-config', + ].join(path.delimiter); + assert.doesNotThrow(function () { + const CONFIG = requireUncached(__dirname + '/../lib/config'); + }, 'Adding one relative and one absolute configuration paths has an error'); + } finally { + if (prev === undefined) delete process.env.NODE_CONFIG_DIR; + else process.env.NODE_CONFIG_DIR = prev; + } + }); });
55-64: Same issue: wrap in it() and restore env (empty string case)This block has the same problem as above.
describe('Empty string should not blow up', function () { - process.env.NODE_CONFIG_DIR = [ - './test/20-config', - '' - ].join(path.delimiter) - - assert.doesNotThrow(function () { - const CONFIG = requireUncached(__dirname + '/../lib/config'); - }, 'Adding an empty string does not result in an error'); + it('does not throw when one path is empty', function () { + const prev = process.env.NODE_CONFIG_DIR; + try { + process.env.NODE_CONFIG_DIR = [ + './test/20-config', + '' + ].join(path.delimiter); + assert.doesNotThrow(function () { + const CONFIG = requireUncached(__dirname + '/../lib/config'); + }, 'Adding an empty string does not result in an error'); + } finally { + if (prev === undefined) delete process.env.NODE_CONFIG_DIR; + else process.env.NODE_CONFIG_DIR = prev; + } + }); });
♻️ Duplicate comments (5)
test/2-config-test.js (5)
215-217: Define custom env vars locally for determinismAvoid relying on values from the “Library initialization” block; set only what this suite needs.
beforeEach(function() { - config = requireUncached(__dirname + '/../lib/config'); + process.env.CUSTOM_JSON_ENVIRONMENT_VAR = 'CUSTOM VALUE FROM JSON ENV MAPPING'; + process.env.CUSTOM_BOOLEAN_TRUE_ENVIRONMENT_VAR = 'true'; + process.env.CUSTOM_BOOLEAN_FALSE_ENVIRONMENT_VAR = 'false'; + process.env.CUSTOM_BOOLEAN_ERROR_ENVIRONMENT_VAR = 'notProperBoolean'; + process.env.CUSTOM_NUMBER_INTEGER_ENVIRONMENT_VAR = '1001'; + process.env.CUSTOM_NUMBER_FLOAT_ENVIRONMENT_VAR = '3.14'; + process.env.CUSTOM_NUMBER_EMPTY_ENVIRONMENT_VAR = ''; + process.env.CUSTOM_NUMBER_STRING_ENVIRONMENT_VAR = 'String'; + process.argv = [process.argv[0], process.argv[1]]; + config = requireUncached(__dirname + '/../lib/config'); });
183-201: Make this suite self-contained: initialize NODE_CONFIG/argv locallyThese tests currently rely on prior suites having set NODE_CONFIG/argv. Initialize them here to remove order dependence and flakiness.
beforeEach(function() { - config = requireUncached(__dirname + '/../lib/config'); + // isolate from other suites + delete process.env.NODE_APP_INSTANCE; + process.env.NODE_CONFIG='{"EnvOverride":{"parm3":"overridden from $NODE_CONFIG","parm4":100}}'; + process.argv = [process.argv[0], process.argv[1]]; + config = requireUncached(__dirname + '/../lib/config'); });Optionally add an afterEach to restore original env/argv.
199-201: Initialize CLI override explicitly and clear conflicting envEnsure this suite covers CLI precedence deterministically by setting argv and unsetting NODE_CONFIG before require.
beforeEach(function() { - config = requireUncached(__dirname + '/../lib/config'); + delete process.env.NODE_CONFIG; + process.argv = [process.argv[0], process.argv[1], '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}']; + config = requireUncached(__dirname + '/../lib/config'); });
569-570: Windows compatibility: use path.delimiter when composing NODE_CONFIG_DIRHardcoding ":" breaks on Windows. Join with the platform-specific delimiter.
- process.env.NODE_CONFIG_DIR = __dirname + '/config:' + __dirname + '/x-config'; + process.env.NODE_CONFIG_DIR = [__dirname + '/config', __dirname + '/x-config'].join(require('path').delimiter);
578-580: Avoid accumulating CLI flags: assign argv instead of pushingpush will append on each beforeEach call, leaking state across tests. Reset argv explicitly.
- process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'); + process.argv = [process.argv[0], process.argv[1], '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'];
🧹 Nitpick comments (9)
test/17-toml.js (1)
4-4: Prevent env leakage: restore NODE_CONFIG_DIR after each testThe suite sets NODE_CONFIG_DIR in beforeEach but never restores it. Since node:test runs in a single process, this can bleed into other files. Add afterEach to restore the previous value.
-const { describe, it, beforeEach } = require('node:test'); +const { describe, it, beforeEach, afterEach } = require('node:test'); @@ - let config; - beforeEach(function() { - process.env.NODE_CONFIG_DIR = __dirname + '/17-config'; - config = requireUncached(__dirname + '/../lib/config'); - }); + let config; + let prevConfigDir; + beforeEach(function() { + prevConfigDir = process.env.NODE_CONFIG_DIR; + process.env.NODE_CONFIG_DIR = __dirname + '/17-config'; + config = requireUncached(__dirname + '/../lib/config'); + }); + afterEach(function() { + if (prevConfigDir === undefined) { + delete process.env.NODE_CONFIG_DIR; + } else { + process.env.NODE_CONFIG_DIR = prevConfigDir; + } + });Also applies to: 10-14
test/0-util.js (2)
71-73: Correct malformed array element in isPromise() negative test cases“1.1” followed by “- 1,” becomes a single expression (1.1 - 1). The intention appears to be two separate elements: 1.1 and -1. Fixing improves clarity and avoids accidental arithmetic.
- 1.1 - - 1, + 1.1, + -1,
245-249: Consider deepStrictEqual over deepEqual for type-safe comparisonsMany assertions use deepEqual; switching to deepStrictEqual avoids loose equality pitfalls and aligns with the modern assert style you’re using elsewhere in this PR. Not mandatory if types are already controlled, but improves robustness.
Also applies to: 253-254, 266-270, 298-299, 305-306, 313-314, 321-322, 333-334, 343-345, 353-354, 678-679, 693-695, 827-829, 834-835, 885-889, 908-913, 923-931, 951-955
test/13-node_env-hostname.js (1)
24-34: Optionally clean up HOST/HOSTNAME after each testMinor but safer: add afterEach blocks to remove or restore env vars to reduce risk of leakage across files.
-const { describe, it, before, beforeEach } = require('node:test'); +const { describe, it, before, beforeEach, afterEach } = require('node:test'); @@ describe('When HOSTNAME env is set', function() { let config; beforeEach(function() { // Test HOST and HOSTNAME delete process.env.HOST; process.env.HOSTNAME = 'some.machine'; config = requireUncached(__dirname + '/../lib/config'); }); + afterEach(function () { + delete process.env.HOSTNAME; + }); @@ describe('When HOST env is set', function() { let config; beforeEach(function() { // Test HOST and HOSTNAME delete process.env.HOSTNAME; process.env.HOST = 'other.machine'; config = requireUncached(__dirname + '/../lib/config'); }); + afterEach(function () { + delete process.env.HOST; + });Also applies to: 40-50
test/x-deferred-configs-ts.js (1)
28-29: Prefer strict assertion variants (strictEqual/deepStrictEqual)To match the rest of the migration and avoid loose equality, switch to strict forms.
- assert.equal(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!'); + assert.strictEqual(CONFIG.welcomeEmail.subject, 'Welcome to New Instance!'); @@ - assert.equal(CONFIG.welcomeEmail.aFunc(), 'Still just a function.'); + assert.strictEqual(CONFIG.welcomeEmail.aFunc(), 'Still just a function.'); @@ - assert.equal(CONFIG.welcomeEmail.justThis, 'Welcome to this New Instance!'); + assert.strictEqual(CONFIG.welcomeEmail.justThis, 'Welcome to this New Instance!'); @@ - assert.deepEqual(CONFIG.get('map.centerPoint'), { lat: 3, lon: 4 }); + assert.deepStrictEqual(CONFIG.get('map.centerPoint'), { lat: 3, lon: 4 }); @@ - assert.equal(CONFIG.original.original, 'an original value'); + assert.strictEqual(CONFIG.original.original, 'an original value'); @@ - assert.equal(CONFIG.original.deferredOriginal, undefined); + assert.strictEqual(CONFIG.original.deferredOriginal, undefined);Also applies to: 32-34, 37-39, 41-43, 45-47, 49-51
test/6-strict-mode.js (1)
95-99: Remove unused variable assignment to avoid lint noiseconfig is not used; require for side effects is sufficient.
- let config = requireUncached(__dirname + '/../lib/config'); + requireUncached(__dirname + '/../lib/config');test/util.js (1)
21-41: Stabilize initParam tests by restoring argv/env after each testThese tests mutate process.argv and process.env without restoration, which can leak into subsequent tests in this file. Add an afterEach to restore prior state.
Example (outside the shown range; adjust imports accordingly):
// add to imports: const { afterEach } = require('node:test'); const argvBackup = process.argv.slice(); const envBackup = { ...process.env }; afterEach(() => { process.argv = argvBackup.slice(); process.env = { ...envBackup }; });test/16-custom-parser.js (1)
82-85: Remove unused parameter from after() hooktopic isn’t used; drop the param for clarity.
- after(function (topic) { + after(function () { delete process.env.NODE_CONFIG_PARSER; requireUncached(__dirname + '/../parser'); });test/2-config-test.js (1)
32-33: Use realistic argv entries instead of undefined placeholdersSome code may read process.argv[0]/[1]; use actual entries or previous values.
- process.argv = [undefined, undefined, '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}']; + process.argv = [process.argv[0], process.argv[1], '--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'];
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (32)
package.json(1 hunks)test/0-util.js(1 hunks)test/1-protected-test.js(8 hunks)test/10-gitcrypt-test.js(3 hunks)test/11-regexp.js(1 hunks)test/12-node_env-override.js(1 hunks)test/13-node_env-hostname.js(1 hunks)test/14-node_env-load-multiple-files.js(1 hunks)test/15-async-configs.js(2 hunks)test/16-custom-parser.js(1 hunks)test/17-toml.js(2 hunks)test/18-skipConfigSources.js(1 hunks)test/19-custom-environment-variables.js(1 hunks)test/2-config-test.js(4 hunks)test/20-multiple-config.js(6 hunks)test/21-date.js(1 hunks)test/22-binary.js(1 hunks)test/22-files-order.js(3 hunks)test/23-serialize.js(1 hunks)test/3-deferred-configs.js(2 hunks)test/4-array-merging.js(2 hunks)test/5-getConfigSources.js(2 hunks)test/6-strict-mode.js(2 hunks)test/7-unicode-situations.js(2 hunks)test/8-config-extending.js(2 hunks)test/9-raw-configs.js(1 hunks)test/makeImmutable-shared-refs.js(1 hunks)test/util.js(1 hunks)test/x-config-js-test-transpiled.js(2 hunks)test/x-config-test-ts-module-exports.js(2 hunks)test/x-config-test-ts.js(2 hunks)test/x-deferred-configs-ts.js(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
- package.json
- test/5-getConfigSources.js
- test/9-raw-configs.js
- test/10-gitcrypt-test.js
- test/4-array-merging.js
- test/22-binary.js
- test/22-files-order.js
- test/14-node_env-load-multiple-files.js
- test/makeImmutable-shared-refs.js
- test/21-date.js
- test/19-custom-environment-variables.js
- test/18-skipConfigSources.js
- test/23-serialize.js
- test/x-config-test-ts-module-exports.js
- test/x-config-test-ts.js
- test/11-regexp.js
- test/3-deferred-configs.js
- test/15-async-configs.js
- test/8-config-extending.js
- test/7-unicode-situations.js
- test/12-node_env-override.js
- test/x-config-js-test-transpiled.js
🧰 Additional context used
🧬 Code Graph Analysis (8)
test/16-custom-parser.js (1)
test/3-deferred-configs.js (2)
require(4-4)assert(5-5)
test/util.js (3)
lib/config.js (3)
require(8-8)config(1030-1030)util(114-114)test/2-config-test.js (16)
require(4-4)requireUncached(3-3)assert(5-5)config(18-18)config(61-61)config(138-138)config(181-181)config(197-197)config(213-213)config(261-261)config(294-294)config(316-316)config(344-344)config(418-418)config(467-467)config(565-565)test/1-protected-test.js (4)
require(4-4)requireUncached(3-3)assert(5-5)config(30-30)
test/13-node_env-hostname.js (10)
test/2-config-test.js (16)
requireUncached(3-3)require(4-4)assert(5-5)config(18-18)config(61-61)config(138-138)config(181-181)config(197-197)config(213-213)config(261-261)config(294-294)config(316-316)config(344-344)config(418-418)config(467-467)config(565-565)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/10-gitcrypt-test.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(9-9)test/15-async-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/4-array-merging.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/1-protected-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-deferred-configs-ts.js (3)
requireUncached(5-5)require(6-6)assert(7-7)test/7-unicode-situations.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)lib/config.js (2)
require(8-8)config(1030-1030)
test/0-util.js (3)
test/8-config-extending.js (4)
require(5-5)require(7-7)assert(6-6)result(30-30)lib/util.js (1)
Path(8-8)test/util.js (1)
testCases(94-116)
test/6-strict-mode.js (12)
test/18-skipConfigSources.js (9)
requireUncached(4-4)require(5-5)assert(6-6)config(11-11)config(36-36)config(60-60)config(94-94)config(119-119)config(144-144)test/2-config-test.js (9)
requireUncached(3-3)require(4-4)assert(5-5)config(18-18)config(61-61)config(138-138)config(181-181)config(197-197)config(213-213)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/10-gitcrypt-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-config-test-ts.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/14-node_env-load-multiple-files.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/4-array-merging.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/1-protected-test.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/x-deferred-configs-ts.js (3)
requireUncached(5-5)require(6-6)assert(7-7)test/7-unicode-situations.js (3)
requireUncached(4-4)require(5-5)assert(6-6)test/8-config-extending.js (4)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)
test/2-config-test.js (3)
test/5-getConfigSources.js (6)
requireUncached(4-4)require(5-5)assert(6-6)config(22-22)config(76-76)config(101-101)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)lib/config.js (3)
require(8-8)config(1030-1030)moduleConfig(214-214)
test/17-toml.js (5)
test/21-date.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/23-serialize.js (3)
requireUncached(5-5)require(6-6)assert(7-7)test/22-files-order.js (4)
requireUncached(3-3)require(4-4)assert(5-5)config(18-18)test/x-config-js-test-transpiled.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/9-raw-configs.js (3)
requireUncached(7-7)require(8-8)assert(9-9)
test/1-protected-test.js (4)
test/util.js (5)
requireUncached(4-4)require(5-5)assert(6-6)result(59-59)result(66-66)test/3-deferred-configs.js (3)
requireUncached(3-3)require(4-4)assert(5-5)test/8-config-extending.js (5)
requireUncached(4-4)require(5-5)require(7-7)assert(6-6)result(30-30)lib/config.js (2)
require(8-8)config(1030-1030)
🔇 Additional comments (4)
test/1-protected-test.js (1)
786-824: Nice isolation for getCmdLineArg() testsThe suite resets process.argv and restores it, making the tests deterministic. Once argvOrg is snapped (see above), this becomes fully robust.
test/6-strict-mode.js (1)
7-70: Refactor to node:test and helper shape looks goodSwitch from vows to describe/it with a properly shaped _expectException that returns a describe body is correct and should run under node:test.
test/util.js (1)
114-116: Good fix: restored intended numeric cases by adding the missing commaThe array now includes both 1.1 and -1 instead of evaluating an expression. This restores coverage.
test/16-custom-parser.js (1)
27-44: Scenario setup is clear and isolatedEach scenario sets NODE_CONFIG_DIR and NODE_CONFIG_PARSER before reloading config. Clean and deterministic.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
test/1-protected-test.js (2)
14-14: Avoid aliasing process.argv; snapshot instead to enable reliable restoreAliasing means any push/mutation to process.argv also mutates argvOrg, defeating the purpose of “original argv.”
Apply this diff:
-const argvOrg = process.argv; +const argvOrg = process.argv.slice();
42-45: Prevent argv pollution across tests: reset from snapshot each setup and then appendUsing push on process.argv causes flags to accumulate across tests. Reset from a clean snapshot every beforeEach.
- process.env.NODE_CONFIG = '{"EnvOverride":{"parm3":"overridden from $NODE_CONFIG","parm4":100}}'; - process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}'); + process.env.NODE_CONFIG = '{"EnvOverride":{"parm3":"overridden from $NODE_CONFIG","parm4":100}}'; + // Reset argv to a clean snapshot to avoid cross-test accumulation + process.argv = argvOrg.slice(); + process.argv.push('--NODE_CONFIG={"EnvOverride":{"parm5":"overridden from --NODE_CONFIG","parm6":101}}');
🧹 Nitpick comments (5)
test/1-protected-test.js (5)
25-25: Force serial execution within this file to avoid flakiness from shared global stateGiven the heavy use of process.env and process.argv, run these tests serially within the file to minimize cross-test interference.
-describe('Protected (hackable) utilities test', function() { +describe('Protected (hackable) utilities test', { concurrency: false }, function() {If you prefer to keep concurrency, ensure rigorous snapshot/restore of env and argv around every test (see next comment).
13-15: Also snapshot process.env so it can be reliably restoredThis guards against cross-file/test leakage when tests run concurrently in workers.
// Make a copy of the command line args -const argvOrg = process.argv; +const argvOrg = process.argv.slice(); +// Snapshot of the original environment to restore after tests in this file +const envOrg = { ...process.env };
49-51: Add afterEach to restore argv and targeted env vars to the original baselineRestoring avoids state leaking into subsequent tests/files. Import afterEach from node:test at the top.
config = requireUncached(__dirname + '/../lib/config'); }); +afterEach(function () { + // Restore argv to baseline snapshot + process.argv = argvOrg.slice(); + + // Restore only the env keys this file mutates + const touched = [ + 'NODE_CONFIG_DIR', + 'NODE_ENV', + 'NODE_APP_INSTANCE', + 'NODE_CONFIG', + 'CUSTOM_JSON_ENVIRONMENT_VAR', + ]; + for (const k of touched) { + if (envOrg[k] === undefined) { + delete process.env[k]; + } else { + process.env[k] = envOrg[k]; + } + } +});And update the import:
-const { describe, it, beforeEach } = require('node:test'); +const { describe, it, beforeEach, afterEach } = require('node:test');
819-823: Fix “revert original process arguments” to avoid re-aliasing and assert by valueAssigning process.argv = argvOrg reintroduces aliasing. Restore from a copy and assert deep equality of contents instead of identity.
- assert.notEqual(process.argv, argvOrg); - process.argv = argvOrg; - assert.equal(process.argv, argvOrg); + assert.notStrictEqual(process.argv, argvOrg); + process.argv = argvOrg.slice(); + assert.deepStrictEqual(process.argv, argvOrg);
4-5: Consider adopting assert.strict APIs for consistency and stronger checks*Using assert.equal/deepEqual can hide subtle coercion issues; assert.strictEqual/deepStrictEqual is preferable. This can be a follow-up codemod across the suite.
If you want, I can generate a codemod script to replace equal/notEqual/deepEqual with their strict counterparts across test files.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
package.json(1 hunks)test/1-protected-test.js(8 hunks)test/2-config-test.js(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- test/2-config-test.js
- package.json
🔇 Additional comments (1)
test/1-protected-test.js (1)
1-6: Migration to node:test looks good overallNice cleanup moving off Vows, keeping tests focused on config.util behavior and requiring the module under test per-setup to avoid require-time side effects.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
markstos
left a comment
There was a problem hiding this comment.
Thanks!
Glad to see vows go.
|
I was surprised it was a block on ESM progress. Kinda wish I’d found a better way to do the transformation. This was all grunt work. |
This is prep work for ESM conversion.
Vows tries to use the module.exports to find tests, and in the process it generates some very, very strange errors when you go from require -> import -> require, which I don't think nodejs quite knows how to do yet.
This fixes #807, #852, #853, and should unblock #846
This will however mess up #845 which I will have to rebase and fix
Summary by CodeRabbit
Tests
Chores