Socket
Socket
Sign inDemoInstall

sinon

Package Overview
Dependencies
Maintainers
2
Versions
208
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sinon - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

GPATH

40

Changelog.txt

@@ -0,1 +1,41 @@

== 1.3.0 / 2012-01-01
* Support using bare functions as fake server response handlers (< 1.3.0
required URL and/or method matcher too)
* Log some internal errors to sinon.log (defaults to noop). Set sinon.log
to your logging utility of choice for better feedback when.
* White-list fake XHRs: Allows some fake requests and some that fall through to
the backend server (Tim Ruffles)
* Decide Date.now support at fake-time. Makes it possible to load something that
polyfills Date.now after Sinon loaded and still have Date.now on fake Dates.
* Mirror properties on replaced function properties
* New methods: spy.yield(), spy.yieldTo(), spy.callArg() and spy.callArgWith()
can be used to invoke callbacks passed to spies (while avoiding the mock-like
upfront yields() and friends). invokeCallback is available as an alias for
yield for people working with strict mode. (Maximilian Antoni)
* New properties: spy.firstCall, spy.secondCall, spy.thirdCall and spy.lastCall.
(Maximilian Antoni)
* New method: stub.returnsArg(), causes stub to return one of its arguments.
(Gavin Huang)
* Stubs now work for inherited methods. This was previously prohibited to avoid
stubbing not-yet-implemented methods. (Felix Geisendörfer)
* server.respond() can now accept the same arguments as server.respondWith() for
quick-and-dirty respondWith+respond. (Gavin Huang)
* Format objects with buster-format in the default bundle. Default to
util.inspect on node unless buster-format is available (not a hard dependency,
more like a 'preference').
* Bug fix: Make sure XHRs can complete even if onreadystatechange handler fails
* Bug fix: Mirror entire Date.prototype, including toUTCString when faking
* Bug fix: Default this object to global in exposed asserts
* Bug fix: sinon.test: use try/finally instead of catch and throw - preserves
stack traces (Kevin Turner)
* Bug fix: Fake `setTimeout` now returns ids greater than 0. (Domenic Denicola)
* Bug fix: NPM install warning (Felix Geisendörfer)
* Bug fix: Fake timers no longer swallows exceptions (Felix Geisendörfer)
* Bug fix: Properly expose all needed asserts for node
* Bug fix: wrapMethod on window property (i.e. when stubbing/spying on global
functions)
* Bug fix: Quote "yield" (Ben Hockey)
* Bug fix: callOrder works correctly when spies have been called multiple times
== 1.2.0 / 2011-09-27

@@ -2,0 +42,0 @@ * Bug fix: abort() switches state to DONE when OPENED and sent. Fix by

103

lib/sinon.js

@@ -13,4 +13,5 @@ /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/

