Skip to content

Commit

Permalink
console: make .assert standard compliant
Browse files Browse the repository at this point in the history
The standard does not throw and has no stack trace.
See https://console.spec.whatwg.org/#assert

PR-URL: #17706
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
BridgeAR committed Dec 26, 2017
1 parent 9ca4ab1 commit 15d880b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 66 deletions.
70 changes: 16 additions & 54 deletions doc/api/console.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,70 +103,33 @@ The global `console` is a special `Console` whose output is sent to
new Console(process.stdout, process.stderr);
```

### console.assert(value[, message][, ...args])
### console.assert(value[, ...message])
<!-- YAML
added: v0.1.101
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/REPLACEME
description: The implementation is now spec compliant and does not throw
anymore.
-->
* `value` {any}
* `message` {any}
* `...args` {any}
* `value` {any} The value tested for being truthy.
* `...message` {any} All arguments besides `value` are used as error message.

A simple assertion test that verifies whether `value` is truthy. If it is not,
an `AssertionError` is thrown. If provided, the error `message` is formatted
using [`util.format()`][] and used as the error message.
`Assertion failed` is logged. If provided, the error `message` is formatted
using [`util.format()`][] by passing along all message arguments. The output is
used as the error message.

```js
console.assert(true, 'does nothing');
// OK
console.assert(false, 'Whoops %s', 'didn\'t work');
// AssertionError: Whoops didn't work
console.assert(false, 'Whoops %s work', 'didn\'t');
// Assertion failed: Whoops didn't work
```

*Note*: The `console.assert()` method is implemented differently in Node.js
than the `console.assert()` method [available in browsers][web-api-assert].

Specifically, in browsers, calling `console.assert()` with a falsy
assertion will cause the `message` to be printed to the console without
interrupting execution of subsequent code. In Node.js, however, a falsy
assertion will cause an `AssertionError` to be thrown.

Functionality approximating that implemented by browsers can be implemented
by extending Node.js' `console` and overriding the `console.assert()` method.

In the following example, a simple module is created that extends and overrides
the default behavior of `console` in Node.js.

<!-- eslint-disable func-name-matching -->
```js
'use strict';

// Creates a simple extension of console with a
// new impl for assert without monkey-patching.
const myConsole = Object.create(console, {
assert: {
value: function assert(assertion, message, ...args) {
try {
console.assert(assertion, message, ...args);
} catch (err) {
console.error(err.stack);
}
},
configurable: true,
enumerable: true,
writable: true,
},
});

module.exports = myConsole;
```

This can then be used as a direct replacement for the built in console:

```js
const console = require('./myConsole');
console.assert(false, 'this message will print, but no error thrown');
console.log('this will also print');
```
*Note*: Calling `console.assert()` with a falsy assertion will only cause the
`message` to be printed to the console without interrupting execution of
subsequent code.

### console.clear()
<!-- YAML
Expand Down Expand Up @@ -531,4 +494,3 @@ This method does not display anything unless used in the inspector. The
[customizing `util.inspect()` colors]: util.html#util_customizing_util_inspect_colors
[inspector]: debugger.html
[note on process I/O]: process.html#process_a_note_on_process_i_o
[web-api-assert]: https://developer.mozilla.org/en-US/docs/Web/API/console/assert
3 changes: 2 additions & 1 deletion lib/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ Console.prototype.trace = function trace(...args) {

Console.prototype.assert = function assert(expression, ...args) {
if (!expression) {
require('assert').ok(false, util.format.apply(null, args));
args[0] = `Assertion failed${args.length === 0 ? '' : `: ${args[0]}`}`;
this.warn(util.format.apply(null, args));
}
};

Expand Down
21 changes: 10 additions & 11 deletions test/parallel/test-console.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ console.timeEnd();
console.time(NaN);
console.timeEnd(NaN);

assert.doesNotThrow(() => {
console.assert(false, '%s should', 'console.assert', 'not throw');
assert.strictEqual(errStrings[errStrings.length - 1],
'Assertion failed: console.assert should not throw\n');
});

assert.doesNotThrow(() => {
console.assert(true, 'this should not throw');
});

assert.strictEqual(strings.length, process.stdout.writeTimes);
assert.strictEqual(errStrings.length, process.stderr.writeTimes);
common.restoreStdout();
Expand Down Expand Up @@ -200,17 +210,6 @@ assert.ok(/^NaN: \d+\.\d{3}ms$/.test(strings.shift().trim()));
assert.strictEqual(errStrings.shift().split('\n').shift(),
'Trace: This is a {"formatted":"trace"} 10 foo');

common.expectsError(() => {
console.assert(false, 'should throw');
}, {
code: 'ERR_ASSERTION',
message: /^should throw$/
});

assert.doesNotThrow(() => {
console.assert(true, 'this should not throw');
});

// hijack stderr to catch `process.emitWarning` which is using
// `process.nextTick`
common.hijackStderr(common.mustCall(function(data) {
Expand Down

0 comments on commit 15d880b

Please sign in to comment.