From b4dfdd7a48f5f2de8a6906e97d1b2121b0cb0b35 Mon Sep 17 00:00:00 2001 From: Benjamin Mularczyk Date: Wed, 1 Nov 2017 01:01:26 +0100 Subject: [PATCH] Fix equality computation for ES6 Sets. --- spec/core/matchers/matchersUtilSpec.js | 16 +++++++++++++++- src/core/matchers/matchersUtil.js | 22 +++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index 98795db5..0214f84d 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -393,13 +393,27 @@ describe("matchersUtil", function() { expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); - it("passes when comparing identical sets with different insertion order", function() { + it("passes when comparing identical sets with different insertion order and simple elements", function() { jasmine.getEnv().requireFunctioningSets(); var setA = new Set([3, 6]); var setB = new Set([6, 3]); expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); }); + it("passes when comparing identical sets with different insertion order and complex elements 1", function() { + jasmine.getEnv().requireFunctioningMaps(); + var setA = new Set([new Set([['a', 3], [6, 1]]), new Set([['y', 3], [6, 1]])]); + var setB = new Set([new Set([[6, 1], ['a', 3]]), new Set([[6, 1], ['y', 3]])]); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); + }); + + it("passes when comparing identical sets with different insertion order and complex elements 2", function() { + jasmine.getEnv().requireFunctioningMaps(); + var setA = new Set([[[1,2], [3,4]], [[5,6], [7,8]]]); + var setB = new Set([[[5,6], [7,8]], [[1,2], [3,4]]]); + expect(jasmineUnderTest.matchersUtil.equals(setA, setB)).toBe(true); + }); + it("fails for sets with different elements", function() { jasmine.getEnv().requireFunctioningSets(); var setA = new Set([6, 3, 5]); diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index 71fc0047..07d191e9 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -296,24 +296,36 @@ getJasmineRequireObj().matchersUtil = function(j$) { // For both sets, check they are all contained in the other set var setPairs = [[a, b], [b, a]]; - var baseIter, baseValueIt, baseValue; - var otherSet, otherIter, otherValueIt, otherValue, found; + var stackPairs = [[aStack, bStack], [bStack, aStack]]; + var baseIter, baseValueIt, baseValue, baseStack; + var otherSet, otherIter, otherValueIt, otherValue, otherStack; + var found; + var prevStackSize; for (i = 0; result && i < setPairs.length; i++) { baseIter = setPairs[i][0].values(); otherSet = setPairs[i][1]; + baseStack = stackPairs[i][0]; + otherStack = stackPairs[i][1]; // For each value in the base set... baseValueIt = baseIter.next(); while (result && !baseValueIt.done) { baseValue = baseValueIt.value; // ... test that it is present in the other set - otherIter = otherSet.values(); - otherValueIt = otherIter.next(); // Optimisation: start looking for value by object identity found = otherSet.has(baseValue); + if (!found) { + otherIter = otherSet.values(); + otherValueIt = otherIter.next(); + } // If not found, compare by value equality while (!found && !otherValueIt.done) { otherValue = otherValueIt.value; - found = eq(baseValue, otherValue, aStack, bStack, customTesters, j$.NullDiffBuilder()); + prevStackSize = baseStack.length; + found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder()); + if (!found && prevStackSize !== baseStack.length) { + baseStack.splice(prevStackSize); + otherStack.splice(prevStackSize); + } otherValueIt = otherIter.next(); } result = result && found;