var sinon = (function () {
var sinon = (function (buster) {
var div = typeof document != "undefined" && document.createElement("div");
var hasOwn = Object.prototype.hasOwnProperty;

@@ -28,3 +29,5 @@ function isNode(obj) {

obj.removeChild(div);
} catch (e) {}
} catch (e) {
// Remove failed, not much we can do about that
}
}

@@ -39,3 +42,11 @@

return {
function mirrorProperties(target, source) {
for (var prop in source) {
if (!hasOwn.call(target, prop)) {
target[prop] = source[prop];
}
}
}
var sinon = {
wrapMethod: function wrapMethod(object, property, method) {

@@ -54,4 +65,4 @@ if (!object) {

if (type != "function") {
throw new TypeError("Attempted to wrap " + type + " property " + property +
" as function");
throw new TypeError("Attempted to wrap " + type + " property " +
property + " as function");
}

@@ -68,3 +79,4 @@

var owned = object.hasOwnProperty(property);
// IE 8 does not support hasOwnProperty on the window object.
var owned = hasOwn.call(object, property);
object[property] = method;

@@ -82,2 +94,3 @@ method.displayName = property;

method.restore.sinon = true;
mirrorProperties(method, wrappedMethod);

@@ -124,3 +137,8 @@ return method;

if (Object.prototype.toString.call(a) == "[object Array]") {
var aString = Object.prototype.toString.call(a);
if (aString != Object.prototype.toString.call(b)) {
return false;
}
if (aString == "[object Array]") {
if (a.length !== b.length) {

@@ -239,19 +257,62 @@ return false;

// uuid, won't ever be equal
return a.getCall(0).callId < b.getCall(0).callId ? -1 : 1;
var aCall = a.getCall(0);
var bCall = b.getCall(0);
var aId = aCall && aCall.callId || -1;
var bId = bCall && bCall.callId || -1;
return aId < bId ? -1 : 1;
});
},
log: function () {},
logError: function (label, err) {
var msg = label + " threw exception: "
sinon.log(msg + "[" + err.name + "] " + err.message);
if (err.stack) { sinon.log(err.stack); }
setTimeout(function () {
err.message = msg + err.message;
throw err;
}, 0);
}
};
}());
if (typeof module == "object" && typeof require == "function") {
module.exports = sinon;
module.exports.spy = require("./sinon/spy");
module.exports.stub = require("./sinon/stub");
module.exports.mock = require("./sinon/mock");
module.exports.collection = require("./sinon/collection");
module.exports.assert = require("./sinon/assert");
module.exports.sandbox = require("./sinon/sandbox");
module.exports.test = require("./sinon/test");
module.exports.testCase = require("./sinon/test_case");
module.exports.assert = require("./sinon/assert");
}
var isNode = typeof module == "object" && typeof require == "function";
if (isNode) {
try {
buster = { format: require("buster-format") };
} catch (e) {}
module.exports = sinon;
module.exports.spy = require("./sinon/spy");
module.exports.stub = require("./sinon/stub");
module.exports.mock = require("./sinon/mock");
module.exports.collection = require("./sinon/collection");
module.exports.assert = require("./sinon/assert");
module.exports.sandbox = require("./sinon/sandbox");
module.exports.test = require("./sinon/test");
module.exports.testCase = require("./sinon/test_case");
module.exports.assert = require("./sinon/assert");
}
if (buster) {
var formatter = sinon.create(buster.format);
formatter.quoteStrings = false;
sinon.format = function () {
return formatter.ascii.apply(formatter, arguments);
};
} else if (isNode) {
try {
var util = require("util");
sinon.format = function (value) {
return typeof value == "object" ? util.inspect(value) : value;
};
} catch (e) {
/* Node, but no util module - would be very old, but better safe than
sorry */
}
}
return sinon;
}(typeof buster == "object" && buster));

@@ -17,3 +17,3 @@ /**

(function (sinon) {
(function (sinon, global) {
var commonJSModule = typeof module == "object" && typeof require == "function";

@@ -52,2 +52,3 @@ var slice = Array.prototype.slice;

function failAssertion(object, msg) {
object = object || global;
var failMethod = object.fail || assert.fail;

@@ -109,3 +110,5 @@ failMethod.call(object, msg);

actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
} catch (e) {}
} catch (e) {
// If this fails, we'll just fall back to the blank string
}

@@ -171,2 +174,2 @@ failAssertion(this, "expected " + expected + " to be " +

}
}(typeof sinon == "object" && sinon || null));
}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));

@@ -19,2 +19,3 @@ /* @depend ../sinon.js */

var push = [].push;
var slice = Array.prototype.slice;

@@ -43,3 +44,2 @@ if (!sinon && commonJSModule) {

sinon.extend(spy, (function () {
var slice = Array.prototype.slice;

@@ -49,3 +49,6 @@ function delegateToCalls(api, method, matchAny, actual, notCalled) {

if (!this.called) {
return !!notCalled;
if (notCalled) {
return notCalled.apply(this, arguments);
}
return false;
}

@@ -96,2 +99,6 @@

this.callCount = 0;
this.firstCall = null;
this.secondCall = null;
this.thirdCall = null;
this.lastCall = null;
this.args = [];

@@ -159,2 +166,7 @@ this.returnValues = [];

this.firstCall = this.getCall(0);
this.secondCall = this.getCall(1);
this.thirdCall = this.getCall(2);
this.lastCall = this.getCall(this.callCount - 1);
return returnValue;

@@ -182,3 +194,3 @@ },

return this.callIds[0] < spyFn.callIds[0];
return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
},

@@ -230,3 +242,3 @@

var spy = this;
var args = [].slice.call(arguments, 1);
var args = slice.call(arguments, 1);
var formatter;

@@ -254,3 +266,4 @@

delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith", true);
delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
function () { return true; });
delegateToCalls(spyApi, "threw", true);

@@ -262,2 +275,15 @@ delegateToCalls(spyApi, "alwaysThrew", false, "threw");

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, "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, "yieldTo", false, "yieldTo", function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});

@@ -302,2 +328,11 @@ spyApi.formatters = {

spyCall = (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);
}
return {

@@ -373,2 +408,34 @@ create: function create(spy, thisValue, args, returnValue, exception, id) {

callArg: function (pos) {
this.args[pos]();
},
callArgWith: function (pos) {
var args = slice.call(arguments, 1);
this.args[pos].apply(null, args);
},
"yield": function () {
var args = this.args;
for (var i = 0, l = args.length; i < l; ++i) {
if (typeof args[i] === "function") {
args[i].apply(null, slice.call(arguments));
return;
}
}
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
},
yieldTo: function (prop) {
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(null, slice.call(arguments, 1));
return;
}
}
throwYieldError(this.proxy, " cannot yield to '" + prop +
"' since no callback was passed.", args);
},
toString: function () {

@@ -375,0 +442,0 @@ var callStr = this.proxy.toString() + "(";

@@ -47,3 +47,3 @@ /**

for (var prop in object) {
if (object.hasOwnProperty(prop) && typeof object[prop] == "function") {
if (typeof object[prop] === "function") {
stub(object, prop);

@@ -138,2 +138,4 @@ }

throw functionStub.exception;
} else if (typeof functionStub.returnArgAt == 'number') {
return arguments[functionStub.returnArgAt];
}

@@ -165,2 +167,12 @@

returnsArg: function returnsArg(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.returnArgAt = pos;
return this;
},
"throws": throwsException,

@@ -167,0 +179,0 @@ throwsException: throwsException,

@@ -46,12 +46,6 @@ /**

result = callback.apply(this, args);
} catch (e) {
exception = e;
} finally {
sandbox.verifyAndRestore();
}
sandbox.verifyAndRestore();
if (exception) {
throw exception;
}
return result;

@@ -58,0 +52,0 @@ };

@@ -69,3 +69,4 @@ /**

if (typeof response.response == "function") {
var args = [request].concat(requestUrl.match(response.url).slice(1));
var ru = response.url;
var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
return response.response.apply(response, args);

@@ -133,24 +134,29 @@ }

respondWith: function respondWith(method, url, body) {
if (arguments.length == 1) {
if (arguments.length == 1 && typeof method != "function") {
this.response = responseArray(method);
} else {
if (!this.responses) {
this.responses = [];
}
return;
}
if (arguments.length == 2) {
body = url;
url = method;
method = null;
}
if (!this.responses) { this.responses = []; }
push.call(this.responses, {
method: method,
url: url,
response: typeof body == "function" ? body : responseArray(body)
});
if (arguments.length == 1) {
body = method;
url = method = null;
}
if (arguments.length == 2) {
body = url;
url = method;
method = null;
}
push.call(this.responses, {
method: method,
url: url,
response: typeof body == "function" ? body : responseArray(body)
});
},
respond: function respond() {
if (arguments.length > 0) this.respondWith.apply(this, arguments);
var queue = this.queue || [];

@@ -184,3 +190,5 @@ var request;

}
} catch (e) {}
} catch (e) {
sinon.logError("Fake server request processing", e);
}
},

@@ -187,0 +195,0 @@

@@ -26,4 +26,4 @@ /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/

sinon.clock = (function () {
var id = 0;
(function (global) {
var id = 1;

@@ -96,3 +96,3 @@ function addTimer(args, recurring) {

return {
sinon.clock = {
now: 0,

@@ -104,5 +104,9 @@

if (typeof now == "number") {
this.now = now;
clock.now = now;
}
if (!!now && typeof now == "object") {
throw new TypeError("now should be milliseconds since UNIX epoch");
}
return clock;

@@ -136,6 +140,11 @@ },

var firstException;
while (timer && tickFrom <= tickTo) {
if (this.timeouts[timer.id]) {
tickFrom = this.now = timer.callAt;
this.callTimer(timer);
try {
this.callTimer(timer);
} catch (e) {
firstException = firstException || e;
}
}

@@ -148,2 +157,6 @@

this.now = tickTo;
if (firstException) {
throw firstException;
}
},

@@ -163,3 +176,3 @@

smallest = this.timeouts[id].callAt;
timer = {

@@ -174,3 +187,3 @@ func: this.timeouts[id].func,

}
return timer || null;

@@ -186,5 +199,10 @@ },

}
} catch (e) {}
} catch (e) {
var exception = e;
}
if (!this.timeouts[timer.id]) {
if (exception) {
throw exception;
}
return;

@@ -198,2 +216,6 @@ }

}
if (exception) {
throw exception;
}
},

@@ -231,38 +253,37 @@

if (NativeDate.now) {
ClockDate.now = function now() {
return ClockDate.clock.now;
};
}
return mirrorDateProperties(ClockDate, NativeDate);
}())
};
if (NativeDate.toSource) {
ClockDate.toSource = function toSource() {
return NativeDate.toSource();
};
}
function mirrorDateProperties(target, source) {
if (source.now) {
target.now = function now() {
return target.clock.now;
};
} else {
delete target.now;
}
ClockDate.toString = function toString() {
return NativeDate.toString();
if (source.toSource) {
target.toSource = function toSource() {
return source.toSource();
};
} else {
delete target.toSource;
}
ClockDate.prototype = NativeDate.prototype;
ClockDate.parse = NativeDate.parse;
ClockDate.UTC = NativeDate.UTC;
target.toString = function toString() {
return source.toString();
};
return ClockDate;
}())
};
}());
target.prototype = source.prototype;
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;
return target;
}
sinon.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
var methods = ["Date", "setTimeout", "setInterval",
"clearTimeout", "clearInterval"];
sinon.useFakeTimers = (function (global) {
var methods = ["Date", "setTimeout", "setInterval", "clearTimeout", "clearInterval"];
function restore() {

@@ -280,9 +301,14 @@ var method;

global[method] = function () {
return clock[method].apply(clock, arguments);
};
if (method == "Date") {
var date = mirrorDateProperties(clock[method], global[method]);
global[method] = date;
} else {
global[method] = function () {
return clock[method].apply(clock, arguments);
};
for (var prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
global[method][prop] = clock[method][prop];
for (var prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
global[method][prop] = clock[method][prop];
}
}

@@ -294,3 +320,3 @@ }

return function useFakeTimers(now) {
sinon.useFakeTimers = function useFakeTimers(now) {
var clock = sinon.clock.create(now);

@@ -313,4 +339,12 @@ clock.restore = restore;

sinon.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
if (typeof module == "object" && typeof require == "function") {
module.exports = sinon;
}

@@ -19,6 +19,14 @@ /**

}
sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
sinon.FakeXMLHttpRequest = (function () {
// wrapper for global
(function(global) {
var xhr = sinon.xhr;
xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
xhr.GlobalActiveXObject = global.ActiveXObject;
xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
/*jsl:ignore*/

@@ -69,2 +77,103 @@ var unsafeHeaders = {

// filtering to enable a white-list version of Sinon FakeXhr,
// where whitelisted requests are passed through to real XHR
function each(collection, callback) {
if (!collection) return;
for (var i = 0, l = collection.length; i < l; i += 1) {
callback(collection[i]);
}
}
function some(collection, callback) {
for (var index = 0; index < collection.length; index++) {
if(callback(collection[index]) === true) return true;
};
return false;
}
// largest arity in XHR is 5 - XHR#open
var apply = function(obj,method,args) {
switch(args.length) {
case 0: return obj[method]();
case 1: return obj[method](args[0]);
case 2: return obj[method](args[0],args[1]);
case 3: return obj[method](args[0],args[1],args[2]);
case 4: return obj[method](args[0],args[1],args[2],args[3]);
case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
};
};
FakeXMLHttpRequest.filters = [];
FakeXMLHttpRequest.addFilter = function(fn) {
this.filters.push(fn)
};
var IE6Re = /MSIE 6/;
FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
var xhr = new sinon.xhr.workingXHR();
each(["open","setRequestHeader","send","abort","getResponseHeader",
"getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
function(method) {
fakeXhr[method] = function() {
return apply(xhr,method,arguments);
};
});
var copyAttrs = function(args) {
each(args, function(attr) {
try {
fakeXhr[attr] = xhr[attr]
} catch(e) {
if(!IE6Re.test(navigator.userAgent)) throw e;
}
});
};
var stateChange = function() {
fakeXhr.readyState = xhr.readyState;
if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
copyAttrs(["status","statusText"]);
}
if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
copyAttrs(["responseText"]);
}
if(xhr.readyState === FakeXMLHttpRequest.DONE) {
copyAttrs(["responseXML"]);
}
if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
};
if(xhr.addEventListener) {
for(var event in fakeXhr.eventListeners) {
if(fakeXhr.eventListeners.hasOwnProperty(event)) {
each(fakeXhr.eventListeners[event],function(handler) {
xhr.addEventListener(event, handler);
});
}
}
xhr.addEventListener("readystatechange",stateChange);
} else {
xhr.onreadystatechange = stateChange;
}
apply(xhr,"open",xhrArgs);
};
FakeXMLHttpRequest.useFilters = false;
function verifyRequestSent(xhr) {
if (xhr.readyState == FakeXMLHttpRequest.DONE) {
throw new Error("Request done");
}
}
function verifyHeadersReceived(xhr) {
if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
throw new Error("No headers received");
}
}
function verifyResponseBodyType(body) {
if (typeof body != "string") {
var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
body + ", which is not a string.");
error.name = "InvalidBodyException";
throw error;
}
}
sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {

@@ -83,3 +192,11 @@ async: true,

this.sendFlag = false;
this.readyStateChange(FakeXMLHttpRequest.OPENED);
if(sinon.FakeXMLHttpRequest.useFilters === true) {
var xhrArgs = arguments;
var defake = some(FakeXMLHttpRequest.filters,function(filter) {
return filter.apply(this,xhrArgs)
});
if (defake) { sinon.FakeXMLHttpRequest.defake(this,arguments); }
} else {
this.readyStateChange(FakeXMLHttpRequest.OPENED);
}
},

@@ -91,3 +208,7 @@

if (typeof this.onreadystatechange == "function") {
this.onreadystatechange();
try {
this.onreadystatechange();
} catch (e) {
sinon.logError("Fake XHR onreadystatechange handler", e);
}
}

@@ -106,3 +227,3 @@

if (this.requestHeaders[header]) {
this.requestHeaders[header] += "," + value;
this.requestHeaders[header] += "," + value;
} else {

@@ -204,10 +325,6 @@ this.requestHeaders[header] = value;

setResponseBody: function setResponseBody(body) {
if (this.readyState == FakeXMLHttpRequest.DONE) {
throw new Error("Request done");
}
verifyRequestSent(this);
verifyHeadersReceived(this);
verifyResponseBodyType(body);
if (this.async && this.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
throw new Error("No headers received");
}
var chunkSize = this.chunkSize || 10;

@@ -232,3 +349,5 @@ var index = 0;

this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
} catch (e) {}
} catch (e) {
// Unable to parse XML - no biggie
}
}

