From 572766aceb9e36e1fc43207549eaae9efedc3837 Mon Sep 17 00:00:00 2001 From: cola119 Date: Sun, 26 Jun 2022 16:36:50 +0900 Subject: [PATCH] util: add `maxArrayLength` option to Set and Map --- doc/api/util.md | 5 +++-- lib/internal/util/inspect.js | 31 ++++++++++++++++++++++++------ test/parallel/test-util-inspect.js | 3 +++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/doc/api/util.md b/doc/api/util.md index fafc54c3fadbfe..d7aa867358ceb9 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -586,8 +586,9 @@ changes: * `showProxy` {boolean} If `true`, `Proxy` inspection includes the [`target` and `handler`][] objects. **Default:** `false`. * `maxArrayLength` {integer} Specifies the maximum number of `Array`, - [`TypedArray`][], [`WeakMap`][], and [`WeakSet`][] elements to include when - formatting. Set to `null` or `Infinity` to show all elements. Set to `0` or + [`TypedArray`][], [`Map`][], [`Set`][], [`WeakMap`][], + and [`WeakSet`][] elements to include when formatting. + Set to `null` or `Infinity` to show all elements. Set to `0` or negative to show no elements. **Default:** `100`. * `maxStringLength` {integer} Specifies the maximum number of characters to include when formatting. Set to `null` or `Infinity` to show all elements. diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 948e2f354ac96d..0fe2be7e960f45 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1487,6 +1487,8 @@ function addNumericSeparatorEnd(integerString) { `${result}${integerString.slice(i)}`; } +const remainingText = (remaining) => `... ${remaining} more item${remaining > 1 ? 's' : ''}`; + function formatNumber(fn, number, numericSeparator) { if (!numericSeparator) { // Format -0 as '-0'. Checking `number === -0` won't distinguish 0 from -0. @@ -1613,7 +1615,7 @@ function formatSpecialArray(ctx, value, recurseTimes, maxLength, output, i) { output.push(ctx.stylize(message, 'undefined')); } } else if (remaining > 0) { - output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); + output.push(remainingText(remaining)); } return output; } @@ -1650,7 +1652,7 @@ function formatArray(ctx, value, recurseTimes) { output.push(formatProperty(ctx, value, recurseTimes, i, kArrayType)); } if (remaining > 0) - output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); + output.push(remainingText(remaining)); return output; } @@ -1665,7 +1667,7 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes) { output[i] = elementFormatter(ctx.stylize, value[i], ctx.numericSeparator); } if (remaining > 0) { - output[maxLength] = `... ${remaining} more item${remaining > 1 ? 's' : ''}`; + output[maxLength] = remainingText(remaining); } if (ctx.showHidden) { // .buffer goes last, it's not a primitive like the others. @@ -1687,22 +1689,40 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes) { } function formatSet(value, ctx, ignored, recurseTimes) { + const length = value.size; + const maxLength = MathMin(MathMax(0, ctx.maxArrayLength), length); + const remaining = length - maxLength; const output = []; ctx.indentationLvl += 2; + let i = 0; for (const v of value) { + if (i >= maxLength) break; ArrayPrototypePush(output, formatValue(ctx, v, recurseTimes)); + i++; + } + if (remaining > 0) { + ArrayPrototypePush(output, remainingText(remaining)); } ctx.indentationLvl -= 2; return output; } function formatMap(value, ctx, ignored, recurseTimes) { + const length = value.size; + const maxLength = MathMin(MathMax(0, ctx.maxArrayLength), length); + const remaining = length - maxLength; const output = []; ctx.indentationLvl += 2; + let i = 0; for (const { 0: k, 1: v } of value) { + if (i >= maxLength) break; output.push( `${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}` ); + i++; + } + if (remaining > 0) { + ArrayPrototypePush(output, remainingText(remaining)); } ctx.indentationLvl -= 2; return output; @@ -1725,8 +1745,7 @@ function formatSetIterInner(ctx, recurseTimes, entries, state) { } const remaining = entries.length - maxLength; if (remaining > 0) { - ArrayPrototypePush(output, - `... ${remaining} more item${remaining > 1 ? 's' : ''}`); + ArrayPrototypePush(output, remainingText(remaining)); } return output; } @@ -1764,7 +1783,7 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) { } ctx.indentationLvl -= 2; if (remaining > 0) { - output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); + output.push(remainingText(remaining)); } return output; } diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 8092c658966493..d0a17849e3d31e 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1171,6 +1171,7 @@ if (typeof Symbol !== 'undefined') { { assert.strictEqual(util.inspect(new Set()), 'Set(0) {}'); assert.strictEqual(util.inspect(new Set([1, 2, 3])), 'Set(3) { 1, 2, 3 }'); + assert.strictEqual(util.inspect(new Set([1, 2, 3]), { maxArrayLength: 1 }), 'Set(3) { 1, ... 2 more items }'); const set = new Set(['foo']); set.bar = 42; assert.strictEqual( @@ -1191,6 +1192,8 @@ if (typeof Symbol !== 'undefined') { assert.strictEqual(util.inspect(new Map()), 'Map(0) {}'); assert.strictEqual(util.inspect(new Map([[1, 'a'], [2, 'b'], [3, 'c']])), "Map(3) { 1 => 'a', 2 => 'b', 3 => 'c' }"); + assert.strictEqual(util.inspect(new Map([[1, 'a'], [2, 'b'], [3, 'c']]), { maxArrayLength: 1 }), + "Map(3) { 1 => 'a', ... 2 more items }"); const map = new Map([['foo', null]]); map.bar = 42; assert.strictEqual(util.inspect(map, true),