Skip to content

Commit

Permalink
console: support console constructor groupIndentation option
Browse files Browse the repository at this point in the history
PR-URL: #32964
Fixes: #32947
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
rickyes authored and addaleax committed Apr 29, 2020
1 parent 38146e7 commit f68428b
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 16 deletions.
23 changes: 15 additions & 8 deletions doc/api/console.md
Expand Up @@ -81,16 +81,19 @@ const { Console } = console;
### `new Console(options)`
<!-- YAML
changes:
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/9744
description: The `ignoreErrors` option was introduced.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/32964
description: The `groupIndentation` option was introduced.
- version: v11.7.0
pr-url: https://github.com/nodejs/node/pull/24978
description: The `inspectOptions` option is introduced.
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/19372
description: The `Console` constructor now supports an `options` argument,
and the `colorMode` option was introduced.
- version: v11.7.0
pr-url: https://github.com/nodejs/node/pull/24978
description: The `inspectOptions` option is introduced.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/9744
description: The `ignoreErrors` option was introduced.
-->

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

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

* `...label` {any}

Increases indentation of subsequent lines by two spaces.
Increases indentation of subsequent lines by spaces for `groupIndentation`
length.

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

Decreases indentation of subsequent lines by two spaces.
Decreases indentation of subsequent lines by spaces for `groupIndentation`
length.

### `console.info([data][, ...args])`
<!-- YAML
Expand Down
27 changes: 21 additions & 6 deletions lib/internal/console/constructor.js
Expand Up @@ -32,6 +32,7 @@ const {
ERR_INCOMPATIBLE_OPTION_PAIR,
},
} = require('internal/errors');
const { validateInteger } = require('internal/validators');
const { previewEntries } = internalBinding('util');
const { Buffer: { isBuffer } } = require('buffer');
const {
Expand All @@ -52,12 +53,14 @@ const kTraceInstant = 'n'.charCodeAt(0);
const kSecond = 1000;
const kMinute = 60 * kSecond;
const kHour = 60 * kMinute;
const kMaxGroupIndentation = 1000;

// Lazy loaded for startup performance.
let cliTable;

// Track amount of indentation required via `console.group()`.
const kGroupIndent = Symbol('kGroupIndent');
const kGroupIndentationWidth = Symbol('kGroupIndentWidth');
const kFormatForStderr = Symbol('kFormatForStderr');
const kFormatForStdout = Symbol('kFormatForStdout');
const kGetInspectOptions = Symbol('kGetInspectOptions');
Expand Down Expand Up @@ -93,7 +96,8 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
stderr = stdout,
ignoreErrors = true,
colorMode = 'auto',
inspectOptions
inspectOptions,
groupIndentation,
} = options;

if (!stdout || typeof stdout.write !== 'function') {
Expand All @@ -106,6 +110,11 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
if (typeof colorMode !== 'boolean' && colorMode !== 'auto')
throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode);

if (groupIndentation !== undefined) {
validateInteger(groupIndentation, 'groupIndentation',
0, kMaxGroupIndentation);
}

if (typeof inspectOptions === 'object' && inspectOptions !== null) {
if (inspectOptions.colors !== undefined &&
options.colorMode !== undefined) {
Expand All @@ -130,7 +139,7 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
}

this[kBindStreamsEager](stdout, stderr);
this[kBindProperties](ignoreErrors, colorMode);
this[kBindProperties](ignoreErrors, colorMode, groupIndentation);
}

const consolePropAttributes = {
Expand Down Expand Up @@ -181,7 +190,8 @@ Console.prototype[kBindStreamsLazy] = function(object) {
});
};

Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) {
Console.prototype[kBindProperties] = function(ignoreErrors, colorMode,
groupIndentation = 2) {
ObjectDefineProperties(this, {
'_stdoutErrorHandler': {
...consolePropAttributes,
Expand All @@ -200,7 +210,11 @@ Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) {
[kCounts]: { ...consolePropAttributes, value: new Map() },
[kColorMode]: { ...consolePropAttributes, value: colorMode },
[kIsConsole]: { ...consolePropAttributes, value: true },
[kGroupIndent]: { ...consolePropAttributes, value: '' }
[kGroupIndent]: { ...consolePropAttributes, value: '' },
[kGroupIndentationWidth]: {
...consolePropAttributes,
value: groupIndentation
},
});
};

Expand Down Expand Up @@ -403,12 +417,13 @@ const consoleMethods = {
if (data.length > 0) {
this.log(...data);
}
this[kGroupIndent] += ' ';
this[kGroupIndent] += ' '.repeat(this[kGroupIndentationWidth]);
},

groupEnd() {
this[kGroupIndent] =
this[kGroupIndent].slice(0, this[kGroupIndent].length - 2);
this[kGroupIndent].slice(0, this[kGroupIndent].length -
this[kGroupIndentationWidth]);
},

// https://console.spec.whatwg.org/#table
Expand Down
88 changes: 86 additions & 2 deletions test/parallel/test-console-group.js
Expand Up @@ -12,7 +12,7 @@ const Console = require('console').Console;

let c, stdout, stderr;

function setup() {
function setup(groupIndentation) {
stdout = '';
hijackStdout(function(data) {
stdout += data;
Expand All @@ -25,7 +25,8 @@ function setup() {

c = new Console({ stdout: process.stdout,
stderr: process.stderr,
colorMode: false });
colorMode: false,
groupIndentation: groupIndentation });
}

function teardown() {
Expand Down Expand Up @@ -155,3 +156,86 @@ function teardown() {
assert(!keys.includes('Symbol(groupIndent)'),
'groupIndent should not be enumerable');
}

// Check custom groupIndentation.
{
setup(3);
const expectedOut = 'Set the groupIndentation parameter to 3\n' +
'This is the outer level\n' +
' Level 2\n' +
' Level 3\n' +
' Back to level 2\n' +
'Back to the outer level\n' +
'Still at the outer level\n';


const expectedErr = ' More of level 3\n';

c.log('Set the groupIndentation parameter to 3');
c.log('This is the outer level');
c.group();
c.log('Level 2');
c.group();
c.log('Level 3');
c.warn('More of level 3');
c.groupEnd();
c.log('Back to level 2');
c.groupEnd();
c.log('Back to the outer level');
c.groupEnd();
c.log('Still at the outer level');

assert.strictEqual(stdout, expectedOut);
assert.strictEqual(stderr, expectedErr);
teardown();
}

// Check the correctness of the groupIndentation parameter.
{
// TypeError
[null, 'str', [], false, true, {}].forEach((e) => {
assert.throws(
() => {
new Console({ stdout: process.stdout,
stderr: process.stderr,
groupIndentation: e });
},
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
}
);
});

// RangeError for integer
[NaN, 1.01].forEach((e) => {
assert.throws(
() => {
new Console({ stdout: process.stdout,
stderr: process.stderr,
groupIndentation: e });
},
{
code: 'ERR_OUT_OF_RANGE',
name: 'RangeError',
message: /an integer/,
}
);
});

// RangeError
[-1, 1001].forEach((e) => {
assert.throws(
() => {
new Console({ stdout: process.stdout,
stderr: process.stderr,
groupIndentation: e });
},
{
code: 'ERR_OUT_OF_RANGE',
name: 'RangeError',
message: />= 0 && <= 1000/,
}
);
});
}

0 comments on commit f68428b

Please sign in to comment.