Skip to content

Commit

Permalink
util: add inspect.defaultOptions
Browse files Browse the repository at this point in the history
Adds util.inspect.defaultOptions which allows customization of the
default util.inspect options, which is useful for functions like
console.log or util.format which implicitly call into util.inspect.

PR-URL: #8013
Fixes: #7566
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
  • Loading branch information
silverwind authored and cjihrig committed Aug 10, 2016
1 parent 0daceff commit cfec3ae
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 15 deletions.
18 changes: 18 additions & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,23 @@ util.inspect(obj);
// "{ bar: 'baz' }"
```

### util.inspect.defaultOptions

The `defaultOptions` value allows customization of the default options used by
`util.inspect`. This is useful for functions like `console.log` or
`util.format` which implicitly call into `util.inspect`. It shall be set to an
object containing one or more valid [`util.inspect()`][] options. Setting
option properties directly is also supported.

```js
const util = require('util');
const arr = Array(101);

console.log(arr); // logs the truncated array
util.inspect.defaultOptions.maxArrayLength = null;
console.log(arr); // logs the full array
```

## Deprecated APIs

The following APIs have been deprecated and should no longer be used. Existing
Expand Down Expand Up @@ -662,6 +679,7 @@ similar built-in functionality through [`Object.assign()`].
[`Array.isArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
[constructor]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
[`util.inspect()`]: #util_util_inspect_object_options
[Customizing `util.inspect` colors]: #util_customizing_util_inspect_colors
[`Error`]: errors.html#errors_class_error
[`console.log()`]: console.html#console_console_log_data
Expand Down
42 changes: 27 additions & 15 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ const internalUtil = require('internal/util');
const binding = process.binding('util');

const isError = internalUtil.isError;
const kDefaultMaxLength = 100;

const inspectDefaultOptions = Object.seal({
showHidden: false,
depth: 2,
colors: false,
customInspect: true,
showProxy: false,
maxArrayLength: 100,
breakLength: 60
});

var Debug;
var simdFormatters;
Expand Down Expand Up @@ -176,29 +185,31 @@ function inspect(obj, opts) {
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (arguments[2] !== undefined) ctx.depth = arguments[2];
if (arguments[3] !== undefined) ctx.colors = arguments[3];
if (typeof opts === 'boolean') {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (ctx.showHidden === undefined) ctx.showHidden = false;
if (ctx.depth === undefined) ctx.depth = 2;
if (ctx.colors === undefined) ctx.colors = false;
if (ctx.customInspect === undefined) ctx.customInspect = true;
if (ctx.showProxy === undefined) ctx.showProxy = false;
// Set default and user-specified options
ctx = Object.assign({}, inspect.defaultOptions, ctx, opts);
if (ctx.colors) ctx.stylize = stylizeWithColor;
if (ctx.maxArrayLength === undefined) ctx.maxArrayLength = kDefaultMaxLength;
if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity;
if (ctx.breakLength === undefined) ctx.breakLength = 60;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;

Object.defineProperty(inspect, 'defaultOptions', {
get: function() {
return inspectDefaultOptions;
},
set: function(options) {
if (options === null || typeof options !== 'object') {
throw new TypeError('"options" must be an object');
}
Object.assign(inspectDefaultOptions, options);
return inspectDefaultOptions;
}
});

// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
Expand Down Expand Up @@ -231,6 +242,7 @@ inspect.styles = {
'regexp': 'red'
};

exports.inspect = inspect;

function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
Expand Down
41 changes: 41 additions & 0 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ assert.equal(util.inspect(Object.create({},
'{ visible: 1 }'
);

assert(/Object/.test(
util.inspect({a: {a: {a: {a: {}}}}}, undefined, undefined, true)
));
assert(!/Object/.test(
util.inspect({a: {a: {a: {a: {}}}}}, undefined, null, true)
));

for (const showHidden of [true, false]) {
const ab = new ArrayBuffer(4);
const dv = new DataView(ab, 1, 2);
Expand Down Expand Up @@ -723,3 +730,37 @@ checkAlignment(new Map(big_array.map(function(y) { return [y, null]; })));
assert.strictEqual(oneLine, util.inspect(obj, {breakLength: breakpoint + 1}));
assert.strictEqual(twoLines, '{ foo: \'abc\',\n bar: \'xyz\' }');
}

// util.inspect.defaultOptions tests
{
const arr = Array(101);
const obj = {a: {a: {a: {a: 1}}}};

const oldOptions = Object.assign({}, util.inspect.defaultOptions);

// Set single option through property assignment
util.inspect.defaultOptions.maxArrayLength = null;
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;
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};
assert(!/1 more item/.test(util.inspect(arr)));
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.strictEqual(
JSON.stringify(util.inspect.defaultOptions),
JSON.stringify(oldOptions)
);
}

0 comments on commit cfec3ae

Please sign in to comment.