/** * @depend ../sinon.js * @depend match.js */ /*jslint eqeqeq: false, onevar: false, plusplus: false*/ /*global module, require, sinon*/ /** * Spy calls * * @author Christian Johansen (christian@cjohansen.no) * @author Maximilian Antoni (mail@maxantoni.de) * @license BSD * * Copyright (c) 2010-2013 Christian Johansen * Copyright (c) 2013 Maximilian Antoni */ "use strict"; (function (sinon) { var commonJSModule = typeof module !== "undefined" && module.exports && typeof require == "function"; if (!sinon && commonJSModule) { sinon = require("../sinon"); } if (!sinon) { return; } function throwYieldError(proxy, text, args) { var msg = sinon.functionName(proxy) + text; if (args.length) { msg += " Received [" + slice.call(args).join(", ") + "]"; } throw new Error(msg); } var slice = Array.prototype.slice; var callProto = { calledOn: function calledOn(thisValue) { if (sinon.match && sinon.match.isMatcher(thisValue)) { return thisValue.test(this.thisValue); } return this.thisValue === thisValue; }, calledWith: function calledWith() { for (var i = 0, l = arguments.length; i < l; i += 1) { if (!sinon.deepEqual(arguments[i], this.args[i])) { return false; } } return true; }, calledWithMatch: function calledWithMatch() { for (var i = 0, l = arguments.length; i < l; i += 1) { var actual = this.args[i]; var expectation = arguments[i]; if (!sinon.match || !sinon.match(expectation).test(actual)) { return false; } } return true; }, calledWithExactly: function calledWithExactly() { return arguments.length == this.args.length && this.calledWith.apply(this, arguments); }, notCalledWith: function notCalledWith() { return !this.calledWith.apply(this, arguments); }, notCalledWithMatch: function notCalledWithMatch() { return !this.calledWithMatch.apply(this, arguments); }, returned: function returned(value) { return sinon.deepEqual(value, this.returnValue); }, threw: function threw(error) { if (typeof error === "undefined" || !this.exception) { return !!this.exception; } return this.exception === error || this.exception.name === error; }, calledWithNew: function calledWithNew() { return this.proxy.prototype && this.thisValue instanceof this.proxy; }, calledBefore: function (other) { return this.callId < other.callId; }, calledAfter: function (other) { return this.callId > other.callId; }, callArg: function (pos) { this.args[pos](); }, callArgOn: function (pos, thisValue) { this.args[pos].apply(thisValue); }, callArgWith: function (pos) { this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1))); }, callArgOnWith: function (pos, thisValue) { var args = slice.call(arguments, 2); this.args[pos].apply(thisValue, args); }, "yield": function () { this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0))); }, yieldOn: function (thisValue) { var args = this.args; for (var i = 0, l = args.length; i < l; ++i) { if (typeof args[i] === "function") { args[i].apply(thisValue, slice.call(arguments, 1)); return; } } throwYieldError(this.proxy, " cannot yield since no callback was passed.", args); }, yieldTo: function (prop) { this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1))); }, yieldToOn: function (prop, thisValue) { var args = this.args; for (var i = 0, l = args.length; i < l; ++i) { if (args[i] && typeof args[i][prop] === "function") { args[i][prop].apply(thisValue, slice.call(arguments, 2)); return; } } throwYieldError(this.proxy, " cannot yield to '" + prop + "' since no callback was passed.", args); }, toString: function () { var callStr = this.proxy.toString() + "("; var args = []; for (var i = 0, l = this.args.length; i < l; ++i) { args.push(sinon.format(this.args[i])); } callStr = callStr + args.join(", ") + ")"; if (typeof this.returnValue != "undefined") { callStr += " => " + sinon.format(this.returnValue); } if (this.exception) { callStr += " !" + this.exception.name; if (this.exception.message) { callStr += "(" + this.exception.message + ")"; } } return callStr; } }; callProto.invokeCallback = callProto.yield; function createSpyCall(spy, thisValue, args, returnValue, exception, id) { if (typeof id !== "number") { throw new TypeError("Call id is not a number"); } var proxyCall = sinon.create(callProto); proxyCall.proxy = spy; proxyCall.thisValue = thisValue; proxyCall.args = args; proxyCall.returnValue = returnValue; proxyCall.exception = exception; proxyCall.callId = id; return proxyCall; } createSpyCall.toString = callProto.toString; // used by mocks sinon.spyCall = createSpyCall; if (typeof define === "function" && define.amd) { define(["module"], function(module) { module.exports = createSpyCall; }); } else if (commonJSModule) { module.exports = createSpyCall; } }(typeof sinon == "object" && sinon || null));