Skip to content

Commit c6d94f8

Browse files
BridgeARMylesBorins
authored andcommitted
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. Backport-PR-URL: #23223 PR-URL: #17002 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Vse Mozhet Byt <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent e3bddee commit c6d94f8

File tree

4 files changed

+150
-13
lines changed

4 files changed

+150
-13
lines changed

doc/api/assert.md

+110-13
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
@@ -37,6 +88,14 @@ changes:
3788
* `expected` {any}
3889
* `message` {any}
3990

91+
**Strict mode**
92+
93+
An alias of [`assert.deepStrictEqual()`][].
94+
95+
**Legacy mode**
96+
97+
> Stability: 0 - Deprecated: Use [`assert.deepStrictEqual()`][] instead.
98+
4099
Tests for deep equality between the `actual` and `expected` parameters.
41100
Primitive values are compared with the [Abstract Equality Comparison][]
42101
( `==` ).
@@ -126,16 +185,26 @@ changes:
126185

127186
Generally identical to `assert.deepEqual()` with a few exceptions:
128187

129-
1. Primitive values are compared using the [Strict Equality Comparison][]
130-
( `===` ). Set values and Map keys are compared using the [SameValueZero][]
188+
### Comparison details
189+
190+
* Primitive values are compared using the [Strict Equality Comparison][]
191+
( `===` ).
192+
* Set values and Map keys are compared using the [SameValueZero][]
131193
comparison. (Which means they are free of the [caveats][]).
132-
2. [`[[Prototype]]`][prototype-spec] of objects are compared using
133-
the [Strict Equality Comparison][] too.
134-
3. [Type tags][Object.prototype.toString()] of objects should be the same.
135-
4. [Object wrappers][] are compared both as objects and unwrapped values.
194+
* [Type tags][Object.prototype.toString()] of objects should be the same.
195+
* [`[[Prototype]]`][prototype-spec] of objects are compared using
196+
the [Strict Equality Comparison][].
197+
* Only [enumerable "own" properties][] are considered.
198+
* [`Error`][] messages are always compared, even though this property is
199+
non-enumerable.
200+
* [Object wrappers][] are compared both as objects and unwrapped values.
201+
* Object properties are compared unordered.
202+
* Map keys and Set items are compared unordered.
203+
* Recursion stops when both sides differ or both sides encounter a circular
204+
reference.
136205

137206
```js
138-
const assert = require('assert');
207+
const assert = require('assert').strict;
139208

140209
assert.deepEqual({ a: 1 }, { a: '1' });
141210
// OK, because 1 == '1'
@@ -251,6 +320,14 @@ added: v0.1.21
251320
* `expected` {any}
252321
* `message` {any}
253322

323+
**Strict mode**
324+
325+
An alias of [`assert.strictEqual()`][].
326+
327+
**Legacy mode**
328+
329+
> Stability: 0 - Deprecated: Use [`assert.strictEqual()`][] instead.
330+
254331
Tests shallow, coercive equality between the `actual` and `expected` parameters
255332
using the [Abstract Equality Comparison][] ( `==` ).
256333

@@ -292,7 +369,7 @@ If `stackStartFunction` is provided, all stack frames above that function will
292369
be removed from stacktrace (see [`Error.captureStackTrace`]).
293370

294371
```js
295-
const assert = require('assert');
372+
const assert = require('assert').strict;
296373

297374
assert.fail(1, 2, undefined, '>');
298375
// AssertionError [ERR_ASSERTION]: 1 > 2
@@ -340,7 +417,7 @@ Throws `value` if `value` is truthy. This is useful when testing the `error`
340417
argument in callbacks.
341418

342419
```js
343-
const assert = require('assert');
420+
const assert = require('assert').strict;
344421

345422
assert.ifError(null);
346423
// OK
@@ -362,6 +439,14 @@ added: v0.1.21
362439
* `expected` {any}
363440
* `message` {any}
364441

442+
**Strict mode**
443+
444+
An alias of [`assert.notDeepStrictEqual()`][].
445+
446+
**Legacy mode**
447+
448+
> Stability: 0 - Deprecated: Use [`assert.notDeepStrictEqual()`][] instead.
449+
365450
Tests for any deep inequality. Opposite of [`assert.deepEqual()`][].
366451

367452
```js
@@ -412,7 +497,7 @@ added: v1.2.0
412497
Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][].
413498

