Add special handling of asymmetric matcher objects as keys in Maps.
The previous Map equality code was assuming that the set of keys would be identical between the two Maps. This change adds insertion-order tracking for each key with its corresponding key. If one of the two keys is an asymmetric equality obj, the keys are eq()'d, and if it succeeds, the corresponding values are compared. Otherwise, the "main" key is looked up directly in the other object; this is to prevent similar-looking obj keys with different obj identities from comparing equal. Fixes #1432.
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user