Permalink
Browse files

doc: improve assert.md regarding ECMAScript terms

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 2, 2017
1 parent 562cf5a commit 3d8379ae60ee2b6c57a55af7b62a878c920a793f
Showing with 57 additions and 16 deletions.
  1. +57 −16 doc/api/assert.md
View
@@ -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!
@@ -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
```
@@ -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');
@@ -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
@@ -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
@@ -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');
@@ -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.