Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

console: Support for console constructor groupIndentation options #32964

Closed
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions doc/api/console.md
Original file line number Diff line number Diff line change
@@ -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}
@@ -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
@@ -302,11 +307,16 @@ values are concatenated. See [`util.format()`][] for more information.
### `console.group([...label])`
<!-- YAML
added: v8.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/32964
description: The `groupIndentation` option was introduced.
-->

* `...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.
@@ -321,9 +331,14 @@ An alias for [`console.group()`][].
### `console.groupEnd()`
<!-- YAML
added: v8.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/32964
description: The `groupIndentation` option was introduced.
-->

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

### `console.info([data][, ...args])`
<!-- YAML
27 changes: 21 additions & 6 deletions lib/internal/console/constructor.js
Original file line number Diff line number Diff line change
@@ -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 {
@@ -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');
@@ -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') {
@@ -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) {
@@ -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 = {
@@ -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,
@@ -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
},
});
};

@@ -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
88 changes: 86 additions & 2 deletions test/parallel/test-console-group.js
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ const Console = require('console').Console;

let c, stdout, stderr;

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

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

function teardown() {
@@ -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/,
}
);
});
}