diff options
-rw-r--r-- | doc/api/console.md | 27 | ||||
-rw-r--r-- | lib/console.js | 24 | ||||
-rw-r--r-- | test/parallel/test-console-group.js | 111 |
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(); +} |