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:
parent
afd290d224
commit
8de83725ac
82
lib/util.js
82
lib/util.js
@ -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) {
|
||||||
|
@ -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:',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user