Permalink
Browse files

Extended spy to include the ability to check a spied function was cal…

…led with specified arguments
  • Loading branch information...
1 parent 00a7011 commit c5d1858e46b552346e008546468acdba680a25a9 Michael Bird committed Dec 2, 2012
Showing with 48 additions and 9 deletions.
  1. +10 −0 example/test-spyon.js
  2. +38 −9 lib/common.js
View
@@ -79,6 +79,16 @@ exports['test_spyon_count_correct'] = function (test, assert) {
test.finish();
};
+exports['test_spyon_with_arguments_correct'] = function (test, assert) {
+ var foo, arr;
+ foo = new Foo();
+ arr = ['a', 'b', null];
+ test.spy.on('setBar', foo);
+ foo.setBar(arr);
+ assert.ok(test.spy.called('setBar').with(arr));
+ test.spy.clear('setBar', foo);
+ test.finish();
+};
exports['test_spyon_accepts_function'] = function (test, assert) {
var foo, func, set;
View
@@ -551,11 +551,11 @@ exports.registerCustomAssertionFunctions = registerCustomAssertionFunctions;
*/
function SpyOn (){
/**
- * This tracks the number of times a function has been fired.
- * @param {Object.<number>}
+ * This tracks the arguments a function has been called with.
+ * @param {Object.<Array>}
* @private
*/
- this._callCount = {};
+ this._calls = {};
/**
* This tracks the function to call
* @param {Object.<Function>}
@@ -577,12 +577,12 @@ SpyOn.prototype.on = function (funcName, context, optFunc) {
} else {
func = context[funcName];
}
- if (this._callCount.hasOwnProperty(funcName)) {
+ if (this._calls.hasOwnProperty(funcName)) {
throw "Function already being tracked.";
}
this.reset(funcName);
wrapper = (function () {
- this._callCount[funcName] += 1;
+ this._calls[funcName].push(Array.prototype.slice.call(arguments));
return func.apply(context, arguments);
}).bind(this);
context[funcName] = wrapper;
@@ -601,7 +601,7 @@ SpyOn.prototype.clear = function (funcName, context, optFunc) {
} else {
context[funcName] = this._funcMap[funcName];
}
- delete this._callCount[funcName];
+ delete this._calls[funcName];
delete this._funcMap[funcName];
return this;
};
@@ -611,14 +611,43 @@ SpyOn.prototype.clear = function (funcName, context, optFunc) {
* @param {string} funcName The name of the function.
*/
SpyOn.prototype.reset = function (funcName) {
- this._callCount[funcName] = 0;
+ this._calls[funcName] = [];
};
/**
* Get the call count for a spied on function.
* @param {string} funcName
*/
SpyOn.prototype.called = function (funcName) {
- return this._callCount[funcName];
-};
+ var calls = this._calls[funcName];
+
+ // checks the actual args match the expected args
+ var checkArgsMatch = function (actualArgs, expectedArgs) {
+ var i;
+ if (actualArgs.length !== expectedArgs.length) {
+ return false;
+ }
+ for (i = 0; i < expectedArgs.length; i++) {
+ if (actualArgs[i] !== expectedArgs[i]) {
+ return false;
+ }
+ }
+ return true;
+ };
+ return {
+ valueOf: function () {
+ return calls.length;
+ },
+ with: function () {
+ var i, j, match;
+ var args = Array.prototype.slice.call(arguments);
+ for (i = 0; i < calls.length; i++) {
+ if (checkArgsMatch(calls[i], args)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+};

0 comments on commit c5d1858

Please sign in to comment.