FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

assert: fix boxed primitives in deepStrictEqual · nodejs/node@22ae8c0 · GitHub

/ node Public

Commit 22ae8c0

Browse files
committed
assert: fix boxed primitives in deepStrictEqual
Unbox all primitives and compare them as well instead of only comparing boxed strings. PR-URL: #15050 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent e13d1df commit 22ae8c0

3 files changed

Lines changed: 46 additions & 2 deletions

File tree

‎doc/api/assert.md‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ changes:
134134
* `expected` {any}
135135
* `message` {any}
136136

137-
Generally identical to `assert.deepEqual()` with three exceptions:
137+
Generally identical to `assert.deepEqual()` with a few exceptions:
138138

139139
1. Primitive values besides `NaN` are compared using the [Strict Equality
140140
Comparison][] ( `===` ). Set and Map values, Map keys and `NaN` are compared
@@ -143,6 +143,7 @@ Generally identical to `assert.deepEqual()` with three exceptions:
143143
2. [`[[Prototype]]`][prototype-spec] of objects are compared using
144144
the [Strict Equality Comparison][] too.
145145
3. [Type tags][Object.prototype.toString()] of objects should be the same.
146+
4. [Object wrappers][] are compared both as objects and unwrapped values.
146147

147148
```js
148149
const assert = require('assert');
@@ -172,8 +173,14 @@ assert.deepEqual(date, fakeDate);
172173
assert.deepStrictEqual(date, fakeDate);
173174
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
174175
// Different type tags
176+
175177
assert.deepStrictEqual(NaN, NaN);
176178
// OK, because of the SameValueZero comparison
179+
180+
assert.deepStrictEqual(new Number(1), new Number(2));
181+
// Fails because the wrapped number is unwrapped and compared as well.
182+
assert.deepStrictEqual(new String('foo'), Object('foo'));
183+
// OK because the object and the string are identical when unwrapped.
177184
```
178185

179186
If the values are not equal, an `AssertionError` is thrown with a `message`
@@ -711,3 +718,4 @@ For more information, see
711718
[enumerable "own" properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
712719
[mdn-equality-guide]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
713720
[prototype-spec]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
721+
[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript

‎lib/assert.js‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,30 @@ function strictDeepEqual(actual, expected) {
215215
if (!areSimilarTypedArrays(actual, expected)) {
216216
return false;
217217
}
218-
219218
// Buffer.compare returns true, so actual.length === expected.length
220219
// if they both only contain numeric keys, we don't need to exam further
221220
if (Object.keys(actual).length === actual.length &&
222221
Object.keys(expected).length === expected.length) {
223222
return true;
224223
}
224+
} else if (typeof actual.valueOf === 'function') {
225+
const actualValue = actual.valueOf();
226+
// Note: Boxed string keys are going to be compared again by Object.keys
227+
if (actualValue !== actual) {
228+
if (!innerDeepEqual(actualValue, expected.valueOf(), true))
229+
return false;
230+
// Fast path for boxed primitives
231+
var lengthActual = 0;
232+
var lengthExpected = 0;
233+
if (typeof actualValue === 'string') {
234+
lengthActual = actual.length;
235+
lengthExpected = expected.length;
236+
}
237+
if (Object.keys(actual).length === lengthActual &&
238+
Object.keys(expected).length === lengthExpected) {
239+
return true;
240+
}
241+
}
225242
}
226243
}
227244

‎test/parallel/test-assert-deep.js‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,4 +489,23 @@ assert.doesNotThrow(() => { assert.deepStrictEqual({ a: NaN }, { a: NaN }); });
489489
assert.doesNotThrow(
490490
() => { assert.deepStrictEqual([ 1, 2, NaN, 4 ], [ 1, 2, NaN, 4 ]); });
491491

492+
// Handle boxed primitives
493+
{
494+
const boxedString = new String('test');
495+
const boxedSymbol = Object(Symbol());
496+
assertOnlyDeepEqual(new Boolean(true), Object(false));
497+
assertOnlyDeepEqual(Object(true), new Number(1));
498+
assertOnlyDeepEqual(new Number(2), new Number(1));
499+
assertOnlyDeepEqual(boxedSymbol, Object(Symbol()));
500+
assertOnlyDeepEqual(boxedSymbol, {});
501+
assertDeepAndStrictEqual(boxedSymbol, boxedSymbol);
502+
assertDeepAndStrictEqual(Object(true), Object(true));
503+
assertDeepAndStrictEqual(Object(2), Object(2));
504+
assertDeepAndStrictEqual(boxedString, Object('test'));
505+
boxedString.slow = true;
506+
assertNotDeepOrStrict(boxedString, Object('test'));
507+
boxedSymbol.slow = true;
508+
assertNotDeepOrStrict(boxedSymbol, {});
509+
}
510+
492511
/* eslint-enable */

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL