diff --git a/spec/core/asymmetric_equality/AnythingSpec.js b/spec/core/asymmetric_equality/AnythingSpec.js index 8ee1f4e5..f248226a 100644 --- a/spec/core/asymmetric_equality/AnythingSpec.js +++ b/spec/core/asymmetric_equality/AnythingSpec.js @@ -23,6 +23,22 @@ describe("Anything", function() { expect(anything.asymmetricMatch([1,2,3])).toBe(true); }); + it("matches a Map", function() { + jasmine.getEnv().requireFunctioningMaps(); + + var anything = new jasmineUnderTest.Anything(); + + expect(anything.asymmetricMatch(new Map())).toBe(true); + }); + + it("matches a Set", function() { + jasmine.getEnv().requireFunctioningSets(); + + var anything = new jasmineUnderTest.Anything(); + + expect(anything.asymmetricMatch(new Set())).toBe(true); + }); + it("doesn't match undefined", function() { var anything = new jasmineUnderTest.Anything(); diff --git a/spec/core/matchers/toEqualSpec.js b/spec/core/matchers/toEqualSpec.js index aaed7759..d1605a4f 100644 --- a/spec/core/matchers/toEqualSpec.js +++ b/spec/core/matchers/toEqualSpec.js @@ -504,6 +504,14 @@ describe("toEqual", function() { expect(compareEquals(actual, expected).message).toEqual(message); }); + it("does not report mismatches when comparing Map key to jasmine.anything()", function() { + jasmine.getEnv().requireFunctioningMaps(); + + var actual = new Map([['a', 1]]), + expected = new Map([[jasmineUnderTest.anything(), 1]]); + expect(compareEquals(actual, expected).pass).toBe(true); + }); + function isNotRunningInBrowser() { return typeof document === 'undefined' } diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index a9801910..71fc0047 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -253,16 +253,34 @@ getJasmineRequireObj().matchersUtil = function(j$) { return false; } - // For both sets of keys, check they map to equal values in both maps + // For both sets of keys, check they map to equal values in both maps. + // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys. var mapKeys = [a.keys(), b.keys()]; - var mapIter, mapKeyIt, mapKey; + var cmpKeys = [b.keys(), a.keys()]; + var mapIter, mapKeyIt, mapKey, mapValueA, mapValueB; + var cmpIter, cmpKeyIt, cmpKey; for (i = 0; result && i < mapKeys.length; i++) { mapIter = mapKeys[i]; + cmpIter = cmpKeys[i]; mapKeyIt = mapIter.next(); + cmpKeyIt = cmpIter.next(); while (result && !mapKeyIt.done) { mapKey = mapKeyIt.value; - result = eq(a.get(mapKey), b.get(mapKey), aStack, bStack, customTesters, j$.NullDiffBuilder()); + cmpKey = cmpKeyIt.value; + mapValueA = a.get(mapKey); + + // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches, + // otherwise explicitly look up the mapKey in the other Map since we want keys with unique + // obj identity (that are otherwise equal) to not match. + if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) && + eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) { + mapValueB = b.get(cmpKey); + } else { + mapValueB = b.get(mapKey); + } + result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder()); mapKeyIt = mapIter.next(); + cmpKeyIt = cmpIter.next(); } }