Skip to content

Commit

Permalink
assert: fix deepEqual regression
Browse files Browse the repository at this point in the history
Change of Object.keys in ES6 breaks assert.deepEqual about primitive
values.

V8: https://code.google.com/p/v8/issues/detail?id=3443

Previously deepEqual depends on Object.key that throws an error for
a primitive value, but now Object.key does not throw.

PR-URL: #193
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
  • Loading branch information
teppeis authored and bnoordhuis committed Dec 22, 2014
1 parent ef10827 commit 00a7456
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
15 changes: 6 additions & 9 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,9 @@ function objEquiv(a, b) {
return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
//~~~I've managed to break Object.keys through screwy arguments passing.
// Converting to array solves the problem.
// if one is a primitive, the other must be same
if (util.isPrimitive(a) || util.isPrimitive(b))
return a === b;
var aIsArgs = isArguments(a),
bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
Expand All @@ -212,13 +213,9 @@ function objEquiv(a, b) {
b = pSlice.call(b);
return _deepEqual(a, b);
}
try {
var ka = Object.keys(a),
kb = Object.keys(b),
key, i;
} catch (e) {//happens when one is a string literal and the other isn't
return false;
}
var ka = Object.keys(a),
kb = Object.keys(b),
key, i;
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length != kb.length)
Expand Down
18 changes: 16 additions & 2 deletions test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,22 @@ nameBuilder2.prototype = Object;
nb2 = new nameBuilder2('Ryan', 'Dahl');
assert.throws(makeBlock(a.deepEqual, nb1, nb2), a.AssertionError);

// String literal + object blew up my implementation...
assert.throws(makeBlock(a.deepEqual, 'a', {}), a.AssertionError);
// primitives and object
assert.throws(makeBlock(a.deepEqual, null, {}), a.AssertionError);
assert.throws(makeBlock(a.deepEqual, undefined, {}), a.AssertionError);
assert.throws(makeBlock(a.deepEqual, 'a', ['a']), a.AssertionError);
assert.throws(makeBlock(a.deepEqual, 'a', {0: 'a'}), a.AssertionError);
assert.throws(makeBlock(a.deepEqual, 1, {}), a.AssertionError);
assert.throws(makeBlock(a.deepEqual, true, {}), a.AssertionError);
if (typeof Symbol === 'symbol') {
assert.throws(makeBlock(assert.deepEqual, Symbol(), {}), a.AssertionError);
}

// primitive wrappers and object
assert.doesNotThrow(makeBlock(a.deepEqual, new String('a'), ['a']), a.AssertionError);
assert.doesNotThrow(makeBlock(a.deepEqual, new String('a'), {0: 'a'}), a.AssertionError);
assert.doesNotThrow(makeBlock(a.deepEqual, new Number(1), {}), a.AssertionError);
assert.doesNotThrow(makeBlock(a.deepEqual, new Boolean(true), {}), a.AssertionError);

// Testing the throwing
function thrower(errorConstructor) {
Expand Down

0 comments on commit 00a7456

Please sign in to comment.