Skip to content

Commit b3e4476

Browse files
committed
assert: add strict functionality export
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. PR-URL: nodejs#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>
1 parent c6aa5ff commit b3e4476

File tree

4 files changed

+132
-18
lines changed

4 files changed

+132
-18
lines changed

doc/api/assert.md

+95-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,57 @@
77
The `assert` module provides a simple set of assertion tests that can be used to
88
test invariants.
99

10+
A `strict` and a `legacy` mode exist, while it is recommended to only use
11+
[`strict mode`][].
12+
13+
For more information about the used equality comparisons see
14+
[MDN's guide on equality comparisons and sameness][mdn-equality-guide].
15+
16+
## Strict mode
17+
<!-- YAML
18+
added: REPLACEME
19+
changes:
20+
- version: REPLACEME
21+
pr-url: https://github.com/nodejs/node/pull/17002
22+
description: Added strict mode to the assert module.
23+
-->
24+
25+
When using the `strict mode`, any `assert` function will use the equality used in
26+
the strict function mode. So [`assert.deepEqual()`][] will, for example, work the
27+
same as [`assert.deepStrictEqual()`][].
28+
29+
It can be accessed using:
30+
31+
```js
32+
const assert = require('assert').strict;
33+
```
34+
35+
## Legacy mode
36+
37+
> Stability: 0 - Deprecated: Use strict mode instead.
38+
39+
When accessing `assert` directly instead of using the `strict` property, the
40+
[Abstract Equality Comparison][] will be used for any function without a
41+
"strict" in its name (e.g. [`assert.deepEqual()`][]).
42+
43+
It can be accessed using:
44+
45+
```js
46+
const assert = require('assert');
47+
```
48+
49+
It is recommended to use the [`strict mode`][] instead as the
50+
[Abstract Equality Comparison][] can often have surprising results. Especially
51+
in case of [`assert.deepEqual()`][] as the used comparison rules there are very
52+
lax.
53+
54+
E.g.
55+
56+
```js
57+
// WARNING: This does not throw an AssertionError!
58+
assert.deepEqual(/a/gi, new Date());
59+
```
60+
1061
## assert(value[, message])
1162
<!-- YAML
1263
added: v0.5.9
@@ -40,6 +91,14 @@ changes:
4091
* `expected` {any}
4192
* `message` {any}
4293

94+
**Strict mode**
95+
96+
An alias of [`assert.deepStrictEqual()`][].
97+
98+
**Legacy mode**
99+
100+
> Stability: 0 - Deprecated: Use [`assert.deepStrictEqual()`][] instead.
101+
43102
Tests for deep equality between the `actual` and `expected` parameters.
44103
Primitive values are compared with the [Abstract Equality Comparison][]
45104
( `==` ).
@@ -146,7 +205,7 @@ are recursively evaluated also by the following rules.
146205
[`Object.is()`][].
147206
* [Type tags][Object.prototype.toString()] of objects should be the same.
148207
* [`[[Prototype]]`][prototype-spec] of objects are compared using
149-
the [Strict Equality Comparison][] too.
208+
the [Strict Equality Comparison][].
150209
* Only [enumerable "own" properties][] are considered.
151210
* [`Error`][] names and messages are always compared, even if these are not
152211
enumerable properties.
@@ -158,7 +217,7 @@ are recursively evaluated also by the following rules.
158217
reference.
159218

160219
```js
161-
const assert = require('assert');
220+
const assert = require('assert').strict;
162221

163222
assert.deepStrictEqual({ a: 1 }, { a: '1' });
164223
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
@@ -278,6 +337,14 @@ added: v0.1.21
278337
* `expected` {any}
279338
* `message` {any}
280339

340+
**Strict mode**
341+
342+
An alias of [`assert.strictEqual()`][].
343+
344+
**Legacy mode**
345+
346+
> Stability: 0 - Deprecated: Use [`assert.strictEqual()`][] instead.
347+
281348
Tests shallow, coercive equality between the `actual` and `expected` parameters
282349
using the [Abstract Equality Comparison][] ( `==` ).
283350

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

326393
```js
327-
const assert = require('assert');
394+
const assert = require('assert').strict;
328395

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

377444
```js
378-
const assert = require('assert');
445+
const assert = require('assert').strict;
379446

380447
assert.ifError(null);
381448
// OK
@@ -413,6 +480,14 @@ changes:
413480
* `expected` {any}
414481
* `message` {any}
415482

483+
**Strict mode**
484+
485+
An alias of [`assert.notDeepStrictEqual()`][].
486+
487+
**Legacy mode**
488+
489+
> Stability: 0 - Deprecated: Use [`assert.notDeepStrictEqual()`][] instead.
490+
416491
Tests for any deep inequality. Opposite of [`assert.deepEqual()`][].
417492

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

491566
```js
492-
const assert = require('assert');
567+
const assert = require('assert').strict;
493568

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

587+
**Strict mode**
588+
589+
An alias of [`assert.notStrictEqual()`][].
590+
591+
**Legacy mode**
592+
593+
> Stability: 0 - Deprecated: Use [`assert.notStrictEqual()`][] instead.
594+
512595
Tests shallow, coercive inequality with the [Abstract Equality Comparison][]
513596
( `!=` ).
514597

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

545628
```js
546-
const assert = require('assert');
629+
const assert = require('assert').strict;
547630

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

580663
```js
581-
const assert = require('assert');
664+
const assert = require('assert').strict;
582665

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

606689
```js
607-
const assert = require('assert');
690+
const assert = require('assert').strict;
608691

609692
assert.strictEqual(1, 2);
610693
// AssertionError: 1 === 2
@@ -728,8 +811,12 @@ For more information, see
728811
[`TypeError`]: errors.html#errors_class_typeerror
729812
[`assert.deepEqual()`]: #assert_assert_deepequal_actual_expected_message
730813
[`assert.deepStrictEqual()`]: #assert_assert_deepstrictequal_actual_expected_message
814+
[`assert.notDeepStrictEqual()`]: #assert_assert_notdeepstrictequal_actual_expected_message
815+
[`assert.notStrictEqual()`]: #assert_assert_notstrictequal_actual_expected_message
731816
[`assert.ok()`]: #assert_assert_ok_value_message
817+
[`assert.strictEqual()`]: #assert_assert_strictequal_actual_expected_message
732818
[`assert.throws()`]: #assert_assert_throws_block_error_message
819+
[`strict mode`]: #assert_strict_mode
733820
[Abstract Equality Comparison]: https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
734821
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
735822
[SameValueZero]: https://tc39.github.io/ecma262/#sec-samevaluezero

doc/api/deprecations.md

+6-10
Original file line numberDiff line numberDiff line change
@@ -774,19 +774,15 @@ Type: Runtime
774774
cause a lot of issues. See https://github.com/nodejs/node/issues/14328 for more
775775
details.
776776
777-
<a id="DEP0098"></a>
778-
### DEP0098: AsyncHooks Embedder AsyncResource.emit{Before,After} APIs
777+
<a id="DEP0089"></a>
778+
### DEP0089: require('assert')
779779
780-
Type: Runtime
781-
782-
The embedded API provided by AsyncHooks exposes emit{Before,After} methods
783-
which are very easy to use incorrectly which can lead to unrecoverable errors.
780+
Type: Documentation-only
784781
785-
Use [`asyncResource.runInAsyncScope()`][] API instead which provides a much
786-
safer, and more convenient, alternative. See
787-
https://github.com/nodejs/node/pull/18513 for more details.
782+
Importing assert directly is not recommended as the exposed functions will use
783+
loose equality checks. Use `require('assert').strict` instead. The API is the
784+
same as the legacy assert but it will always use strict equality checks.
788785
789-
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
790786
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
791787
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
792788
[`Buffer.from(buffer)`]: buffer.html#buffer_class_method_buffer_from_buffer

lib/assert.js

+12
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,15 @@ assert.doesNotThrow = function doesNotThrow(block, error, message) {
210210
};
211211

212212
assert.ifError = function ifError(err) { if (err) throw err; };
213+
214+
// Expose a strict only variant of assert
215+
function strict(value, message) {
216+
if (!value) innerFail(value, true, message, '==', strict);
217+
}
218+
assert.strict = Object.assign(strict, assert, {
219+
equal: assert.strictEqual,
220+
deepEqual: assert.deepStrictEqual,
221+
notEqual: assert.notStrictEqual,
222+
notDeepEqual: assert.notDeepStrictEqual
223+
});
224+
assert.strict.strict = assert.strict;

test/parallel/test-assert.js

+19
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,22 @@ common.expectsError(
761761
message: /^'Error: foo' === 'Error: foobar'$/
762762
}
763763
);
764+
765+
// Test strict assert
766+
{
767+
const a = require('assert');
768+
const assert = require('assert').strict;
769+
/* eslint-disable no-restricted-properties */
770+
assert.throws(() => assert.equal(1, true), assert.AssertionError);
771+
assert.notEqual(0, false);
772+
assert.throws(() => assert.deepEqual(1, true), assert.AssertionError);
773+
assert.notDeepEqual(0, false);
774+
assert.equal(assert.strict, assert.strict.strict);
775+
assert.equal(assert.equal, assert.strictEqual);
776+
assert.equal(assert.deepEqual, assert.deepStrictEqual);
777+
assert.equal(assert.notEqual, assert.notStrictEqual);
778+
assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual);
779+
assert.equal(Object.keys(assert).length, Object.keys(a).length);
780+
/* eslint-enable no-restricted-properties */
781+
assert(7);
782+
}

0 commit comments

Comments
 (0)