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: make .assert standard compliant #17706

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
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 @@ -536,4 +499,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 @@ -199,7 +199,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