Skip to content

Commit 154b18f

Browse files
rickyestargos
authored andcommitted
console: support console constructor groupIndentation option
PR-URL: #32964 Fixes: #32947 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 71bccdd commit 154b18f

File tree

3 files changed

+123
-16
lines changed

3 files changed

+123
-16
lines changed

doc/api/console.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,19 @@ const { Console } = console;
8181
### `new Console(options)`
8282
<!-- YAML
8383
changes:
84-
- version: v8.0.0
85-
pr-url: https://github.com/nodejs/node/pull/9744
86-
description: The `ignoreErrors` option was introduced.
84+
- version: REPLACEME
85+
pr-url: https://github.com/nodejs/node/pull/32964
86+
description: The `groupIndentation` option was introduced.
87+
- version: v11.7.0
88+
pr-url: https://github.com/nodejs/node/pull/24978
89+
description: The `inspectOptions` option is introduced.
8790
- version: v10.0.0
8891
pr-url: https://github.com/nodejs/node/pull/19372
8992
description: The `Console` constructor now supports an `options` argument,
9093
and the `colorMode` option was introduced.
91-
- version: v11.7.0
92-
pr-url: https://github.com/nodejs/node/pull/24978
93-
description: The `inspectOptions` option is introduced.
94+
- version: v8.0.0
95+
pr-url: https://github.com/nodejs/node/pull/9744
96+
description: The `ignoreErrors` option was introduced.
9497
-->
9598

9699
* `options` {Object}
@@ -107,6 +110,8 @@ changes:
107110
**Default:** `'auto'`.
108111
* `inspectOptions` {Object} Specifies options that are passed along to
109112
[`util.inspect()`][].
113+
* `groupIndentation` {number} Set group indentation.
114+
**Default:** `2`.
110115

111116
Creates a new `Console` with one or two writable stream instances. `stdout` is a
112117
writable stream to print log or info output. `stderr` is used for warning or
@@ -306,7 +311,8 @@ added: v8.5.0
306311

307312
* `...label` {any}
308313

309-
Increases indentation of subsequent lines by two spaces.
314+
Increases indentation of subsequent lines by spaces for `groupIndentation`
315+
length.
310316

311317
If one or more `label`s are provided, those are printed first without the
312318
additional indentation.
@@ -323,7 +329,8 @@ An alias for [`console.group()`][].
323329
added: v8.5.0
324330
-->
325331

326-
Decreases indentation of subsequent lines by two spaces.
332+
Decreases indentation of subsequent lines by spaces for `groupIndentation`
333+
length.
327334

328335
### `console.info([data][, ...args])`
329336
<!-- YAML

lib/internal/console/constructor.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const {
3030
ERR_INCOMPATIBLE_OPTION_PAIR,
3131
},
3232
} = require('internal/errors');
33+
const { validateInteger } = require('internal/validators');
3334
const { previewEntries } = internalBinding('util');
3435
const { Buffer: { isBuffer } } = require('buffer');
3536
const {
@@ -47,11 +48,14 @@ const kTraceBegin = 'b'.charCodeAt(0);
4748
const kTraceEnd = 'e'.charCodeAt(0);
4849
const kTraceInstant = 'n'.charCodeAt(0);
4950

51+
const kMaxGroupIndentation = 1000;
52+
5053
// Lazy loaded for startup performance.
5154
let cliTable;
5255

5356
// Track amount of indentation required via `console.group()`.
5457
const kGroupIndent = Symbol('kGroupIndent');
58+
const kGroupIndentationWidth = Symbol('kGroupIndentWidth');
5559
const kFormatForStderr = Symbol('kFormatForStderr');
5660
const kFormatForStdout = Symbol('kFormatForStdout');
5761
const kGetInspectOptions = Symbol('kGetInspectOptions');
@@ -87,7 +91,8 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
8791
stderr = stdout,
8892
ignoreErrors = true,
8993
colorMode = 'auto',
90-
inspectOptions
94+
inspectOptions,
95+
groupIndentation,
9196
} = options;
9297

9398
if (!stdout || typeof stdout.write !== 'function') {
@@ -100,6 +105,11 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
100105
if (typeof colorMode !== 'boolean' && colorMode !== 'auto')
101106
throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode);
102107

108+
if (groupIndentation !== undefined) {
109+
validateInteger(groupIndentation, 'groupIndentation',
110+
0, kMaxGroupIndentation);
111+
}
112+
103113
if (typeof inspectOptions === 'object' && inspectOptions !== null) {
104114
if (inspectOptions.colors !== undefined &&
105115
options.colorMode !== undefined) {
@@ -124,7 +134,7 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
124134
}
125135

126136
this[kBindStreamsEager](stdout, stderr);
127-
this[kBindProperties](ignoreErrors, colorMode);
137+
this[kBindProperties](ignoreErrors, colorMode, groupIndentation);
128138
}
129139

