util: implement %o and %O as formatting specifiers
Implementing the %o and %O formatting specifiers for util.format. Based on discussion in issue, this specifier should just call util.inspect to format the value. PR-URL: https://github.com/nodejs/node/pull/14558 Fixes: https://github.com/nodejs/node/issues/14545 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
This commit is contained in:
parent
753b68f9d8
commit
211df3fe8c
@ -167,6 +167,14 @@ corresponding argument. Supported placeholders are:
|
|||||||
* `%f` - Floating point value.
|
* `%f` - Floating point value.
|
||||||
* `%j` - JSON. Replaced with the string `'[Circular]'` if the argument
|
* `%j` - JSON. Replaced with the string `'[Circular]'` if the argument
|
||||||
contains circular references.
|
contains circular references.
|
||||||
|
* `%o` - Object. A string representation of an object
|
||||||
|
with generic JavaScript object formatting.
|
||||||
|
Similar to `util.inspect()` with options `{ showHidden: true, depth: 4, showProxy: true }`.
|
||||||
|
This will show the full object including non-enumerable symbols and properties.
|
||||||
|
* `%O` - Object. A string representation of an object
|
||||||
|
with generic JavaScript object formatting.
|
||||||
|
Similar to `util.inspect()` without options.
|
||||||
|
This will show the full object not including non-enumerable symbols and properties.
|
||||||
* `%%` - single percent sign (`'%'`). This does not consume an argument.
|
* `%%` - single percent sign (`'%'`). This does not consume an argument.
|
||||||
|
|
||||||
If the placeholder does not have a corresponding argument, the placeholder is
|
If the placeholder does not have a corresponding argument, the placeholder is
|
||||||
|
11
lib/util.js
11
lib/util.js
@ -137,6 +137,17 @@ function format(f) {
|
|||||||
str += f.slice(lastPos, i);
|
str += f.slice(lastPos, i);
|
||||||
str += String(arguments[a++]);
|
str += String(arguments[a++]);
|
||||||
break;
|
break;
|
||||||
|
case 79: // 'O'
|
||||||
|
if (lastPos < i)
|
||||||
|
str += f.slice(lastPos, i);
|
||||||
|
str += inspect(arguments[a++]);
|
||||||
|
break;
|
||||||
|
case 111: // 'o'
|
||||||
|
if (lastPos < i)
|
||||||
|
str += f.slice(lastPos, i);
|
||||||
|
str += inspect(arguments[a++],
|
||||||
|
{ showHidden: true, depth: 4, showProxy: true });
|
||||||
|
break;
|
||||||
case 37: // '%'
|
case 37: // '%'
|
||||||
if (lastPos < i)
|
if (lastPos < i)
|
||||||
str += f.slice(lastPos, i);
|
str += f.slice(lastPos, i);
|
||||||
|
@ -101,6 +101,84 @@ assert.strictEqual(util.format('%j', '42'), '"42"');
|
|||||||
assert.strictEqual(util.format('%j %j', 42, 43), '42 43');
|
assert.strictEqual(util.format('%j %j', 42, 43), '42 43');
|
||||||
assert.strictEqual(util.format('%j %j', 42), '42 %j');
|
assert.strictEqual(util.format('%j %j', 42), '42 %j');
|
||||||
|
|
||||||
|
// Object format specifier
|
||||||
|
const obj = {
|
||||||
|
foo: 'bar',
|
||||||
|
foobar: 1,
|
||||||
|
func: function() {}
|
||||||
|
};
|
||||||
|
const nestedObj = {
|
||||||
|
foo: 'bar',
|
||||||
|
foobar: {
|
||||||
|
foo: 'bar',
|
||||||
|
func: function() {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert.strictEqual(util.format('%o'), '%o');
|
||||||
|
assert.strictEqual(util.format('%o', 42), '42');
|
||||||
|
assert.strictEqual(util.format('%o', 'foo'), '\'foo\'');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%o', obj),
|
||||||
|
'{ foo: \'bar\',\n' +
|
||||||
|
' foobar: 1,\n' +
|
||||||
|
' func: \n' +
|
||||||
|
' { [Function: func]\n' +
|
||||||
|
' [length]: 0,\n' +
|
||||||
|
' [name]: \'func\',\n' +
|
||||||
|
' [prototype]: func { [constructor]: [Circular] } } }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%o', nestedObj),
|
||||||
|
'{ foo: \'bar\',\n' +
|
||||||
|
' foobar: \n' +
|
||||||
|
' { foo: \'bar\',\n' +
|
||||||
|
' func: \n' +
|
||||||
|
' { [Function: func]\n' +
|
||||||
|
' [length]: 0,\n' +
|
||||||
|
' [name]: \'func\',\n' +
|
||||||
|
' [prototype]: func { [constructor]: [Circular] } } } }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%o %o', obj, obj),
|
||||||
|
'{ foo: \'bar\',\n' +
|
||||||
|
' foobar: 1,\n' +
|
||||||
|
' func: \n' +
|
||||||
|
' { [Function: func]\n' +
|
||||||
|
' [length]: 0,\n' +
|
||||||
|
' [name]: \'func\',\n' +
|
||||||
|
' [prototype]: func { [constructor]: [Circular] } } }' +
|
||||||
|
' { foo: \'bar\',\n' +
|
||||||
|
' foobar: 1,\n' +
|
||||||
|
' func: \n' +
|
||||||
|
' { [Function: func]\n' +
|
||||||
|
' [length]: 0,\n' +
|
||||||
|
' [name]: \'func\',\n' +
|
||||||
|
' [prototype]: func { [constructor]: [Circular] } } }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%o %o', obj),
|
||||||
|
'{ foo: \'bar\',\n' +
|
||||||
|
' foobar: 1,\n' +
|
||||||
|
' func: \n' +
|
||||||
|
' { [Function: func]\n' +
|
||||||
|
' [length]: 0,\n' +
|
||||||
|
' [name]: \'func\',\n' +
|
||||||
|
' [prototype]: func { [constructor]: [Circular] } } } %o');
|
||||||
|
|
||||||
|
assert.strictEqual(util.format('%O'), '%O');
|
||||||
|
assert.strictEqual(util.format('%O', 42), '42');
|
||||||
|
assert.strictEqual(util.format('%O', 'foo'), '\'foo\'');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%O', obj),
|
||||||
|
'{ foo: \'bar\', foobar: 1, func: [Function: func] }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%O', nestedObj),
|
||||||
|
'{ foo: \'bar\', foobar: { foo: \'bar\', func: [Function: func] } }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%O %O', obj, obj),
|
||||||
|
'{ foo: \'bar\', foobar: 1, func: [Function: func] } ' +
|
||||||
|
'{ foo: \'bar\', foobar: 1, func: [Function: func] }');
|
||||||
|
assert.strictEqual(
|
||||||
|
util.format('%O %O', obj),
|
||||||
|
'{ foo: \'bar\', foobar: 1, func: [Function: func] } %O');
|
||||||
|
|
||||||
// Various format specifiers
|
// Various format specifiers
|
||||||
assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo');
|
assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo');
|
||||||
assert.strictEqual(util.format('%s:%s'), '%s:%s');
|
assert.strictEqual(util.format('%s:%s'), '%s:%s');
|
||||||
@ -125,6 +203,10 @@ assert.strictEqual(util.format('%f:%f'), '%f:%f');
|
|||||||
assert.strictEqual(util.format('o: %j, a: %j', {}, []), 'o: {}, a: []');
|
assert.strictEqual(util.format('o: %j, a: %j', {}, []), 'o: {}, a: []');
|
||||||
assert.strictEqual(util.format('o: %j, a: %j', {}), 'o: {}, a: %j');
|
assert.strictEqual(util.format('o: %j, a: %j', {}), 'o: {}, a: %j');
|
||||||
assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j');
|
assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j');
|
||||||
|
assert.strictEqual(util.format('o: %o, a: %O', {}, []), 'o: {}, a: []');
|
||||||
|
assert.strictEqual(util.format('o: %o, a: %o', {}), 'o: {}, a: %o');
|
||||||
|
assert.strictEqual(util.format('o: %O, a: %O'), 'o: %O, a: %O');
|
||||||
|
|
||||||
|
|
||||||
// Invalid format specifiers
|
// Invalid format specifiers
|
||||||
assert.strictEqual(util.format('a% b', 'x'), 'a% b x');
|
assert.strictEqual(util.format('a% b', 'x'), 'a% b x');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user