diff --git a/doc/api/util.md b/doc/api/util.md index d6be620b42c56d..c1813fa0c540f7 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -557,12 +557,11 @@ changes: (in combination with `compact` set to `true` or any number >= `1`). **Default:** `80`. * `compact` {boolean|integer} Setting this to `false` causes each object key - to be displayed on a new line. It will also add new lines to text that is + to be displayed on a new line. It will break on new lines in text that is longer than `breakLength`. If set to a number, the most `n` inner elements are united on a single line as long as all properties fit into - `breakLength`. Short array elements are also grouped together. No - text will be reduced below 16 characters, no matter the `breakLength` size. - For more information, see the example below. **Default:** `3`. + `breakLength`. Short array elements are also grouped together. For more + information, see the example below. **Default:** `3`. * `sorted` {boolean|Function} If set to `true` or a function, all properties of an object, and `Set` and `Map` entries are sorted in the resulting string. If set to `true` the [default sort][] is used. If set to a function, @@ -630,8 +629,8 @@ const util = require('util'); const o = { a: [1, 2, [[ - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' + - 'eiusmod tempor incididunt ut labore et dolore magna aliqua.', + 'Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, sed do ' + + 'eiusmod \ntempor incididunt ut labore et dolore magna aliqua.', 'test', 'foo']], 4], b: new Map([['za', 1], ['zb', 'test']]) @@ -641,13 +640,13 @@ console.log(util.inspect(o, { compact: true, depth: 5, breakLength: 80 })); // { a: // [ 1, // 2, -// [ [ 'Lorem ipsum dolor sit amet, consectetur [...]', // A long line +// [ [ 'Lorem ipsum dolor sit amet,\nconsectetur [...]', // A long line // 'test', // 'foo' ] ], // 4 ], // b: Map(2) { 'za' => 1, 'zb' => 'test' } } -// Setting `compact` to false changes the output to be more reader friendly. +// Setting `compact` to false or an integer creates more reader friendly output. console.log(util.inspect(o, { compact: false, depth: 5, breakLength: 80 })); // { @@ -656,10 +655,9 @@ console.log(util.inspect(o, { compact: false, depth: 5, breakLength: 80 })); // 2, // [ // [ -// 'Lorem ipsum dolor sit amet, consectetur ' + -// 'adipiscing elit, sed do eiusmod tempor ' + -// 'incididunt ut labore et dolore magna ' + -// 'aliqua., +// 'Lorem ipsum dolor sit amet,\n' + +// 'consectetur adipiscing elit, sed do eiusmod \n' + +// 'tempor incididunt ut labore et dolore magna aliqua.', // 'test', // 'foo' // ] @@ -674,8 +672,6 @@ console.log(util.inspect(o, { compact: false, depth: 5, breakLength: 80 })); // Setting `breakLength` to e.g. 150 will print the "Lorem ipsum" text in a // single line. -// Reducing the `breakLength` will split the "Lorem ipsum" text in smaller -// chunks. ``` The `showHidden` option allows [`WeakMap`][] and [`WeakSet`][] entries to be diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index fed88e963a178c..ac2731d8112e79 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -5,6 +5,7 @@ const { ArrayIsArray, ArrayPrototypeFilter, ArrayPrototypeForEach, + ArrayPrototypePop, ArrayPrototypePush, ArrayPrototypePushApply, ArrayPrototypeSort, @@ -619,6 +620,7 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, output) { } // Get all own property names and symbols. keys = ReflectOwnKeys(obj); + ArrayPrototypePush(ctx.seen, main); for (const key of keys) { // Ignore the `constructor` property and keys that exist on layers above. if (key === 'constructor' || @@ -639,6 +641,7 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, output) { ArrayPrototypePush(output, value); } } + ArrayPrototypePop(ctx.seen); // Limit the inspection to up to three prototype layers. Using `recurseTimes` // is not a good choice here, because it's as if the properties are declared // on the current object from the users perspective. diff --git a/test/parallel/test-util-inspect-getters-accessing-this.js b/test/parallel/test-util-inspect-getters-accessing-this.js index 3d185b134e852d..998cd82db8f4b3 100644 --- a/test/parallel/test-util-inspect-getters-accessing-this.js +++ b/test/parallel/test-util-inspect-getters-accessing-this.js @@ -7,24 +7,61 @@ require('../common'); const assert = require('assert'); -const util = require('util'); +const { inspect } = require('util'); -class X { - constructor() { - this._y = 123; - } +{ + class X { + constructor() { + this._y = 123; + } - get y() { - return this._y; + get y() { + return this._y; + } } + + const result = inspect(new X(), { + getters: true, + showHidden: true + }); + + assert.strictEqual( + result, + 'X { _y: 123, [y]: [Getter: 123] }' + ); } -const result = util.inspect(new X(), { - getters: true, - showHidden: true -}); +// Regression test for https://github.com/nodejs/node/issues/37054 +{ + class A { + constructor(B) { + this.B = B; + } + get b() { + return this.B; + } + } + + class B { + constructor() { + this.A = new A(this); + } + get a() { + return this.A; + } + } + + const result = inspect(new B(), { + depth: 1, + getters: true, + showHidden: true + }); -assert.strictEqual( - result, - 'X { _y: 123, [y]: [Getter: 123] }' -); + assert.strictEqual( + result, + ' B {\n' + + ' A: A { B: [Circular *1], [b]: [Getter] [Circular *1] },\n' + + ' [a]: [Getter] A { B: [Circular *1], [b]: [Getter] [Circular *1] }\n' + + '}', + ); +}