console: add console.count() and console.clear()
Both are simple utility functions defined by the WHATWG console spec (https://console.spec.whatwg.org/). PR-URL: https://github.com/nodejs/node/pull/12678 Ref: https://github.com/nodejs/node/issues/12675 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
parent
98bae29304
commit
cc43c8fb54
@ -167,6 +167,76 @@ console.assert(false, 'this message will print, but no error thrown');
|
|||||||
console.log('this will also print');
|
console.log('this will also print');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### console.clear()
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
When `stdout` is a TTY, calling `console.clear()` will attempt to clear the
|
||||||
|
TTY. When `stdout` is not a TTY, this method does nothing.
|
||||||
|
|
||||||
|
*Note*: The specific operation of `console.clear()` can vary across operating
|
||||||
|
systems and terminal types. For most Linux operating systems, `console.clear()`
|
||||||
|
operates similarly to the `clear` shell command. On Windows, `console.clear()`
|
||||||
|
will clear only the output in the current terminal viewport for the Node.js
|
||||||
|
binary.
|
||||||
|
|
||||||
|
### console.count([label])
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* `label` {string} The display label for the counter. Defaults to `'default'`.
|
||||||
|
|
||||||
|
Maintains an internal counter specific to `label` and outputs to `stdout` the
|
||||||
|
number of times `console.count()` has been called with the given `label`.
|
||||||
|
|
||||||
|
<!-- eslint-skip -->
|
||||||
|
```js
|
||||||
|
> console.count()
|
||||||
|
default: 1
|
||||||
|
undefined
|
||||||
|
> console.count('default')
|
||||||
|
default: 2
|
||||||
|
undefined
|
||||||
|
> console.count('abc')
|
||||||
|
abc: 1
|
||||||
|
undefined
|
||||||
|
> console.count('xyz')
|
||||||
|
xyz: 1
|
||||||
|
undefined
|
||||||
|
> console.count('abc')
|
||||||
|
abc: 2
|
||||||
|
undefined
|
||||||
|
> console.count()
|
||||||
|
default: 3
|
||||||
|
undefined
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
### console.countReset([label = 'default'])
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* `label` {string} The display label for the counter. Defaults to `'default'`.
|
||||||
|
|
||||||
|
Resets the internal counter specific to `label`.
|
||||||
|
|
||||||
|
<!-- eslint-skip -->
|
||||||
|
```js
|
||||||
|
> console.count('abc');
|
||||||
|
abc: 1
|
||||||
|
undefined
|
||||||
|
> console.countReset('abc');
|
||||||
|
undefined
|
||||||
|
> console.count('abc');
|
||||||
|
abc: 1
|
||||||
|
undefined
|
||||||
|
>
|
||||||
|
```
|
||||||
|
<!-- eslint-enable -->
|
||||||
|
|
||||||
### console.dir(obj[, options])
|
### console.dir(obj[, options])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.1.101
|
added: v0.1.101
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
const errors = require('internal/errors');
|
const errors = require('internal/errors');
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
|
const kCounts = Symbol('counts');
|
||||||
|
|
||||||
function Console(stdout, stderr, ignoreErrors = true) {
|
function Console(stdout, stderr, ignoreErrors = true) {
|
||||||
if (!(this instanceof Console)) {
|
if (!(this instanceof Console)) {
|
||||||
@ -55,6 +56,8 @@ function Console(stdout, stderr, ignoreErrors = true) {
|
|||||||
prop.value = createWriteErrorHandler(stderr);
|
prop.value = createWriteErrorHandler(stderr);
|
||||||
Object.defineProperty(this, '_stderrErrorHandler', prop);
|
Object.defineProperty(this, '_stderrErrorHandler', prop);
|
||||||
|
|
||||||
|
this[kCounts] = new Map();
|
||||||
|
|
||||||
// bind the prototype functions to this Console instance
|
// bind the prototype functions to this Console instance
|
||||||
var keys = Object.keys(Console.prototype);
|
var keys = Object.keys(Console.prototype);
|
||||||
for (var v = 0; v < keys.length; v++) {
|
for (var v = 0; v < keys.length; v++) {
|
||||||
@ -166,6 +169,42 @@ Console.prototype.assert = function assert(expression, ...args) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Defined by: https://console.spec.whatwg.org/#clear
|
||||||
|
Console.prototype.clear = function clear() {
|
||||||
|
// It only makes sense to clear if _stdout is a TTY.
|
||||||
|
// Otherwise, do nothing.
|
||||||
|
if (this._stdout.isTTY) {
|
||||||
|
// The require is here intentionally to avoid readline being
|
||||||
|
// required too early when console is first loaded.
|
||||||
|
const { cursorTo, clearScreenDown } = require('readline');
|
||||||
|
cursorTo(this._stdout, 0, 0);
|
||||||
|
clearScreenDown(this._stdout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Defined by: https://console.spec.whatwg.org/#count
|
||||||
|
Console.prototype.count = function count(label = 'default') {
|
||||||
|
// Ensures that label is a string, and only things that can be
|
||||||
|
// coerced to strings. e.g. Symbol is not allowed
|
||||||
|
label = `${label}`;
|
||||||
|
const counts = this[kCounts];
|
||||||
|
let count = counts.get(label);
|
||||||
|
if (count === undefined)
|
||||||
|
count = 1;
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
counts.set(label, count);
|
||||||
|
this.log(`${label}: ${count}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Not yet defined by the https://console.spec.whatwg.org, but
|
||||||
|
// proposed to be added and currently implemented by Edge. Having
|
||||||
|
// the ability to reset counters is important to help prevent
|
||||||
|
// the counter from being a memory leak.
|
||||||
|
Console.prototype.countReset = function countReset(label = 'default') {
|
||||||
|
const counts = this[kCounts];
|
||||||
|
counts.delete(`${label}`);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = new Console(process.stdout, process.stderr);
|
module.exports = new Console(process.stdout, process.stderr);
|
||||||
module.exports.Console = Console;
|
module.exports.Console = Console;
|
||||||
|
22
test/parallel/test-console-clear.js
Normal file
22
test/parallel/test-console-clear.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const stdoutWrite = process.stdout.write;
|
||||||
|
|
||||||
|
// The sequence for moving the cursor to 0,0 and clearing screen down
|
||||||
|
const check = '\u001b[1;1H\u001b[0J';
|
||||||
|
|
||||||
|
function doTest(isTTY, check) {
|
||||||
|
let buf = '';
|
||||||
|
process.stdout.isTTY = isTTY;
|
||||||
|
process.stdout.write = (string) => buf += string;
|
||||||
|
console.clear();
|
||||||
|
process.stdout.write = stdoutWrite;
|
||||||
|
assert.strictEqual(buf, check);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fake TTY
|
||||||
|
doTest(true, check);
|
||||||
|
doTest(false, '');
|
63
test/parallel/test-console-count.js
Normal file
63
test/parallel/test-console-count.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const stdoutWrite = process.stdout.write;
|
||||||
|
|
||||||
|
let buf = '';
|
||||||
|
|
||||||
|
process.stdout.write = (string) => buf = string;
|
||||||
|
|
||||||
|
console.count();
|
||||||
|
assert.strictEqual(buf, 'default: 1\n');
|
||||||
|
|
||||||
|
// 'default' and undefined are equivalent
|
||||||
|
console.count('default');
|
||||||
|
assert.strictEqual(buf, 'default: 2\n');
|
||||||
|
|
||||||
|
console.count('a');
|
||||||
|
assert.strictEqual(buf, 'a: 1\n');
|
||||||
|
|
||||||
|
console.count('b');
|
||||||
|
assert.strictEqual(buf, 'b: 1\n');
|
||||||
|
|
||||||
|
console.count('a');
|
||||||
|
assert.strictEqual(buf, 'a: 2\n');
|
||||||
|
|
||||||
|
console.count();
|
||||||
|
assert.strictEqual(buf, 'default: 3\n');
|
||||||
|
|
||||||
|
console.count({});
|
||||||
|
assert.strictEqual(buf, '[object Object]: 1\n');
|
||||||
|
|
||||||
|
console.count(1);
|
||||||
|
assert.strictEqual(buf, '1: 1\n');
|
||||||
|
|
||||||
|
console.count(null);
|
||||||
|
assert.strictEqual(buf, 'null: 1\n');
|
||||||
|
|
||||||
|
console.count('null');
|
||||||
|
assert.strictEqual(buf, 'null: 2\n');
|
||||||
|
|
||||||
|
console.countReset();
|
||||||
|
console.count();
|
||||||
|
assert.strictEqual(buf, 'default: 1\n');
|
||||||
|
|
||||||
|
console.countReset('a');
|
||||||
|
console.count('a');
|
||||||
|
assert.strictEqual(buf, 'a: 1\n');
|
||||||
|
|
||||||
|
// countReset('a') only reset the a counter
|
||||||
|
console.count();
|
||||||
|
assert.strictEqual(buf, 'default: 2\n');
|
||||||
|
|
||||||
|
process.stdout.write = stdoutWrite;
|
||||||
|
|
||||||
|
// Symbol labels do not work
|
||||||
|
assert.throws(
|
||||||
|
() => console.count(Symbol('test')),
|
||||||
|
/^TypeError: Cannot convert a Symbol value to a string$/);
|
||||||
|
assert.throws(
|
||||||
|
() => console.countReset(Symbol('test')),
|
||||||
|
/^TypeError: Cannot convert a Symbol value to a string$/);
|
Loading…
x
Reference in New Issue
Block a user