1
0
Fork 0
arangodb/js/node/node_modules/sinon/test/sinon/call_test.js

1270 lines
41 KiB
JavaScript

/*jslint onevar: false, eqeqeq: false*/
/*globals window sinon buster*/
/**
* @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";
if (typeof require === "function" && typeof module === "object") {
var buster = require("../runner");
var sinon = require("../../lib/sinon");
}
(function () {
function spyCallCalledTests(method) {
return {
setUp: spyCallSetUp,
"returns true if all args match": function () {
var args = this.args;
assert(this.call[method](args[0], args[1], args[2]));
},
"returns true if first args match": function () {
var args = this.args;
assert(this.call[method](args[0], args[1]));
},
"returns true if first arg match": function () {
var args = this.args;
assert(this.call[method](args[0]));
},
"returns true for no args": function () {
assert(this.call[method]());
},
"returns false for too many args": function () {
var args = this.args;
assert.isFalse(this.call[method](args[0], args[1], args[2], args[3], {}));
},
"returns false for wrong arg": function () {
var args = this.args;
assert.isFalse(this.call[method](args[0], args[2]));
}
};
}
function spyCallNotCalledTests(method) {
return {
setUp: spyCallSetUp,
"returns false if all args match": function () {
var args = this.args;
assert.isFalse(this.call[method](args[0], args[1], args[2]));
},
"returns false if first args match": function () {
var args = this.args;
assert.isFalse(this.call[method](args[0], args[1]));
},
"returns false if first arg match": function () {
var args = this.args;
assert.isFalse(this.call[method](args[0]));
},
"returns false for no args": function () {
assert.isFalse(this.call[method]());
},
"returns true for too many args": function () {
var args = this.args;
assert(this.call[method](args[0], args[1], args[2], args[3], {}));
},
"returns true for wrong arg": function () {
var args = this.args;
assert(this.call[method](args[0], args[2]));
}
};
}
function spyCallSetUp() {
this.thisValue = {};
this.args = [{}, [], new Error(), 3];
this.returnValue = function () {};
this.call = sinon.spyCall(function () {}, this.thisValue,
this.args, this.returnValue, null, 0);
}
function spyCallCallSetup() {
this.args = [];
this.proxy = sinon.spy();
this.call = sinon.spyCall(this.proxy, {}, this.args, null, null, 0);
}
buster.testCase("sinon.spy.call", {
"callObject": {
setUp: spyCallSetUp,
"gets call object": function () {
var spy = sinon.spy.create();
spy();
var firstCall = spy.getCall(0);
assert.isFunction(firstCall.calledOn);
assert.isFunction(firstCall.calledWith);
assert.isFunction(firstCall.returned);
},
"stores given call id": function () {
var call = sinon.spyCall(function () {}, {}, [], null, null, 42);
assert.same(call.callId, 42);
},
"throws if callId is undefined": function () {
assert.exception(function () {
sinon.spyCall.create(function () {}, {}, []);
});
},
// This is actually a spy test:
"records ascending call id's": function () {
var spy = sinon.spy();
spy();
assert(this.call.callId < spy.getCall(0).callId);
},
"exposes thisValue property": function () {
var spy = sinon.spy();
var obj = {};
spy.call(obj);
assert.same(spy.getCall(0).thisValue, obj);
}
},
"callCalledOn": {
setUp: spyCallSetUp,
"calledOn should return true": function () {
assert(this.call.calledOn(this.thisValue));
},
"calledOn should return false": function () {
assert.isFalse(this.call.calledOn({}));
}
},
"call.calledWith": spyCallCalledTests("calledWith"),
"call.calledWithMatch": spyCallCalledTests("calledWithMatch"),
"call.notCalledWith": spyCallNotCalledTests("notCalledWith"),
"call.notCalledWithMatch": spyCallNotCalledTests("notCalledWithMatch"),
"call.calledWithExactly": {
setUp: spyCallSetUp,
"returns true when all args match": function () {
var args = this.args;
assert(this.call.calledWithExactly(args[0], args[1], args[2], args[3]));
},
"returns false for too many args": function () {
var args = this.args;
assert.isFalse(this.call.calledWithExactly(args[0], args[1], args[2], args[3], {}));
},
"returns false for too few args": function () {
var args = this.args;
assert.isFalse(this.call.calledWithExactly(args[0], args[1]));
},
"returns false for unmatching args": function () {
var args = this.args;
assert.isFalse(this.call.calledWithExactly(args[0], args[1], args[1]));
},
"returns true for no arguments": function () {
var call = sinon.spyCall(function () {}, {}, [], null, null, 0);
assert(call.calledWithExactly());
},
"returns false when called with no args but matching one": function () {
var call = sinon.spyCall(function () {}, {}, [], null, null, 0);
assert.isFalse(call.calledWithExactly({}));
}
},
"call.callArg": {
setUp: spyCallCallSetup,
"calls argument at specified index": function () {
var callback = sinon.spy();
this.args.push(1, 2, callback);
this.call.callArg(2);
assert(callback.called);
},
"throws if argument at specified index is not callable": function () {
this.args.push(1);
var call = this.call;
assert.exception(function () {
call.callArg(0);
}, "TypeError");
},
"throws if no index is specified": function () {
var call = this.call;
assert.exception(function () {
call.callArg();
}, "TypeError");
},
"throws if index is not number": function () {
var call = this.call;
assert.exception(function () {
call.callArg({});
}, "TypeError");
}
},
"call.callArgOn": {
setUp: spyCallCallSetup,
"calls argument at specified index": function () {
var callback = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(1, 2, callback);
this.call.callArgOn(2, thisObj);
assert(callback.called);
assert(callback.calledOn(thisObj));
},
"throws if argument at specified index is not callable": function () {
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(1);
var call = this.call;
assert.exception(function () {
call.callArgOn(0, thisObj);
}, "TypeError");
},
"throws if index is not number": function () {
var thisObj = { name1: "value1", name2: "value2" };
var call = this.call;
assert.exception(function () {
call.callArgOn({}, thisObj);
}, "TypeError");
}
},
"call.callArgWith": {
setUp: spyCallCallSetup,
"calls 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));
},
"calls callback without args": function () {
var callback = sinon.spy();
this.args.push(1, callback);
this.call.callArgWith(1);
assert(callback.calledWith());
},
"calls 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));
},
"throws if no index is specified": function () {
var call = this.call;
assert.exception(function () {
call.callArgWith();
}, "TypeError");
},
"throws if index is not number": function () {
var call = this.call;
assert.exception(function () {
call.callArgWith({});
}, "TypeError");
}
},
"call.callArgOnWith": {
setUp: spyCallCallSetup,
"calls argument at specified index with provided args": function () {
var object = {};
var thisObj = { name1: "value1", name2: "value2" };
var callback = sinon.spy();
this.args.push(1, callback);
this.call.callArgOnWith(1, thisObj, object);
assert(callback.calledWith(object));
assert(callback.calledOn(thisObj));
},
"calls callback without args": function () {
var callback = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(1, callback);
this.call.callArgOnWith(1, thisObj);
assert(callback.calledWith());
assert(callback.calledOn(thisObj));
},
"calls callback with multiple args": function () {
var object = {};
var array = [];
var thisObj = { name1: "value1", name2: "value2" };
var callback = sinon.spy();
this.args.push(1, 2, callback);
this.call.callArgOnWith(2, thisObj, object, array);
assert(callback.calledWith(object, array));
assert(callback.calledOn(thisObj));
},
"throws if index is not number": function () {
var thisObj = { name1: "value1", name2: "value2" };
var call = this.call;
assert.exception(function () {
call.callArgOnWith({}, thisObj);
}, "TypeError");
}
},
"call.yieldTest": {
setUp: spyCallCallSetup,
"invokes only argument as callback": function () {
var callback = sinon.spy();
this.args.push(callback);
this.call.yield();
assert(callback.calledOnce);
assert.equals(callback.args[0].length, 0);
},
"throws understandable error if no callback is passed": function () {
var call = this.call;
try {
call.yield();
throw new Error();
} catch (e) {
assert.equals(e.message, "spy cannot yield since no callback was passed.");
}
},
"includes 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) {
assert.equals(e.message, "somethingAwesome cannot yield since no callback was passed. " +
"Received [23, 42]");
}
},
"invokes last argument as callback": function () {
var spy = sinon.spy();
this.args.push(24, {}, spy);
this.call.yield();
assert(spy.calledOnce);
assert.equals(spy.args[0].length, 0);
},
"invokes 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);
assert.isFalse(spy2.called);
},
"invokes 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"));
},
"throws if callback throws": function () {
this.args.push(function () {
throw new Error("d'oh!");
});
var call = this.call;
assert.exception(function () {
call.yield();
});
}
},
"call.invokeCallback": {
"is alias for yield": function () {
var call = sinon.spyCall(function () {}, {}, [], null, null, 0);
assert.same(call.yield, call.invokeCallback);
}
},
"call.yieldOnTest": {
setUp: spyCallCallSetup,
"invokes only argument as callback": function () {
var callback = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(callback);
this.call.yieldOn(thisObj);
assert(callback.calledOnce);
assert(callback.calledOn(thisObj));
assert.equals(callback.args[0].length, 0);
},
"throws understandable error if no callback is passed": function () {
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
try {
call.yieldOn(thisObj);
throw new Error();
} catch (e) {
assert.equals(e.message, "spy cannot yield since no callback was passed.");
}
},
"includes stub name and actual arguments in error": function () {
this.proxy.displayName = "somethingAwesome";
this.args.push(23, 42);
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
try {
call.yieldOn(thisObj);
throw new Error();
} catch (e) {
assert.equals(e.message, "somethingAwesome cannot yield since no callback was passed. " +
"Received [23, 42]");
}
},
"invokes last argument as callback": function () {
var spy = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(24, {}, spy);
this.call.yieldOn(thisObj);
assert(spy.calledOnce);
assert.equals(spy.args[0].length, 0);
assert(spy.calledOn(thisObj));
},
"invokes first of two callbacks": function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(24, {}, spy, spy2);
this.call.yieldOn(thisObj);
assert(spy.calledOnce);
assert(spy.calledOn(thisObj));
assert.isFalse(spy2.called);
},
"invokes callback with arguments": function () {
var obj = { id: 42 };
var spy = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(spy);
this.call.yieldOn(thisObj, obj, "Crazy");
assert(spy.calledWith(obj, "Crazy"));
assert(spy.calledOn(thisObj));
},
"throws if callback throws": function () {
this.args.push(function () {
throw new Error("d'oh!");
});
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
assert.exception(function () {
call.yieldOn(thisObj);
});
}
},
"call.yieldTo": {
setUp: spyCallCallSetup,
"invokes only argument as callback": function () {
var callback = sinon.spy();
this.args.push({
success: callback
});
this.call.yieldTo("success");
assert(callback.calledOnce);
assert.equals(callback.args[0].length, 0);
},
"throws understandable error if no callback is passed": function () {
var call = this.call;
try {
call.yieldTo("success");
throw new Error();
} catch (e) {
assert.equals(e.message, "spy cannot yield to 'success' since no callback was passed.");
}
},
"includes 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) {
assert.equals(e.message, "somethingAwesome cannot yield to 'success' since no callback was passed. " +
"Received [23, 42]");
}
},
"invokes property on last argument as callback": function () {
var spy = sinon.spy();
this.args.push(24, {}, { success: spy });
this.call.yieldTo("success");
assert(spy.calledOnce);
assert.equals(spy.args[0].length, 0);
},
"invokes 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);
assert.isFalse(spy2.called);
},
"invokes 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"));
},
"throws if callback throws": function () {
this.args.push({
success: function () {
throw new Error("d'oh!");
}
});
var call = this.call;
assert.exception(function () {
call.yieldTo("success");
});
}
},
"call.yieldToOn": {
setUp: spyCallCallSetup,
"invokes only argument as callback": function () {
var callback = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push({
success: callback
});
this.call.yieldToOn("success", thisObj);
assert(callback.calledOnce);
assert.equals(callback.args[0].length, 0);
assert(callback.calledOn(thisObj));
},
"throws understandable error if no callback is passed": function () {
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
try {
call.yieldToOn("success", thisObj);
throw new Error();
} catch (e) {
assert.equals(e.message, "spy cannot yield to 'success' since no callback was passed.");
}
},
"includes stub name and actual arguments in error": function () {
this.proxy.displayName = "somethingAwesome";
this.args.push(23, 42);
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
try {
call.yieldToOn("success", thisObj);
throw new Error();
} catch (e) {
assert.equals(e.message, "somethingAwesome cannot yield to 'success' since no callback was passed. " +
"Received [23, 42]");
}
},
"invokes property on last argument as callback": function () {
var spy = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(24, {}, { success: spy });
this.call.yieldToOn("success", thisObj);
assert(spy.calledOnce);
assert(spy.calledOn(thisObj));
assert.equals(spy.args[0].length, 0);
},
"invokes first of two possible callbacks": function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push(24, {}, { error: spy }, { error: spy2 });
this.call.yieldToOn("error", thisObj);
assert(spy.calledOnce);
assert(spy.calledOn(thisObj));
assert.isFalse(spy2.called);
},
"invokes callback with arguments": function () {
var obj = { id: 42 };
var spy = sinon.spy();
var thisObj = { name1: "value1", name2: "value2" };
this.args.push({ success: spy });
this.call.yieldToOn("success", thisObj, obj, "Crazy");
assert(spy.calledWith(obj, "Crazy"));
assert(spy.calledOn(thisObj));
},
"throws if callback throws": function () {
this.args.push({
success: function () {
throw new Error("d'oh!");
}
});
var call = this.call;
var thisObj = { name1: "value1", name2: "value2" };
assert.exception(function () {
call.yieldToOn("success", thisObj);
});
}
},
"call.toString": {
setUp: function () {
this.format = sinon.format;
},
tearDown: function () {
sinon.format = this.format;
},
"includes spy name": function () {
var object = { doIt: sinon.spy() };
object.doIt();
assert.equals(object.doIt.getCall(0).toString(), "doIt()");
},
"includes single argument": function () {
var object = { doIt: sinon.spy() };
object.doIt(42);
assert.equals(object.doIt.getCall(0).toString(), "doIt(42)");
},
"includes all arguments": function () {
var object = { doIt: sinon.spy() };
object.doIt(42, "Hey");
assert.equals(object.doIt.getCall(0).toString(), "doIt(42, Hey)");
},
"includes explicit return value": function () {
var object = { doIt: sinon.stub().returns(42) };
object.doIt(42, "Hey");
assert.equals(object.doIt.getCall(0).toString(), "doIt(42, Hey) => 42");
},
"includes empty string return value": function () {
var object = { doIt: sinon.stub().returns("") };
object.doIt(42, "Hey");
assert.equals(object.doIt.getCall(0).toString(), "doIt(42, Hey) => ");
},
"includes exception": function () {
var object = { doIt: sinon.stub().throws("TypeError") };
try {
object.doIt();
} catch (e) {}
assert.equals(object.doIt.getCall(0).toString(), "doIt() !TypeError");
},
"includes exception message if any": function () {
var object = { doIt: sinon.stub().throws("TypeError", "Oh noes!") };
try {
object.doIt();
} catch (e) {}
assert.equals(object.doIt.getCall(0).toString(), "doIt() !TypeError(Oh noes!)");
},
"formats arguments with sinon.format": function () {
sinon.format = sinon.stub().returns("Forty-two");
var object = { doIt: sinon.spy() };
object.doIt(42);
assert.equals(object.doIt.getCall(0).toString(), "doIt(Forty-two)");
assert(sinon.format.calledWith(42));
},
"formats return value with sinon.format": function () {
sinon.format = sinon.stub().returns("Forty-two");
var object = { doIt: sinon.stub().returns(42) };
object.doIt();
assert.equals(object.doIt.getCall(0).toString(), "doIt() => Forty-two");
assert(sinon.format.calledWith(42));
}
},
"constructor": {
setUp: function () {
this.CustomConstructor = function () {};
this.customPrototype = this.CustomConstructor.prototype;
sinon.spy(this, "CustomConstructor");
},
"creates original object": function () {
var myInstance = new this.CustomConstructor();
assert(this.customPrototype.isPrototypeOf(myInstance));
},
"does not interfere with instanceof": function () {
var myInstance = new this.CustomConstructor();
assert(myInstance instanceof this.CustomConstructor);
},
"records usage": function () {
var myInstance = new this.CustomConstructor();
assert(this.CustomConstructor.called);
}
},
"function": {
"throws if spying on non-existent property": function () {
var myObj = {};
assert.exception(function () {
sinon.spy(myObj, "ouch");
});
refute.defined(myObj.ouch);
},
"throws if spying on non-existent object": function () {
assert.exception(function () {
sinon.spy(undefined, "ouch");
});
},
"haves toString method": function () {
var obj = { meth: function () {} };
sinon.spy(obj, "meth");
assert.equals(obj.meth.toString(), "meth");
},
"toString should say 'spy' when unable to infer name": function () {
var spy = sinon.spy();
assert.equals(spy.toString(), "spy");
},
"toString should report name of spied function": function () {
function myTestFunc() {}
var spy = sinon.spy(myTestFunc);
assert.equals(spy.toString(), "myTestFunc");
},
"toString should prefer displayName property if available": function () {
function myTestFunc() {}
myTestFunc.displayName = "My custom method";
var spy = sinon.spy(myTestFunc);
assert.equals(spy.toString(), "My custom method");
},
"toString should prefer property name if possible": function () {
var obj = {};
obj.meth = sinon.spy();
obj.meth();
assert.equals(obj.meth.toString(), "meth");
}
},
"reset": (function () {
function assertReset(spy) {
assert(!spy.called);
assert(!spy.calledOnce);
assert.equals(spy.args.length, 0);
assert.equals(spy.returnValues.length, 0);
assert.equals(spy.exceptions.length, 0);
assert.equals(spy.thisValues.length, 0);
assert.isNull(spy.firstCall);
assert.isNull(spy.secondCall);
assert.isNull(spy.thirdCall);
assert.isNull(spy.lastCall);
}
return {
"resets spy state": function () {
var spy = sinon.spy();
spy();
spy.reset();
assertReset(spy);
},
"resets call order state": function () {
var spies = [sinon.spy(), sinon.spy()];
spies[0]();
spies[1]();
spies[0].reset();
assert(!spies[0].calledBefore(spies[1]));
},
"resets fakes returned by withArgs": function () {
var spy = sinon.spy();
var fakeA = spy.withArgs("a");
var fakeB = spy.withArgs("b");
spy("a");
spy("b");
spy("c");
var fakeC = spy.withArgs("c");
spy.reset();
assertReset(fakeA);
assertReset(fakeB);
assertReset(fakeC);
}
}
}()),
"withArgs": {
"defines withArgs method": function () {
var spy = sinon.spy();
assert.isFunction(spy.withArgs);
},
"records single call": function () {
var spy = sinon.spy().withArgs(1);
spy(1);
assert.equals(spy.callCount, 1);
},
"records non-matching call on original spy": function () {
var spy = sinon.spy();
var argSpy = spy.withArgs(1);
spy(1);
spy(2);
assert.equals(spy.callCount, 2);
assert.equals(argSpy.callCount, 1);
},
"records non-matching call with several arguments separately": function () {
var spy = sinon.spy();
var argSpy = spy.withArgs(1, "str", {});
spy(1);
spy(1, "str", {});
assert.equals(spy.callCount, 2);
assert.equals(argSpy.callCount, 1);
},
"records for partial argument match": function () {
var spy = sinon.spy();
var argSpy = spy.withArgs(1, "str", {});
spy(1);
spy(1, "str", {});
spy(1, "str", {}, []);
assert.equals(spy.callCount, 3);
assert.equals(argSpy.callCount, 2);
},
"records filtered spy when original throws": function () {
var spy = sinon.spy(function () {
throw new Error("Oops");
});
var argSpy = spy.withArgs({}, []);
assert.exception(function () {
spy(1);
});
assert.exception(function () {
spy({}, []);
});
assert.equals(spy.callCount, 2);
assert.equals(argSpy.callCount, 1);
},
"returns existing override for arguments": function () {
var spy = sinon.spy();
var argSpy = spy.withArgs({}, []);
var another = spy.withArgs({}, []);
spy();
spy({}, []);
spy({}, [], 2);
assert.same(another, argSpy);
refute.same(another, spy);
assert.equals(spy.callCount, 3);
assert.equals(spy.withArgs({}, []).callCount, 2);
},
"chains withArgs calls on original spy": function () {
var spy = sinon.spy();
var numArgSpy = spy.withArgs({}, []).withArgs(3);
spy();
spy({}, []);
spy(3);
assert.equals(spy.callCount, 3);
assert.equals(numArgSpy.callCount, 1);
assert.equals(spy.withArgs({}, []).callCount, 1);
},
"initializes filtered spy with callCount": function () {
var spy = sinon.spy();
spy("a");
spy("b");
spy("b");
spy("c");
spy("c");
spy("c");
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
var argSpy3 = spy.withArgs("c");
assert.equals(argSpy1.callCount, 1);
assert.equals(argSpy2.callCount, 2);
assert.equals(argSpy3.callCount, 3);
assert(argSpy1.called);
assert(argSpy2.called);
assert(argSpy3.called);
assert(argSpy1.calledOnce);
assert(argSpy2.calledTwice);
assert(argSpy3.calledThrice);
},
"initializes filtered spy with first, second, third and last call": function () {
var spy = sinon.spy();
spy("a", 1);
spy("b", 2);
spy("b", 3);
spy("b", 4);
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy1.firstCall.calledWithExactly("a", 1));
assert(argSpy1.lastCall.calledWithExactly("a", 1));
assert(argSpy2.firstCall.calledWithExactly("b", 2));
assert(argSpy2.secondCall.calledWithExactly("b", 3));
assert(argSpy2.thirdCall.calledWithExactly("b", 4));
assert(argSpy2.lastCall.calledWithExactly("b", 4));
},
"initializes filtered spy with arguments": function () {
var spy = sinon.spy();
spy("a");
spy("b");
spy("b", "c", "d");
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy1.getCall(0).calledWithExactly("a"));
assert(argSpy2.getCall(0).calledWithExactly("b"));
assert(argSpy2.getCall(1).calledWithExactly("b", "c", "d"));
},
"initializes filtered spy with thisValues": function () {
var spy = sinon.spy();
var thisValue1 = {};
var thisValue2 = {};
var thisValue3 = {};
spy.call(thisValue1, "a");
spy.call(thisValue2, "b");
spy.call(thisValue3, "b");
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy1.getCall(0).calledOn(thisValue1));
assert(argSpy2.getCall(0).calledOn(thisValue2));
assert(argSpy2.getCall(1).calledOn(thisValue3));
},
"initializes filtered spy with return values": function () {
var spy = sinon.spy(function (value) { return value; });
spy("a");
spy("b");
spy("b");
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy1.getCall(0).returned("a"));
assert(argSpy2.getCall(0).returned("b"));
assert(argSpy2.getCall(1).returned("b"));
},
"initializes filtered spy with call order": function () {
var spy = sinon.spy();
spy("a");
spy("b");
spy("b");
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy2.getCall(0).calledAfter(argSpy1.getCall(0)));
assert(argSpy2.getCall(1).calledAfter(argSpy1.getCall(0)));
},
"initializes filtered spy with exceptions": function () {
var spy = sinon.spy(function (x, y) {
var error = new Error();
error.name = y;
throw error;
});
try {
spy("a", "1");
} catch (ignored) {}
try {
spy("b", "2");
} catch (ignored) {}
try {
spy("b", "3");
} catch (ignored) {}
var argSpy1 = spy.withArgs("a");
var argSpy2 = spy.withArgs("b");
assert(argSpy1.getCall(0).threw("1"));
assert(argSpy2.getCall(0).threw("2"));
assert(argSpy2.getCall(1).threw("3"));
}
},
"printf" : {
"name" : {
"named" : function () {
var named = sinon.spy(function cool() { });
assert.equals(named.printf('%n'), 'cool');
},
"anon" : function () {
var anon = sinon.spy(function () {});
assert.equals(anon.printf('%n'), 'spy');
var noFn = sinon.spy();
assert.equals(noFn.printf('%n'), 'spy');
},
},
"count" : function () {
// Throwing just to make sure it has no effect.
var spy = sinon.spy(sinon.stub().throws());
function call() {
try {
spy();
} catch (e) {}
}
call();
assert.equals(spy.printf('%c'), 'once');
call();
assert.equals(spy.printf('%c'), 'twice');
call();
assert.equals(spy.printf('%c'), 'thrice');
call();
assert.equals(spy.printf('%c'), '4 times');
},
"calls" : {
"oneLine" : function () {
function test(arg, expected) {
var spy = sinon.spy();
spy(arg);
assert.equals(spy.printf('%C'), '\n ' + expected);
}
test(true, 'spy(true)');
test(false, 'spy(false)');
test(undefined, 'spy(undefined)');
test(1, 'spy(1)');
test(0, 'spy(0)');
test(-1, 'spy(-1)');
test(-1.1, 'spy(-1.1)');
test(Infinity, 'spy(Infinity)');
test(['a'], 'spy(["a"])');
test({ a : 'a' }, 'spy({ a: "a" })');
},
"multiline" : function () {
var str = 'spy\ntest';
var spy = sinon.spy();
spy(str);
spy(str);
spy(str);
assert.equals(spy.printf('%C'),
'\n spy(' + str + ')' +
'\n\n spy(' + str + ')' +
'\n\n spy(' + str + ')');
spy.reset();
spy('test');
spy('spy\ntest');
spy('spy\ntest');
assert.equals(spy.printf('%C'),
'\n spy(test)' +
'\n spy(' + str + ')' +
'\n\n spy(' + str + ')');
}
},
"thisValues" : function () {
var spy = sinon.spy();
spy();
assert.equals(spy.printf('%t'), 'undefined');
spy.reset();
spy.call(true);
assert.equals(spy.printf('%t'), 'true');
}
}
});
}());