130140
const consolePropAttributes = {
@@ -175,7 +185,8 @@ Console.prototype[kBindStreamsLazy] = function(object) {
175185
});
176186
};
177187

178-
Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) {
188+
Console.prototype[kBindProperties] = function(ignoreErrors, colorMode,
189+
groupIndentation = 2) {
179190
ObjectDefineProperties(this, {
180191
'_stdoutErrorHandler': {
181192
...consolePropAttributes,
@@ -194,7 +205,11 @@ Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) {
194205
[kCounts]: { ...consolePropAttributes, value: new Map() },
195206
[kColorMode]: { ...consolePropAttributes, value: colorMode },
196207
[kIsConsole]: { ...consolePropAttributes, value: true },
197-
[kGroupIndent]: { ...consolePropAttributes, value: '' }
208+
[kGroupIndent]: { ...consolePropAttributes, value: '' },
209+
[kGroupIndentationWidth]: {
210+
...consolePropAttributes,
211+
value: groupIndentation
212+
},
198213
});
199214
};
200215

@@ -397,12 +412,13 @@ const consoleMethods = {
397412
if (data.length > 0) {
398413
this.log(...data);
399414
}
400-
this[kGroupIndent] += ' ';
415+
this[kGroupIndent] += ' '.repeat(this[kGroupIndentationWidth]);
401416
},
402417

403418
groupEnd() {
404419
this[kGroupIndent] =
405-
this[kGroupIndent].slice(0, this[kGroupIndent].length - 2);
420+
this[kGroupIndent].slice(0, this[kGroupIndent].length -
421+
this[kGroupIndentationWidth]);
406422
},
407423

408424
// https://console.spec.whatwg.org/#table

test/parallel/test-console-group.js

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const Console = require('console').Console;
1212

1313
let c, stdout, stderr;
1414

15-
function setup() {
15+
function setup(groupIndentation) {
1616
stdout = '';
1717
hijackStdout(function(data) {
1818
stdout += data;
@@ -25,7 +25,8 @@ function setup() {
2525

2626
c = new Console({ stdout: process.stdout,
2727
stderr: process.stderr,
28-
colorMode: false });
28+
colorMode: false,
29+
groupIndentation: groupIndentation });
2930
}
3031

3132
function teardown() {
@@ -155,3 +156,86 @@ function teardown() {
155156
assert(!keys.includes('Symbol(groupIndent)'),
156157
'groupIndent should not be enumerable');
157158
}
159+
160+
// Check custom groupIndentation.
161+
{
162+
setup(3);
163+
const expectedOut = 'Set the groupIndentation parameter to 3\n' +
164+
'This is the outer level\n' +
165+
' Level 2\n' +
166+
' Level 3\n' +
167+
' Back to level 2\n' +
168+
'Back to the outer level\n' +
169+
'Still at the outer level\n';
170+
171+
172+
const expectedErr = ' More of level 3\n';
173+
174+
c.log('Set the groupIndentation parameter to 3');
175+
c.log('This is the outer level');
176+
c.group();
177+
c.log('Level 2');
178+
c.group();
179+
c.log('Level 3');
180+
c.warn('More of level 3');
181+
c.groupEnd();
182+
c.log('Back to level 2');
183+
c.groupEnd();
184+
c.log('Back to the outer level');
185+
c.groupEnd();
186+
c.log('Still at the outer level');
187+
188+
assert.strictEqual(stdout, expectedOut);
189+
assert.strictEqual(stderr, expectedErr);
190+
teardown();
191+
}
192+
193+
// Check the correctness of the groupIndentation parameter.
194+
{
195+
// TypeError
196+
[null, 'str', [], false, true, {}].forEach((e) => {
197+
assert.throws(
198+
() => {
199+
new Console({ stdout: process.stdout,
200+
stderr: process.stderr,
201+
groupIndentation: e });
202+
},
203+
{
204+
code: 'ERR_INVALID_ARG_TYPE',
205+
name: 'TypeError'
206+
}
207+
);
208+
});
209+
210+
// RangeError for integer
211+
[NaN, 1.01].forEach((e) => {
212+
assert.throws(
213+
() => {
214+
new Console({ stdout: process.stdout,
215+
stderr: process.stderr,
216+
groupIndentation: e });
217+
},
218+
{
219+
code: 'ERR_OUT_OF_RANGE',
220+
name: 'RangeError',
221+
message: /an integer/,
222+
}
223+
);
224+
});
225+
226+
// RangeError
227+
[-1, 1001].forEach((e) => {
228+
assert.throws(
229+
() => {
230+
new Console({ stdout: process.stdout,
231+
stderr: process.stderr,
232+
groupIndentation: e });
233+
},
234+
{
235+
code: 'ERR_OUT_OF_RANGE',
236+
name: 'RangeError',
237+
message: />= 0 && <= 1000/,
238+
}
239+
);
240+
});
241+
}

0 commit comments

Comments
 (0)