From ea880235539f4d3fa07cc0396e2fa0ac40a3736f Mon Sep 17 00:00:00 2001 From: slackersoft Date: Tue, 16 Dec 2014 17:05:32 -0800 Subject: [PATCH] Check for `ObjectContaining` on either side of equality. - Also clean up `undefined` check. Fixes #682 --- lib/jasmine-core/jasmine.js | 12 ++++++------ spec/core/ObjectContainingSpec.js | 12 ++++++++++++ spec/core/matchers/matchersUtilSpec.js | 6 ++++-- src/core/ObjectContaining.js | 8 ++------ src/core/matchers/matchersUtil.js | 4 ++++ 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 3f0639bd..8658bb3b 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1552,13 +1552,9 @@ getJasmineRequireObj().ObjectContaining = function(j$) { ObjectContaining.prototype.asymmetricMatch = function(other) { if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } - var hasKey = function(obj, keyName) { - return obj !== null && !j$.util.isUndefined(obj[keyName]); - }; - for (var property in this.sample) { - if (!hasKey(other, property) && hasKey(this.sample, property) || - !j$.matchersUtil.equals(other[property], this.sample[property])) { + if (!Object.prototype.hasOwnProperty.call(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { return false; } } @@ -2259,6 +2255,10 @@ getJasmineRequireObj().matchersUtil = function(j$) { return b.asymmetricMatch(a); } + if (a instanceof j$.ObjectContaining) { + return a.asymmetricMatch(b); + } + if (b instanceof j$.ObjectContaining) { return b.asymmetricMatch(a); } diff --git a/spec/core/ObjectContainingSpec.js b/spec/core/ObjectContainingSpec.js index 0bdb2e5b..d87f03e2 100644 --- a/spec/core/ObjectContainingSpec.js +++ b/spec/core/ObjectContainingSpec.js @@ -43,4 +43,16 @@ describe("ObjectContaining", function() { expect(containing.asymmetricMatch({one: {two: {}}})).toBe(true); }); + + it("matches when key is present with undefined value", function() { + var containing = new j$.ObjectContaining({ one: undefined }); + + expect(containing.asymmetricMatch({ one: undefined })).toBe(true); + }); + + it("does not match when key with undefined value is not present", function() { + var containing = new j$.ObjectContaining({ one: undefined }); + + expect(containing.asymmetricMatch({})).toBe(false); + }); }); diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index 2e68a3d2..cfc0e1cb 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -191,9 +191,11 @@ describe("matchersUtil", function() { var obj = { foo: 3, bar: 7 - }; + }, + containing = new j$.ObjectContaining({foo: 3}); - expect(j$.matchersUtil.equals(obj, new j$.ObjectContaining({foo: 3}))).toBe(true); + expect(j$.matchersUtil.equals(obj, containing)).toBe(true); + expect(j$.matchersUtil.equals(containing, obj)).toBe(true); }); it("passes when a custom equality matcher returns true", function() { diff --git a/src/core/ObjectContaining.js b/src/core/ObjectContaining.js index 89b8489d..db8bbb1d 100644 --- a/src/core/ObjectContaining.js +++ b/src/core/ObjectContaining.js @@ -7,13 +7,9 @@ getJasmineRequireObj().ObjectContaining = function(j$) { ObjectContaining.prototype.asymmetricMatch = function(other) { if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } - var hasKey = function(obj, keyName) { - return obj !== null && !j$.util.isUndefined(obj[keyName]); - }; - for (var property in this.sample) { - if (!hasKey(other, property) && hasKey(this.sample, property) || - !j$.matchersUtil.equals(other[property], this.sample[property])) { + if (!Object.prototype.hasOwnProperty.call(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { return false; } } diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index 241cb472..a1ca9741 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -71,6 +71,10 @@ getJasmineRequireObj().matchersUtil = function(j$) { return b.asymmetricMatch(a); } + if (a instanceof j$.ObjectContaining) { + return a.asymmetricMatch(b); + } + if (b instanceof j$.ObjectContaining) { return b.asymmetricMatch(a); }