From 2fe9f933172c5c8bcd383f556c3f877d1f29a392 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 2 Jun 2019 16:07:08 +0200 Subject: [PATCH 1/2] util: refactor inspecting long lines Using the `util.inspect` `compact` mode set to something else than `true` resulted in breaking long lines in case the line would exceed the `breakLength` option and if it contained whitespace and or new lines. It turned out that this behavior was less useful than originally expected and it is now changed to only break on line breaks if the `breakLength` option is exceeded for the inspected string. This should be align better with the user expectation than the former behavior. Fixes: https://github.com/nodejs/node/issues/27690 --- lib/internal/util/inspect.js | 37 +++--------------- test/parallel/test-util-inspect.js | 62 ++++++++---------------------- 2 files changed, 22 insertions(+), 77 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 8735c40ac013be..6c09b5b8bb390f 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1071,37 +1071,12 @@ function formatBigInt(fn, value) { function formatPrimitive(fn, value, ctx) { if (typeof value === 'string') { if (ctx.compact !== true && - 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); - const divisor = Math.max(averageLineLength, kMinLineLength); - if (readableRegExps[divisor] === undefined) { - // Build a new RegExp that naturally breaks text into multiple lines. - // - // Rules - // 1. Greedy match all text up the max line length that ends with a - // whitespace or the end of the string. - // 2. If none matches, non-greedy match any text up to a whitespace or - // the end of the string. - // - // eslint-disable-next-line max-len, node-core/no-unescaped-regexp-dot - readableRegExps[divisor] = new RegExp(`(.|\\n){1,${divisor}}(\\s|$)|(\\n|.)+?(\\s|$)`, 'gm'); - } - const matches = value.match(readableRegExps[divisor]); - if (matches.length > 1) { - const indent = ' '.repeat(ctx.indentationLvl); - let res = `${fn(strEscape(matches[0]), 'string')} +\n`; - const lastIndex = matches.length - 1; - for (let i = 1; i < lastIndex; i++) { - res += `${indent} ${fn(strEscape(matches[i]), 'string')} +\n`; - } - res += `${indent} ${fn(strEscape(matches[lastIndex]), 'string')}`; - return res; - } + value.length > kMinLineLength && + value.length > ctx.breakLength - ctx.indentationLvl - 4) { + return value + .split(/(?<=\n)/) + .map((line) => fn(strEscape(line), 'string')) + .join(` +\n${' '.repeat(ctx.indentationLvl + 2)}`); } return fn(strEscape(value), 'string'); } diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 834b0c0236abcd..5d51ef4dddf453 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -89,7 +89,7 @@ assert.strictEqual(util.inspect(new Date('')), (new Date('')).toString()); assert.strictEqual(util.inspect('\n\u0001'), "'\\n\\u0001'"); assert.strictEqual( util.inspect(`${Array(75).fill(1)}'\n\u001d\n\u0003`), - `"${Array(75).fill(1)}'\\n" +\n '\\u001d\\n\\u0003'` + `"${Array(75).fill(1)}'\\n" +\n '\\u001d\\n' +\n '\\u0003'` ); assert.strictEqual(util.inspect([]), '[]'); assert.strictEqual(util.inspect(Object.create([])), 'Array {}'); @@ -1505,10 +1505,9 @@ util.inspect(process); ' 2,', ' [', ' [', - " 'Lorem ipsum dolor\\nsit amet,\\tconsectetur ' +", - " 'adipiscing elit, sed do eiusmod tempor ' +", - " 'incididunt ut labore et dolore magna ' +", - " 'aliqua.',", + " 'Lorem ipsum dolor\\n' +", + " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod " + + "tempor incididunt ut labore et dolore magna aliqua.',", " 'test',", " 'foo'", ' ]', @@ -1525,12 +1524,9 @@ util.inspect(process); out = util.inspect(o.a[2][0][0], { compact: false, breakLength: 30 }); expect = [ - "'Lorem ipsum dolor\\nsit ' +", - " 'amet,\\tconsectetur ' +", - " 'adipiscing elit, sed do ' +", - " 'eiusmod tempor incididunt ' +", - " 'ut labore et dolore magna ' +", - " 'aliqua.'" + "'Lorem ipsum dolor\\n' +", + " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod tempor " + + "incididunt ut labore et dolore magna aliqua.'" ].join('\n'); assert.strictEqual(out, expect); @@ -1544,30 +1540,7 @@ util.inspect(process); '12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890', { compact: false, breakLength: 3 }); expect = [ - "'12 45 78 01 34 ' +", - " '67 90 23 56 89 ' +", - " '123456789012345678901234567890'" - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect( - '12 45 78 01 34 67 90 23 56 89 1234567890123 0', - { compact: false, breakLength: 3 }); - expect = [ - "'12 45 78 01 34 ' +", - " '67 90 23 56 89 ' +", - " '1234567890123 0'" - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect( - '12 45 78 01 34 67 90 23 56 89 12345678901234567 0', - { compact: false, breakLength: 3 }); - expect = [ - "'12 45 78 01 34 ' +", - " '67 90 23 56 89 ' +", - " '12345678901234567 ' +", - " '0'" + "'12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890'" ].join('\n'); assert.strictEqual(out, expect); @@ -1606,7 +1579,7 @@ util.inspect(process); o[util.inspect.custom] = () => ({ a: '12 45 78 01 34 67 90 23' }); out = util.inspect(o, { compact: false, breakLength: 3 }); - expect = "{\n a: '12 45 78 01 34 ' +\n '67 90 23'\n}"; + expect = "{\n a: '12 45 78 01 34 67 90 23'\n}"; assert.strictEqual(out, expect); } @@ -2210,16 +2183,13 @@ assert.strictEqual( ' b: {', ' x: 5,', ' c: {', - " x: '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ' +", - " '10000000000000000 00000000000000000 ',", + " x: '10000000000000000 00000000000000000 10000000000000000 " + + '00000000000000000 10000000000000000 00000000000000000 ' + + '10000000000000000 00000000000000000 10000000000000000 ' + + '00000000000000000 10000000000000000 00000000000000000 ' + + '10000000000000000 00000000000000000 10000000000000000 ' + + '00000000000000000 10000000000000000 00000000000000000 ' + + "10000000000000000 00000000000000000 ',", ' d: 2,', ' e: 3', ' }', From 3ab4a3d7c53a896120478f334eab82bc79c5df82 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 4 Jun 2019 19:47:02 +0200 Subject: [PATCH 2/2] fixup! remove unused code --- lib/internal/util/inspect.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 6c09b5b8bb390f..d46a85a2bc009d 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -127,8 +127,6 @@ const numberRegExp = /^(0|[1-9][0-9]*)$/; const coreModuleRegExp = /^ at (?:[^/\\(]+ \(|)((?