Skip to content

Commit

Permalink
assert: improve assert.fail() API
Browse files Browse the repository at this point in the history
assert.fail() has two possible function signatures, both of which are
not intuitive. It virtually guarantees that people who try to use
assert.fail() without carefully reading the docs will end up using it
incorrectly.

This change maintains backwards compatibility with the two valid uses
(arguments 1 2 and 4 supplied but argument 3 falsy, and argument 3
supplied but arguments 1 2 and 4 all falsy) but also adds the far more
intuitive first-argument-only and first-two-arguments-only
possibilities.

assert.fail('boom');
// AssertionError: boom

assert.fail('a', 'b');
// AssertionError: 'a' != 'b'

Backport-PR-URL: #15479
PR-URL: #12293
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
Trott authored and MylesBorins committed Oct 10, 2017
1 parent 1213f38 commit ddae3ca
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
9 changes: 8 additions & 1 deletion doc/api/assert.md
Expand Up @@ -194,14 +194,15 @@ If the values are not equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message` property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned. parameter is undefined, a default error message is assigned.


## assert.fail(message)
## assert.fail(actual, expected[, message[, operator[, stackStartFunction]]]) ## assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])
<!-- YAML <!-- YAML
added: v0.1.21 added: v0.1.21
--> -->
* `actual` {any} * `actual` {any}
* `expected` {any} * `expected` {any}
* `message` {any} * `message` {any}
* `operator` {string} * `operator` {string} (default: '!=')
* `stackStartFunction` {function} (default: `assert.fail`) * `stackStartFunction` {function} (default: `assert.fail`)


Throws an `AssertionError`. If `message` is falsy, the error message is set as Throws an `AssertionError`. If `message` is falsy, the error message is set as
Expand All @@ -221,6 +222,12 @@ assert.fail(1, 2, 'fail');


assert.fail(1, 2, 'whoops', '>'); assert.fail(1, 2, 'whoops', '>');
// AssertionError: whoops // AssertionError: whoops

assert.fail('boom');
// AssertionError: boom

assert.fail('a', 'b');
// AssertionError: 'a' != 'b'
``` ```


Example use of `stackStartFunction` for truncating the exception's stacktrace: Example use of `stackStartFunction` for truncating the exception's stacktrace:
Expand Down
4 changes: 4 additions & 0 deletions lib/assert.js
Expand Up @@ -77,6 +77,10 @@ function getMessage(self) {
// display purposes. // display purposes.


function fail(actual, expected, message, operator, stackStartFunction) { function fail(actual, expected, message, operator, stackStartFunction) {
if (arguments.length === 1)
message = actual;
if (arguments.length === 2)
operator = '!=';
throw new assert.AssertionError({ throw new assert.AssertionError({
message: message, message: message,
actual: actual, actual: actual,
Expand Down
30 changes: 30 additions & 0 deletions test/parallel/test-assert-fail.js
Expand Up @@ -3,6 +3,36 @@
require('../common'); require('../common');
const assert = require('assert'); const assert = require('assert');


// no args
assert.throws(
() => { assert.fail(); },
/^AssertionError: undefined undefined undefined$/
);

// one arg = message
assert.throws(
() => { assert.fail('custom message'); },
/^AssertionError: custom message$/
);

// two args only, operator defaults to '!='
assert.throws(
() => { assert.fail('first', 'second'); },
/^AssertionError: 'first' != 'second'$/
);

// three args
assert.throws(
() => { assert.fail('ignored', 'ignored', 'another custom message'); },
/^AssertionError: another custom message$/
);

// no third arg (but a fourth arg)
assert.throws(
() => { assert.fail('first', 'second', undefined, 'operator'); },
/^AssertionError: 'first' operator 'second'$/
);

// The stackFrameFunction should exclude the foo frame // The stackFrameFunction should exclude the foo frame
assert.throws( assert.throws(
function foo() { assert.fail('first', 'second', 'message', '!==', foo); }, function foo() { assert.fail('first', 'second', 'message', '!==', foo); },
Expand Down

0 comments on commit ddae3ca

Please sign in to comment.