summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/console.md27
-rw-r--r--lib/console.js24
-rw-r--r--test/parallel/test-console-group.js111
3 files changed, 159 insertions, 3 deletions
diff --git a/doc/api/console.md b/doc/api/console.md
index 08fcfa027c..ee130d7b97 100644
--- a/doc/api/console.md
+++ b/doc/api/console.md
@@ -286,6 +286,32 @@ If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`][] is called on each argument and the resulting string
values are concatenated. See [`util.format()`][] for more information.
+### console.group([...label])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `label` {any}
+
+Increases indentation of subsequent lines by two spaces.
+
+If one or more `label`s are provided, those are printed first without the
+additional indentation.
+
+### console.groupCollapsed()
+<!-- YAML
+ added: REPLACEME
+-->
+
+An alias for [`console.group()`][].
+
+### console.groupEnd()
+<!-- YAML
+added: REPLACEME
+-->
+
+Decreases indentation of subsequent lines by two spaces.
+
### console.info([data][, ...args])
<!-- YAML
added: v0.1.100
@@ -390,6 +416,7 @@ added: v0.1.100
The `console.warn()` function is an alias for [`console.error()`][].
[`console.error()`]: #console_console_error_data_args
+[`console.group()`]: #console_console_group_label
[`console.log()`]: #console_console_log_data_args
[`console.time()`]: #console_console_time_label
[`console.timeEnd()`]: #console_console_timeend_label
diff --git a/lib/console.js b/lib/console.js
index b0701ba32c..13e3c05631 100644
--- a/lib/console.js
+++ b/lib/console.js
@@ -25,6 +25,9 @@ const errors = require('internal/errors');
const util = require('util');
const kCounts = Symbol('counts');
+// Track amount of indentation required via `console.group()`.
+const kGroupIndent = Symbol('groupIndent');
+
function Console(stdout, stderr, ignoreErrors = true) {
if (!(this instanceof Console)) {
return new Console(stdout, stderr, ignoreErrors);
@@ -57,6 +60,7 @@ function Console(stdout, stderr, ignoreErrors = true) {
Object.defineProperty(this, '_stderrErrorHandler', prop);
this[kCounts] = new Map();
+ this[kGroupIndent] = '';
// bind the prototype functions to this Console instance
var keys = Object.keys(Console.prototype);
@@ -111,7 +115,7 @@ function write(ignoreErrors, stream, string, errorhandler) {
Console.prototype.log = function log(...args) {
write(this._ignoreErrors,
this._stdout,
- `${util.format.apply(null, args)}\n`,
+ `${this[kGroupIndent]}${util.format.apply(null, args)}\n`,
this._stdoutErrorHandler);
};
@@ -122,7 +126,7 @@ Console.prototype.info = Console.prototype.log;
Console.prototype.warn = function warn(...args) {
write(this._ignoreErrors,
this._stderr,
- `${util.format.apply(null, args)}\n`,
+ `${this[kGroupIndent]}${util.format.apply(null, args)}\n`,
this._stderrErrorHandler);
};
@@ -134,7 +138,7 @@ Console.prototype.dir = function dir(object, options) {
options = Object.assign({ customInspect: false }, options);
write(this._ignoreErrors,
this._stdout,
- `${util.inspect(object, options)}\n`,
+ `${this[kGroupIndent]}${util.inspect(object, options)}\n`,
this._stdoutErrorHandler);
};
@@ -214,6 +218,20 @@ Console.prototype.countReset = function countReset(label = 'default') {
counts.delete(`${label}`);
};
+Console.prototype.group = function group(...data) {
+ if (data.length > 0) {
+ this.log(...data);
+ }
+ this[kGroupIndent] += ' ';
+};
+
+Console.prototype.groupCollapsed = Console.prototype.group;
+
+Console.prototype.groupEnd = function groupEnd() {
+ this[kGroupIndent] =
+ this[kGroupIndent].slice(0, this[kGroupIndent].length - 2);
+};
+
module.exports = new Console(process.stdout, process.stderr);
module.exports.Console = Console;
diff --git a/test/parallel/test-console-group.js b/test/parallel/test-console-group.js
new file mode 100644
index 0000000000..8f7d84f2f1
--- /dev/null
+++ b/test/parallel/test-console-group.js
@@ -0,0 +1,111 @@
+'use strict';
+const common = require('../common');
+
+const assert = require('assert');
+const Console = require('console').Console;
+
+let c, stdout, stderr;
+
+function setup() {
+ stdout = '';
+ common.hijackStdout(function(data) {
+ stdout += data;
+ });
+
+ stderr = '';
+ common.hijackStderr(function(data) {
+ stderr += data;
+ });
+
+ c = new Console(process.stdout, process.stderr);
+}
+
+function teardown() {
+ common.restoreStdout();
+ common.restoreStderr();
+}
+
+// Basic group() functionality
+{
+ setup();
+ const expectedOut = '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('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();
+}
+
+// Group indentation is tracked per Console instance.
+{
+ setup();
+ const expectedOut = 'No indentation\n' +
+ 'None here either\n' +
+ ' Now the first console is indenting\n' +
+ 'But the second one does not\n';
+ const expectedErr = '';
+
+ const c2 = new Console(process.stdout, process.stderr);
+ c.log('No indentation');
+ c2.log('None here either');
+ c.group();
+ c.log('Now the first console is indenting');
+ c2.log('But the second one does not');
+
+ assert.strictEqual(stdout, expectedOut);
+ assert.strictEqual(stderr, expectedErr);
+ teardown();
+}
+
+// Make sure labels work.
+{
+ setup();
+ const expectedOut = 'This is a label\n' +
+ ' And this is the data for that label\n';
+ const expectedErr = '';
+
+ c.group('This is a label');
+ c.log('And this is the data for that label');
+
+ assert.strictEqual(stdout, expectedOut);
+ assert.strictEqual(stderr, expectedErr);
+ teardown();
+}
+
+// Check that console.groupCollapsed() is an alias of console.group()
+{
+ setup();
+ const expectedOut = 'Label\n' +
+ ' Level 2\n' +
+ ' Level 3\n';
+ const expectedErr = '';
+
+ c.groupCollapsed('Label');
+ c.log('Level 2');
+ c.groupCollapsed();
+ c.log('Level 3');
+
+ assert.strictEqual(stdout, expectedOut);
+ assert.strictEqual(stderr, expectedErr);
+ teardown();
+}