Commit fb4891d1 authored by Tristan Cavelier's avatar Tristan Cavelier

sinon.js updated

parent fd8a8709
/** /**
* Sinon.JS 1.6.0, 2013/02/18 * Sinon.JS 1.7.3, 2013/06/20
* *
* @author Christian Johansen (christian@cjohansen.no) * @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
...@@ -33,9 +33,7 @@ ...@@ -33,9 +33,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
var sinon = (function () { this.sinon = (function () {
"use strict";
var buster = (function (setTimeout, B) { var buster = (function (setTimeout, B) {
var isNode = typeof require == "function" && typeof module == "object"; var isNode = typeof require == "function" && typeof module == "object";
var div = typeof document != "undefined" && document.createElement("div"); var div = typeof document != "undefined" && document.createElement("div");
...@@ -505,6 +503,10 @@ var sinon = (function (buster) { ...@@ -505,6 +503,10 @@ var sinon = (function (buster) {
} }
} }
function isRestorable (obj) {
return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
}
var sinon = { var sinon = {
wrapMethod: function wrapMethod(object, property, method) { wrapMethod: function wrapMethod(object, property, method) {
if (!object) { if (!object) {
...@@ -617,6 +619,10 @@ var sinon = (function (buster) { ...@@ -617,6 +619,10 @@ var sinon = (function (buster) {
return true; return true;
} }
if (aString == "[object Date]") {
return a.valueOf() === b.valueOf();
}
var prop, aLength = 0, bLength = 0; var prop, aLength = 0, bLength = 0;
for (prop in a) { for (prop in a) {
...@@ -631,11 +637,7 @@ var sinon = (function (buster) { ...@@ -631,11 +637,7 @@ var sinon = (function (buster) {
bLength += 1; bLength += 1;
} }
if (aLength != bLength) { return aLength == bLength;
return false;
}
return true;
}, },
functionName: function functionName(func) { functionName: function functionName(func) {
...@@ -755,6 +757,19 @@ var sinon = (function (buster) { ...@@ -755,6 +757,19 @@ var sinon = (function (buster) {
throw new TypeError("The constructor should be a function."); throw new TypeError("The constructor should be a function.");
} }
return sinon.stub(sinon.create(constructor.prototype)); return sinon.stub(sinon.create(constructor.prototype));
},
restore: function (object) {
if (object !== null && typeof object === "object") {
for (var prop in object) {
if (isRestorable(object[prop])) {
object[prop].restore();
}
}
}
else if (isRestorable(object)) {
object.restore();
}
} }
}; };
...@@ -1044,559 +1059,568 @@ var sinon = (function (buster) { ...@@ -1044,559 +1059,568 @@ var sinon = (function (buster) {
/*jslint eqeqeq: false, onevar: false, plusplus: false*/ /*jslint eqeqeq: false, onevar: false, plusplus: false*/
/*global module, require, sinon*/ /*global module, require, sinon*/
/** /**
* Spy functions * Spy calls
* *
* @author Christian Johansen (christian@cjohansen.no) * @author Christian Johansen (christian@cjohansen.no)
* @author Maximilian Antoni (mail@maxantoni.de)
* @license BSD * @license BSD
* *
* Copyright (c) 2010-2013 Christian Johansen * Copyright (c) 2010-2013 Christian Johansen
* Copyright (c) 2013 Maximilian Antoni
*/ */
(function (sinon) { var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module == "object" && typeof require == "function";
var spyCall;
var callId = 0;
var push = [].push;
var slice = Array.prototype.slice;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
}
if (!sinon) { if (!this.sinon && commonJSModule) {
return; var sinon = require("../sinon");
} }
function spy(object, property) {
if (!property && typeof object == "function") {
return spy.create(object);
}
if (!object && !property) { (function (sinon) {
return spy.create(function () { }); 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 method = object[property];
return sinon.wrapMethod(object, property, spy.create(method));
} }
sinon.extend(spy, (function () { var slice = Array.prototype.slice;
function delegateToCalls(api, method, matchAny, actual, notCalled) { var callProto = {
api[method] = function () { calledOn: function calledOn(thisValue) {
if (!this.called) { if (sinon.match && sinon.match.isMatcher(thisValue)) {
if (notCalled) { return thisValue.test(this.thisValue);
return notCalled.apply(this, arguments); }
} 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 false;
} }
}
var currentCall; return true;
var matches = 0; },
for (var i = 0, l = this.callCount; i < l; i += 1) {
currentCall = this.getCall(i);
if (currentCall[actual || method].apply(currentCall, arguments)) {
matches += 1;
if (matchAny) { calledWithMatch: function calledWithMatch() {
return true; 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 matches === this.callCount;
};
}
function matchingFake(fakes, args, strict) {
if (!fakes) {
return;
} }
return true;
},
var alen = args.length; calledWithExactly: function calledWithExactly() {
return arguments.length == this.args.length &&
this.calledWith.apply(this, arguments);
},
for (var i = 0, l = fakes.length; i < l; i++) { notCalledWith: function notCalledWith() {
if (fakes[i].matches(args, strict)) { return !this.calledWith.apply(this, arguments);
return fakes[i]; },
}
}
}
function incrementCallCount() { notCalledWithMatch: function notCalledWithMatch() {
this.called = true; return !this.calledWithMatch.apply(this, arguments);
this.callCount += 1; },
this.notCalled = false;
this.calledOnce = this.callCount == 1;
this.calledTwice = this.callCount == 2;
this.calledThrice = this.callCount == 3;
}
function createCallProperties() { returned: function returned(value) {
this.firstCall = this.getCall(0); return sinon.deepEqual(value, this.returnValue);
this.secondCall = this.getCall(1); },
this.thirdCall = this.getCall(2);
this.lastCall = this.getCall(this.callCount - 1);
}
var vars = "a,b,c,d,e,f,g,h,i,j,k,l"; threw: function threw(error) {
function createProxy(func) { if (typeof error === "undefined" || !this.exception) {
// Retain the function length: return !!this.exception;
var p;
if (func.length) {
eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
") { return p.invoke(func, this, slice.call(arguments)); });");
} }
else {
p = function proxy() {
return p.invoke(func, this, slice.call(arguments));
};
}
return p;
}
var uuid = 0; return this.exception === error || this.exception.name === error;
},
// Public API
var spyApi = {
reset: function () {
this.called = false;
this.notCalled = true;
this.calledOnce = false;
this.calledTwice = false;
this.calledThrice = false;
this.callCount = 0;
this.firstCall = null;
this.secondCall = null;
this.thirdCall = null;
this.lastCall = null;
this.args = [];
this.returnValues = [];
this.thisValues = [];
this.exceptions = [];
this.callIds = [];
if (this.fakes) {
for (var i = 0; i < this.fakes.length; i++) {
this.fakes[i].reset();
}
}
},
create: function create(func) { calledWithNew: function calledWithNew(thisValue) {
var name; return this.thisValue instanceof this.proxy;
},
if (typeof func != "function") { calledBefore: function (other) {
func = function () { }; return this.callId < other.callId;
} else { },
name = sinon.functionName(func);
}
var proxy = createProxy(func); calledAfter: function (other) {
return this.callId > other.callId;
},
sinon.extend(proxy, spy); callArg: function (pos) {
delete proxy.create; this.args[pos]();
sinon.extend(proxy, func); },
proxy.reset(); callArgOn: function (pos, thisValue) {
proxy.prototype = func.prototype; this.args[pos].apply(thisValue);
proxy.displayName = name || "spy"; },
proxy.toString = sinon.functionToString;
proxy._create = sinon.spy.create;
proxy.id = "spy#" + uuid++;
return proxy; callArgWith: function (pos) {
}, this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
},
invoke: function invoke(func, thisValue, args) { callArgOnWith: function (pos, thisValue) {
var matching = matchingFake(this.fakes, args); var args = slice.call(arguments, 2);
var exception, returnValue; this.args[pos].apply(thisValue, args);
},
incrementCallCount.call(this); "yield": function () {
push.call(this.thisValues, thisValue); this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
push.call(this.args, args); },
push.call(this.callIds, callId++);
try { yieldOn: function (thisValue) {
if (matching) { var args = this.args;
returnValue = matching.invoke(func, thisValue, args); for (var i = 0, l = args.length; i < l; ++i) {
} else { if (typeof args[i] === "function") {
returnValue = (this.func || func).apply(thisValue, args); args[i].apply(thisValue, slice.call(arguments, 1));
} return;
} catch (e) {
push.call(this.returnValues, undefined);
exception = e;
throw e;
} finally {
push.call(this.exceptions, exception);
} }
}
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
},
push.call(this.returnValues, returnValue); yieldTo: function (prop) {
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
},
createCallProperties.call(this); 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);
},
return returnValue; toString: function () {
}, var callStr = this.proxy.toString() + "(";
var args = [];
getCall: function getCall(i) { for (var i = 0, l = this.args.length; i < l; ++i) {
if (i < 0 || i >= this.callCount) { args.push(sinon.format(this.args[i]));
return null; }
}
return spyCall.create(this, this.thisValues[i], this.args[i], callStr = callStr + args.join(", ") + ")";
this.returnValues[i], this.exceptions[i],
this.callIds[i]);
},
calledBefore: function calledBefore(spyFn) { if (typeof this.returnValue != "undefined") {
if (!this.called) { callStr += " => " + sinon.format(this.returnValue);
return false; }
}
if (!spyFn.called) { if (this.exception) {
return true; callStr += " !" + this.exception.name;
if (this.exception.message) {
callStr += "(" + this.exception.message + ")";
} }
}
return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1]; return callStr;
}, }
};
calledAfter: function calledAfter(spyFn) { callProto.invokeCallback = callProto.yield;
if (!this.called || !spyFn.called) {
return false;
}
return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1]; 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
withArgs: function () { sinon.spyCall = createSpyCall;
var args = slice.call(arguments); }(typeof sinon == "object" && sinon || null));
if (this.fakes) { /**
var match = matchingFake(this.fakes, args, true); * @depend ../sinon.js
*/
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
/*global module, require, sinon*/
/**
* Spy functions
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
if (match) { (function (sinon) {
return match; var commonJSModule = typeof module == "object" && typeof require == "function";
} var push = Array.prototype.push;
} else { var slice = Array.prototype.slice;
this.fakes = []; var callId = 0;
}
var original = this; function spy(object, property) {
var fake = this._create(); if (!property && typeof object == "function") {
fake.matchingAguments = args; return spy.create(object);
push.call(this.fakes, fake); }
fake.withArgs = function () { if (!object && !property) {
return original.withArgs.apply(original, arguments); return spy.create(function () { });
}; }
for (var i = 0; i < this.args.length; i++) { var method = object[property];
if (fake.matches(this.args[i])) { return sinon.wrapMethod(object, property, spy.create(method));
incrementCallCount.call(fake); }
push.call(fake.thisValues, this.thisValues[i]);
push.call(fake.args, this.args[i]);
push.call(fake.returnValues, this.returnValues[i]);
push.call(fake.exceptions, this.exceptions[i]);
push.call(fake.callIds, this.callIds[i]);
}
}
createCallProperties.call(fake);
return fake; function matchingFake(fakes, args, strict) {
}, if (!fakes) {
return;
}
matches: function (args, strict) { var alen = args.length;
var margs = this.matchingAguments;
if (margs.length <= args.length && for (var i = 0, l = fakes.length; i < l; i++) {
sinon.deepEqual(margs, args.slice(0, margs.length))) { if (fakes[i].matches(args, strict)) {
return !strict || margs.length == args.length; return fakes[i];
} }
}, }
}
printf: function (format) { function incrementCallCount() {
var spy = this; this.called = true;
var args = slice.call(arguments, 1); this.callCount += 1;
var formatter; this.notCalled = false;
this.calledOnce = this.callCount == 1;
this.calledTwice = this.callCount == 2;
this.calledThrice = this.callCount == 3;
}
return (format || "").replace(/%(.)/g, function (match, specifyer) { function createCallProperties() {
formatter = spyApi.formatters[specifyer]; this.firstCall = this.getCall(0);
this.secondCall = this.getCall(1);
this.thirdCall = this.getCall(2);
this.lastCall = this.getCall(this.callCount - 1);
}
if (typeof formatter == "function") { var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
return formatter.call(null, spy, args); function createProxy(func) {
} else if (!isNaN(parseInt(specifyer), 10)) { // Retain the function length:
return sinon.format(args[specifyer - 1]); var p;
} if (func.length) {
eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
") { return p.invoke(func, this, slice.call(arguments)); });");
}
else {
p = function proxy() {
return p.invoke(func, this, slice.call(arguments));
};
}
return p;
}
return "%" + specifyer; var uuid = 0;
});
// Public API
var spyApi = {
reset: function () {
this.called = false;
this.notCalled = true;
this.calledOnce = false;
this.calledTwice = false;
this.calledThrice = false;
this.callCount = 0;
this.firstCall = null;
this.secondCall = null;
this.thirdCall = null;
this.lastCall = null;
this.args = [];
this.returnValues = [];
this.thisValues = [];
this.exceptions = [];
this.callIds = [];
if (this.fakes) {
for (var i = 0; i < this.fakes.length; i++) {
this.fakes[i].reset();
}
} }
}; },
delegateToCalls(spyApi, "calledOn", true); create: function create(func) {
delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn"); var name;
delegateToCalls(spyApi, "calledWith", true);
delegateToCalls(spyApi, "calledWithMatch", true);
delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
delegateToCalls(spyApi, "alwaysCalledWithMatch", false, "calledWithMatch");
delegateToCalls(spyApi, "calledWithExactly", true);
delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
function () { return true; });
delegateToCalls(spyApi, "neverCalledWithMatch", false, "notCalledWithMatch",
function () { return true; });
delegateToCalls(spyApi, "threw", true);
delegateToCalls(spyApi, "alwaysThrew", false, "threw");
delegateToCalls(spyApi, "returned", true);
delegateToCalls(spyApi, "alwaysReturned", false, "returned");
delegateToCalls(spyApi, "calledWithNew", true);
delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgWith = spyApi.callArg;
delegateToCalls(spyApi, "callArgOn", false, "callArgOnWith", function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgOnWith = spyApi.callArgOn;
delegateToCalls(spyApi, "yield", false, "yield", function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
// "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
spyApi.invokeCallback = spyApi.yield;
delegateToCalls(spyApi, "yieldOn", false, "yieldOn", function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});
delegateToCalls(spyApi, "yieldToOn", false, "yieldToOn", function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});
spyApi.formatters = { if (typeof func != "function") {
"c": function (spy) { func = function () { };
return sinon.timesInWords(spy.callCount); } else {
}, name = sinon.functionName(func);
}
"n": function (spy) { var proxy = createProxy(func);
return spy.toString();
},
"C": function (spy) { sinon.extend(proxy, spy);
var calls = []; delete proxy.create;
sinon.extend(proxy, func);
for (var i = 0, l = spy.callCount; i < l; ++i) { proxy.reset();
var stringifiedCall = " " + spy.getCall(i).toString(); proxy.prototype = func.prototype;
if (/\n/.test(calls[i - 1])) { proxy.displayName = name || "spy";
stringifiedCall = "\n" + stringifiedCall; proxy.toString = sinon.functionToString;
} proxy._create = sinon.spy.create;
push.call(calls, stringifiedCall); proxy.id = "spy#" + uuid++;
}
return calls.length > 0 ? "\n" + calls.join("\n") : ""; return proxy;
}, },
"t": function (spy) { invoke: function invoke(func, thisValue, args) {
var objects = []; var matching = matchingFake(this.fakes, args);
var exception, returnValue;
for (var i = 0, l = spy.callCount; i < l; ++i) { incrementCallCount.call(this);
push.call(objects, sinon.format(spy.thisValues[i])); push.call(this.thisValues, thisValue);
push.call(this.args, args);
push.call(this.callIds, callId++);
try {
if (matching) {
returnValue = matching.invoke(func, thisValue, args);
} else {
returnValue = (this.func || func).apply(thisValue, args);
} }
} catch (e) {
push.call(this.returnValues, undefined);
exception = e;
throw e;
} finally {
push.call(this.exceptions, exception);
}
return objects.join(", "); push.call(this.returnValues, returnValue);
},
"*": function (spy, args) { createCallProperties.call(this);
var formatted = [];
for (var i = 0, l = args.length; i < l; ++i) { return returnValue;
push.call(formatted, sinon.format(args[i])); },
}
return formatted.join(", "); getCall: function getCall(i) {
if (i < 0 || i >= this.callCount) {
return null;
} }
};
return spyApi;
}()));
spyCall = (function () { return sinon.spyCall(this, this.thisValues[i], this.args[i],
this.returnValues[i], this.exceptions[i],
this.callIds[i]);
},
function throwYieldError(proxy, text, args) { calledBefore: function calledBefore(spyFn) {
var msg = sinon.functionName(proxy) + text; if (!this.called) {
if (args.length) { return false;
msg += " Received [" + slice.call(args).join(", ") + "]";
} }
throw new Error(msg);
}
var callApi = { if (!spyFn.called) {
create: function create(spy, thisValue, args, returnValue, exception, id) { return true;
var proxyCall = sinon.create(spyCall); }
delete proxyCall.create;
proxyCall.proxy = spy;
proxyCall.thisValue = thisValue;
proxyCall.args = args;
proxyCall.returnValue = returnValue;
proxyCall.exception = exception;
proxyCall.callId = typeof id == "number" && id || callId++;
return proxyCall;
},
calledOn: function calledOn(thisValue) { return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
if (sinon.match && sinon.match.isMatcher(thisValue)) { },
return thisValue.test(this.thisValue);
}
return this.thisValue === thisValue;
},
calledWith: function calledWith() { calledAfter: function calledAfter(spyFn) {
for (var i = 0, l = arguments.length; i < l; i += 1) { if (!this.called || !spyFn.called) {
if (!sinon.deepEqual(arguments[i], this.args[i])) { return false;
return false; }
}
}
return true; return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
}, },
calledWithMatch: function calledWithMatch() { withArgs: function () {
for (var i = 0, l = arguments.length; i < l; i += 1) { var args = slice.call(arguments);
var actual = this.args[i];
var expectation = arguments[i];
if (!sinon.match || !sinon.match(expectation).test(actual)) {
return false;
}
}
return true;
},
calledWithExactly: function calledWithExactly() { if (this.fakes) {
return arguments.length == this.args.length && var match = matchingFake(this.fakes, args, true);
this.calledWith.apply(this, arguments);
},
notCalledWith: function notCalledWith() { if (match) {
return !this.calledWith.apply(this, arguments); return match;
}, }
} else {
this.fakes = [];
}
notCalledWithMatch: function notCalledWithMatch() { var original = this;
return !this.calledWithMatch.apply(this, arguments); var fake = this._create();
}, fake.matchingAguments = args;
push.call(this.fakes, fake);
returned: function returned(value) { fake.withArgs = function () {
return sinon.deepEqual(value, this.returnValue); return original.withArgs.apply(original, arguments);
}, };
threw: function threw(error) { for (var i = 0; i < this.args.length; i++) {
if (typeof error == "undefined" || !this.exception) { if (fake.matches(this.args[i])) {
return !!this.exception; incrementCallCount.call(fake);
push.call(fake.thisValues, this.thisValues[i]);
push.call(fake.args, this.args[i]);
push.call(fake.returnValues, this.returnValues[i]);
push.call(fake.exceptions, this.exceptions[i]);
push.call(fake.callIds, this.callIds[i]);
} }
}
createCallProperties.call(fake);
if (typeof error == "string") { return fake;
return this.exception.name == error; },
}
return this.exception === error; matches: function (args, strict) {
}, var margs = this.matchingAguments;
calledWithNew: function calledWithNew(thisValue) { if (margs.length <= args.length &&
return this.thisValue instanceof this.proxy; sinon.deepEqual(margs, args.slice(0, margs.length))) {
}, return !strict || margs.length == args.length;
}
},
calledBefore: function (other) { printf: function (format) {
return this.callId < other.callId; var spy = this;
}, var args = slice.call(arguments, 1);
var formatter;
calledAfter: function (other) { return (format || "").replace(/%(.)/g, function (match, specifyer) {
return this.callId > other.callId; formatter = spyApi.formatters[specifyer];
},
callArg: function (pos) { if (typeof formatter == "function") {
this.args[pos](); return formatter.call(null, spy, args);
}, } else if (!isNaN(parseInt(specifyer), 10)) {
return sinon.format(args[specifyer - 1]);
}
callArgOn: function (pos, thisValue) { return "%" + specifyer;
this.args[pos].apply(thisValue); });
}, }
};
callArgWith: function (pos) { function delegateToCalls(method, matchAny, actual, notCalled) {
this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1))); spyApi[method] = function () {
}, if (!this.called) {
if (notCalled) {
return notCalled.apply(this, arguments);
}
return false;
}
callArgOnWith: function (pos, thisValue) { var currentCall;
var args = slice.call(arguments, 2); var matches = 0;
this.args[pos].apply(thisValue, args);
},
"yield": function () { for (var i = 0, l = this.callCount; i < l; i += 1) {
this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0))); currentCall = this.getCall(i);
},
if (currentCall[actual || method].apply(currentCall, arguments)) {
matches += 1;
yieldOn: function (thisValue) { if (matchAny) {
var args = this.args; return true;
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) { return matches === this.callCount;
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1))); };
}, }
yieldToOn: function (prop, thisValue) { delegateToCalls("calledOn", true);
var args = this.args; delegateToCalls("alwaysCalledOn", false, "calledOn");
for (var i = 0, l = args.length; i < l; ++i) { delegateToCalls("calledWith", true);
if (args[i] && typeof args[i][prop] === "function") { delegateToCalls("calledWithMatch", true);
args[i][prop].apply(thisValue, slice.call(arguments, 2)); delegateToCalls("alwaysCalledWith", false, "calledWith");
return; delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
} delegateToCalls("calledWithExactly", true);
} delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
throwYieldError(this.proxy, " cannot yield to '" + prop + delegateToCalls("neverCalledWith", false, "notCalledWith",
"' since no callback was passed.", args); function () { return true; });
}, delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
function () { return true; });
delegateToCalls("threw", true);
delegateToCalls("alwaysThrew", false, "threw");
delegateToCalls("returned", true);
delegateToCalls("alwaysReturned", false, "returned");
delegateToCalls("calledWithNew", true);
delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
delegateToCalls("callArg", false, "callArgWith", function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgWith = spyApi.callArg;
delegateToCalls("callArgOn", false, "callArgOnWith", function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgOnWith = spyApi.callArgOn;
delegateToCalls("yield", false, "yield", function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
// "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
spyApi.invokeCallback = spyApi.yield;
delegateToCalls("yieldOn", false, "yieldOn", function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
delegateToCalls("yieldTo", false, "yieldTo", function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});
delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});
toString: function () { spyApi.formatters = {
var callStr = this.proxy.toString() + "("; "c": function (spy) {
var args = []; return sinon.timesInWords(spy.callCount);
},
for (var i = 0, l = this.args.length; i < l; ++i) { "n": function (spy) {
push.call(args, sinon.format(this.args[i])); return spy.toString();
} },
callStr = callStr + args.join(", ") + ")"; "C": function (spy) {
var calls = [];
if (typeof this.returnValue != "undefined") { for (var i = 0, l = spy.callCount; i < l; ++i) {
callStr += " => " + sinon.format(this.returnValue); var stringifiedCall = " " + spy.getCall(i).toString();
if (/\n/.test(calls[i - 1])) {
stringifiedCall = "\n" + stringifiedCall;
} }
push.call(calls, stringifiedCall);
}
if (this.exception) { return calls.length > 0 ? "\n" + calls.join("\n") : "";
callStr += " !" + this.exception.name; },
if (this.exception.message) { "t": function (spy) {
callStr += "(" + this.exception.message + ")"; var objects = [];
}
}
return callStr; for (var i = 0, l = spy.callCount; i < l; ++i) {
push.call(objects, sinon.format(spy.thisValues[i]));
} }
};
callApi.invokeCallback = callApi.yield;
return callApi;
}());
spy.spyCall = spyCall; return objects.join(", ");
},
"*": function (spy, args) {
var formatted = [];
// This steps outside the module sandbox and will be removed for (var i = 0, l = args.length; i < l; ++i) {
sinon.spyCall = spyCall; push.call(formatted, sinon.format(args[i]));
}
return formatted.join(", ");
}
};
sinon.extend(spy, spyApi);
spy.spyCall = sinon.spyCall;
if (commonJSModule) { if (commonJSModule) {
module.exports = spy; module.exports = spy;
...@@ -2926,15 +2950,16 @@ if (typeof sinon == "undefined") { ...@@ -2926,15 +2950,16 @@ if (typeof sinon == "undefined") {
(function () { (function () {
var push = [].push; var push = [].push;
sinon.Event = function Event(type, bubbles, cancelable) { sinon.Event = function Event(type, bubbles, cancelable, target) {
this.initEvent(type, bubbles, cancelable); this.initEvent(type, bubbles, cancelable, target);
}; };
sinon.Event.prototype = { sinon.Event.prototype = {
initEvent: function(type, bubbles, cancelable) { initEvent: function(type, bubbles, cancelable, target) {
this.type = type; this.type = type;
this.bubbles = bubbles; this.bubbles = bubbles;
this.cancelable = cancelable; this.cancelable = cancelable;
this.target = target;
}, },
stopPropagation: function () {}, stopPropagation: function () {},
...@@ -3038,6 +3063,23 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; ...@@ -3038,6 +3063,23 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.status = 0; this.status = 0;
this.statusText = ""; this.statusText = "";
var xhr = this;
var events = ["loadstart", "load", "abort", "loadend"];
function addEventListener(eventName) {
xhr.addEventListener(eventName, function (event) {
var listener = xhr["on" + eventName];
if (listener && typeof listener == "function") {
listener(event);
}
});
}
for (var i = events.length - 1; i >= 0; i--) {
addEventListener(events[i]);
}
if (typeof FakeXMLHttpRequest.onCreate == "function") { if (typeof FakeXMLHttpRequest.onCreate == "function") {
FakeXMLHttpRequest.onCreate(this); FakeXMLHttpRequest.onCreate(this);
} }
...@@ -3191,6 +3233,13 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; ...@@ -3191,6 +3233,13 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
} }
this.dispatchEvent(new sinon.Event("readystatechange")); this.dispatchEvent(new sinon.Event("readystatechange"));
switch (this.readyState) {
case FakeXMLHttpRequest.DONE:
this.dispatchEvent(new sinon.Event("load", false, false, this));
this.dispatchEvent(new sinon.Event("loadend", false, false, this));
break;
}
}, },
setRequestHeader: function setRequestHeader(header, value) { setRequestHeader: function setRequestHeader(header, value) {
...@@ -3246,6 +3295,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; ...@@ -3246,6 +3295,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
if (typeof this.onSend == "function") { if (typeof this.onSend == "function") {
this.onSend(this); this.onSend(this);
} }
this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
}, },
abort: function abort() { abort: function abort() {
...@@ -3260,6 +3311,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; ...@@ -3260,6 +3311,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
} }
this.readyState = sinon.FakeXMLHttpRequest.UNSENT; this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
this.dispatchEvent(new sinon.Event("abort", false, false, this));
if (typeof this.onerror === "function") {
this.onerror();
}
}, },
getResponseHeader: function getResponseHeader(header) { getResponseHeader: function getResponseHeader(header) {
...@@ -3340,6 +3396,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; ...@@ -3340,6 +3396,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.status = typeof status == "number" ? status : 200; this.status = typeof status == "number" ? status : 200;
this.statusText = FakeXMLHttpRequest.statusCodes[this.status]; this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
this.setResponseBody(body || ""); this.setResponseBody(body || "");
if (typeof this.onload === "function"){
this.onload();
}
} }
}); });
...@@ -4149,7 +4209,14 @@ if (typeof module == "object" && typeof require == "function") { ...@@ -4149,7 +4209,14 @@ if (typeof module == "object" && typeof require == "function") {
if (!sinon.calledInOrder(arguments)) { if (!sinon.calledInOrder(arguments)) {
try { try {
expected = [].join.call(arguments, ", "); expected = [].join.call(arguments, ", ");
actual = sinon.orderByFirstCall(slice.call(arguments)).join(", "); var calls = slice.call(arguments);
var i = calls.length;
while (i) {
if (!calls[--i].called) {
calls.splice(i, 1);
}
}
actual = sinon.orderByFirstCall(calls).join(", ");
} catch (e) { } catch (e) {
// If this fails, we'll just fall back to the blank string // If this fails, we'll just fall back to the blank string
} }
...@@ -4218,6 +4285,6 @@ if (typeof module == "object" && typeof require == "function") { ...@@ -4218,6 +4285,6 @@ if (typeof module == "object" && typeof require == "function") {
} else { } else {
sinon.assert = assert; sinon.assert = assert;
} }
}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global)); }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
return sinon;}.call(typeof window != 'undefined' && window || {})); return sinon;}.call(typeof window != 'undefined' && window || {}));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment