diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 26125ea1..edab42b4 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -4472,12 +4472,7 @@ getJasmineRequireObj().DiffBuilder = function (j$) { }; function dereferencePath(objectPath, actual, expected, pp) { - var i, asymmetricResult; - - for (i = 0; i < objectPath.components.length; i++) { - actual = actual[objectPath.components[i]]; - expected = expected[objectPath.components[i]]; - + function handleAsymmetricExpected() { if (j$.isAsymmetricEqualityTester_(expected) && j$.isFunction_(expected.valuesForDiff_)) { var asymmetricResult = expected.valuesForDiff_(actual, pp); expected = asymmetricResult.self; @@ -4485,6 +4480,15 @@ getJasmineRequireObj().DiffBuilder = function (j$) { } } + var i; + handleAsymmetricExpected(); + + for (i = 0; i < objectPath.components.length; i++) { + actual = actual[objectPath.components[i]]; + expected = expected[objectPath.components[i]]; + handleAsymmetricExpected(); + } + return {actual: actual, expected: expected}; } diff --git a/spec/core/asymmetric_equality/ObjectContainingSpec.js b/spec/core/asymmetric_equality/ObjectContainingSpec.js index 8cad948d..97df2555 100644 --- a/spec/core/asymmetric_equality/ObjectContainingSpec.js +++ b/spec/core/asymmetric_equality/ObjectContainingSpec.js @@ -149,7 +149,7 @@ describe("ObjectContaining", function() { }); }); - it("includes keys that are present in only sample", function() { + it("includes keys that are present only in sample", function() { var sample = {a: 1, b: 2}, other = {a: 3}, containing = new jasmineUnderTest.ObjectContaining(sample), diff --git a/spec/core/matchers/DiffBuilderSpec.js b/spec/core/matchers/DiffBuilderSpec.js index 6d82c3f8..01220ce0 100644 --- a/spec/core/matchers/DiffBuilderSpec.js +++ b/spec/core/matchers/DiffBuilderSpec.js @@ -133,4 +133,50 @@ describe("DiffBuilder", function () { expect(diffBuilder.getMessage()).toEqual(expectedMsg); }); + + it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ at the root', function() { + var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]), + diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}), + expectedMsg = 'Expected $.foo = 1 to equal 2.\n' + + "Expected $.baz = undefined to equal 3."; + + + diffBuilder.setRoots( + {foo: 1, bar: 2}, + jasmine.objectContaining({foo: 2, baz: 3}) + ); + + diffBuilder.withPath('foo', function() { + diffBuilder.recordMismatch(); + }); + diffBuilder.withPath('baz', function() { + diffBuilder.recordMismatch(); + }); + + expect(diffBuilder.getMessage()).toEqual(expectedMsg); + }); + + it('builds diffs involving asymmetric equality testers that implement valuesForDiff_ below the root', function() { + var prettyPrinter = jasmineUnderTest.makePrettyPrinter([]), + diffBuilder = new jasmineUnderTest.DiffBuilder({prettyPrinter: prettyPrinter}), + expectedMsg = 'Expected $.x.foo = 1 to equal 2.\n' + + "Expected $.x.baz = undefined to equal 3."; + + + diffBuilder.setRoots( + {x: {foo: 1, bar: 2}}, + {x: jasmine.objectContaining({foo: 2, baz: 3})} + ); + + diffBuilder.withPath('x', function() { + diffBuilder.withPath('foo', function () { + diffBuilder.recordMismatch(); + }); + diffBuilder.withPath('baz', function () { + diffBuilder.recordMismatch(); + }); + }); + + expect(diffBuilder.getMessage()).toEqual(expectedMsg); + }); }); diff --git a/spec/core/matchers/toEqualSpec.js b/spec/core/matchers/toEqualSpec.js index 081329d9..db7f3ffb 100644 --- a/spec/core/matchers/toEqualSpec.js +++ b/spec/core/matchers/toEqualSpec.js @@ -429,17 +429,30 @@ describe("toEqual", function() { expect(compareEquals(actual, expected).message).toEqual(message); }); - it("reports mismatches involving objectContaining and an object", function() { - var actual = {x: {a: 1, b: 4, c: 3, extra: 'ignored'}}; - var expected = {x: jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3})}; - expect(compareEquals(actual, expected).message).toEqual('Expected $.x.b = 4 to equal 2.'); + it('reports mismatches between an object and objectContaining', function() { + var actual = {a: 1, b: 4, c: 3, extra: 'ignored'}; + var expected = jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3, d: 4}); + expect(compareEquals(actual, expected).message) + .toEqual( + 'Expected $.b = 4 to equal 2.\n' + + 'Expected $.d = undefined to equal 4.' + ); }); it("reports mismatches between a non-object and objectContaining", function() { - var actual = {x: 1}; - var expected = {x: jasmineUnderTest.objectContaining({a: 1})}; + var actual = 1; + var expected = jasmineUnderTest.objectContaining({a: 1}); expect(compareEquals(actual, expected).message).toEqual( - "Expected $.x = 1 to equal ''." + "Expected 1 to equal ''." + ); + }); + + it("reports mismatches involving a nested objectContaining", function() { + var actual = {x: {a: 1, b: 4, c: 3, extra: 'ignored'}}; + var expected = {x: jasmineUnderTest.objectContaining({a: 1, b: 2, c: 3, d: 4})}; + expect(compareEquals(actual, expected).message).toEqual( + 'Expected $.x.b = 4 to equal 2.\n' + + 'Expected $.x.d = undefined to equal 4.' ); }); diff --git a/src/core/matchers/DiffBuilder.js b/src/core/matchers/DiffBuilder.js index 83333d8a..70b52ea7 100644 --- a/src/core/matchers/DiffBuilder.js +++ b/src/core/matchers/DiffBuilder.js @@ -72,12 +72,7 @@ getJasmineRequireObj().DiffBuilder = function (j$) { }; function dereferencePath(objectPath, actual, expected, pp) { - var i, asymmetricResult; - - for (i = 0; i < objectPath.components.length; i++) { - actual = actual[objectPath.components[i]]; - expected = expected[objectPath.components[i]]; - + function handleAsymmetricExpected() { if (j$.isAsymmetricEqualityTester_(expected) && j$.isFunction_(expected.valuesForDiff_)) { var asymmetricResult = expected.valuesForDiff_(actual, pp); expected = asymmetricResult.self; @@ -85,6 +80,15 @@ getJasmineRequireObj().DiffBuilder = function (j$) { } } + var i; + handleAsymmetricExpected(); + + for (i = 0; i < objectPath.components.length; i++) { + actual = actual[objectPath.components[i]]; + expected = expected[objectPath.components[i]]; + handleAsymmetricExpected(); + } + return {actual: actual, expected: expected}; }