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

[v10.x] Backport util PRs #23039

Closed
wants to merge 7 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
2 changes: 1 addition & 1 deletion benchmark/util/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const inputs = {
};

const bench = common.createBenchmark(main, {
n: [4e6],
n: [1e5],
type: Object.keys(inputs)
});

Expand Down
4 changes: 2 additions & 2 deletions benchmark/util/inspect-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const common = require('../common');
const util = require('util');

const bench = common.createBenchmark(main, {
n: [1e3],
len: [1e5],
n: [5e2],
len: [1e2, 1e5],
type: [
'denseArray',
'sparseArray',
Expand Down
2 changes: 1 addition & 1 deletion benchmark/util/inspect-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const util = require('util');
const common = require('../common.js');

const bench = common.createBenchmark(main, { n: [1e6] });
const bench = common.createBenchmark(main, { n: [2e4] });

function main({ n }) {
const proxyA = new Proxy({}, { get: () => {} });
Expand Down
4 changes: 2 additions & 2 deletions benchmark/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const opts = {
none: undefined
};
const bench = common.createBenchmark(main, {
n: [2e6],
n: [2e4],
method: [
'Object',
'Object_empty',
Expand Down Expand Up @@ -81,7 +81,7 @@ function main({ method, n, option }) {
benchmark(n, new Error('error'), options);
break;
case 'Array':
benchmark(n, Array(20).fill().map((_, i) => i), options);
benchmark(n, Array(50).fill().map((_, i) => i), options);
break;
case 'TypedArray':
obj = new Uint8Array(Array(50).fill().map((_, i) => i));
Expand Down
29 changes: 9 additions & 20 deletions benchmark/util/normalize-encoding.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@ const assert = require('assert');

const groupedInputs = {
group_common: ['undefined', 'utf8', 'utf-8', 'base64',
'binary', 'latin1', 'ucs-2'],
group_upper: ['UTF-8', 'UTF8', 'UCS2', 'UTF-16LE',
'UTF16LE', 'BASE64', 'UCS-2'],
group_uncommon: ['foo', '1', 'false', 'undefined', '[]', '{}'],
'binary', 'latin1', 'ucs2'],
group_upper: ['UTF-8', 'UTF8', 'UCS2',
'UTF16LE', 'BASE64', 'UCS2'],
group_uncommon: ['foo'],
group_misc: ['', 'utf16le', 'hex', 'HEX', 'BINARY']
};

const inputs = [
'',
'utf8', 'utf-8', 'UTF-8',
'UTF8', 'Utf8', 'uTf-8', 'utF-8',
'ucs2', 'UCS2', 'UcS2',
'ucs-2', 'UCS-2', 'UcS-2',
'utf16le', 'utf-16le', 'UTF-16LE', 'UTF16LE',
'', 'utf8', 'utf-8', 'UTF-8', 'UTF8', 'Utf8',
'ucs2', 'UCS2', 'utf16le', 'UTF16LE',
'binary', 'BINARY', 'latin1', 'base64', 'BASE64',
'hex', 'HEX', 'foo', '1', 'false', 'undefined', '[]', '{}'];
'hex', 'HEX', 'foo', 'undefined'
];

const bench = common.createBenchmark(main, {
input: inputs.concat(Object.keys(groupedInputs)),
n: [1e7]
n: [1e5]
}, {
flags: '--expose-internals'
});
Expand All @@ -39,16 +36,8 @@ function getInput(input) {
return groupedInputs.group_uncommon;
case 'group_misc':
return groupedInputs.group_misc;
case '1':
return [1];
case 'false':
return [false];
case 'undefined':
return [undefined];
case '[]':
return [[]];
case '{}':
return [{}];
default:
return [input];
}
Expand Down
2 changes: 1 addition & 1 deletion benchmark/util/splice-one.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const common = require('../common');

const bench = common.createBenchmark(main, {
n: [1e7],
n: [1e5],
pos: ['start', 'middle', 'end'],
size: [10, 100, 500],
}, { flags: ['--expose-internals'] });
Expand Down
2 changes: 1 addition & 1 deletion benchmark/util/type-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const bench = common.createBenchmark(main, {
type: Object.keys(args),
version: ['native', 'js'],
argument: ['true', 'false-primitive', 'false-object'],
n: [5e6]
n: [1e5]
}, {
flags: ['--expose-internals']
});
Expand Down
84 changes: 77 additions & 7 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ stream.write('With ES6');
<!-- YAML
added: v0.3.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/22788
description: The `sorted` option is supported now.
- version: v10.6.0
pr-url: https://github.com/nodejs/node/pull/20725
description: Inspecting linked lists and similar objects is now possible
Expand Down Expand Up @@ -420,7 +423,10 @@ changes:
objects the same as arrays. Note that no text will be reduced below 16
characters, no matter the `breakLength` size. For more information, see the
example below. **Default:** `true`.

* `sorted` {boolean|Function} If set to `true` or a function, all properties
of an object and Set and Map entries will be sorted in the returned string.
If set to `true` the [default sort][] is going to be used. If set to a
function, it is used as a [compare function][].
* Returns: {string} The representation of passed object

The `util.inspect()` method returns a string representation of `object` that is
Expand Down Expand Up @@ -534,6 +540,34 @@ console.log(inspect(weakSet, { showHidden: true }));
// WeakSet { { a: 1 }, { b: 2 } }
```

The `sorted` option makes sure the output is identical, no matter of the
properties insertion order:

```js
const { inspect } = require('util');
const assert = require('assert');

const o1 = {
b: [2, 3, 1],
a: '`a` comes before `b`',
c: new Set([2, 3, 1])
};
console.log(inspect(o1, { sorted: true }));
// { a: '`a` comes before `b`', b: [ 2, 3, 1 ], c: Set { 1, 2, 3 } }
console.log(inspect(o1, { sorted: (a, b) => b.localeCompare(a) }));
// { c: Set { 3, 2, 1 }, b: [ 2, 3, 1 ], a: '`a` comes before `b`' }

const o2 = {
c: new Set([2, 1, 3]),
a: '`a` comes before `b`',
b: [2, 3, 1]
};
assert.strict.equal(
inspect(o1, { sorted: true }),
inspect(o2, { sorted: true })
);
```

Please note that `util.inspect()` is a synchronous method that is mainly
intended as a debugging tool. Some input values can have a significant
performance overhead that can block the event loop. Use this function
Expand Down Expand Up @@ -572,9 +606,10 @@ terminals.

<!-- type=misc -->

Objects may also define their own `[util.inspect.custom](depth, opts)`
(or the equivalent but deprecated `inspect(depth, opts)`) function that
`util.inspect()` will invoke and use the result of when inspecting the object:
Objects may also define their own
[`[util.inspect.custom](depth, opts)`][util.inspect.custom] (or the equivalent
but deprecated `inspect(depth, opts)`) function, which `util.inspect()` will
invoke and use the result of when inspecting the object:

```js
const util = require('util');
Expand Down Expand Up @@ -626,10 +661,41 @@ util.inspect(obj);
### util.inspect.custom
<!-- YAML
added: v6.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/20857
description: This is now defined as a shared symbol.
-->

A {symbol} that can be used to declare custom inspect functions, see
[Custom inspection functions on Objects][].
* {symbol} that can be used to declare custom inspect functions.

In addition to being accessible through `util.inspect.custom`, this
symbol is [registered globally][global symbol registry] and can be
accessed in any environment as `Symbol.for('nodejs.util.inspect.custom')`.

```js
const inspect = Symbol.for('nodejs.util.inspect.custom');

class Password {
constructor(value) {
this.value = value;
}

toString() {
return 'xxxxxxxx';
}

[inspect]() {
return `Password <${this.toString()}>`;
}
}

const password = new Password('r0sebud');
console.log(password);
// Prints Password <xxxxxxxx>
```

See [Custom inspection functions on Objects][] for more details.

### util.inspect.defaultOptions
<!-- YAML
Expand Down Expand Up @@ -2076,7 +2142,6 @@ Deprecated predecessor of `console.log`.
[`Array.isArray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
[`ArrayBuffer.isView()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView
[async function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
[`assert.deepStrictEqual()`]: assert.html#assert_assert_deepstrictequal_actual_expected_message
[`Buffer.isBuffer()`]: buffer.html#buffer_class_method_buffer_isbuffer_obj
[`console.error()`]: console.html#console_console_error_data_args
Expand Down Expand Up @@ -2118,6 +2183,11 @@ Deprecated predecessor of `console.log`.
[Module Namespace Object]: https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects
[WHATWG Encoding Standard]: https://encoding.spec.whatwg.org/
[Common System Errors]: errors.html#errors_common_system_errors
[async function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
[compare function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters
[constructor]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
[default sort]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
[global symbol registry]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for
[list of deprecated APIS]: deprecations.html#deprecations_list_of_deprecated_apis
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
[util.inspect.custom]: #util_util_inspect_custom
2 changes: 1 addition & 1 deletion lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ module.exports = {

// Symbol used to provide a custom inspect function for an object as an
// alternative to using 'inspect'
customInspectSymbol: Symbol('util.inspect.custom'),
customInspectSymbol: Symbol.for('nodejs.util.inspect.custom'),

// Used by the buffer module to capture an internal reference to the
// default isEncoding implementation, just in case userland overrides it.
Expand Down
Loading