From 68116c3a7c72a7d00561ba8a56ea045d9d327a6e Mon Sep 17 00:00:00 2001 From: Lellansin Date: Fri, 27 Mar 2026 12:49:20 +0800 Subject: [PATCH] util: honor breakLength Infinity with unlimited depth Preserve single-line formatting for util.inspect() when breakLength is Infinity and depth is unlimited, while keeping explicit compact settings and customized defaultOptions.compact behavior unchanged. Add regression coverage for depth: Infinity, depth: null, explicit compact: 3, explicit compact: 1, and custom defaultOptions.compact. Fixes: https://github.com/nodejs/node/issues/60475 --- lib/internal/util/inspect.js | 5 ++++- test/parallel/test-util-inspect.js | 36 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index c611eb97fc0755..1f282abcff4aec 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -2660,7 +2660,10 @@ function reduceToSingleString( // Consolidate all entries of the local most inner depth up to // `ctx.compact`, as long as the properties are smaller than // `ctx.breakLength`. - if (ctx.currentDepth - recurseTimes < ctx.compact && + if (((ctx.breakLength === Infinity && + (ctx.depth === Infinity || ctx.depth === null) && + ctx.compact === 3) || + ctx.currentDepth - recurseTimes < ctx.compact) && entries === output.length) { // Line up all entries on a single line in case the entries do not // exceed `breakLength`. Add 10 as constant to start next to all other diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index e60320d0591233..5af2708813d197 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1615,6 +1615,36 @@ if (typeof Symbol !== 'undefined') { assert.strictEqual(twoLines, "{\n foo: 'abc',\n bar: 'xyz'\n}"); } +{ + const obj = { + a: { + b: { + c: { + d: 1, + }, + }, + }, + }; + + assert.strictEqual( + util.inspect(obj, { breakLength: Infinity, depth: Infinity }), + '{ a: { b: { c: { d: 1 } } } }', + ); + assert.strictEqual( + util.inspect(obj, { breakLength: Infinity, depth: null }), + '{ a: { b: { c: { d: 1 } } } }', + ); + assert.strictEqual( + util.inspect(obj, { breakLength: Infinity, depth: Infinity, compact: 3 }), + '{ a: { b: { c: { d: 1 } } } }', + ); + + assert.strictEqual( + util.inspect(obj, { breakLength: Infinity, depth: Infinity, compact: 1 }), + '{\n a: {\n b: {\n c: { d: 1 }\n }\n }\n}', + ); +} + // util.inspect.defaultOptions tests. { const arr = new Array(101).fill(); @@ -1631,6 +1661,12 @@ if (typeof Symbol !== 'undefined') { assert.doesNotMatch(util.inspect(obj), /Object/); util.inspect.defaultOptions.depth = oldOptions.depth; assert.match(util.inspect(obj), /Object/); + util.inspect.defaultOptions.compact = 1; + assert.strictEqual( + util.inspect(obj, { breakLength: Infinity, depth: Infinity }), + '{\n a: {\n a: {\n a: { a: 1 }\n }\n }\n}', + ); + util.inspect.defaultOptions.compact = oldOptions.compact; assert.strictEqual( JSON.stringify(util.inspect.defaultOptions), JSON.stringify(oldOptions)