Skip to content

Commit

Permalink
assert: add strict functionality export
Browse files Browse the repository at this point in the history
Requireing the strict version will allow to use `assert.equal`,
`assert.deepEqual` and there negated counterparts to be used with
strict comparison instead of using e.g. `assert.strictEqual`.

The API is identical to the regular assert export and only differs
in the way that all functions use strict compairson.

Backport-PR-URL: #19230
PR-URL: #17002
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
BridgeAR authored and MylesBorins committed Mar 20, 2018
1 parent 5a78c6c commit bae5de1
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 19 deletions.
103 changes: 95 additions & 8 deletions doc/api/assert.md
Expand Up @@ -7,6 +7,57 @@
The `assert` module provides a simple set of assertion tests that can be used to
test invariants.

A `strict` and a `legacy` mode exist, while it is recommended to only use
[`strict mode`][].

For more information about the used equality comparisons see
[MDN's guide on equality comparisons and sameness][mdn-equality-guide].

## Strict mode
<!-- YAML
added: REPLACEME
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/17002
description: Added strict mode to the assert module.
-->

When using the `strict mode`, any `assert` function will use the equality used in
the strict function mode. So [`assert.deepEqual()`][] will, for example, work the
same as [`assert.deepStrictEqual()`][].

It can be accessed using:

```js
const assert = require('assert').strict;
```

## Legacy mode

> Stability: 0 - Deprecated: Use strict mode instead.
When accessing `assert` directly instead of using the `strict` property, the
[Abstract Equality Comparison][] will be used for any function without a
"strict" in its name (e.g. [`assert.deepEqual()`][]).

It can be accessed using:

```js
const assert = require('assert');
```

It is recommended to use the [`strict mode`][] instead as the
[Abstract Equality Comparison][] can often have surprising results. Especially
in case of [`assert.deepEqual()`][] as the used comparison rules there are very
lax.

E.g.

```js
// WARNING: This does not throw an AssertionError!
assert.deepEqual(/a/gi, new Date());
```

## assert(value[, message])
<!-- YAML
added: v0.5.9
Expand Down Expand Up @@ -40,6 +91,14 @@ changes:
* `expected` {any}
* `message` {any}

**Strict mode**

An alias of [`assert.deepStrictEqual()`][].

**Legacy mode**

> Stability: 0 - Deprecated: Use [`assert.deepStrictEqual()`][] instead.
Tests for deep equality between the `actual` and `expected` parameters.
Primitive values are compared with the [Abstract Equality Comparison][]
( `==` ).
Expand Down Expand Up @@ -146,7 +205,7 @@ are recursively evaluated also by the following rules.
[`Object.is()`][].
* [Type tags][Object.prototype.toString()] of objects should be the same.
* [`[[Prototype]]`][prototype-spec] of objects are compared using
the [Strict Equality Comparison][] too.
the [Strict Equality Comparison][].
* Only [enumerable "own" properties][] are considered.
* [`Error`][] names and messages are always compared, even if these are not
enumerable properties.
Expand All @@ -158,7 +217,7 @@ are recursively evaluated also by the following rules.
reference.

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
Expand Down Expand Up @@ -278,6 +337,14 @@ added: v0.1.21
* `expected` {any}
* `message` {any}

**Strict mode**

An alias of [`assert.strictEqual()`][].

**Legacy mode**

> Stability: 0 - Deprecated: Use [`assert.strictEqual()`][] instead.
Tests shallow, coercive equality between the `actual` and `expected` parameters
using the [Abstract Equality Comparison][] ( `==` ).

Expand Down Expand Up @@ -324,7 +391,7 @@ all stack frames above that function will be removed from stacktrace (see
`Failed` will be used.

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2
Expand Down Expand Up @@ -375,7 +442,7 @@ Throws `value` if `value` is truthy. This is useful when testing the `error`
argument in callbacks.

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.ifError(null);
// OK
Expand Down Expand Up @@ -413,6 +480,14 @@ changes:
* `expected` {any}
* `message` {any}

**Strict mode**

An alias of [`assert.notDeepStrictEqual()`][].

**Legacy mode**

> Stability: 0 - Deprecated: Use [`assert.notDeepStrictEqual()`][] instead.
Tests for any deep inequality. Opposite of [`assert.deepEqual()`][].

```js
Expand Down Expand Up @@ -489,7 +564,7 @@ changes:
Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][].

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
Expand All @@ -509,6 +584,14 @@ added: v0.1.21
* `expected` {any}
* `message` {any}

**Strict mode**

An alias of [`assert.notStrictEqual()`][].

**Legacy mode**

> Stability: 0 - Deprecated: Use [`assert.notStrictEqual()`][] instead.
Tests shallow, coercive inequality with the [Abstract Equality Comparison][]
( `!=` ).

Expand Down Expand Up @@ -543,7 +626,7 @@ Tests strict inequality between the `actual` and `expected` parameters as
determined by the [SameValue Comparison][].

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.notStrictEqual(1, 2);
// OK
Expand Down Expand Up @@ -578,7 +661,7 @@ parameter is an instance of an [`Error`][] then it will be thrown instead of the
`AssertionError`.

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.ok(true);
// OK
Expand All @@ -604,7 +687,7 @@ Tests strict equality between the `actual` and `expected` parameters as
determined by the [SameValue Comparison][].

```js
const assert = require('assert');
const assert = require('assert').strict;

assert.strictEqual(1, 2);
// AssertionError: 1 === 2
Expand Down Expand Up @@ -728,8 +811,12 @@ For more information, see
[`TypeError`]: errors.html#errors_class_typeerror
[`assert.deepEqual()`]: #assert_assert_deepequal_actual_expected_message
[`assert.deepStrictEqual()`]: #assert_assert_deepstrictequal_actual_expected_message
[`assert.notDeepStrictEqual()`]: #assert_assert_notdeepstrictequal_actual_expected_message
[`assert.notStrictEqual()`]: #assert_assert_notstrictequal_actual_expected_message
[`assert.ok()`]: #assert_assert_ok_value_message
[`assert.strictEqual()`]: #assert_assert_strictequal_actual_expected_message
[`assert.throws()`]: #assert_assert_throws_block_error_message
[`strict mode`]: #assert_strict_mode
[Abstract Equality Comparison]: https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
[SameValueZero]: https://tc39.github.io/ecma262/#sec-samevaluezero
Expand Down
17 changes: 6 additions & 11 deletions doc/api/deprecations.md
Expand Up @@ -774,19 +774,15 @@ Type: Runtime
cause a lot of issues. See https://github.com/nodejs/node/issues/14328 for more
details.
<a id="DEP0098"></a>
### DEP0098: AsyncHooks Embedder AsyncResource.emit{Before,After} APIs
<a id="DEP0089"></a>
### DEP0089: require('assert')
Type: Runtime
The embedded API provided by AsyncHooks exposes emit{Before,After} methods
which are very easy to use incorrectly which can lead to unrecoverable errors.
Type: Documentation-only
Use [`asyncResource.runInAsyncScope()`][] API instead which provides a much
safer, and more convenient, alternative. See
https://github.com/nodejs/node/pull/18513 for more details.
Importing assert directly is not recommended as the exposed functions will use
loose equality checks. Use `require('assert').strict` instead. The API is the
same as the legacy assert but it will always use strict equality checks.
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
[`Buffer.from(buffer)`]: buffer.html#buffer_class_method_buffer_from_buffer
Expand All @@ -796,7 +792,6 @@ https://github.com/nodejs/node/pull/18513 for more details.
[`Server.getConnections()`]: net.html#net_server_getconnections_callback
[`Server.listen({fd: <number>})`]: net.html#net_server_listen_handle_backlog_callback
[`SlowBuffer`]: buffer.html#buffer_class_slowbuffer
[`asyncResource.runInAsyncScope()`]: async_hooks.html#async_hooks_asyncresource_runinasyncscope_fn_thisarg_args
[`child_process`]: child_process.html
[`console.error()`]: console.html#console_console_error_data_args
[`console.log()`]: console.html#console_console_log_data_args
Expand Down
12 changes: 12 additions & 0 deletions lib/assert.js
Expand Up @@ -210,3 +210,15 @@ assert.doesNotThrow = function doesNotThrow(block, error, message) {
};

assert.ifError = function ifError(err) { if (err) throw err; };

// Expose a strict only variant of assert
function strict(value, message) {
if (!value) innerFail(value, true, message, '==', strict);
}
assert.strict = Object.assign(strict, assert, {
equal: assert.strictEqual,
deepEqual: assert.deepStrictEqual,
notEqual: assert.notStrictEqual,
notDeepEqual: assert.notDeepStrictEqual
});
assert.strict.strict = assert.strict;
19 changes: 19 additions & 0 deletions test/parallel/test-assert.js
Expand Up @@ -761,3 +761,22 @@ common.expectsError(
message: /^'Error: foo' === 'Error: foobar'$/
}
);

// Test strict assert
{
const a = require('assert');
const assert = require('assert').strict;
/* eslint-disable no-restricted-properties */
assert.throws(() => assert.equal(1, true), assert.AssertionError);
assert.notEqual(0, false);
assert.throws(() => assert.deepEqual(1, true), assert.AssertionError);
assert.notDeepEqual(0, false);
assert.equal(assert.strict, assert.strict.strict);
assert.equal(assert.equal, assert.strictEqual);
assert.equal(assert.deepEqual, assert.deepStrictEqual);
assert.equal(assert.notEqual, assert.notStrictEqual);
assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual);
assert.equal(Object.keys(assert).length, Object.keys(a).length);
/* eslint-enable no-restricted-properties */
assert(7);
}

0 comments on commit bae5de1

Please sign in to comment.