Skip to content

Commit

Permalink
util: change util.inspect depth default
Browse files Browse the repository at this point in the history
The current default is not ideal in most use cases. Therefore it is
changed to showing unlimited depth in case util.inspect is called
directly. The default is kept as before for console.log and similar.

Using console.dir will now show a depth of up to five and
console.assert / console.trace will show a unlimited depth.

PR-URL: #17907
Refs: #12693
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
BridgeAR committed Jan 16, 2018
1 parent 9d39581 commit b994b8e
Showing 6 changed files with 60 additions and 33 deletions.
33 changes: 24 additions & 9 deletions doc/api/util.md
Original file line number Diff line number Diff line change
@@ -327,6 +327,9 @@ stream.write('With ES6');
<!-- YAML
added: v0.3.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/17907
description: The `depth` default changed to Infinity.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/REPLACEME
description: The `compact` option is supported now.
@@ -349,9 +352,6 @@ changes:
* `options` {Object}
* `showHidden` {boolean} If `true`, the `object`'s non-enumerable symbols and
properties will be included in the formatted result. Defaults to `false`.
* `depth` {number} Specifies the number of times to recurse while formatting
the `object`. This is useful for inspecting large complicated objects.
Defaults to `2`. To make it recurse indefinitely pass `null`.
* `colors` {boolean} If `true`, the output will be styled with ANSI color
codes. Defaults to `false`. Colors are customizable, see
[Customizing `util.inspect` colors][].
@@ -362,8 +362,8 @@ changes:
objects. Defaults to `false`.
* `maxArrayLength` {number} Specifies the maximum number of array and
`TypedArray` elements to include when formatting. Defaults to `100`. Set to
`null` to show all array elements. Set to `0` or negative to show no array
elements.
`null` or `Infinity` to show all array elements. Set to `0` or negative to
show no array elements.
* `breakLength` {number} The length at which an object's keys are split
across multiple lines. Set to `Infinity` to format an object as a single
line. Defaults to 60 for legacy compatibility.
@@ -374,6 +374,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. Defaults to `true`.
* `depth` {number} Specifies the number visible nested Objects in an `object`.
This is useful to minimize the inspection output for large complicated
objects. To make it recurse indefinitely pass `null` or `Infinity`. Defaults
to `Infinity`.

The `util.inspect()` method returns a string representation of `object` that is
intended for debugging. The output of `util.inspect` may change at any time
@@ -398,12 +402,23 @@ util.inspect(new Bar()); // 'Bar {}'
util.inspect(baz); // '[foo] {}'
```

The following example inspects all properties of the `util` object:
The following example limits the inspected output of the `paths` property:

```js
const util = require('util');

console.log(util.inspect(util, { showHidden: true, depth: null }));
console.log(util.inspect(module, { depth: 0 }));
// Instead of showing all entries in `paths` `[Array]` is used to limit the
// output for readability:

