| (function (sinonChai) { |
| "use strict"; |
| |
| // Module systems magic dance. |
| |
| if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { |
| // NodeJS |
| module.exports = sinonChai; |
| } else if (typeof define === "function" && define.amd) { |
| // AMD |
| define(function () { |
| return sinonChai; |
| }); |
| } else { |
| // Other environment (usually <script> tag): plug in to global chai instance directly. |
| chai.use(sinonChai); |
| } |
| }(function sinonChai(chai, utils) { |
| "use strict"; |
| |
| var slice = Array.prototype.slice; |
| |
| function isSpy(putativeSpy) { |
| return typeof putativeSpy === "function" && |
| typeof putativeSpy.getCall === "function" && |
| typeof putativeSpy.calledWithExactly === "function"; |
| } |
| |
| function isCall(putativeCall) { |
| return putativeCall && isSpy(putativeCall.proxy); |
| } |
| |
| function assertCanWorkWith(assertion) { |
| if (!isSpy(assertion._obj) && !isCall(assertion._obj)) { |
| throw new TypeError(utils.inspect(assertion._obj) + " is not a spy or a call to a spy!"); |
| } |
| } |
| |
| function getMessages(spy, action, nonNegatedSuffix, always, args) { |
| var verbPhrase = always ? "always have " : "have "; |
| nonNegatedSuffix = nonNegatedSuffix || ""; |
| if (isSpy(spy.proxy)) { |
| spy = spy.proxy; |
| } |
| |
| function printfArray(array) { |
| return spy.printf.apply(spy, array); |
| } |
| |
| return { |
| affirmative: printfArray(["expected %n to " + verbPhrase + action + nonNegatedSuffix].concat(args)), |
| negative: printfArray(["expected %n to not " + verbPhrase + action].concat(args)) |
| }; |
| } |
| |
| function sinonProperty(name, action, nonNegatedSuffix) { |
| utils.addProperty(chai.Assertion.prototype, name, function () { |
| assertCanWorkWith(this); |
| |
| var messages = getMessages(this._obj, action, nonNegatedSuffix, false); |
| this.assert(this._obj[name], messages.affirmative, messages.negative); |
| }); |
| } |
| |
| function createSinonMethodHandler(sinonName, action, nonNegatedSuffix) { |
| return function () { |
| assertCanWorkWith(this); |
| |
| var alwaysSinonMethod = "always" + sinonName[0].toUpperCase() + sinonName.substring(1); |
| var shouldBeAlways = utils.flag(this, "always") && typeof this._obj[alwaysSinonMethod] === "function"; |
| var sinonMethod = shouldBeAlways ? alwaysSinonMethod : sinonName; |
| |
| var messages = getMessages(this._obj, action, nonNegatedSuffix, shouldBeAlways, slice.call(arguments)); |
| this.assert(this._obj[sinonMethod].apply(this._obj, arguments), messages.affirmative, messages.negative); |
| }; |
| } |
| |
| function sinonMethodAsProperty(name, action, nonNegatedSuffix) { |
| var handler = createSinonMethodHandler(name, action, nonNegatedSuffix); |
| utils.addProperty(chai.Assertion.prototype, name, handler); |
| } |
| |
| function exceptionalSinonMethod(chaiName, sinonName, action, nonNegatedSuffix) { |
| var handler = createSinonMethodHandler(sinonName, action, nonNegatedSuffix); |
| utils.addMethod(chai.Assertion.prototype, chaiName, handler); |
| } |
| |
| function sinonMethod(name, action, nonNegatedSuffix) { |
| exceptionalSinonMethod(name, name, action, nonNegatedSuffix); |
| } |
| |
| utils.addProperty(chai.Assertion.prototype, "always", function () { |
| utils.flag(this, "always", true); |
| }); |
| |
| sinonProperty("called", "been called", " at least once, but it was never called"); |
| sinonProperty("calledOnce", "been called exactly once", ", but it was called %c%C"); |
| sinonProperty("calledTwice", "been called exactly twice", ", but it was called %c%C"); |
| sinonProperty("calledThrice", "been called exactly thrice", ", but it was called %c%C"); |
| sinonMethodAsProperty("calledWithNew", "been called with new"); |
| sinonMethod("calledBefore", "been called before %1"); |
| sinonMethod("calledAfter", "been called after %1"); |
| sinonMethod("calledOn", "been called with %1 as this", ", but it was called with %t instead"); |
| sinonMethod("calledWith", "been called with arguments %*", "%C"); |
| sinonMethod("calledWithExactly", "been called with exact arguments %*", "%C"); |
| sinonMethod("calledWithMatch", "been called with arguments matching %*", "%C"); |
| sinonMethod("returned", "returned %1"); |
| exceptionalSinonMethod("thrown", "threw", "thrown %1"); |
| })); |