Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add withArgs behavior to stubs

  • Loading branch information...
commit 6293a1ed4d5ab800240244068bf38d2a55402778 1 parent 9028d3b
Christian Johansen cjohansen authored
47 lib/sinon/spy.js
View
@@ -63,20 +63,22 @@
};
}
- function matchingSpy(spies, args) {
- if (!spies) {
+ function matchingFake(fakes, args, strict) {
+ if (!fakes) {
return;
}
var alen = args.length;
- for (var i = 0, l = spies.length; i < l; i++) {
- if (spies[i].matches(args)) {
- return spies[i];
+ for (var i = 0, l = fakes.length; i < l; i++) {
+ if (fakes[i].matches(args, strict)) {
+ return fakes[i];
}
}
}
+ var uuid = 0;
+
// Public API
var spyApi = {
called: false,
@@ -110,12 +112,14 @@
proxy.prototype = func.prototype;
proxy.displayName = name || "spy";
proxy.toString = sinon.functionToString;
+ proxy._create = sinon.spy.create;
+ proxy.id = "spy#" + uuid++;
return proxy;
},
invoke: function invoke(func, thisValue, args) {
- var matching = matchingSpy(this.spies, args);
+ var matching = matchingFake(this.fakes, args);
var exception, returnValue;
this.called = true;
this.callCount += 1;
@@ -130,7 +134,7 @@
if (matching) {
returnValue = matching.invoke(func, thisValue, args);
} else {
- returnValue = func.apply(thisValue, args);
+ returnValue = (this.func || func).apply(thisValue, args);
}
} catch (e) {
this.returnValues.push(undefined);
@@ -176,23 +180,36 @@
},
withArgs: function () {
- if (!this.spies) {
- this.spies = [];
+ var args = slice.call(arguments);
+
+ if (this.fakes) {
+ var match = matchingFake(this.fakes, args, true);
+
+ if (match) {
+ return match;
+ }
+ } else {
+ this.fakes = [];
}
- var spy = sinon.spy();
- spy.matchingAguments = slice.call(arguments);
- this.spies.push(spy);
+ var original = this;
+ var fake = this._create();
+ fake.matchingAguments = args;
+ this.fakes.push(fake);
+
+ fake.withArgs = function () {
+ return original.withArgs.apply(original, arguments);
+ };
- return spy;
+ return fake;
},
- matches: function (args) {
+ matches: function (args, strict) {
var margs = this.matchingAguments;
if (margs.length <= args.length &&
sinon.deepEqual(margs, args.slice(0, margs.length))) {
- return true;
+ return !strict || margs.length == args.length;
}
}
};
10 lib/sinon/stub.js
View
@@ -53,6 +53,8 @@
return sinon.wrapMethod(object, property, wrapper);
}
+ var uuid = 0;
+
sinon.extend(stub, (function () {
var slice = Array.prototype.slice;
@@ -77,11 +79,13 @@
return functionStub.returnValue;
};
- if (sinon.spy) {
- functionStub = sinon.spy.create(functionStub);
- }
+ functionStub.id = "stub#" + uuid++;
+ var orig = functionStub;
+ functionStub = sinon.spy.create(functionStub);
+ functionStub.func = orig;
sinon.extend(functionStub, stub);
+ functionStub._create = sinon.stub.create;
functionStub.displayName = "stub";
functionStub.toString = sinon.functionToString;
26 test/sinon/spy_test.js
View
@@ -1342,6 +1342,32 @@
assertEquals(2, spy.callCount);
assertEquals(1, argSpy.callCount);
+ },
+
+ "should return existing override for arguments": function () {
+ var spy = sinon.spy();
+ var argSpy = spy.withArgs({}, []);
+ var another = spy.withArgs({}, []);
+ spy();
+ spy({}, []);
+ spy({}, [], 2);
+
+ assertSame(argSpy, another);
+ assertNotSame(spy, another);
+ assertEquals(3, spy.callCount);
+ assertEquals(2, spy.withArgs({}, []).callCount);
+ },
+
+ "should chain withArgs calls on original spy": function () {
+ var spy = sinon.spy();
+ var numArgSpy = spy.withArgs({}, []).withArgs(3);
+ spy();
+ spy({}, []);
+ spy(3);
+
+ assertEquals(3, spy.callCount);
+ assertEquals(1, numArgSpy.callCount);
+ assertEquals(1, spy.withArgs({}, []).callCount);
}
});
}());
38 test/sinon/stub_test.js
View
@@ -405,4 +405,42 @@
assertEquals("meth", obj.meth.toString());
}
});
+
+ testCase("StubWithArgsTest", {
+ "should define withArgs method": function () {
+ var stub = sinon.stub();
+
+ assertFunction(stub.withArgs);
+ },
+
+ "should create filtered stub": function () {
+ var stub = sinon.stub();
+ var other = stub.withArgs(23);
+
+ assertNotSame(stub, other);
+ assertFunction(stub.returns);
+ assertFunction(other.returns);
+ },
+
+ "should filter return values based on arguments": function () {
+ var stub = sinon.stub().returns(23);
+ stub.withArgs(42).returns(99);
+
+ assertEquals(23, stub());
+ assertEquals(99, stub(42));
+ },
+
+ "should filter exceptions based on arguments": function () {
+ var stub = sinon.stub().returns(23);
+ stub.withArgs(42).throws();
+
+ assertNoException(function () {
+ stub();
+ });
+
+ assertException(function () {
+ stub(42);
+ });
+ }
+ });
}());
Please sign in to comment.
Something went wrong with that request. Please try again.