util: show meaningful values for boxed primitives
Before, `new String('foo')` would be inspected as `"{}"` which is simply not very helpful. Now, a more meaningful `"[String: 'foo']"` result will be returned from `util.inspect()`. Boxed String, Boolean, and Number types are all supported. Closes #7047
This commit is contained in:
parent
f1de13b8ab
commit
8874a31748
62
lib/util.js
62
lib/util.js
@ -239,6 +239,28 @@ function formatValue(ctx, value, recurseTimes) {
|
|||||||
keys = Object.getOwnPropertyNames(value);
|
keys = Object.getOwnPropertyNames(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This could be a boxed primitive (new String(), etc.), check valueOf()
|
||||||
|
// NOTE: Avoid calling `valueOf` on `Date` instance because it will return
|
||||||
|
// a number which, when object has some additional user-stored `keys`,
|
||||||
|
// will be printed out.
|
||||||
|
var formatted;
|
||||||
|
var raw = value;
|
||||||
|
try {
|
||||||
|
// the .valueOf() call can fail for a multitude of reasons
|
||||||
|
if (!isDate(value))
|
||||||
|
raw = value.valueOf();
|
||||||
|
} catch (e) {
|
||||||
|
// ignore...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isString(raw)) {
|
||||||
|
// for boxed Strings, we have to remove the 0-n indexed entries,
|
||||||
|
// since they just noisey up the output and are redundant
|
||||||
|
keys = keys.filter(function(key) {
|
||||||
|
return !(key >= 0 && key < raw.length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Some type of object without properties can be shortcutted.
|
// Some type of object without properties can be shortcutted.
|
||||||
if (keys.length === 0) {
|
if (keys.length === 0) {
|
||||||
if (isFunction(value)) {
|
if (isFunction(value)) {
|
||||||
@ -254,6 +276,19 @@ function formatValue(ctx, value, recurseTimes) {
|
|||||||
if (isError(value)) {
|
if (isError(value)) {
|
||||||
return formatError(value);
|
return formatError(value);
|
||||||
}
|
}
|
||||||
|
// now check the `raw` value to handle boxed primitives
|
||||||
|
if (isString(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
return ctx.stylize('[String: ' + formatted + ']', 'string');
|
||||||
|
}
|
||||||
|
if (isNumber(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
return ctx.stylize('[Number: ' + formatted + ']', 'number');
|
||||||
|
}
|
||||||
|
if (isBoolean(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var base = '', array = false, braces = ['{', '}'];
|
var base = '', array = false, braces = ['{', '}'];
|
||||||
@ -285,6 +320,24 @@ function formatValue(ctx, value, recurseTimes) {
|
|||||||
base = ' ' + formatError(value);
|
base = ' ' + formatError(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make boxed primitive Strings look like such
|
||||||
|
if (isString(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
base = ' ' + '[String: ' + formatted + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make boxed primitive Numbers look like such
|
||||||
|
if (isNumber(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
base = ' ' + '[Number: ' + formatted + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make boxed primitive Booleans look like such
|
||||||
|
if (isBoolean(raw)) {
|
||||||
|
formatted = formatPrimitiveNoColor(ctx, raw);
|
||||||
|
base = ' ' + '[Boolean: ' + formatted + ']';
|
||||||
|
}
|
||||||
|
|
||||||
if (keys.length === 0 && (!array || value.length == 0)) {
|
if (keys.length === 0 && (!array || value.length == 0)) {
|
||||||
return braces[0] + base + braces[1];
|
return braces[0] + base + braces[1];
|
||||||
}
|
}
|
||||||
@ -338,6 +391,15 @@ function formatPrimitive(ctx, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function formatPrimitiveNoColor(ctx, value) {
|
||||||
|
var stylize = ctx.stylize;
|
||||||
|
ctx.stylize = stylizeNoColor;
|
||||||
|
var str = formatPrimitive(ctx, value);
|
||||||
|
ctx.stylize = stylize;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function formatError(value) {
|
function formatError(value) {
|
||||||
return '[' + Error.prototype.toString.call(value) + ']';
|
return '[' + Error.prototype.toString.call(value) + ']';
|
||||||
}
|
}
|
||||||
|
@ -213,3 +213,25 @@ test_lines({
|
|||||||
very_long_key: 'very_long_value',
|
very_long_key: 'very_long_value',
|
||||||
even_longer_key: ['with even longer value in array']
|
even_longer_key: ['with even longer value in array']
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// test boxed primitives output the correct values
|
||||||
|
assert.equal(util.inspect(new String('test')), '[String: \'test\']');
|
||||||
|
assert.equal(util.inspect(new Boolean(false)), '[Boolean: false]');
|
||||||
|
assert.equal(util.inspect(new Boolean(true)), '[Boolean: true]');
|
||||||
|
assert.equal(util.inspect(new Number(0)), '[Number: 0]');
|
||||||
|
assert.equal(util.inspect(new Number(-0)), '[Number: -0]');
|
||||||
|
assert.equal(util.inspect(new Number(-1.1)), '[Number: -1.1]');
|
||||||
|
assert.equal(util.inspect(new Number(13.37)), '[Number: 13.37]');
|
||||||
|
|
||||||
|
// test boxed primitives with own properties
|
||||||
|
var str = new String('baz');
|
||||||
|
str.foo = 'bar';
|
||||||
|
assert.equal(util.inspect(str), '{ [String: \'baz\'] foo: \'bar\' }');
|
||||||
|
|
||||||
|
var bool = new Boolean(true);
|
||||||
|
bool.foo = 'bar';
|
||||||
|
assert.equal(util.inspect(bool), '{ [Boolean: true] foo: \'bar\' }');
|
||||||
|
|
||||||
|
var num = new Number(13.37);
|
||||||
|
num.foo = 'bar';
|
||||||
|
assert.equal(util.inspect(num), '{ [Number: 13.37] foo: \'bar\' }');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user