From cd9d5284cd5d8da94814e66b66691bacdb649e3b Mon Sep 17 00:00:00 2001 From: Kyriacos Souroullas and Sheel Choksi Date: Mon, 28 Oct 2013 15:26:48 -0700 Subject: [PATCH] Matchers can have a negativeCompare - Passing in a 'negativeCompare' will cause that function to be used when it is a 'not' assertion - Otherwise, the reversal of the compare's result will be used instead [finishes #59703824] --- spec/core/CustomMatchersSpec.js | 22 ++++++++++ spec/core/ExpectationSpec.js | 75 ++++++++++++++++++++++++++++++++- src/core/Expectation.js | 13 +++++- 3 files changed, 107 insertions(+), 3 deletions(-) diff --git a/spec/core/CustomMatchersSpec.js b/spec/core/CustomMatchersSpec.js index 9f449aa2..ee3e49a0 100644 --- a/spec/core/CustomMatchersSpec.js +++ b/spec/core/CustomMatchersSpec.js @@ -56,6 +56,28 @@ describe("Custom Matchers (Integration)", function() { env.execute(); }); + it("uses the negative compare function for a negative comparison, if provided", function(done) { + env.addMatchers({ + toBeReal: function() { + return { + compare: function() { return { pass: true }; }, + negativeCompare: function() { return { pass: true }; } + }; + } + }); + + env.it("spec with custom negative comparison matcher", function() { + env.expect(true).not.toBeReal(); + }); + + var specExpectations = function(result) { + expect(result.status).toEqual('passed'); + } + + env.addReporter({ specDone: specExpectations, jasmineDone: done }); + env.execute(); + }); + it("generates messages with the same rules as built in matchers absent a custom message", function(done) { env.addMatchers({ toBeReal: function() { diff --git a/spec/core/ExpectationSpec.js b/spec/core/ExpectationSpec.js index a86c4f66..4c6d6c17 100644 --- a/spec/core/ExpectationSpec.js +++ b/spec/core/ExpectationSpec.js @@ -317,4 +317,77 @@ describe("Expectation", function() { message: "I am a custom message" }); }); -}); \ No newline at end of file + + it("reports a passing result to the spec when the 'not' comparison passes, given a negativeCompare", function() { + var matchers = { + toFoo: function() { + return { + compare: function() { return { pass: true }; }, + negativeCompare: function() { return { pass: true }; } + }; + } + }, + addExpectationResult = jasmine.createSpy("addExpectationResult"), + actual = "an actual", + expectation; + + j$.Expectation.addMatchers(matchers); + + expectation = new j$.Expectation({ + matchers: matchers, + actual: "an actual", + addExpectationResult: addExpectationResult, + isNot: true + }); + + expectation.toFoo("hello"); + + expect(addExpectationResult).toHaveBeenCalledWith(true, { + matcherName: "toFoo", + passed: true, + expected: "hello", + actual: actual, + message: "" + }); + }); + + it("reports a failing result and a custom fail message to the spec when the 'not' comparison fails, given a negativeCompare", function() { + var matchers = { + toFoo: function() { + return { + compare: function() { return { pass: true }; }, + negativeCompare: function() { + return { + pass: false, + message: "I'm a custom message" + }; + } + }; + } + }, + addExpectationResult = jasmine.createSpy("addExpectationResult"), + actual = "an actual", + expectation; + + j$.Expectation.addMatchers(matchers); + + expectation = new j$.Expectation({ + matchers: matchers, + actual: "an actual", + addExpectationResult: addExpectationResult, + isNot: true + }); + + expectation.toFoo("hello"); + + expect(addExpectationResult).toHaveBeenCalledWith(false, { + matcherName: "toFoo", + passed: false, + expected: "hello", + actual: actual, + message: "I'm a custom message" + }); + }); + +}); + diff --git a/src/core/Expectation.js b/src/core/Expectation.js index e8205eb9..3f82c09c 100644 --- a/src/core/Expectation.js +++ b/src/core/Expectation.js @@ -22,12 +22,21 @@ getJasmineRequireObj().Expectation = function() { args.unshift(this.actual); - var result = matcherFactory(this.util, this.customEqualityTesters).compare.apply(null, args); + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } if (this.isNot) { - result.pass = !result.pass; + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; } + var result = matcherCompare.apply(null, args); + if (!result.pass) { if (!result.message) { args.unshift(this.isNot);