@@ -319,19 +438,10 @@

return FakeXMLHttpRequest;
}());
(function (global) {
var GlobalXMLHttpRequest = global.XMLHttpRequest;
var GlobalActiveXObject = global.ActiveXObject;
var supportsActiveX = typeof ActiveXObject != "undefined";
var supportsXHR = typeof XMLHttpRequest != "undefined";
sinon.useFakeXMLHttpRequest = function () {
sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
if (supportsXHR) {
global.XMLHttpRequest = GlobalXMLHttpRequest;
if (xhr.supportsXHR) {
global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
}
if (supportsActiveX) {
global.ActiveXObject = GlobalActiveXObject;
if (xhr.supportsActiveX) {
global.ActiveXObject = xhr.GlobalActiveXObject;
}

@@ -345,14 +455,14 @@

};
if (supportsXHR) {
if (xhr.supportsXHR) {
global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
}
if (supportsActiveX) {
if (xhr.supportsActiveX) {
global.ActiveXObject = function ActiveXObject(objId) {
if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
return new sinon.FakeXMLHttpRequest();
}
return new GlobalActiveXObject(objId);
return new xhr.GlobalActiveXObject(objId);
};

@@ -363,6 +473,8 @@ }

};
}(this));
sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
})(this);
if (typeof module == "object" && typeof require == "function") {
module.exports = sinon;
}
{
"name": "sinon",
"description": "JavaScript test spies, stubs and mocks.",
"version": "1.2.0",
"homepage": "http://cjohansen.no/sinon/",
"author": "Christian Johansen",
"repository": {
"type": "git",
"url": "http://github.com/cjohansen/Sinon.JS.git"
},
"bugs": {
"mail": "christian@cjohansen.no",
"web": "http://github.com/cjohansen/Sinon.JS/issues"
},
"licenses": [
{ "type": "BSD",
"url": "http://github.com/cjohansen/Sinon.JS/blob/master/LICENSE"
}
],
"main": "./lib/sinon.js",
"engines": { "node": ">=0.1.103" }
"name": "sinon",
"description": "JavaScript test spies, stubs and mocks.",
"version": "1.3.0",
"homepage": "http://cjohansen.no/sinon/",
"author": "Christian Johansen",
"repository": {
"type": "git",
"url": "http://github.com/cjohansen/Sinon.JS.git"
},
"bugs": {
"mail": "christian@cjohansen.no",
"url": "http://github.com/cjohansen/Sinon.JS/issues"
},
"licenses": [
{ "type": "BSD",
"url": "http://github.com/cjohansen/Sinon.JS/blob/master/LICENSE"
}
],
"main": "./lib/sinon.js",
"engines": { "node": ">=0.1.103" }
}
/*
* Copyright 2009 Google Inc.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software

@@ -594,2 +594,3 @@ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

global.assertNotNull = assertNotNull;
global.assertNull = assertNull;
}

@@ -106,2 +106,32 @@ /*jslint onevar: false, eqeqeq: false*/

}, "TypeError");
},
"should not throw if object is window object": function () {
window.sinonTestMethod = function () {};
try {
assertNoException(function () {
sinon.wrapMethod(window, "sinonTestMethod", function () {});
});
} finally {
// IE 8 does not support delete on global properties.
window.sinonTestMethod = undefined;
}
},
"should mirror function properties": function () {
var object = { method: function () {} };
object.method.prop = 42;
sinon.wrapMethod(object, "method", function () {});
assertEquals(42, object.method.prop);
},
"should not mirror and overwrite existing properties": function () {
var object = { method: function () {} };
object.method.called = 42;
sinon.stub(object, "method");
assertSame(false, object.method.called);
}

