mirror of https://gitee.com/bigwinds/arangodb
1270 lines
41 KiB
JavaScript
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');
|
|
}
|
|
}
|
|
});
|
|
}());
|
|
|