Skip to content

Commit

Permalink
doc: improve assert.md regarding ECMAScript terms
Browse files Browse the repository at this point in the history
Use the term "Abstract Equality Comparison" and "Strict Equality
Comparison" from ECMAScript specification to refer to the operations
done by `==` and `===`, instead of "equal comparison operator" and
"strict equality operator".

Clarify that deep strict comparisons checks `[[Prototype]]`
property, instead of the vague "object prototypes".

Suggest using `Object.is()` to avoid the caveats of +0, -0 and NaN.

Add a MDN link explaining what enumerable "own" properties are.

PR-URL: #11128
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
  • Loading branch information
joyeecheung committed Feb 27, 2017
1 parent 562cf5a commit 3d8379a
Showing 1 changed file with 57 additions and 16 deletions.
73 changes: 57 additions & 16 deletions doc/api/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ changes:
-->

Tests for deep equality between the `actual` and `expected` parameters.
Primitive values are compared with the equal comparison operator ( `==` ).

Only enumerable "own" properties are considered. The `deepEqual()`
implementation does not test object prototypes, attached symbols, or
non-enumerable properties. This can lead to some potentially surprising
results. For example, the following example does not throw an `AssertionError`
because the properties on the [`Error`][] object are non-enumerable:
Primitive values are compared with the [Abstract Equality Comparison][]
( `==` ).

Only [enumerable "own" properties][] are considered. The
[`assert.deepEqual()`][] implementation does not test the
[`[[Prototype]]`][prototype-spec] of objects, attached symbols, or
non-enumerable properties — for such checks, consider using
[assert.deepStrictEqual()][] instead. This can lead to some
potentially surprising results. For example, the following example does not
throw an `AssertionError` because the properties on the [`Error`][] object are
not enumerable:

```js
// WARNING: This does not throw an AssertionError!
Expand Down Expand Up @@ -113,17 +117,20 @@ changes:
description: Handle non-`Uint8Array` typed arrays correctly.
-->

Generally identical to `assert.deepEqual()` with two exceptions. First,
primitive values are compared using the strict equality operator ( `===` ).
Second, object comparisons include a strict equality check of their prototypes.
Generally identical to `assert.deepEqual()` with two exceptions:

1. Primitive values are compared using the [Strict Equality Comparison][]
( `===` ).
2. [`[[Prototype]]`][prototype-spec] of objects are compared using
the [Strict Equality Comparison][] too.

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

assert.deepEqual({a:1}, {a:'1'});
assert.deepEqual({a: 1}, {a: '1'});
// OK, because 1 == '1'

assert.deepStrictEqual({a:1}, {a:'1'});
assert.deepStrictEqual({a: 1}, {a: '1'});
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
// because 1 !== '1' using strict equality
```
Expand Down Expand Up @@ -200,7 +207,7 @@ added: v0.1.21
-->

Tests shallow, coercive equality between the `actual` and `expected` parameters
using the equal comparison operator ( `==` ).
using the [Abstract Equality Comparison][] ( `==` ).

```js
const assert = require('assert');
Expand Down Expand Up @@ -330,7 +337,7 @@ the `message` parameter is undefined, a default error message is assigned.
added: v0.1.21
-->

Tests shallow, coercive inequality with the not equal comparison operator
Tests shallow, coercive inequality with the [Abstract Equality Comparison][]
( `!=` ).

```js
Expand All @@ -355,7 +362,7 @@ parameter is undefined, a default error message is assigned.
added: v0.1.21
-->

Tests strict inequality as determined by the strict not equal operator
Tests strict inequality as determined by the [Strict Equality Comparison][]
( `!==` ).

```js
Expand Down Expand Up @@ -407,7 +414,8 @@ assert.ok(false, 'it\'s false');
added: v0.1.21
-->

Tests strict equality as determined by the strict equality operator ( `===` ).
Tests strict equality as determined by the [Strict Equality Comparison][]
( `===` ).

```js
const assert = require('assert');
Expand Down Expand Up @@ -493,10 +501,43 @@ assert.throws(myFunction, 'missing foo', 'did not throw with expected message');
assert.throws(myFunction, /missing foo/, 'did not throw with expected message');
```

## Caveats

For the following cases, consider using ES2015 [`Object.is()`][],
which uses the [SameValueZero][] comparison.

```js
const a = 0;
const b = -a;
assert.notStrictEqual(a, b);
// AssertionError: 0 !== -0
// Strict Equality Comparison doesn't distinguish between -0 and +0...
assert(!Object.is(a, b));
// but Object.is() does!

const str1 = "foo";
const str2 = "foo";
assert.strictEqual(str1 / 1, str2 / 1);
// AssertionError: NaN === NaN
// Strict Equality Comparison can't be used to check NaN...
assert(Object.is(str1 / 1, str2 / 1));
// but Object.is() can!
```

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

[`assert.deepEqual()`]: #assert_assert_deepequal_actual_expected_message
[`assert.deepStrictEqual()`]: #assert_assert_deepstrictequal_actual_expected_message
[`assert.ok()`]: #assert_assert_ok_value_message
[`assert.throws()`]: #assert_assert_throws_block_error_message
[`Error`]: errors.html#errors_class_error
[`RegExp`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
[`TypeError`]: errors.html#errors_class_typeerror
[Abstract Equality Comparison]: https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
[Strict Equality Comparison]: https://tc39.github.io/ecma262/#sec-strict-equality-comparison
[`Object.is()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
[SameValueZero]: https://tc39.github.io/ecma262/#sec-samevaluezero
[prototype-spec]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
[mdn-equality-guide]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
[enumerable "own" properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties

0 comments on commit 3d8379a

Please sign in to comment.