Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

console,util: revert #23162 #29592

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
71 changes: 39 additions & 32 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,28 +181,27 @@ The `--throw-deprecation` command line flag and `process.throwDeprecation`
property take precedence over `--trace-deprecation` and
`process.traceDeprecation`.

## util.format(format\[, ...args\])
## util.format(\[format\]\[, ...args\])
<!-- YAML
added: v0.5.3
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/29592
description: The output string's formatting will again dependent on the type
of the first argument.
- version: v12.11.0
pr-url: https://github.com/nodejs/node/pull/29606
description: The `%c` specifier is ignored now.
- version: v12.0.0
pr-url: https://github.com/nodejs/node/pull/23162
description: The output string's formatting is no longer dependent on the
type of the first argument. This change removes previously
present quotes from strings that were being output when the
first argument was not a string.
- version: v11.4.0
pr-url: https://github.com/nodejs/node/pull/23708
description: The `%d`, `%f` and `%i` specifiers now support Symbols
properly.
- version: v12.0.0
pr-url: https://github.com/nodejs/node/pull/23162
description: The `format` argument is now only taken as such if it actually
contains format specifiers.
- version: v12.0.0
pr-url: https://github.com/nodejs/node/pull/23162
description: If the `format` argument is not a format string, the output
string's formatting is no longer dependent on the type of the
first argument. This change removes previously present quotes
from strings that were being output when the first argument
was not a string.
- version: v11.4.0
pr-url: https://github.com/nodejs/node/pull/24806
description: The `%o` specifier's `depth` has default depth of 4 again.
Expand All @@ -219,11 +218,14 @@ changes:
-->

* `format` {string} A `printf`-like format string.
* `...args` {any}
* Returns: {string} The formatted string

The `util.format()` method returns a formatted string using the first argument
as a `printf`-like format string which can contain zero or more format
specifiers. Each specifier is replaced with the converted value from the
corresponding argument. Supported specifiers are:
If the first argument `format` is a string and `args` is not empty, the
`util.format()` method returns a formatted string using the first argument as a
`printf`-like format string which can contain zero or more format specifiers.
Each specifier is replaced with the converted value from the corresponding
argument. Supported specifiers are:

* `%s` - `String` will be used to convert all values except `BigInt`, `Object`
and `-0`. `BigInt` values will be represented with an `n` and Objects that
Expand All @@ -246,7 +248,6 @@ corresponding argument. Supported specifiers are:
* `%c` - `CSS`. This specifier is currently ignored, and will skip any CSS
passed in.
* `%%` - single percent sign (`'%'`). This does not consume an argument.
* Returns: {string} The formatted string

If a specifier does not have a corresponding argument, it is not replaced:

Expand All @@ -255,45 +256,51 @@ util.format('%s:%s', 'foo');
// Returns: 'foo:%s'
```

Values that are not part of the format string are formatted using
`util.inspect()` if their type is not `string`.

If there are more arguments passed to the `util.format()` method than the
number of specifiers, the extra arguments are concatenated to the returned
string, separated by spaces:
If there are more arguments than the number of specifiers, the extra arguments
are concatenated to the returned string, separated by spaces:

```js
util.format('%s:%s', 'foo', 'bar', 'baz');
// Returns: 'foo:bar baz'
```

If the first argument does not contain a valid format specifier, `util.format()`
returns a string that is the concatenation of all arguments separated by spaces:
Values that are not consumed by the format string are formatted using
`util.inspect()` if their type is not `string`:

```js
util.format(1, 2, 3);
// Returns: '1 2 3'
util.format('string', 5n, 'string');
// Returns 'string 5n string'
```

If only one argument is passed to `util.format()`, it is returned as it is
without any formatting:
All values are formatted using `util.inspect()`, if the first argument's type is
not `string`:

```js
util.format('%% %s');
// Returns: '%% %s'
util.format(5n, 'string \n line 1', [1]);
// Returns: "5n 'string \\n line 1' [ 1 ]"
```

If only a single argument of type `string` is passed to `util.format()`, it is
returned as it is without any formatting:

```js
util.format('%% %s \n line 2');
// Returns: '%% %s \n line 2'
```

`util.format()` is a synchronous method that is intended as a debugging tool.
Some input values can have a significant performance overhead that can block the
event loop. Use this function with care and never in a hot code path.

## util.formatWithOptions(inspectOptions, format\[, ...args\])
## util.formatWithOptions(inspectOptions\[, format\]\[, ...args\])
<!-- YAML
added: v10.0.0
-->

* `inspectOptions` {Object}
* `format` {string}
* `...args` {any}
* Returns: {string}

This function is identical to [`util.format()`][], except in that it takes
an `inspectOptions` argument which specifies options that are passed along to
Expand Down
6 changes: 5 additions & 1 deletion lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1700,7 +1700,11 @@ function formatWithOptionsInternal(inspectOptions, ...args) {
while (a < args.length) {
const value = args[a];
str += join;
str += typeof value !== 'string' ? inspect(value, inspectOptions) : value;
if (typeof value !== 'string' || typeof first !== 'string') {
str += inspect(value, inspectOptions);
} else {
str += value;
}
join = ' ';
a++;
}
Expand Down
18 changes: 13 additions & 5 deletions test/parallel/test-util-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,17 +367,17 @@ Object.setPrototypeOf(BadCustomError, Error);
assert.strictEqual(util.format(new BadCustomError('foo')),
'[BadCustomError: foo]');

// The format of arguments should not depend on type of the first argument
// The argument formatting depends on the type of the first argument.
assert.strictEqual(util.format('1', '1'), '1 1');
assert.strictEqual(util.format(1, '1'), '1 1');
assert.strictEqual(util.format(1, '1'), "1 '1'");
assert.strictEqual(util.format('1', 1), '1 1');
assert.strictEqual(util.format(1, -0), '1 -0');
assert.strictEqual(util.format('1', () => {}), '1 [Function (anonymous)]');
assert.strictEqual(util.format(1, () => {}), '1 [Function (anonymous)]');
assert.strictEqual(util.format('1', "'"), "1 '");
assert.strictEqual(util.format(1, "'"), "1 '");
assert.strictEqual(util.format(1, "'"), '1 "\'"');
assert.strictEqual(util.format('1', 'number'), '1 number');
assert.strictEqual(util.format(1, 'number'), '1 number');
assert.strictEqual(util.format(1, 'number'), "1 'number'");
assert.strictEqual(util.format(5n), '5n');
assert.strictEqual(util.format(5n, 5n), '5n 5n');

Expand All @@ -393,7 +393,15 @@ assert.strictEqual(
'\u001b[33m1\u001b[39m ' +
'\u001b[33m5n\u001b[39m ' +
'\u001b[1mnull\u001b[22m ' +
'foobar'
"\u001b[32m'foobar'\u001b[39m"
);

assert.strictEqual(
util.formatWithOptions(
{ colors: true },
'string', true, 'foobar'
),
'string \u001b[33mtrue\u001b[39m foobar'
);

assert.strictEqual(
Expand Down