From 4a531b948eb0bccf8da740c0bf7e44c7e561fc86 Mon Sep 17 00:00:00 2001 From: sangwook Date: Wed, 19 Nov 2025 23:48:20 +0900 Subject: [PATCH 1/2] test: add util.inspect breakLength regression --- test/parallel/test-util-inspect.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index ae45615c2c65ac..317fce6f29e9b7 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -589,6 +589,25 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324'); }), "[ 'foo', <1 empty item>, ... 99 more items ]"); } +// `breakLength: Infinity` should force single-line output even if `depth` is +// explicitly set to `Infinity`. +{ + const tree = {}; + for (let i = 0; i < 5; i++) { + const branch = tree[`field${i}`] = { leaves: {} }; + for (let j = 0; j < 5; j++) { + branch.leaves[`leaf${j}`] = new Array(10).fill(`value-${i}-${j}`); + } + } + + const options = { breakLength: Infinity, compact: 3 }; + const singleLine = util.inspect(tree, options); + assert.strictEqual(singleLine.includes('\n'), false); + + const deepOptions = { ...options, depth: Infinity }; + assert.strictEqual(util.inspect(tree, deepOptions).includes('\n'), false); +} + // Test for Array constructor in different context. { const map = new Map(); From a3ba562ea87d4be62a05a3eebf39fc07202ece56 Mon Sep 17 00:00:00 2001 From: sangwook Date: Thu, 20 Nov 2025 00:36:01 +0900 Subject: [PATCH 2/2] lib: honor util.inspect breakLength Infinity --- lib/internal/util/inspect.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 83c254c3d6c464..ba418153115123 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -2022,7 +2022,14 @@ function formatError(err, constructor, tag, ctx, keys) { return stack; } +function isUnlimitedDepth(ctx) { + return ctx.depth === null || ctx.depth === Infinity; +} + function groupArrayElements(ctx, output, value) { + if (!NumberIsFinite(ctx.breakLength) && isUnlimitedDepth(ctx)) { + return output; + } let totalLength = 0; let maxLength = 0; let i = 0; @@ -2640,8 +2647,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 && - entries === output.length) { + const allowInline = + (!NumberIsFinite(ctx.breakLength) && isUnlimitedDepth(ctx)) || + ctx.currentDepth - recurseTimes < ctx.compact; + if (allowInline && 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 // factors that may reduce `breakLength`.