From a6a19629248d376b2e9a06c8c41a8d6660ed0b4e Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 31 May 2015 16:49:55 -0500 Subject: [PATCH] add toHaveBeenCalledTimes matcher Fix #853 --- .../matchers/toHaveBeenCalledTimesSpec.js | 81 +++++++++++++++++++ src/core/matchers/requireMatchers.js | 1 + src/core/matchers/toHaveBeenCalledTimes..js | 30 +++++++ 3 files changed, 112 insertions(+) create mode 100644 spec/core/matchers/toHaveBeenCalledTimesSpec.js create mode 100644 src/core/matchers/toHaveBeenCalledTimes..js diff --git a/spec/core/matchers/toHaveBeenCalledTimesSpec.js b/spec/core/matchers/toHaveBeenCalledTimesSpec.js new file mode 100644 index 00000000..3953ee1e --- /dev/null +++ b/spec/core/matchers/toHaveBeenCalledTimesSpec.js @@ -0,0 +1,81 @@ +describe("toHaveBeenCalledTimes", function() { + it("passes when the actual matches the expected", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + calledSpy = j$.createSpy('called-spy'), + result; + calledSpy(); + + result = matcher.compare(calledSpy, 1); + expect(result.pass).toBe(true); + }); + + it("fails when expected numbers is not supplied", function(){ + var matcher = j$.matchers.toHaveBeenCalledTimes(), + spy = j$.createSpy('spy'), + result; + + spy(); + expect(function() { + matcher.compare(spy); + }).toThrowError('Expected times failed is required as an argument.'); + }); + + it("fails when the actual was called less than the expected", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + uncalledSpy = j$.createSpy('uncalled spy'), + result; + + result = matcher.compare(uncalledSpy, 2); + expect(result.pass).toBe(false); + }); + + it("fails when the actual was called more than expected", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + uncalledSpy = j$.createSpy('uncalled spy'), + result; + + uncalledSpy(); + uncalledSpy(); + + result = matcher.compare(uncalledSpy, 1); + expect(result.pass).toBe(false); + }); + + it("throws an exception when the actual is not a spy", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + fn = function() {}; + + expect(function() { + matcher.compare(fn); + }).toThrowError("Expected a spy, but got Function."); + }); + + it("has a custom message on failure that tells it was called only once", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + spy = j$.createSpy('sample-spy'), + result; + spy(); + spy(); + spy(); + spy(); + + result = matcher.compare(spy, 1); + + expect(result.message).toEqual('Expected spy sample-spy to have been called once. It was called ' + 4 + ' times.'); + }); + + it("has a custom message on failure that tells how many times it was called", function() { + var matcher = j$.matchers.toHaveBeenCalledTimes(), + spy = j$.createSpy('sample-spy'), + result; + spy(); + spy(); + spy(); + spy(); + + result = matcher.compare(spy, 2); + + expect(result.message).toEqual('Expected spy sample-spy to have been called 2 times. It was called ' + 4 + ' times.'); + }); +}); + diff --git a/src/core/matchers/requireMatchers.js b/src/core/matchers/requireMatchers.js index 2b21a7a4..63f22ce9 100644 --- a/src/core/matchers/requireMatchers.js +++ b/src/core/matchers/requireMatchers.js @@ -14,6 +14,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) { 'toEqual', 'toHaveBeenCalled', 'toHaveBeenCalledWith', + 'toHaveBeenCalledTimes', 'toMatch', 'toThrow', 'toThrowError' diff --git a/src/core/matchers/toHaveBeenCalledTimes..js b/src/core/matchers/toHaveBeenCalledTimes..js new file mode 100644 index 00000000..b59cc4f4 --- /dev/null +++ b/src/core/matchers/toHaveBeenCalledTimes..js @@ -0,0 +1,30 @@ +getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { + + function toHaveBeenCalledTimes() { + return { + compare: function(actual, expected) { + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + var args = Array.prototype.slice.call(arguments, 0), + result = { pass: false }; + + if(!expected){ + throw new Error('Expected times failed is required as an argument.'); + } + + actual = args[0]; + var calls = actual.calls.count(); + var timesMessage = expected === 1 ? 'once' : expected + ' times'; + result.pass = calls === expected; + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' : + 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.'; + return result; + } + }; + } + + return toHaveBeenCalledTimes; +};