Comparing version 1.4.2 to 1.5.0
@@ -0,1 +1,14 @@ | ||
== 1.5.0 / 2012-10-19 | ||
* Don't force "use strict" on Sinon consumers | ||
* Don't assume objects have hasOwnProperties. Fixes problem with e.g. | ||
stubbing properties on process.env | ||
* Preserve function length for spy (Maximilian Antoni) | ||
* Add 'invokeCallback' alias for 'yield' on calls (Maximilian Antoni) | ||
* Added matcher support for calledOn (Maximilian Antoni) | ||
* Retain original expectation messages, for failed mocks under sinon.test | ||
(Giorgos Giannoutsos) | ||
* Allow yields* and callsArg* to create sequences of calls. (Domenic Denicola) | ||
* sinon.js can catch itself in endless loop while filling stub prototype | ||
with asynch methods (Jan Kopriva) | ||
== 1.4.2 / 2012-07-11 | ||
@@ -2,0 +15,0 @@ * sinon.match for arrays (Maximilian Antoni) |
@@ -21,2 +21,3 @@ /** | ||
var push = [].push; | ||
var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
@@ -97,3 +98,3 @@ if (!sinon && commonJSModule) { | ||
if (typeof original != "function") { | ||
if (!object.hasOwnProperty(property)) { | ||
if (!hasOwnProperty.call(object, property)) { | ||
throw new TypeError("Cannot stub non-existent own property " + property); | ||
@@ -100,0 +101,0 @@ } |
@@ -105,2 +105,14 @@ /** | ||
var vars = "a,b,c,d,e,f,g,h,i,j,k,l"; | ||
function createProxy(func) { | ||
// Retain the function length: | ||
if (func.length) { | ||
return eval("(function proxy(" + vars.substring(0, func.length * 2 - 1) + | ||
") { return proxy.invoke(func, this, slice.call(arguments)); })"); | ||
} | ||
return function proxy() { | ||
return proxy.invoke(func, this, slice.call(arguments)); | ||
}; | ||
} | ||
var uuid = 0; | ||
@@ -142,5 +154,3 @@ | ||
function proxy() { | ||
return proxy.invoke(func, this, slice.call(arguments)); | ||
} | ||
var proxy = createProxy(func); | ||
@@ -371,3 +381,3 @@ sinon.extend(proxy, spy); | ||
return { | ||
var callApi = { | ||
create: function create(spy, thisValue, args, returnValue, exception, id) { | ||
@@ -387,2 +397,5 @@ var proxyCall = sinon.create(spyCall); | ||
calledOn: function calledOn(thisValue) { | ||
if (sinon.match && sinon.match.isMatcher(thisValue)) { | ||
return thisValue.test(this.thisValue); | ||
} | ||
return this.thisValue === thisValue; | ||
@@ -510,2 +523,4 @@ }, | ||
}; | ||
callApi.invokeCallback = callApi.yield; | ||
return callApi; | ||
}()); | ||
@@ -512,0 +527,0 @@ |
@@ -58,12 +58,24 @@ /** | ||
function getChangingValue(stub, property) { | ||
var index = stub.callCount - 1; | ||
var prop = index in stub[property] ? stub[property][index] : stub[property + "Last"]; | ||
stub[property + "Last"] = prop; | ||
return prop; | ||
} | ||
function getCallback(stub, args) { | ||
if (stub.callArgAt < 0) { | ||
var callArgAt = getChangingValue(stub, "callArgAts"); | ||
if (callArgAt < 0) { | ||
var callArgProp = getChangingValue(stub, "callArgProps"); | ||
for (var i = 0, l = args.length; i < l; ++i) { | ||
if (!stub.callArgProp && typeof args[i] == "function") { | ||
if (!callArgProp && typeof args[i] == "function") { | ||
return args[i]; | ||
} | ||
if (stub.callArgProp && args[i] && | ||
typeof args[i][stub.callArgProp] == "function") { | ||
return args[i][stub.callArgProp]; | ||
if (callArgProp && args[i] && | ||
typeof args[i][callArgProp] == "function") { | ||
return args[i][callArgProp]; | ||
} | ||
@@ -75,3 +87,3 @@ } | ||
return args[stub.callArgAt]; | ||
return args[callArgAt]; | ||
} | ||
@@ -82,8 +94,8 @@ | ||
function getCallbackError(stub, func, args) { | ||
if (stub.callArgAt < 0) { | ||
if (stub.callArgAtsLast < 0) { | ||
var msg; | ||
if (stub.callArgProp) { | ||
if (stub.callArgPropsLast) { | ||
msg = sinon.functionName(stub) + | ||
" expected to yield to '" + stub.callArgProp + | ||
" expected to yield to '" + stub.callArgPropsLast + | ||
"', but no object with such a property was passed." | ||
@@ -102,3 +114,3 @@ } else { | ||
return "argument at index " + stub.callArgAt + " is not a function: " + func; | ||
return "argument at index " + stub.callArgAtsLast + " is not a function: " + func; | ||
} | ||
@@ -121,3 +133,3 @@ | ||
function callCallback(stub, args) { | ||
if (typeof stub.callArgAt == "number") { | ||
if (stub.callArgAts.length > 0) { | ||
var func = getCallback(stub, args); | ||
@@ -129,8 +141,13 @@ | ||
var index = stub.callCount - 1; | ||
var callbackArguments = getChangingValue(stub, "callbackArguments"); | ||
var callbackContext = getChangingValue(stub, "callbackContexts"); | ||
if (stub.callbackAsync) { | ||
nextTick(function() { | ||
func.apply(stub.callbackContext, stub.callbackArguments); | ||
func.apply(callbackContext, callbackArguments); | ||
}); | ||
} else { | ||
func.apply(stub.callbackContext, stub.callbackArguments); | ||
func.apply(callbackContext, callbackArguments); | ||
} | ||
@@ -179,2 +196,7 @@ } | ||
functionStub.callArgAts = []; | ||
functionStub.callbackArguments = []; | ||
functionStub.callbackContexts = []; | ||
functionStub.callArgProps = []; | ||
sinon.extend(functionStub, stub); | ||
@@ -218,4 +240,6 @@ functionStub._create = sinon.stub.create; | ||
this.callArgAt = pos; | ||
this.callbackArguments = []; | ||
this.callArgAts.push(pos); | ||
this.callbackArguments.push([]); | ||
this.callbackContexts.push(undefined); | ||
this.callArgProps.push(undefined); | ||
@@ -233,5 +257,6 @@ return this; | ||
this.callArgAt = pos; | ||
this.callbackArguments = []; | ||
this.callbackContext = context; | ||
this.callArgAts.push(pos); | ||
this.callbackArguments.push([]); | ||
this.callbackContexts.push(context); | ||
this.callArgProps.push(undefined); | ||
@@ -246,4 +271,6 @@ return this; | ||
this.callArgAt = pos; | ||
this.callbackArguments = slice.call(arguments, 1); | ||
this.callArgAts.push(pos); | ||
this.callbackArguments.push(slice.call(arguments, 1)); | ||
this.callbackContexts.push(undefined); | ||
this.callArgProps.push(undefined); | ||
@@ -261,5 +288,6 @@ return this; | ||
this.callArgAt = pos; | ||
this.callbackArguments = slice.call(arguments, 2); | ||
this.callbackContext = context; | ||
this.callArgAts.push(pos); | ||
this.callbackArguments.push(slice.call(arguments, 2)); | ||
this.callbackContexts.push(context); | ||
this.callArgProps.push(undefined); | ||
@@ -270,4 +298,6 @@ return this; | ||
yields: function () { | ||
this.callArgAt = -1; | ||
this.callbackArguments = slice.call(arguments, 0); | ||
this.callArgAts.push(-1); | ||
this.callbackArguments.push(slice.call(arguments, 0)); | ||
this.callbackContexts.push(undefined); | ||
this.callArgProps.push(undefined); | ||
@@ -282,5 +312,6 @@ return this; | ||
this.callArgAt = -1; | ||
this.callbackArguments = slice.call(arguments, 1); | ||
this.callbackContext = context; | ||
this.callArgAts.push(-1); | ||
this.callbackArguments.push(slice.call(arguments, 1)); | ||
this.callbackContexts.push(context); | ||
this.callArgProps.push(undefined); | ||
@@ -291,5 +322,6 @@ return this; | ||
yieldsTo: function (prop) { | ||
this.callArgAt = -1; | ||
this.callArgProp = prop; | ||
this.callbackArguments = slice.call(arguments, 1); | ||
this.callArgAts.push(-1); | ||
this.callbackArguments.push(slice.call(arguments, 1)); | ||
this.callbackContexts.push(undefined); | ||
this.callArgProps.push(prop); | ||
@@ -304,6 +336,6 @@ return this; | ||
this.callArgAt = -1; | ||
this.callArgProp = prop; | ||
this.callbackArguments = slice.call(arguments, 2); | ||
this.callbackContext = context; | ||
this.callArgAts.push(-1); | ||
this.callbackArguments.push(slice.call(arguments, 2)); | ||
this.callbackContexts.push(context); | ||
this.callArgProps.push(prop); | ||
@@ -313,6 +345,9 @@ return this; | ||
}; | ||
// create asynchronous versions of callsArg* and yields* methods | ||
for (var method in proto) { | ||
if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/)) { | ||
// need to avoid creating anotherasync versions of the newly added async methods | ||
if (proto.hasOwnProperty(method) && | ||
method.match(/^(callsArg|yields|thenYields$)/) && | ||
!method.match(/Async/)) { | ||
proto[method + 'Async'] = (function (syncFnName) { | ||
@@ -326,5 +361,5 @@ return function () { | ||
} | ||
return proto; | ||
}())); | ||
@@ -331,0 +366,0 @@ |
@@ -46,3 +46,11 @@ /** | ||
result = callback.apply(this, args); | ||
} finally { | ||
} catch (e) { | ||
exception = e; | ||
} | ||
if (typeof exception !== "undefined") { | ||
sandbox.restore(); | ||
throw exception; | ||
} | ||
else { | ||
sandbox.verifyAndRestore(); | ||
@@ -49,0 +57,0 @@ } |
/** | ||
* @depend ../../sinon.js | ||
* @depend event.js | ||
@@ -3,0 +4,0 @@ */ |
{ | ||
"name": "sinon", | ||
"description": "JavaScript test spies, stubs and mocks.", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"homepage": "http://cjohansen.no/sinon/", | ||
@@ -6,0 +6,0 @@ "author": "Christian Johansen", |
@@ -107,2 +107,15 @@ /*jslint onevar: false, eqeqeq: false, plusplus: false*/ | ||
assert.equals(this.collection.stub(object, "method"), object.method); | ||
}, | ||
"on node": { | ||
requiresSupportFor: { "process": typeof process !== "undefined" }, | ||
setUp: function () { | ||
process.env.HELL = "Ain't too bad"; | ||
}, | ||
"stubs environment property": function () { | ||
this.collection.stub(process.env, "HELL", "froze over"); | ||
assert.equals(process.env.HELL, "froze over"); | ||
} | ||
} | ||
@@ -109,0 +122,0 @@ }, |
@@ -25,2 +25,22 @@ /*jslint onevar: false*/ | ||
"should contain asynchronous versions of callsArg*, yields*, and thenYields methods": function() { | ||
var stub = sinon.stub.create(); | ||
var syncVersions = 0; | ||
var asyncVersions = 0; | ||
for (var method in stub) { | ||
if (stub.hasOwnProperty(method) && method.match(/^(callsArg|yields|thenYields$)/)) { | ||
if (!method.match(/Async/)) { | ||
syncVersions++; | ||
} else if (method.match(/Async/)) { | ||
asyncVersions++; | ||
} | ||
} | ||
} | ||
assert.same(syncVersions, asyncVersions, | ||
"Stub prototype should contain same amount of synchronous and asynchronous methods"); | ||
}, | ||
"returns": { | ||
@@ -726,3 +746,3 @@ "returns specified value": function () { | ||
assert(spy.calledOnce); | ||
} | ||
}, | ||
}, | ||
@@ -1054,9 +1074,9 @@ | ||
}, | ||
"passes call to callsArgWith": function () { | ||
var object = {}; | ||
sinon.spy(this.stub, "callsArgWith"); | ||
this.stub.callsArgWithAsync(1, object); | ||
assert(this.stub.callsArgWith.calledWith(1, object)); | ||
@@ -1069,3 +1089,3 @@ }, | ||
this.stub.callsArgWithAsync(1, object, array); | ||
var callback = sinon.spy(done(function () { | ||
@@ -1088,3 +1108,3 @@ assert(callback.calledWith(object, array)); | ||
}, | ||
"passes call to callsArgOn": function () { | ||
@@ -1101,3 +1121,3 @@ sinon.spy(this.stub, "callsArgOn"); | ||
this.stub.callsArgOnAsync(2, context); | ||
var callback = sinon.spy(done(function () { | ||
@@ -1108,3 +1128,3 @@ assert(callback.calledOn(context)); | ||
this.stub(1, 2, callback); | ||
assert(!callback.called); | ||
@@ -1119,3 +1139,3 @@ } | ||
}, | ||
"passes call to callsArgOnWith": function () { | ||
@@ -1134,3 +1154,3 @@ var object = {}; | ||
this.stub.callsArgOnWithAsync(1, context, object); | ||
var callback = sinon.spy(done(function () { | ||
@@ -1142,3 +1162,3 @@ assert(callback.calledOn(context)) | ||
this.stub(1, callback); | ||
assert(!callback.called); | ||
@@ -1162,3 +1182,3 @@ } | ||
var spy = sinon.spy(done); | ||
stub(spy); | ||
@@ -1194,5 +1214,5 @@ | ||
})); | ||
this.stub(spy); | ||
assert(!spy.called); | ||
@@ -1211,3 +1231,3 @@ } | ||
}, | ||
"asynchronously yields to property of object argument": function (done) { | ||
@@ -1245,3 +1265,3 @@ var stub = sinon.stub().yieldsToAsync("success"); | ||
this.stub.yieldsToOnAsync("success", context); | ||
var callback = sinon.spy(done(function () { | ||
@@ -1257,3 +1277,119 @@ assert(callback.calledOnce); | ||
} | ||
}, | ||
"yields* calls should be chainable to produce a sequence": function () { | ||
var context = { foo: "bar" }; | ||
var obj = { method1: sinon.spy(), method2: sinon.spy() }; | ||
var obj2 = { method2: sinon.spy() }; | ||
var stub = sinon.stub().yields(1, 2) | ||
.yieldsOn(context, 3, 4) | ||
.yieldsTo("method1", 5, 6) | ||
.yieldsToOn("method2", context, 7, 8); | ||
var spy1 = sinon.spy(); | ||
var spy2 = sinon.spy(); | ||
stub(spy1); | ||
stub(spy2); | ||
stub(obj); | ||
stub(obj); | ||
stub(obj2); // should continue doing the last thing | ||
assert(spy1.calledOnce); | ||
assert(spy1.calledWithExactly(1, 2)); | ||
assert(spy2.calledOnce); | ||
assert(spy2.calledAfter(spy1)); | ||
assert(spy2.calledOn(context)); | ||
assert(spy2.calledWithExactly(3, 4)); | ||
assert(obj.method1.calledOnce); | ||
assert(obj.method1.calledAfter(spy2)); | ||
assert(obj.method1.calledWithExactly(5, 6)); | ||
assert(obj.method2.calledOnce); | ||
assert(obj.method2.calledAfter(obj.method1)); | ||
assert(obj.method2.calledOn(context)); | ||
assert(obj.method2.calledWithExactly(7, 8)); | ||
assert(obj2.method2.calledOnce); | ||
assert(obj2.method2.calledAfter(obj.method2)); | ||
assert(obj2.method2.calledOn(context)); | ||
assert(obj2.method2.calledWithExactly(7, 8)); | ||
}, | ||
"callsArg* calls should be chainable to produce a sequence": function () { | ||
var spy1 = sinon.spy(); | ||
var spy2 = sinon.spy(); | ||
var spy3 = sinon.spy(); | ||
var spy4 = sinon.spy(); | ||
var spy5 = sinon.spy(); | ||
var decoy = sinon.spy(); | ||
var context = { foo: "bar" }; | ||
var stub = sinon.stub().callsArg(0) | ||
.callsArgWith(1, "a", "b") | ||
.callsArgOn(2, context) | ||
.callsArgOnWith(3, context, "c", "d"); | ||
stub(spy1); | ||
stub(decoy, spy2); | ||
stub(decoy, decoy, spy3); | ||
stub(decoy, decoy, decoy, spy4); | ||
stub(decoy, decoy, decoy, spy5); // should continue doing last thing | ||
assert(spy1.calledOnce); | ||
assert(spy2.calledOnce); | ||
assert(spy2.calledAfter(spy1)); | ||
assert(spy2.calledWithExactly("a", "b")); | ||
assert(spy3.calledOnce); | ||
assert(spy3.calledAfter(spy2)); | ||
assert(spy3.calledOn(context)); | ||
assert(spy4.calledOnce); | ||
assert(spy4.calledAfter(spy3)); | ||
assert(spy4.calledOn(context)); | ||
assert(spy4.calledWithExactly("c", "d")); | ||
assert(spy5.calledOnce); | ||
assert(spy5.calledAfter(spy4)); | ||
assert(spy5.calledOn(context)); | ||
assert(spy5.calledWithExactly("c", "d")); | ||
assert(decoy.notCalled); | ||
}, | ||
"yields* calls and callsArg* in combination should be chainable to produce a sequence": function () { | ||
var stub = sinon.stub().yields(1, 2) | ||
.callsArg(1) | ||
.yieldsTo("method") | ||
.callsArgWith(2, "a", "b"); | ||
var obj = { method: sinon.spy() }; | ||
var spy1 = sinon.spy(); | ||
var spy2 = sinon.spy(); | ||
var spy3 = sinon.spy(); | ||
var decoy = sinon.spy(); | ||
stub(spy1); | ||
stub(decoy, spy2); | ||
stub(obj); | ||
stub(decoy, decoy, spy3); | ||
assert(spy1.calledOnce); | ||
assert(spy2.calledOnce); | ||
assert(spy2.calledAfter(spy1)); | ||
assert(obj.method.calledOnce); | ||
assert(obj.method.calledAfter(spy2)); | ||
assert(spy3.calledOnce); | ||
assert(spy3.calledAfter(obj.method)); | ||
assert(spy3.calledWithExactly("a", "b")); | ||
assert(decoy.notCalled); | ||
} | ||
}); |
@@ -132,9 +132,17 @@ /*jslint onevar: false, eqeqeq: false, browser: true*/ | ||
var object = { method: method }; | ||
var exception; | ||
assert.exception(function () { | ||
try { | ||
sinon.test(function () { | ||
this.mock(object).expects("method"); | ||
this.mock(object).expects("method").withExactArgs(1).once(); | ||
object.method(42); | ||
}).call({}); | ||
}, "ExpectationError"); | ||
} catch (e) { | ||
exception = e; | ||
} | ||
assert.same(exception.name, "ExpectationError"); | ||
assert.equals(exception.message, | ||
"Unexpected call: method(42)\n" + | ||
" Expected method(1) once (never called)"); | ||
assert.same(object.method, method); | ||
@@ -141,0 +149,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 too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
1
1329399
53
25999
3