Skip to content

Commit 892c51f

Browse files
committed
util: improve inspect edge cases
This makes sure `compact` number mode causes small proxies and map entries to be printed on a single line. It also fixed the line break calculation for `compact` mode when not set to `true`. It now also adds the additional whitespace, comma and quotes to the formula to prevent exceeding the `breakLength`. PR-URL: #27109 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent bd9109c commit 892c51f

File tree

2 files changed

+47
-47
lines changed

2 files changed

+47
-47
lines changed

lib/internal/util/inspect.js

+46-46
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,8 @@ function formatProxy(ctx, proxy, recurseTimes) {
424424
formatValue(ctx, proxy[1], recurseTimes)
425425
];
426426
ctx.indentationLvl -= 2;
427-
return reduceToSingleString(ctx, res, '', ['Proxy [', ']']);
427+
return reduceToSingleString(
428+
ctx, res, '', ['Proxy [', ']'], kArrayExtrasType, recurseTimes);
428429
}
429430

430431
function findTypedConstructor(value) {
@@ -786,37 +787,8 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
786787
}
787788
}
788789

789-
let combine = false;
790-
if (typeof ctx.compact === 'number') {
791-
// Memorize the original output length. In case the the output is grouped,
792-
// prevent lining up the entries on a single line.
793-
const entries = output.length;
794-
// Group array elements together if the array contains at least six separate
795-
// entries.
796-
if (extrasType === kArrayExtrasType && output.length > 6) {
797-
output = groupArrayElements(ctx, output);
798-
}
799-
// `ctx.currentDepth` is set to the most inner depth of the currently
800-
// inspected object part while `recurseTimes` is the actual current depth
801-
// that is inspected.
802-
//
803-
// Example:
804-
//
805-
// const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } }
806-
//
807-
// The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max
808-
// depth of 1.
809-
//
810-
// Consolidate all entries of the local most inner depth up to
811-
// `ctx.compact`, as long as the properties are smaller than
812-
// `ctx.breakLength`.
813-
if (ctx.currentDepth - recurseTimes < ctx.compact &&
814-
entries === output.length) {
815-
combine = true;
816-
}
817-
}
818-
819-
const res = reduceToSingleString(ctx, output, base, braces, combine);
790+
const res = reduceToSingleString(
791+
ctx, output, base, braces, extrasType, recurseTimes);
820792
const budget = ctx.budget[ctx.indentationLvl] || 0;
821793
const newLength = budget + res.length;
822794
ctx.budget[ctx.indentationLvl] = newLength;
@@ -984,9 +956,10 @@ function formatBigInt(fn, value) {
984956
function formatPrimitive(fn, value, ctx) {
985957
if (typeof value === 'string') {
986958
if (ctx.compact !== true &&
987-
ctx.indentationLvl + value.length > ctx.breakLength &&
988-
value.length > kMinLineLength) {
989-
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl;
959+
ctx.indentationLvl + value.length + 4 > ctx.breakLength &&
960+
value.length > kMinLineLength) {
961+
// Subtract the potential quotes, the space and the plus as well (4).
962+
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl - 4;
990963
const maxLineLength = Math.max(rawMaxLineLength, kMinLineLength);
991964
const lines = Math.ceil(value.length / maxLineLength);
992965
const averageLineLength = Math.ceil(value.length / lines);
@@ -1231,7 +1204,8 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) {
12311204
formatValue(ctx, entries[pos], recurseTimes),
12321205
formatValue(ctx, entries[pos + 1], recurseTimes)
12331206
];
1234-
output[i] = reduceToSingleString(ctx, res, '', ['[', ']']);
1207+
output[i] = reduceToSingleString(
1208+
ctx, res, '', ['[', ']'], kArrayExtrasType, recurseTimes);
12351209
}
12361210
}
12371211
ctx.indentationLvl -= 2;
@@ -1368,17 +1342,43 @@ function isBelowBreakLength(ctx, output, start, base) {
13681342
return base === '' || !base.includes('\n');
13691343
}
13701344

1371-
function reduceToSingleString(ctx, output, base, braces, combine = false) {
1345+
function reduceToSingleString(
1346+
ctx, output, base, braces, extrasType, recurseTimes) {
13721347
if (ctx.compact !== true) {
1373-
if (combine) {
1374-
// Line up all entries on a single line in case the entries do not exceed
1375-
// `breakLength`. Add 10 as constant to start next to all other factors
1376-
// that may reduce `breakLength`.
1377-
const start = output.length + ctx.indentationLvl +
1378-
braces[0].length + base.length + 10;
1379-
if (isBelowBreakLength(ctx, output, start, base)) {
1380-
return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')} ` +
1381-
braces[1];
1348+
if (typeof ctx.compact === 'number' && ctx.compact >= 1) {
1349+
// Memorize the original output length. In case the the output is grouped,
1350+
// prevent lining up the entries on a single line.
1351+
const entries = output.length;
1352+
// Group array elements together if the array contains at least six
1353+
// separate entries.
1354+
if (extrasType === kArrayExtrasType && entries > 6) {
1355+
output = groupArrayElements(ctx, output);
1356+
}
1357+
// `ctx.currentDepth` is set to the most inner depth of the currently
1358+
// inspected object part while `recurseTimes` is the actual current depth
1359+
// that is inspected.
1360+
//
1361+
// Example:
1362+
//
1363+
// const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } }
1364+
//
1365+
// The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max
1366+
// depth of 1.
1367+
//
1368+
// Consolidate all entries of the local most inner depth up to
1369+
// `ctx.compact`, as long as the properties are smaller than
1370+
// `ctx.breakLength`.
1371+
if (ctx.currentDepth - recurseTimes < ctx.compact &&
1372+
entries === output.length) {
1373+
// Line up all entries on a single line in case the entries do not
1374+
// exceed `breakLength`. Add 10 as constant to start next to all other
1375+
// factors that may reduce `breakLength`.
1376+
const start = output.length + ctx.indentationLvl +
1377+
braces[0].length + base.length + 10;
1378+
if (isBelowBreakLength(ctx, output, start, base)) {
1379+
return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')}` +
1380+
` ${braces[1]}`;
1381+
}
13821382
}
13831383
}
13841384
// Line up each entry on an individual line.

test/parallel/test-util-inspect.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1674,7 +1674,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
16741674
return 'BazError';
16751675
}
16761676
}, undefined]
1677-
].forEach(([Class, message, messages], i) => {
1677+
].forEach(([Class, message], i) => {
16781678
console.log('Test %i', i);
16791679
const foo = new Class(message);
16801680
const name = foo.name;

0 commit comments

Comments
 (0)