From 3d8379ae60ee2b6c57a55af7b62a878c920a793f Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 3 Feb 2017 06:02:29 +0800 Subject: [PATCH] doc: improve assert.md regarding ECMAScript terms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: https://github.com/nodejs/node/pull/11128 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso --- doc/api/assert.md | 73 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index b94f6ee9080ea0..e28c2cf7059c1f 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -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,6 +501,32 @@ 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 @@ -500,3 +534,10 @@ assert.throws(myFunction, /missing foo/, 'did not throw with expected 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 \ No newline at end of file