414499
```js
415-
const assert = require('assert');
500+
const assert = require('assert').strict;
416501

417502
assert.notDeepEqual({ a: 1 }, { a: '1' });
418503
// AssertionError: { a: 1 } notDeepEqual { a: '1' }
@@ -433,6 +518,14 @@ added: v0.1.21
433518
* `expected` {any}
434519
* `message` {any}
435520

521+
**Strict mode**
522+
523+
An alias of [`assert.notStrictEqual()`][].
524+
525+
**Legacy mode**
526+
527+
> Stability: 0 - Deprecated: Use [`assert.notStrictEqual()`][] instead.
528+
436529
Tests shallow, coercive inequality with the [Abstract Equality Comparison][]
437530
( `!=` ).
438531

@@ -465,7 +558,7 @@ Tests strict inequality as determined by the [Strict Equality Comparison][]
465558
( `!==` ).
466559

467560
```js
468-
const assert = require('assert');
561+
const assert = require('assert').strict;
469562

470563
assert.notStrictEqual(1, 2);
471564
// OK
@@ -496,7 +589,7 @@ property set equal to the value of the `message` parameter. If the `message`
496589
parameter is `undefined`, a default error message is assigned.
497590

498591
```js
499-
const assert = require('assert');
592+
const assert = require('assert').strict;
500593

501594
assert.ok(true);
502595
// OK
@@ -522,7 +615,7 @@ Tests strict equality as determined by the [Strict Equality Comparison][]
522615
( `===` ).
523616

524617
```js
525-
const assert = require('assert');
618+
const assert = require('assert').strict;
526619

527620
assert.strictEqual(1, 2);
528621
// AssertionError: 1 === 2
@@ -643,8 +736,12 @@ For more information, see
643736
[`TypeError`]: errors.html#errors_class_typeerror
644737
[`assert.deepEqual()`]: #assert_assert_deepequal_actual_expected_message
645738
[`assert.deepStrictEqual()`]: #assert_assert_deepstrictequal_actual_expected_message
739+
[`assert.notDeepStrictEqual()`]: #assert_assert_notdeepstrictequal_actual_expected_message
740+
[`assert.notStrictEqual()`]: #assert_assert_notstrictequal_actual_expected_message
646741
[`assert.ok()`]: #assert_assert_ok_value_message
742+
[`assert.strictEqual()`]: #assert_assert_strictequal_actual_expected_message
647743
[`assert.throws()`]: #assert_assert_throws_block_error_message
744+
[`strict mode`]: #assert_strict_mode
648745
[Abstract Equality Comparison]: https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
649746
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
650747
[SameValueZero]: https://tc39.github.io/ecma262/#sec-samevaluezero

doc/api/deprecations.md

+9
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,15 @@ Type: Runtime
684684
cause a lot of issues. See https://github.com/nodejs/node/issues/14328 for more
685685
details.
686686
687+
<a id="DEP0089"></a>
688+
### DEP0089: require('assert')
689+
690+
Type: Documentation-only
691+
692+
Importing assert directly is not recommended as the exposed functions will use
693+
loose equality checks. Use `require('assert').strict` instead. The API is the
694+
same as the legacy assert but it will always use strict equality checks.
695+
687696
<a id="DEP0098"></a>
688697
### DEP0098: AsyncHooks Embedder AsyncResource.emit{Before,After} APIs
689698

lib/assert.js

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

669669
assert.ifError = function ifError(err) { if (err) throw err; };
670+
671+
// Expose a strict only variant of assert
672+
function strict(value, message) {
673+
if (!value) innerFail(value, true, message, '==', strict);
674+
}
675+
assert.strict = Object.assign(strict, assert, {
676+
equal: assert.strictEqual,
677+
deepEqual: assert.deepStrictEqual,
678+
notEqual: assert.notStrictEqual,
679+
notDeepEqual: assert.notDeepStrictEqual
680+
});
681+
assert.strict.strict = assert.strict;

test/parallel/test-assert.js

+19
Original file line numberDiff line numberDiff line change
@@ -696,3 +696,22 @@ common.expectsError(
696696
message: /^'Error: foo' === 'Error: foobar'$/
697697
}
698698
);
699+
700+
// Test strict assert
701+
{
702+
const a = require('assert');
703+
const assert = require('assert').strict;
704+
/* eslint-disable no-restricted-properties */
705+
assert.throws(() => assert.equal(1, true), assert.AssertionError);
706+
assert.notEqual(0, false);
707+
assert.throws(() => assert.deepEqual(1, true), assert.AssertionError);
708+
assert.notDeepEqual(0, false);
709+
assert.equal(assert.strict, assert.strict.strict);
710+
assert.equal(assert.equal, assert.strictEqual);
711+
assert.equal(assert.deepEqual, assert.deepStrictEqual);
712+
assert.equal(assert.notEqual, assert.notStrictEqual);
713+
assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual);
714+
assert.equal(Object.keys(assert).length, Object.keys(a).length);
715+
/* eslint-enable no-restricted-properties */
716+
assert(7);
717+
}

0 commit comments

Comments
 (0)