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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (keys.length === 0) {
|
||||
if (isFunction(value)) {
|
||||
@ -254,6 +276,19 @@ function formatValue(ctx, value, recurseTimes) {
|
||||
if (isError(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 = ['{', '}'];
|
||||
@ -285,6 +320,24 @@ function formatValue(ctx, value, recurseTimes) {
|
||||
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)) {
|
||||
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) {
|
||||
return '[' + Error.prototype.toString.call(value) + ']';
|
||||
}
|
||||
|
@ -213,3 +213,25 @@ test_lines({
|
||||
very_long_key: 'very_long_value',
|
||||
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