Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ corresponding argument. Supported placeholders are:
* `%f` - Floating point value.
* `%j` - JSON. Replaced with the string `'[Circular]'` if the argument
contains circular references.
* `%o` - Object. A string representation of an object.
Similar to `util.inspect()` without options.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Indent this line

* `%O` - Object. Same as `%o`.
* `%%` - single percent sign (`'%'`). This does not consume an argument.

If the placeholder does not have a corresponding argument, the placeholder is
Expand Down
6 changes: 6 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ function format(f) {
str += f.slice(lastPos, i);
str += String(arguments[a++]);
break;
case 79: // 'O'
case 111: // 'o'
if (lastPos < i)
str += f.slice(lastPos, i);
str += inspect(arguments[a++]);
break;
case 37: // '%'
if (lastPos < i)
str += f.slice(lastPos, i);
Expand Down
51 changes: 51 additions & 0 deletions test/parallel/test-util-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,53 @@ assert.strictEqual(util.format('%j', '42'), '"42"');
assert.strictEqual(util.format('%j %j', 42, 43), '42 43');
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\', 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');

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
assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo');
assert.strictEqual(util.format('%s:%s'), '%s:%s');
Expand All @@ -125,6 +172,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: %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
assert.strictEqual(util.format('a% b', 'x'), 'a% b x');
Expand Down