util: remove erroneous whitespace

When inspecting nested objects some times a whitespace was added at
the end of a line. This fixes this erroneous space.

Besides that the `breakLength` was not followed if a single property
was longer than the breakLength. It will now break a single property
into the key and value in such cases.

PR-URL: https://github.com/nodejs/node/pull/20802
Refs: https://github.com/nodejs/node/issues/20253
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
Ruben Bridgewater 2018-05-17 03:19:56 +02:00
parent afd290d224
commit 8de83725ac
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
4 changed files with 57 additions and 53 deletions

View File

@ -416,7 +416,7 @@ function getPrefix(constructor, tag) {
return ''; return '';
} }
function formatValue(ctx, value, recurseTimes, ln) { function formatValue(ctx, value, recurseTimes) {
// Primitive types cannot have properties // Primitive types cannot have properties
if (typeof value !== 'object' && typeof value !== 'function') { if (typeof value !== 'object' && typeof value !== 'function') {
return formatPrimitive(ctx.stylize, value, ctx); return formatPrimitive(ctx.stylize, value, ctx);
@ -582,7 +582,7 @@ function formatValue(ctx, value, recurseTimes, ln) {
return ctx.stylize(dateToISOString.call(value), 'date'); return ctx.stylize(dateToISOString.call(value), 'date');
} }
// Make dates with properties first say the date // Make dates with properties first say the date
base = `${dateToISOString.call(value)}`; base = dateToISOString.call(value);
} else if (isError(value)) { } else if (isError(value)) {
// Make error with message first say the error // Make error with message first say the error
base = formatError(value); base = formatError(value);
@ -683,7 +683,7 @@ function formatValue(ctx, value, recurseTimes, ln) {
} }
ctx.seen.pop(); ctx.seen.pop();
return reduceToSingleString(ctx, output, base, braces, ln); return reduceToSingleString(ctx, output, base, braces);
} }
function formatNumber(fn, value) { function formatNumber(fn, value) {
@ -758,7 +758,23 @@ function formatNamespaceObject(ctx, value, recurseTimes, keys) {
const len = keys.length; const len = keys.length;
const output = new Array(len); const output = new Array(len);
for (var i = 0; i < len; i++) { for (var i = 0; i < len; i++) {
output[i] = formatNamespaceProperty(ctx, value, recurseTimes, keys[i]); try {
output[i] = formatProperty(ctx, value, recurseTimes, keys[i], 0);
} catch (err) {
if (!(err instanceof ReferenceError)) {
throw err;
}
// Use the existing functionality. This makes sure the indentation and
// line breaks are always correct. Otherwise it is very difficult to keep
// this aligned, even though this is a hacky way of dealing with this.
const tmp = { [keys[i]]: '' };
output[i] = formatProperty(ctx, tmp, recurseTimes, keys[i], 0);
const pos = output[i].lastIndexOf(' ');
// We have to find the last whitespace and have to replace that value as
// it will be visualized as a regular string.
output[i] = output[i].slice(0, pos + 1) +
ctx.stylize('<uninitialized>', 'special');
}
} }
return output; return output;
} }
@ -986,42 +1002,21 @@ function formatPromise(ctx, value, recurseTimes, keys) {
return output; return output;
} }
function formatKey(ctx, key, enumerable) {
if (typeof key === 'symbol') {
return `[${ctx.stylize(key.toString(), 'symbol')}]`;
}
if (enumerable === false) {
return `[${key}]`;
}
if (keyStrRegExp.test(key)) {
return ctx.stylize(key, 'name');
}
return ctx.stylize(strEscape(key), 'string');
}
function formatNamespaceProperty(ctx, ns, recurseTimes, key) {
let value;
try {
value = formatValue(ctx, ns[key], recurseTimes, true);
} catch (err) {
if (err instanceof ReferenceError) {
value = ctx.stylize('<uninitialized>', 'special');
} else {
throw err;
}
}
return `${formatKey(ctx, key)}: ${value}`;
}
function formatProperty(ctx, value, recurseTimes, key, array) { function formatProperty(ctx, value, recurseTimes, key, array) {
let str; let name, str;
let extra = ' ';
const desc = Object.getOwnPropertyDescriptor(value, key) || const desc = Object.getOwnPropertyDescriptor(value, key) ||
{ value: value[key], enumerable: true }; { value: value[key], enumerable: true };
if (desc.value !== undefined) { if (desc.value !== undefined) {
const diff = array !== 0 || ctx.compact === false ? 2 : 3; const diff = array !== 0 || ctx.compact === false ? 2 : 3;
ctx.indentationLvl += diff; ctx.indentationLvl += diff;
str = formatValue(ctx, desc.value, recurseTimes, array === 0); str = formatValue(ctx, desc.value, recurseTimes);
if (diff === 3) {
const len = ctx.colors ? removeColors(str).length : str.length;
if (ctx.breakLength < len) {
extra = `\n${' '.repeat(ctx.indentationLvl)}`;
}
}
ctx.indentationLvl -= diff; ctx.indentationLvl -= diff;
} else if (desc.get !== undefined) { } else if (desc.get !== undefined) {
if (desc.set !== undefined) { if (desc.set !== undefined) {
@ -1037,11 +1032,19 @@ function formatProperty(ctx, value, recurseTimes, key, array) {
if (array === 1) { if (array === 1) {
return str; return str;
} }
if (typeof key === 'symbol') {
return `${formatKey(ctx, key, desc.enumerable)}: ${str}`; name = `[${ctx.stylize(key.toString(), 'symbol')}]`;
} else if (desc.enumerable === false) {
name = `[${key}]`;
} else if (keyStrRegExp.test(key)) {
name = ctx.stylize(key, 'name');
} else {
name = ctx.stylize(strEscape(key), 'string');
}
return `${name}:${extra}${str}`;
} }
function reduceToSingleString(ctx, output, base, braces, addLn) { function reduceToSingleString(ctx, output, base, braces) {
const breakLength = ctx.breakLength; const breakLength = ctx.breakLength;
let i = 0; let i = 0;
if (ctx.compact === false) { if (ctx.compact === false) {
@ -1070,11 +1073,10 @@ function reduceToSingleString(ctx, output, base, braces, addLn) {
// we need to force the first item to be on the next line or the // we need to force the first item to be on the next line or the
// items will not line up correctly. // items will not line up correctly.
const indentation = ' '.repeat(ctx.indentationLvl); const indentation = ' '.repeat(ctx.indentationLvl);
const extraLn = addLn === true ? `\n${indentation}` : '';
const ln = base === '' && braces[0].length === 1 ? const ln = base === '' && braces[0].length === 1 ?
' ' : `${base ? ` ${base}` : base}\n${indentation} `; ' ' : `${base ? ` ${base}` : ''}\n${indentation} `;
const str = join(output, `,\n${indentation} `); const str = join(output, `,\n${indentation} `);
return `${extraLn}${braces[0]}${ln}${str} ${braces[1]}`; return `${braces[0]}${ln}${str} ${braces[1]}`;
} }
function isBoolean(arg) { function isBoolean(arg) {

View File

@ -16,7 +16,8 @@ const url = new URL('https://username:password@host.name:8080/path/name/?que=ry#
assert.strictEqual( assert.strictEqual(
util.inspect(url), util.inspect(url),
`URL { `URL {
href: 'https://username:password@host.name:8080/path/name/?que=ry#hash', href:
'https://username:password@host.name:8080/path/name/?que=ry#hash',
origin: 'https://host.name:8080', origin: 'https://host.name:8080',
protocol: 'https:', protocol: 'https:',
username: 'username', username: 'username',
@ -32,7 +33,8 @@ assert.strictEqual(
assert.strictEqual( assert.strictEqual(
util.inspect(url, { showHidden: true }), util.inspect(url, { showHidden: true }),
`URL { `URL {
href: 'https://username:password@host.name:8080/path/name/?que=ry#hash', href:
'https://username:password@host.name:8080/path/name/?que=ry#hash',
origin: 'https://host.name:8080', origin: 'https://host.name:8080',
protocol: 'https:', protocol: 'https:',
username: 'username', username: 'username',
@ -46,7 +48,7 @@ assert.strictEqual(
hash: '#hash', hash: '#hash',
cannotBeBase: false, cannotBeBase: false,
special: true, special: true,
[Symbol(context)]:\x20 [Symbol(context)]:
URLContext { URLContext {
flags: 2032, flags: 2032,
scheme: 'https:', scheme: 'https:',