From 00a7456c1958b0bf2db7b6cd42ffb598b29d3b41 Mon Sep 17 00:00:00 2001 From: teppeis Date: Mon, 22 Dec 2014 00:56:33 +0900 Subject: [PATCH] assert: fix deepEqual regression 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: https://github.com/iojs/io.js/pull/193 Reviewed-By: Ben Noordhuis --- lib/assert.js | 15 ++++++--------- test/parallel/test-assert.js | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index a05a4872884369..7e18a071e9c988 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -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)) @@ -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) diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 84ea9249c5972f..13dffe2fe011e9 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -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) {