// Module {
// id: '<repl>',
// exports: {},
// parent: undefined,
// filename: null,
// loaded: false,
// children: [],
// paths: [Array] }
```

Values may supply their own custom `inspect(depth, opts)` functions, when
@@ -423,7 +438,7 @@ const o = {
'foo']], 4],
b: new Map([['za', 1], ['zb', 'test']])
};
console.log(util.inspect(o, { compact: true, depth: 5, breakLength: 80 }));
console.log(util.inspect(o, { compact: true, breakLength: 80 }));

// This will print

@@ -437,7 +452,7 @@ console.log(util.inspect(o, { compact: true, depth: 5, breakLength: 80 }));
// b: Map { 'za' => 1, 'zb' => 'test' } }

// Setting `compact` to false changes the output to be more reader friendly.
console.log(util.inspect(o, { compact: false, depth: 5, breakLength: 80 }));
console.log(util.inspect(o, { compact: false, breakLength: 80 }));

// {
// a: [
5 changes: 3 additions & 2 deletions lib/repl.js
Original file line number Diff line number Diff line change
@@ -103,8 +103,9 @@ function hasOwnProperty(obj, prop) {
// Can overridden with custom print functions, such as `probe` or `eyes.js`.
// This is the default "writer" value if none is passed in the REPL options.
const writer = exports.writer = (obj) => util.inspect(obj, writer.options);
writer.options =
Object.assign({}, util.inspect.defaultOptions, { showProxy: true });
writer.options = Object.assign({},
util.inspect.defaultOptions,
{ showProxy: true, depth: 2 });

exports._builtinLibs = internalModule.builtinLibs;

5 changes: 2 additions & 3 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ const {

const inspectDefaultOptions = Object.seal({
showHidden: false,
depth: 2,
depth: null,
colors: false,
customInspect: true,
showProxy: false,
@@ -317,8 +317,7 @@ Object.defineProperty(inspect, 'defaultOptions', {
if (options === null || typeof options !== 'object') {
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'Object');
}
Object.assign(inspectDefaultOptions, options);
return inspectDefaultOptions;
return _extend(inspectDefaultOptions, options);
}
});

8 changes: 8 additions & 0 deletions test/parallel/test-stream-buffer-list.js
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
require('../common');
const assert = require('assert');
const BufferList = require('internal/streams/BufferList');
const util = require('util');

// Test empty buffer list.
const emptyList = new BufferList();
@@ -25,3 +26,10 @@ assert.strictEqual(list.join(','), 'foo');
const shifted = list.shift();
assert.strictEqual(shifted, 'foo');
assert.deepStrictEqual(list, new BufferList());

const tmp = util.inspect.defaultOptions.colors;
util.inspect.defaultOptions = { colors: true };
assert.strictEqual(
util.inspect(list),
'BufferList { length: \u001b[33m0\u001b[39m }');
util.inspect.defaultOptions = { colors: tmp };
16 changes: 10 additions & 6 deletions test/parallel/test-util-inspect-proxy.js
Original file line number Diff line number Diff line change
@@ -48,13 +48,17 @@ const expected1 = 'Proxy [ {}, {} ]';
const expected2 = 'Proxy [ Proxy [ {}, {} ], {} ]';
const expected3 = 'Proxy [ Proxy [ Proxy [ {}, {} ], {} ], Proxy [ {}, {} ] ]';
const expected4 = 'Proxy [ Proxy [ {}, {} ], Proxy [ Proxy [ {}, {} ], {} ] ]';
const expected5 = 'Proxy [ Proxy [ Proxy [ Proxy [Array], {} ],' +
const expected5 = 'Proxy [ Proxy [ Proxy [ Proxy [ {}, {} ], {} ],' +
' Proxy [ {}, {} ] ],\n Proxy [ Proxy [ {}, {} ]' +
', Proxy [ Proxy [Array], {} ] ] ]';
const expected6 = 'Proxy [ Proxy [ Proxy [ Proxy [Array], Proxy [Array]' +
' ],\n Proxy [ Proxy [Array], Proxy [Array] ] ],\n' +
' Proxy [ Proxy [ Proxy [Array], Proxy [Array] ],\n' +
' Proxy [ Proxy [Array], Proxy [Array] ] ] ]';
', Proxy [ Proxy [ {}, {} ], {} ] ] ]';
const expected6 = 'Proxy [ Proxy [ Proxy [ Proxy [ Proxy [ {}, {} ], {} ], ' +
'Proxy [ {}, {} ] ],\n' +
' Proxy [ Proxy [ {}, {} ], ' +
'Proxy [ Proxy [ {}, {} ], {} ] ] ],\n' +
' Proxy [ Proxy [ Proxy [ Proxy [ {}, {} ], {} ], ' +
'Proxy [ {}, {} ] ],\n' +
' Proxy [ Proxy [ {}, {} ], ' +
'Proxy [ Proxy [ {}, {} ], {} ] ] ] ]';
assert.strictEqual(
util.inspect(proxy1, { showProxy: true, depth: null }),
expected1);
26 changes: 13 additions & 13 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ assert.strictEqual(util.inspect({ a: 1, b: 2 }), '{ a: 1, b: 2 }');
assert.strictEqual(util.inspect({ 'a': {} }), '{ a: {} }');
assert.strictEqual(util.inspect({ 'a': { 'b': 2 } }), '{ a: { b: 2 } }');
assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }),
'{ a: { b: { c: [Object] } } }');
'{ a: { b: { c: { d: 2 } } } }');
assert.strictEqual(
util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }, false, null),
'{ a: { b: { c: { d: 2 } } } }');
@@ -106,7 +106,7 @@ assert.strictEqual(util.inspect((new JSStream())._externalStream),
assert.strictEqual(util.inspect({ a: regexp }, false, 0), '{ a: /regexp/ }');
}

assert(/Object/.test(
assert(!/Object/.test(
util.inspect({ a: { a: { a: { a: {} } } } }, undefined, undefined, true)
));
assert(!/Object/.test(
@@ -1012,15 +1012,15 @@ if (typeof Symbol !== 'undefined') {
// Empty and circular before depth
{
const arr = [[[[]]]];
assert.strictEqual(util.inspect(arr), '[ [ [ [] ] ] ]');
assert.strictEqual(util.inspect(arr, { depth: 2 }), '[ [ [ [] ] ] ]');
arr[0][0][0][0] = [];
assert.strictEqual(util.inspect(arr), '[ [ [ [Array] ] ] ]');
assert.strictEqual(util.inspect(arr, { depth: 2 }), '[ [ [ [Array] ] ] ]');
arr[0][0][0] = {};
assert.strictEqual(util.inspect(arr), '[ [ [ {} ] ] ]');
assert.strictEqual(util.inspect(arr, { depth: 2 }), '[ [ [ {} ] ] ]');
arr[0][0][0] = { a: 2 };
assert.strictEqual(util.inspect(arr), '[ [ [ [Object] ] ] ]');
assert.strictEqual(util.inspect(arr, { depth: 2 }), '[ [ [ [Object] ] ] ]');
arr[0][0][0] = arr;
assert.strictEqual(util.inspect(arr), '[ [ [ [Circular] ] ] ]');
assert.strictEqual(util.inspect(arr, { depth: 2 }), '[ [ [ [Circular] ] ] ]');
}

// Corner cases.
@@ -1117,22 +1117,22 @@ if (typeof Symbol !== 'undefined') {
assert(!/1 more item/.test(util.inspect(arr)));
util.inspect.defaultOptions.maxArrayLength = oldOptions.maxArrayLength;
assert(/1 more item/.test(util.inspect(arr)));
util.inspect.defaultOptions.depth = null;
assert(!/Object/.test(util.inspect(obj)));
util.inspect.defaultOptions.depth = oldOptions.depth;
util.inspect.defaultOptions.depth = 2;
assert(/Object/.test(util.inspect(obj)));
util.inspect.defaultOptions.depth = oldOptions.depth;
assert(!/Object/.test(util.inspect(obj)));
assert.strictEqual(
JSON.stringify(util.inspect.defaultOptions),
JSON.stringify(oldOptions)
);

// Set multiple options through object assignment
util.inspect.defaultOptions = { maxArrayLength: null, depth: null };
util.inspect.defaultOptions = { maxArrayLength: null, depth: 2 };
assert(!/1 more item/.test(util.inspect(arr)));
assert(!/Object/.test(util.inspect(obj)));
assert(/Object/.test(util.inspect(obj)));
util.inspect.defaultOptions = oldOptions;
assert(/1 more item/.test(util.inspect(arr)));
assert(/Object/.test(util.inspect(obj)));
assert(!/Object/.test(util.inspect(obj)));
assert.strictEqual(
JSON.stringify(util.inspect.defaultOptions),
JSON.stringify(oldOptions)

0 comments on commit b994b8e

Please sign in to comment.