@@ -160,2 +190,30 @@ });

testCase("SinonDeepEqualTest", {
"should pass null": function () {
assert(sinon.deepEqual(null, null));
},
"should not pass null and object": function () {
assertFalse(sinon.deepEqual(null, {}));
},
"should not pass object and null": function () {
assertFalse(sinon.deepEqual({}, null));
},
"should not pass error and object": function () {
assertFalse(sinon.deepEqual(new Error(), {}));
},
"should not pass object and error": function () {
assertFalse(sinon.deepEqual({}, new Error()));
},
"should not pass regexp and object": function () {
assertFalse(sinon.deepEqual(/.*/, {}));
},
"should not pass object and regexp": function () {
assertFalse(sinon.deepEqual({}, /.*/));
},
"should pass primitives": function () {

@@ -336,2 +394,18 @@ assert(sinon.deepEqual(1, 1));

});
testCase("LogTest", {
"should do nothing gracefully": function () {
sinon.log("Oh, hiya");
}
});
testCase("FormatTest", {
"should format with buster by default": function () {
assertEquals("{ id: 42 }", sinon.format({ id: 42 }));
},
"should format strings without quotes": function () {
assertEquals("Hey", sinon.format("Hey"));
}
});
}());

@@ -405,2 +405,13 @@ /*jslint onevar: false*/

assert(sinon.assert.pass.calledWith("callOrder"));
},
"should pass for multiple calls to same spy": function () {
var first = sinon.spy();
var second = sinon.spy();
first();
second();
first();
sinon.assert.callOrder(first, second, first);
}

@@ -445,3 +456,3 @@ });

