diff options
-rw-r--r-- | doc/api/util.md | 15 | ||||
-rw-r--r-- | lib/internal/util/inspect.js | 34 | ||||
-rw-r--r-- | test/parallel/test-util-inspect.js | 36 |
3 files changed, 71 insertions, 14 deletions
diff --git a/doc/api/util.md b/doc/api/util.md index d53e18b217..2826e0f1a6 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -389,6 +389,9 @@ stream.write('With ES6'); added: v0.3.0 changes: - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/26269 + description: The `compact` option accepts numbers for a new output mode. + - version: REPLACEME pr-url: https://github.com/nodejs/node/pull/24971 description: Internal properties no longer appear in the context argument of a custom inspection function. @@ -461,11 +464,13 @@ changes: * `breakLength` {integer} The length at which an object's keys are split across multiple lines. Set to `Infinity` to format an object as a single line. **Default:** `60` for legacy compatibility. - * `compact` {boolean} Setting this to `false` causes each object key to - be displayed on a new line. It will also add new lines to text that is - longer than `breakLength`. Note that no text will be reduced below 16 - characters, no matter the `breakLength` size. For more information, see the - example below. **Default:** `true`. + * `compact` {boolean|integer} Setting this to `false` causes each object key + to be displayed on a new line. It will also add new lines to text that is + longer than `breakLength`. If set to a number, the most `n` inner elements + are united on a single line as long as all properties fit into + `breakLength`. Note that no text will be reduced below 16 characters, no + matter the `breakLength` size. For more information, see the example below. + **Default:** `true`. * `sorted` {boolean|Function} If set to `true` or a function, all properties of an object, and `Set` and `Map` entries are sorted in the resulting string. If set to `true` the [default sort][] is used. If set to a function, diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 40bc76f817..277cc9aa42 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -164,6 +164,7 @@ function inspect(value, opts) { budget: {}, indentationLvl: 0, seen: [], + currentDepth: 0, stylize: stylizeNoColor, showHidden: inspectDefaultOptions.showHidden, depth: inspectDefaultOptions.depth, @@ -769,6 +770,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { recurseTimes += 1; ctx.seen.push(value); + ctx.currentDepth = recurseTimes; let output; const indentationLvl = ctx.indentationLvl; try { @@ -792,7 +794,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { } } - const res = reduceToSingleString(ctx, output, base, braces); + const combine = typeof ctx.compact === 'number' && + ctx.currentDepth - recurseTimes < ctx.compact; + + const res = reduceToSingleString(ctx, output, base, braces, combine); const budget = ctx.budget[ctx.indentationLvl] || 0; const newLength = budget + res.length; ctx.budget[ctx.indentationLvl] = newLength; @@ -833,7 +838,7 @@ function formatBigInt(fn, value) { function formatPrimitive(fn, value, ctx) { if (typeof value === 'string') { - if (ctx.compact === false && + if (ctx.compact !== true && ctx.indentationLvl + value.length > ctx.breakLength && value.length > kMinLineLength) { const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl; @@ -1143,7 +1148,7 @@ function formatProperty(ctx, value, recurseTimes, key, type) { const desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key], enumerable: true }; if (desc.value !== undefined) { - const diff = (type !== kObjectType || ctx.compact === false) ? 2 : 3; + const diff = (type !== kObjectType || ctx.compact !== true) ? 2 : 3; ctx.indentationLvl += diff; str = formatValue(ctx, desc.value, recurseTimes); if (diff === 3) { @@ -1200,16 +1205,27 @@ function formatProperty(ctx, value, recurseTimes, key, type) { return `${name}:${extra}${str}`; } -function reduceToSingleString(ctx, output, base, braces) { +function reduceToSingleString(ctx, output, base, braces, combine = false) { const breakLength = ctx.breakLength; let i = 0; - if (ctx.compact === false) { - const indentation = ' '.repeat(ctx.indentationLvl); - let res = `${base ? `${base} ` : ''}${braces[0]}\n${indentation} `; + if (ctx.compact !== true) { + if (combine) { + const totalLength = output.reduce((sum, cur) => sum + cur.length, 0); + if (totalLength + output.length * 2 < breakLength) { + let res = `${base ? `${base} ` : ''}${braces[0]} `; + for (; i < output.length - 1; i++) { + res += `${output[i]}, `; + } + res += `${output[i]} ${braces[1]}`; + return res; + } + } + const indentation = `\n${' '.repeat(ctx.indentationLvl)}`; + let res = `${base ? `${base} ` : ''}${braces[0]}${indentation} `; for (; i < output.length - 1; i++) { - res += `${output[i]},\n${indentation} `; + res += `${output[i]},${indentation} `; } - res += `${output[i]}\n${indentation}${braces[1]}`; + res += `${output[i]}${indentation}${braces[1]}`; return res; } if (output.length * 2 <= breakLength) { diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 4e9f5ac004..fdba7ebe1b 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1498,6 +1498,42 @@ util.inspect(process); assert.strict.equal(out, expected); + out = util.inspect(map, { compact: 2, showHidden: true, depth: 9 }); + + expected = [ + 'Map {', + ' Promise {', + ' [', + ' [', + ' 1,', + ' Set { [ 1, 2, [length]: 2 ], [size]: 1 },', + ' [length]: 2', + ' ],', + ' [length]: 1', + ' ]', + ' } => Uint8Array [', + ' [BYTES_PER_ELEMENT]: 1,', + ' [length]: 0,', + ' [byteLength]: 0,', + ' [byteOffset]: 0,', + ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', + ' ],', + ' [Set Iterator] { [ 1, 2, [length]: 2 ] } => [Map Iterator] {', + ' Uint8Array [', + ' [BYTES_PER_ELEMENT]: 1,', + ' [length]: 0,', + ' [byteLength]: 0,', + ' [byteOffset]: 0,', + ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', + ' ],', + ' [Circular]', + ' },', + ' [size]: 2', + '}' + ].join('\n'); + + assert.strict.equal(out, expected); + out = util.inspect(map, { showHidden: true, depth: 9, breakLength: 4 }); expected = [ 'Map {', |