From 892c51f330f99b7eb57481e183df61530a9c5956 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Fri, 5 Apr 2019 22:02:57 +0200 Subject: [PATCH] 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: https://github.com/nodejs/node/pull/27109 Reviewed-By: Anna Henningsen Reviewed-By: Minwoo Jung Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/internal/util/inspect.js | 92 +++++++++++++++--------------- test/parallel/test-util-inspect.js | 2 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index e5a8b2ecb6d189..5439c27d254e32 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -424,7 +424,8 @@ function formatProxy(ctx, proxy, recurseTimes) { formatValue(ctx, proxy[1], recurseTimes) ]; ctx.indentationLvl -= 2; - return reduceToSingleString(ctx, res, '', ['Proxy [', ']']); + return reduceToSingleString( + ctx, res, '', ['Proxy [', ']'], kArrayExtrasType, recurseTimes); } function findTypedConstructor(value) { @@ -786,37 +787,8 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { } } - let combine = false; - if (typeof ctx.compact === 'number') { - // Memorize the original output length. In case the the output is grouped, - // prevent lining up the entries on a single line. - const entries = output.length; - // Group array elements together if the array contains at least six separate - // entries. - if (extrasType === kArrayExtrasType && output.length > 6) { - output = groupArrayElements(ctx, output); - } - // `ctx.currentDepth` is set to the most inner depth of the currently - // inspected object part while `recurseTimes` is the actual current depth - // that is inspected. - // - // Example: - // - // const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } } - // - // The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max - // depth of 1. - // - // 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) { - combine = true; - } - } - - const res = reduceToSingleString(ctx, output, base, braces, combine); + const res = reduceToSingleString( + ctx, output, base, braces, extrasType, recurseTimes); const budget = ctx.budget[ctx.indentationLvl] || 0; const newLength = budget + res.length; ctx.budget[ctx.indentationLvl] = newLength; @@ -984,9 +956,10 @@ function formatBigInt(fn, value) { function formatPrimitive(fn, value, ctx) { if (typeof value === 'string') { if (ctx.compact !== true && - ctx.indentationLvl + value.length > ctx.breakLength && - value.length > kMinLineLength) { - const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl; + ctx.indentationLvl + value.length + 4 > ctx.breakLength && + value.length > kMinLineLength) { + // Subtract the potential quotes, the space and the plus as well (4). + const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl - 4; const maxLineLength = Math.max(rawMaxLineLength, kMinLineLength); const lines = Math.ceil(value.length / maxLineLength); const averageLineLength = Math.ceil(value.length / lines); @@ -1231,7 +1204,8 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) { formatValue(ctx, entries[pos], recurseTimes), formatValue(ctx, entries[pos + 1], recurseTimes) ]; - output[i] = reduceToSingleString(ctx, res, '', ['[', ']']); + output[i] = reduceToSingleString( + ctx, res, '', ['[', ']'], kArrayExtrasType, recurseTimes); } } ctx.indentationLvl -= 2; @@ -1368,17 +1342,43 @@ function isBelowBreakLength(ctx, output, start, base) { return base === '' || !base.includes('\n'); } -function reduceToSingleString(ctx, output, base, braces, combine = false) { +function reduceToSingleString( + ctx, output, base, braces, extrasType, recurseTimes) { if (ctx.compact !== true) { - if (combine) { - // 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`. - const start = output.length + ctx.indentationLvl + - braces[0].length + base.length + 10; - if (isBelowBreakLength(ctx, output, start, base)) { - return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')} ` + - braces[1]; + if (typeof ctx.compact === 'number' && ctx.compact >= 1) { + // Memorize the original output length. In case the the output is grouped, + // prevent lining up the entries on a single line. + const entries = output.length; + // Group array elements together if the array contains at least six + // separate entries. + if (extrasType === kArrayExtrasType && entries > 6) { + output = groupArrayElements(ctx, output); + } + // `ctx.currentDepth` is set to the most inner depth of the currently + // inspected object part while `recurseTimes` is the actual current depth + // that is inspected. + // + // Example: + // + // const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } } + // + // The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max + // depth of 1. + // + // 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) { + // 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`. + const start = output.length + ctx.indentationLvl + + braces[0].length + base.length + 10; + if (isBelowBreakLength(ctx, output, start, base)) { + return `${base ? `${base} ` : ''}${braces[0]} ${join(output, ', ')}` + + ` ${braces[1]}`; + } } } // Line up each entry on an individual line. diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 1de812286a2c28..ee3c5588933a6c 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1674,7 +1674,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'"); return 'BazError'; } }, undefined] -].forEach(([Class, message, messages], i) => { +].forEach(([Class, message], i) => { console.log('Test %i', i); const foo = new Class(message); const name = foo.name;