var stub = this.stub;
assertException(function () {

@@ -458,3 +469,3 @@ sinon.assert.calledOn(stub, object);

var stub = this.stub;
sinon.assert.calledOn(stub, object);

@@ -483,3 +494,3 @@

var stub = this.stub;
assertException(function () {

@@ -497,3 +508,3 @@ sinon.assert.calledWith(stub, object, 1);

var stub = this.stub;
assertNoException(function () {

@@ -524,3 +535,3 @@ sinon.assert.calledWith(stub, object, 1);

var stub = this.stub;
assertException(function () {

@@ -538,3 +549,3 @@ sinon.assert.calledWithExactly(stub, object, 1);

var stub = this.stub;
assertNoException(function () {

@@ -565,3 +576,3 @@ sinon.assert.calledWithExactly(stub, object, 1);

var stub = this.stub;
assertException(function () {

@@ -579,3 +590,3 @@ sinon.assert.neverCalledWith(stub, object, 1);

var stub = this.stub;
assertNoException(function () {

@@ -605,3 +616,3 @@ sinon.assert.neverCalledWith(stub, object, 1);

var stub = this.stub;
assertException(function () {

@@ -618,3 +629,3 @@ sinon.assert.threw(stub, 1, 2);

var stub = this.stub;
assertNoException(function () {

@@ -657,3 +668,3 @@ sinon.assert.threw(stub, 1, 2);

this.stub.callCount = 3;
assertNoException(function () {

@@ -841,2 +852,14 @@ sinon.assert.callCount(stub, 3);

"should fail exposed asserts without errors": function () {
sinon.assert.expose(global, {
includeFail: false
});
try {
assertCalled(sinon.spy());
} catch (e) {
assertEquals("expected spy to have been called at least once but was never called", e.message);
}
},
"should expose asserts into object without prefixes": function () {

@@ -890,3 +913,3 @@ var test = {};

"assert.called exception message": function () {
assertEquals("expected doSomething to have been called at " +
assertEquals("expected doSomething to have been called at " +
"least once but was never called",

@@ -899,3 +922,3 @@ this.message("called", this.obj.doSomething));

assertEquals("expected doSomething to not have been called " +
assertEquals("expected doSomething to not have been called " +
"but was called once\n doSomething()",

@@ -911,3 +934,3 @@ this.message("notCalled", this.obj.doSomething));

assertEquals("expected doSomething to not have been called " +
assertEquals("expected doSomething to not have been called " +
"but was called 4 times\n doSomething()\n " +

@@ -924,3 +947,3 @@ "doSomething()\n doSomething()\n doSomething()",

assertEquals("expected doSomething to not have been called " +
assertEquals("expected doSomething to not have been called " +
"but was called 4 times\n doSomething()\n " +

@@ -940,3 +963,3 @@ "doSomething(3)\n doSomething(42, 1)\n doSomething()",

assertEquals("expected doSomething, doop, foo to be called in " +
assertEquals("expected doSomething, doop, foo to be called in " +
"order but were called as doop, doSomething, foo",

@@ -943,0 +966,0 @@ this.message("callOrder", this.obj.doSomething, obj.doop, obj.foo));

@@ -1161,3 +1161,3 @@ /*jslint onevar: false, eqeqeq: false*/

assertFalse(this.spy1.calledBefore(this.spy2));
assert(this.spy1.calledBefore(this.spy2));
}

@@ -1211,2 +1211,356 @@ });

testCase("SpyFirstCallTest", {
"should be undefined by default": function () {
var spy = sinon.spy();
assertNull(spy.firstCall);
},
"should be equal to getCall(0) result after first call": function () {
var spy = sinon.spy();
spy();
var call0 = spy.getCall(0);
assertEquals(call0.callId, spy.firstCall.callId);
assertSame(call0.spy, spy.firstCall.spy);
}
});
testCase("SpySecondCallTest", {
"should be null by default": function () {
var spy = sinon.spy();
assertNull(spy.secondCall);
},
"should still be null after first call": function () {
var spy = sinon.spy();
spy();
assertNull(spy.secondCall);
},
"should be equal to getCall(1) result after second call": function () {
var spy = sinon.spy();
spy();
spy();
var call1 = spy.getCall(1);
assertEquals(call1.callId, spy.secondCall.callId);
assertSame(call1.spy, spy.secondCall.spy);
}
});
testCase("SpyThirdCallTest", {
"should be undefined by default": function () {
var spy = sinon.spy();
assertNull(spy.thirdCall);
},
"should still be undefined after second call": function () {
var spy = sinon.spy();
spy();
spy();
assertNull(spy.thirdCall);
},
"should be equal to getCall(1) result after second call": function () {
var spy = sinon.spy();
spy();
spy();
spy();
var call2 = spy.getCall(2);
assertEquals(call2.callId, spy.thirdCall.callId);
assertSame(call2.spy, spy.thirdCall.spy);
}
});
testCase("SpyLastCallTest", {
"should be undefined by default": function () {
var spy = sinon.spy();
assertNull(spy.lastCall);
},
"should be same as firstCall after first call": function () {
var spy = sinon.spy();
spy();
assertSame(spy.firstCall.callId, spy.lastCall.callId);
assertSame(spy.firstCall.spy, spy.lastCall.spy);
},
"should be same as secondCall after second call": function () {
var spy = sinon.spy();
spy();
spy();
assertSame(spy.secondCall.callId, spy.lastCall.callId);
assertSame(spy.secondCall.spy, spy.lastCall.spy);
},
"should be same as thirdCall after third call": function () {
var spy = sinon.spy();
spy();
spy();
spy();
assertSame(spy.thirdCall.callId, spy.lastCall.callId);
assertSame(spy.thirdCall.spy, spy.lastCall.spy);
},
"should be equal to getCall(3) result after fourth call": function () {
var spy = sinon.spy();
spy();
spy();
spy();
spy();
var call3 = spy.getCall(3);
assertEquals(call3.callId, spy.lastCall.callId);
assertSame(call3.spy, spy.lastCall.spy);
},
"should be equal to getCall(4) result after fifth call": function () {
var spy = sinon.spy();
spy();
spy();
spy();
spy();
spy();
var call4 = spy.getCall(4);
assertEquals(call4.callId, spy.lastCall.callId);
assertSame(call4.spy, spy.lastCall.spy);
}
});
testCase("SpyCallArgTest", {
"should be function": function () {
var spy = sinon.spy();
assertFunction(spy.callArg);
},
"should invoke argument at index for all calls": function () {
var spy = sinon.spy();
var callback = sinon.spy();
spy(1, 2, callback);
spy(3, 4, callback);
spy.callArg(2);
assert(callback.calledTwice);
assert(callback.alwaysCalledWith());
},
"should throw if argument at index is not a function": function () {
var spy = sinon.spy();
spy();
assertException(function () {
spy.callArg(1);
}, "TypeError");
},
"should throw if spy was not yet invoked": function () {
var spy = sinon.spy();
try {
spy.callArg(0);
throw new Error();
} catch (e) {
assertEquals("spy cannot call arg since it was not yet invoked.", e.message);
}
},
"should include spy name in error message": function () {
var api = { someMethod: function () {} };
var spy = sinon.spy(api, "someMethod");
try {
spy.callArg(0);
throw new Error();
} catch (e) {
assertEquals("someMethod cannot call arg since it was not yet invoked.", e.message);
}
},
"should throw if index is not a number": function () {
var spy = sinon.spy();
spy();
assertException(function () {
spy.callArg("");
}, "TypeError");
},
"should pass additional arguments": function () {
var spy = sinon.spy();
var callback = sinon.spy();
var array = [];
var object = {};
spy(callback);
spy.callArg(0, "abc", 123, array, object);
assert(callback.calledWith("abc", 123, array, object));
}
});
testCase("SpyCallArgWithTest", {
"should be alias for callArg": function () {
var spy = sinon.spy();
assertSame(spy.callArg, spy.callArgWith);
}
});
testCase("SpyYieldTest", {
"should be function": function () {
var spy = sinon.spy();
assertFunction(spy.yield);
},
"should invoke first function arg for all calls": function () {
var spy = sinon.spy();
var callback = sinon.spy();
spy(1, 2, callback);
spy(3, 4, callback);
spy.yield();
assert(callback.calledTwice);
assert(callback.alwaysCalledWith());
},
"should throw if spy was not yet invoked": function () {
var spy = sinon.spy();
try {
spy.yield();
throw new Error();
} catch (e) {
assertEquals("spy cannot yield since it was not yet invoked.", e.message);
}
},
"should include spy name in error message": function () {
var api = { someMethod: function () {} };
var spy = sinon.spy(api, "someMethod");
try {
spy.yield();
throw new Error();
} catch (e) {
assertEquals("someMethod cannot yield since it was not yet invoked.", e.message);
}
},
"should pass additional arguments": function () {
var spy = sinon.spy();
var callback = sinon.spy();
var array = [];
var object = {};
spy(callback);
spy.yield("abc", 123, array, object);
assert(callback.calledWith("abc", 123, array, object));
}
});
testCase("SpyInvokeCallbackTest", {
"should be alias for yield": function () {
var spy = sinon.spy();
assertSame(spy.yield, spy.invokeCallback);
}
});
testCase("SpyYieldToTest", {
"should be function": function () {
var spy = sinon.spy();
assertFunction(spy.yieldTo);
},
"should invoke first function arg for all calls": function () {
var spy = sinon.spy();
var callback = sinon.spy();
spy(1, 2, { success: callback });
spy(3, 4, { success: callback });
spy.yieldTo("success");
assert(callback.calledTwice);
assert(callback.alwaysCalledWith());
},
"should throw if spy was not yet invoked": function () {
var spy = sinon.spy();
try {
spy.yieldTo("success");
throw new Error();
} catch (e) {
assertEquals("spy cannot yield to 'success' since it was not yet invoked.", e.message);
}
},
"should include spy name in error message": function () {
var api = { someMethod: function () {} };
var spy = sinon.spy(api, "someMethod");
try {
spy.yieldTo("success");
throw new Error();
} catch (e) {
assertEquals("someMethod cannot yield to 'success' since it was not yet invoked.", e.message);
}
},
"should pass additional arguments": function () {
var spy = sinon.spy();
var callback = sinon.spy();
var array = [];
var object = {};
spy({ test: callback });
spy.yieldTo("test", "abc", 123, array, object);
assert(callback.calledWith("abc", 123, array, object));
}
});
function spyCallSetUp() {

@@ -1380,2 +1734,266 @@ this.thisValue = {};

function spyCallCallSetup() {
this.args = [];
this.proxy = sinon.spy();
this.call = sinon.spy.spyCall.create(this.proxy, {}, this.args);
}
testCase("SpyCallCallArgTest", {
setUp: spyCallCallSetup,
"should call argument at specified index": function () {
var callback = sinon.spy();
this.args.push(1, 2, callback);
this.call.callArg(2);
assert(callback.called);
},
"should throw if argument at specified index is not callable": function () {
this.args.push(1);
var call = this.call;
assertException(function () {
call.callArg(0);
}, "TypeError");
},
"should throw if no index is specified": function () {
var call = this.call;
assertException(function () {
call.callArg();
}, "TypeError");
},
"should throw if index is not number": function () {
var call = this.call;
assertException(function () {
call.callArg({});
}, "TypeError");
}
});
testCase("SpyCallCallArgWithTest", {
setUp: spyCallCallSetup,
"should call argument at specified index with provided args": function () {
var object = {};
var callback = sinon.spy();
this.args.push(1, callback);
this.call.callArgWith(1, object);
assert(callback.calledWith(object));
},
"should call callback without args": function () {
var callback = sinon.spy();
this.args.push(1, callback);
this.call.callArgWith(1);
assert(callback.calledWith());
},
"should call callback wit multiple args": function () {
var object = {};
var array = [];
var callback = sinon.spy();
this.args.push(1, 2, callback);
this.call.callArgWith(2, object, array);
assert(callback.calledWith(object, array));
},
"should throw if no index is specified": function () {
var call = this.call;
assertException(function () {
call.callArgWith();
}, "TypeError");
},
"should throw if index is not number": function () {
var call = this.call;
assertException(function () {
call.callArgWith({});
}, "TypeError");
}
});
testCase("SpyCallYieldTest", {
setUp: spyCallCallSetup,
"should invoke only argument as callback": function () {
var callback = sinon.spy();
this.args.push(callback);
this.call.yield();
assert(callback.calledOnce);
assertEquals(0, callback.args[0].length);
},
"should throw understandable error if no callback is passed": function () {
var call = this.call;
try {
call.yield();
throw new Error();
} catch (e) {
assertEquals("spy cannot yield since no callback was passed.",
e.message);
}
},
"should include stub name and actual arguments in error": function () {
this.proxy.displayName = "somethingAwesome";
this.args.push(23, 42);
var call = this.call;
try {
call.yield();
throw new Error();
} catch (e) {
assertEquals("somethingAwesome cannot yield since no callback was passed. " +
"Received [23, 42]", e.message);
}
},
"should invoke last argument as callback": function () {
var spy = sinon.spy();
this.args.push(24, {}, spy);
this.call.yield();
assert(spy.calledOnce);
assertEquals(0, spy.args[0].length);
},
"should invoke first of two callbacks": function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
this.args.push(24, {}, spy, spy2);
this.call.yield();
assert(spy.calledOnce);
assertFalse(spy2.called);
},
"should invoke callback with arguments": function () {
var obj = { id: 42 };
var spy = sinon.spy();
this.args.push(spy);
this.call.yield(obj, "Crazy");
assert(spy.calledWith(obj, "Crazy"));
},
"should throw if callback throws": function () {
this.args.push(function () {
throw new Error("d'oh!")
});
var call = this.call;
assertException(function () {
call.yield();
});
}
});
testCase("SpyCallYieldToTest", {
setUp: spyCallCallSetup,
"should invoke only argument as callback": function () {
var callback = sinon.spy();
this.args.push({
success: callback
});
this.call.yieldTo("success");
assert(callback.calledOnce);
assertEquals(0, callback.args[0].length);
},
"should throw understandable error if no callback is passed": function () {
var call = this.call;
try {
call.yieldTo("success");
throw new Error();
} catch (e) {
assertEquals("spy cannot yield to 'success' since no callback was passed.",
e.message);
}
},
"should include stub name and actual arguments in error": function () {
this.proxy.displayName = "somethingAwesome";
this.args.push(23, 42);
var call = this.call;
try {
call.yieldTo("success");
throw new Error();
} catch (e) {
assertEquals("somethingAwesome cannot yield to 'success' since no callback was passed. " +
"Received [23, 42]", e.message);
}
},
"should invoke property on last argument as callback": function () {
var spy = sinon.spy();
this.args.push(24, {}, { success: spy });
this.call.yieldTo("success");
assert(spy.calledOnce);
assertEquals(0, spy.args[0].length);
},
"should invoke first of two possible callbacks": function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
this.args.push(24, {}, { error: spy }, { error: spy2 });
this.call.yieldTo("error");
assert(spy.calledOnce);
assertFalse(spy2.called);
},
"should invoke callback with arguments": function () {
var obj = { id: 42 };
var spy = sinon.spy();
this.args.push({ success: spy });
this.call.yieldTo("success", obj, "Crazy");
assert(spy.calledWith(obj, "Crazy"));
},
"should throw if callback throws": function () {
this.args.push({
success: function () {
throw new Error("d'oh!")
}
});
var call = this.call;
assertException(function () {
call.yieldTo("success");
});
}
});
testCase("SpyCallToStringTest", {

@@ -1554,2 +2172,6 @@ setUp: function () {

assertEquals(0, spy.thisValues.length);
assertNull(spy.firstCall);
assertNull(spy.secondCall);
assertNull(spy.thirdCall);
assertNull(spy.lastCall);
},

@@ -1556,0 +2178,0 @@

@@ -70,3 +70,41 @@ /*jslint onevar: false*/

});
testCase("StubReturnsArgTest", {
"should have returnsArg method": function() {
var stub = sinon.stub.create();
assertFunction(stub.returnsArg);
},
"should return argument at specified index": function() {
var stub = sinon.stub.create();
stub.returnsArg(0);
var object = {};
assertSame(object, stub(object));
},
"should return stub": function () {
var stub = sinon.stub.create();
assertSame(stub, stub.returnsArg(0));
},
"should throw if no index is specified": function () {
var stub = sinon.stub.create();
assertException(function () {
stub.returnsArg();
}, "TypeError");
},
"should throw if index is not number": function () {
var stub = sinon.stub.create();
assertException(function () {
stub.returnsArg({});
}, "TypeError");
}
});
testCase("StubThrowsTest", {

@@ -389,2 +427,12 @@ "should throw specified exception": function () {

"should stub prototype methods": function () {
function Obj() {};
Obj.prototype.func1 = function() {};
var obj = new Obj();
var stub = sinon.stub(obj);
assertFunction(obj.func1.restore);
},
"should return object": function () {

@@ -396,12 +444,7 @@ var object = {};

"should not stub inherited methods": function () {
var getName = function () {};
var person = { getName: getName };
var dude = sinon.create(person);
"should only stub functions": function () {
var object = {foo: 'bar'};
sinon.stub(object);
sinon.stub(dude);
assertUndefined(dude.toString.restore);
assertUndefined(dude.valueOf.restore);
assertSame(getName, dude.getName);
assertEquals('bar', object.foo);
}

@@ -408,0 +451,0 @@ });

@@ -401,2 +401,11 @@ /*jslint onevar: false, browser: false, regexp: false, browser: true*/

error.message);
},
"should be able to pass the same args to respond directly": function() {
this.server.respond("Oh yeah! Duffman!");
assertEquals([200, {}, "Oh yeah! Duffman!"], this.getRootAsync.respond.args[0]);
assertEquals([200, {}, "Oh yeah! Duffman!"], this.getPathAsync.respond.args[0]);
assertEquals([200, {}, "Oh yeah! Duffman!"], this.postRootAsync.respond.args[0]);
assertEquals([200, {}, "Oh yeah! Duffman!"], this.postPathAsync.respond.args[0]);
}

@@ -491,2 +500,18 @@ });

"should add function handler without method or url filter": function () {
this.server.respondWith(function (xhr) {
xhr.respond(200, { "Content-Type": "application/json" }, '{"id":42}');
});
var request = new sinon.FakeXMLHttpRequest();
request.open("GET", "/whatever");
request.send();
this.server.respond();
assertEquals(200, request.status);
assertEquals({ "Content-Type": "application/json" }, request.responseHeaders);
assertEquals('{"id":42}', request.responseText);
},
"should not process request further if processed by function": function () {

@@ -493,0 +518,0 @@ var handler = sinon.spy();

@@ -184,8 +184,12 @@ /*jslint onevar: false, eqeqeq: false, plusplus: false*/

"should trigger even when some throw": function () {
var clock = this.clock;
var stubs = [sinon.stub.create().throws(), sinon.stub.create()];
this.clock.setTimeout(stubs[0], 100);
this.clock.setTimeout(stubs[1], 120);
this.clock.tick(120);
clock.setTimeout(stubs[0], 100);
clock.setTimeout(stubs[1], 120);
assertException(function() {
clock.tick(120);
});
assert(stubs[0].called);

@@ -196,6 +200,10 @@ assert(stubs[1].called);

"should call function with global object or null (strict mode) as this": function () {
var clock = this.clock;
var stub = sinon.stub.create().throws();
this.clock.setTimeout(stub, 100);
this.clock.tick(100);
clock.setTimeout(stub, 100);
assertException(function() {
clock.tick(100);
});
assert(stub.calledOn(global) || stub.calledOn(null));

@@ -380,2 +388,14 @@ },

assertEquals(11, i);
},
"should not silently catch exceptions": function () {
var clock = this.clock;
clock.setTimeout(function() {
throw new Exception('oh no!');
}, 1000);
assertException(function() {
clock.tick(1000);
});
}

@@ -635,3 +655,3 @@ });

} else {
jstestdriver.console.log("Browser does not support Date.now");
jstestdriver.console.log("Environment does not support Date.now");
assertUndefined(this.clock.Date.now);

@@ -649,2 +669,6 @@ }

"should mirror toUTCString method": function () {
assertSame(Date.prototype.toUTCString, this.clock.Date.prototype.toUTCString);
},
"should mirror toSource if supported": function () {

@@ -654,3 +678,3 @@ if (Date.toSource) {

} else {
jstestdriver.console.log("Browser does not support Date.toSource");
jstestdriver.console.log("Environment does not support Date.toSource");
assertUndefined(this.clock.Date.toSource);

@@ -666,5 +690,17 @@ }

testCase("SinonStubTimersTest", {
setUp: function () {
this.dateNow = global.Date.now;
},
tearDown: function () {
this.clock.restore();
if (this.clock) {
this.clock.restore();
}
clearTimeout(this.timer);
if (typeof this.dateNow == "undefined") {
delete global.Date.now;
} else {
global.Date.now = this.dateNow;
}
},

@@ -799,2 +835,16 @@

"decide on Date.now support at call-time when supported": function () {
global.Date.now = function () {};
this.clock = sinon.useFakeTimers(0);
assertEquals("function", typeof Date.now);
},
"decide on Date.now support at call-time when unsupported": function () {
global.Date.now = null;
this.clock = sinon.useFakeTimers(0);
assertUndefined(Date.now);
},
"should restore Date constructor": function () {

@@ -828,4 +878,10 @@ this.clock = sinon.useFakeTimers(0);

assertSame(sinon.timers.clearInterval, clearInterval);
},
"should not be able to use date object for now": function () {
assertException(function () {
sinon.useFakeTimers(new Date(2011, 9, 1));
});
}
});
}(typeof global != "undefined" ? global : this));

@@ -525,2 +525,13 @@ /*jslint onevar: false, eqeqeq: false, browser: true*/

});
},
"should throw if body is not a string": function () {
var xhr = new sinon.FakeXMLHttpRequest();
xhr.open("GET", "/");
xhr.send();
xhr.setResponseHeaders({});
assertException(function () {
xhr.setResponseBody({});
}, "InvalidBodyException");
}

@@ -642,2 +653,9 @@ });

assertEquals("'tis some body text", this.xhr.responseText);
},
"should complete request when onreadystatechange fails": function () {
this.xhr.onreadystatechange = sinon.stub().throws();
this.xhr.respond(200, {}, "'tis some body text");
assertEquals(4, this.xhr.onreadystatechange.callCount);
}

@@ -935,3 +953,137 @@ });

});
testCase("XHRFiltering",{
setUp: function() {
sinon.FakeXMLHttpRequest.useFilters = true;
sinon.FakeXMLHttpRequest.filters = [];
sinon.useFakeXMLHttpRequest();
},
tearDown: function() {
sinon.FakeXMLHttpRequest.useFilters = false;
sinon.FakeXMLHttpRequest.restore();
},
"should not defake XHR requests that don't match a filter": function() {
var mock = sinon.mock(sinon.FakeXMLHttpRequest)
try {
mock.expects("defake").never()
sinon.FakeXMLHttpRequest.addFilter(function() { return false });
new XMLHttpRequest().open("GET","http://example.com");
} finally { mock.verify(); }
},
"should defake XHR requests that match a filter": function() {
var mock = sinon.mock(sinon.FakeXMLHttpRequest)
try {
mock.expects("defake").once()
sinon.FakeXMLHttpRequest.addFilter(function() { return true });
new XMLHttpRequest().open("GET","http://example.com");
} finally { mock.verify(); }
}
});
var runWithWorkingXHROveride = function(workingXHR,test) {
try {
var original = sinon.xhr.workingXHR;
sinon.xhr.workingXHR = workingXHR;
test();
} finally {
sinon.xhr.workingXHR = original;
}
};
var fakeXhr;
testCase("DefakedXHR",{
setUp: function() {
fakeXhr = new sinon.FakeXMLHttpRequest();
},
"should update attributes from working XHR object when ready state changes": function() {
var workingXHRInstance;
var readyStateCb;
var workingXHROverride = function() {
workingXHRInstance = this;
this.addEventListener = function(str,fn) {
readyStateCb = fn;
};
this.open = function() {};
};
runWithWorkingXHROveride(workingXHROverride,function() {
sinon.FakeXMLHttpRequest.defake(fakeXhr,[]);
workingXHRInstance.statusText = "This is the status text of the real XHR";
workingXHRInstance.readyState = 4;
readyStateCb();
assertEquals(
"This is the status text of the real XHR",
fakeXhr.statusText
);
});
},
"should pass on methods to working XHR object": function() {
var workingXHRInstance;
var spy;
var workingXHROverride = function() {
workingXHRInstance = this;
this.addEventListener = this.open = function() {};
};
runWithWorkingXHROveride(workingXHROverride,function() {
sinon.FakeXMLHttpRequest.defake(fakeXhr,[]);
workingXHRInstance.getResponseHeader = spy = sinon.spy();
fakeXhr.getResponseHeader();
sinon.assert.calledOnce(spy);
});
},
"should call leagacy onreadystatechange handlers": function() {
var workingXHRInstance;
var spy;
var readyStateCb;
var workingXHROverride = function() {
workingXHRInstance = this;
this.addEventListener = function(str,fn) {
readyStateCb = fn;
};
this.open = function() {};
};
runWithWorkingXHROveride(workingXHROverride,function() {
sinon.FakeXMLHttpRequest.defake(fakeXhr,[]);
fakeXhr.onreadystatechange = spy = sinon.spy()
readyStateCb();
sinon.assert.calledOnce(spy);
});
}
});
AsyncTestCase("DefakedXHRTest",{
setUp: function() {
sinon.FakeXMLHttpRequest.useFilters = true;
sinon.FakeXMLHttpRequest.filters = [];
sinon.useFakeXMLHttpRequest();
sinon.FakeXMLHttpRequest.addFilter(function() {return true;});
},
tearDown: function() {
sinon.FakeXMLHttpRequest.useFilters = false;
sinon.FakeXMLHttpRequest.restore();
},
"test loads resource asynchronously": function(q) {
q.call(function(callbacks) {
var req = new XMLHttpRequest;
var responseReceived = callbacks.add(function(responseText) {
assertMatch(/loaded successfully/, responseText);
});
req.onreadystatechange = function() {
if(this.readyState == 4) {
responseReceived(this.responseText);
}
};
setTimeout(callbacks.addErrback("timeout on ajax"),1000);
req.open("GET","/test/test/resources/xhr_target.txt",true);
req.send();
});
},
"test loads resource synchronously": function() {
var req = new XMLHttpRequest;
req.open("GET","/test/test/resources/xhr_target.txt",false);
req.send();
assertMatch(/loaded successfully/, req.responseText);
}
});
if (typeof ActiveXObject == "undefined") {

@@ -943,3 +1095,3 @@ testCase("StubXHRActiveXTest", {

"should notify user of missing ActiveXObject": function () {
jstestdriver.console.log("Browser does not support ActiveXObject");
jstestdriver.console.log("Environment does not support ActiveXObject");
},

@@ -1008,3 +1160,3 @@

"should notify user of missing XMLHttpRequest": function () {
jstestdriver.console.log("Browser does not support XMLHttpRequest");
jstestdriver.console.log("Environment does not support XMLHttpRequest");
},

@@ -1011,0 +1163,0 @@

@@ -17,2 +17,4 @@ /*jslint onevar: false, eqeqeq: false*/

var testCase = (function () {
var silent = typeof process == "object" && process.env.SILENT || false;
function green(str) {

@@ -70,3 +72,3 @@ return "\033[1m\033[32m" + str + "\033[0m";

if (errorCount == 0) {
if (errorCount == 0 && !silent) {
print(green("OK: " + name));

@@ -73,0 +75,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc