Comparing version 7.5.0 to 8.0.0
8.0.0 / 2019-12-22 | ||
================== | ||
The major release is caused by removing old mistakes and upgrading dependencies that themselves have had new major releases. | ||
* Upgrade nise, @sinonjs/formatio, @sinonjs/samsam and @sinonjs/referee | ||
* Update lolex and nise to get new async timer methods (see https://github.com/sinonjs/lolex/blob/master/CHANGELOG.md) | ||
* Remove `sinon.spyCall` | ||
* Remove `sinon.sandbox.create` | ||
* Remove obsolete `deprecated.printWarning` stubbing from test | ||
7.5.0 / 2019-09-23 | ||
@@ -3,0 +14,0 @@ ================== |
@@ -43,3 +43,3 @@ # Contributing to Sinon.JS | ||
* They allow Sinon.JS users to easily understand the consequences of updating to a newer version | ||
* They allow Sinon.JS users to understand the consequences of updating to a newer version | ||
* They help contributors understand what is going on with the codebase, allowing features and fixes to be developed faster | ||
@@ -120,3 +120,3 @@ * They save maintainers time when compiling the changelog for a new release | ||
To build simply run | ||
To build run | ||
@@ -123,0 +123,0 @@ $ node build.js |
@@ -5,3 +5,2 @@ "use strict"; | ||
var createSandbox = require("./sinon/create-sandbox"); | ||
var deprecated = require("@sinonjs/commons").deprecated; | ||
var extend = require("./sinon/util/core/extend"); | ||
@@ -18,3 +17,3 @@ var fakeTimers = require("./sinon/util/fake-timers"); | ||
match: require("@sinonjs/samsam").createMatcher, | ||
spyCall: require("./sinon/call"), | ||
restoreObject: require("./sinon/restore-object"), | ||
@@ -44,16 +43,6 @@ expectation: require("./sinon/mock-expectation"), | ||
var legacySandboxAPI = { | ||
sandbox: { | ||
create: deprecated.wrap( | ||
createSandbox, | ||
// eslint-disable-next-line max-len | ||
"`sandbox.create()` is deprecated. Use default sandbox at `sinon.sandbox` or create new sandboxes with `sinon.createSandbox()`" | ||
) | ||
} | ||
}; | ||
var sandbox = new Sandbox(); | ||
var api = extend(sandbox, legacySandboxAPI, apiMethods); | ||
var api = extend(sandbox, apiMethods); | ||
module.exports = api; |
@@ -10,2 +10,3 @@ "use strict"; | ||
var stringSlice = require("@sinonjs/commons").prototypes.string.slice; | ||
var globalObject = require("@sinonjs/commons").global; | ||
@@ -64,3 +65,3 @@ var arraySlice = arrayProto.slice; | ||
function failAssertion(object, msg) { | ||
var obj = object || global; | ||
var obj = object || globalObject; | ||
var failMethod = obj.fail || assert.fail; | ||
@@ -67,0 +68,0 @@ failMethod.call(obj, msg); |
"use strict"; | ||
var arrayProto = require("@sinonjs/commons").prototypes.array; | ||
var spy = require("./spy"); | ||
var createProxy = require("./proxy"); | ||
var nextTick = require("./util/core/next-tick"); | ||
var forEach = arrayProto.forEach; | ||
var slice = arrayProto.slice; | ||
@@ -14,27 +13,5 @@ | ||
function cleanProxy(f) { | ||
var undesirableProperties = [ | ||
"instantiateFake", | ||
"callArg", | ||
"callArgOn", | ||
"callArgOnWith", | ||
"callArgWith", | ||
"invokeCallback", | ||
"throwArg", | ||
"withArgs", | ||
"yield", | ||
"yieldOn", | ||
"yieldTo", | ||
"yieldToOn" | ||
]; | ||
forEach(undesirableProperties, function(key) { | ||
delete f[key]; | ||
}); | ||
return f; | ||
} | ||
var uuid = 0; | ||
function wrapFunc(f) { | ||
var proxy; | ||
var fakeInstance = function() { | ||
@@ -44,15 +21,13 @@ var lastArg = arguments.length > 0 ? arguments[arguments.length - 1] : undefined; | ||
/* eslint-disable no-use-before-define */ | ||
p.lastArg = lastArg; | ||
p.callback = callback; | ||
/* eslint-enable no-use-before-define */ | ||
proxy.lastArg = lastArg; | ||
proxy.callback = callback; | ||
return f && f.apply(this, arguments); | ||
}; | ||
var p = cleanProxy(spy(fakeInstance)); | ||
proxy = createProxy(fakeInstance, f || fakeInstance); | ||
p.displayName = "fake"; | ||
p.id = "fake#" + uuid++; | ||
proxy.displayName = "fake"; | ||
proxy.id = "fake#" + uuid++; | ||
return p; | ||
return proxy; | ||
} | ||
@@ -59,0 +34,0 @@ |
"use strict"; | ||
var arrayProto = require("@sinonjs/commons").prototypes.array; | ||
var spyInvoke = require("./spy").invoke; | ||
var spyCallToString = require("./call").toString; | ||
var proxyInvoke = require("./proxy-invoke"); | ||
var proxyCallToString = require("./proxy-call").toString; | ||
var timesInWords = require("./util/core/times-in-words"); | ||
@@ -73,3 +73,3 @@ var extend = require("./util/core/extend"); | ||
create: function create(methodName) { | ||
var expectation = extend.nonEnum(stub.create(), mockExpectation); | ||
var expectation = extend.nonEnum(stub(), mockExpectation); | ||
delete expectation.create; | ||
@@ -84,3 +84,3 @@ expectation.method = methodName; | ||
return spyInvoke.apply(this, arguments); | ||
return proxyInvoke.apply(this, arguments); | ||
}, | ||
@@ -282,3 +282,3 @@ | ||
var callStr = spyCallToString.call({ | ||
var callStr = proxyCallToString.call({ | ||
proxy: this.method || "anonymous mock expectation", | ||
@@ -285,0 +285,0 @@ args: args |
@@ -5,3 +5,3 @@ "use strict"; | ||
var mockExpectation = require("./mock-expectation"); | ||
var spyCallToString = require("./call").toString; | ||
var proxyCallToString = require("./proxy-call").toString; | ||
var extend = require("./util/core/extend"); | ||
@@ -80,3 +80,3 @@ var deepEqual = require("@sinonjs/samsam").deepEqual; | ||
var expectation = mockExpectation.create(method); | ||
extend.nonEnum(expectation, this.object[method]); | ||
expectation.wrappedMethod = this.object[method].wrappedMethod; | ||
push(this.expectations[method], expectation); | ||
@@ -173,3 +173,3 @@ usePromiseLibrary(this.promiseLibrary, expectation); | ||
"Unexpected call: " + | ||
spyCallToString.call({ | ||
proxyCallToString.call({ | ||
proxy: method, | ||
@@ -192,3 +192,3 @@ args: args | ||
"Unexpected call: " + | ||
spyCallToString.call({ | ||
proxyCallToString.call({ | ||
proxy: method, | ||
@@ -195,0 +195,0 @@ args: args, |
"use strict"; | ||
var arrayProto = require("@sinonjs/commons").prototypes.array; | ||
var createBehavior = require("./behavior").create; | ||
var createProxy = require("./proxy"); | ||
var extend = require("./util/core/extend"); | ||
var functionName = require("@sinonjs/commons").functionName; | ||
var functionToString = require("./util/core/function-to-string"); | ||
var getPropertyDescriptor = require("./util/core/get-property-descriptor"); | ||
var deepEqual = require("@sinonjs/samsam").deepEqual; | ||
var isEsModule = require("./util/core/is-es-module"); | ||
var spyCall = require("./call"); | ||
var spyEntireObject = require("./spy-entire-object"); | ||
var proxyCallUtil = require("./proxy-call-util"); | ||
var walkObject = require("./util/core/walk-object"); | ||
var wrapMethod = require("./util/core/wrap-method"); | ||
@@ -18,3 +17,2 @@ var sinonFormat = require("./util/core/format"); | ||
/* cache references to library methods so that they also can be stubbed without problems */ | ||
var concat = arrayProto.concat; | ||
var forEach = arrayProto.forEach; | ||
@@ -25,169 +23,13 @@ var pop = arrayProto.pop; | ||
var filter = Array.prototype.filter; | ||
var ErrorConstructor = Error.prototype.constructor; | ||
var bind = Function.prototype.bind; | ||
var callId = 0; | ||
var uuid = 0; | ||
function spy(object, property, types) { | ||
var descriptor, methodDesc; | ||
if (isEsModule(object)) { | ||
throw new TypeError("ES Modules cannot be spied"); | ||
function matches(fake, args, strict) { | ||
var margs = fake.matchingArguments; | ||
if (margs.length <= args.length && deepEqual(slice(args, 0, margs.length), margs)) { | ||
return !strict || margs.length === args.length; | ||
} | ||
if (!property && typeof object === "function") { | ||
return spy.create(object); | ||
} | ||
if (!property && typeof object === "object") { | ||
return spyEntireObject(spy, object); | ||
} | ||
if (!object && !property) { | ||
return spy.create(function() { | ||
return; | ||
}); | ||
} | ||
if (!types) { | ||
return wrapMethod(object, property, spy.create(object[property])); | ||
} | ||
descriptor = {}; | ||
methodDesc = getPropertyDescriptor(object, property); | ||
forEach(types, function(type) { | ||
descriptor[type] = spy.create(methodDesc[type]); | ||
}); | ||
return wrapMethod(object, property, descriptor); | ||
return false; | ||
} | ||
function incrementCallCount() { | ||
this.called = true; | ||
this.callCount += 1; | ||
this.notCalled = false; | ||
this.calledOnce = this.callCount === 1; | ||
this.calledTwice = this.callCount === 2; | ||
this.calledThrice = this.callCount === 3; | ||
} | ||
function createCallProperties() { | ||
this.firstCall = this.getCall(0); | ||
this.secondCall = this.getCall(1); | ||
this.thirdCall = this.getCall(2); | ||
this.lastCall = this.getCall(this.callCount - 1); | ||
} | ||
function createProxy(func, proxyLength) { | ||
// Retain the function length: | ||
var p; | ||
if (proxyLength) { | ||
// Do not change this to use an eval. Projects that depend on sinon block the use of eval. | ||
// ref: https://github.com/sinonjs/sinon/issues/710 | ||
switch (proxyLength) { | ||
/*eslint-disable no-unused-vars, max-len*/ | ||
case 1: | ||
p = function proxy(a) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 2: | ||
p = function proxy(a, b) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 3: | ||
p = function proxy(a, b, c) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 4: | ||
p = function proxy(a, b, c, d) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 5: | ||
p = function proxy(a, b, c, d, e) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 6: | ||
p = function proxy(a, b, c, d, e, f) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 7: | ||
p = function proxy(a, b, c, d, e, f, g) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 8: | ||
p = function proxy(a, b, c, d, e, f, g, h) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 9: | ||
p = function proxy(a, b, c, d, e, f, g, h, i) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 10: | ||
p = function proxy(a, b, c, d, e, f, g, h, i, j) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 11: | ||
p = function proxy(a, b, c, d, e, f, g, h, i, j, k) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
case 12: | ||
p = function proxy(a, b, c, d, e, f, g, h, i, j, k, l) { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
default: | ||
p = function proxy() { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
break; | ||
/*eslint-enable*/ | ||
} | ||
} else { | ||
p = function proxy() { | ||
return p.invoke(func, this, slice(arguments)); | ||
}; | ||
} | ||
var nameDescriptor = Object.getOwnPropertyDescriptor(func, "name"); | ||
if (nameDescriptor && nameDescriptor.configurable) { | ||
// IE 11 functions don't have a name. | ||
// Safari 9 has names that are not configurable. | ||
Object.defineProperty(p, "name", nameDescriptor); | ||
} | ||
extend.nonEnum(p, { | ||
isSinonProxy: true, | ||
called: false, | ||
notCalled: true, | ||
calledOnce: false, | ||
calledTwice: false, | ||
calledThrice: false, | ||
callCount: 0, | ||
firstCall: null, | ||
secondCall: null, | ||
thirdCall: null, | ||
lastCall: null, | ||
args: [], | ||
returnValues: [], | ||
thisValues: [], | ||
exceptions: [], | ||
callIds: [], | ||
errorsWithCallStack: [] | ||
}); | ||
return p; | ||
} | ||
var uuid = 0; | ||
// Public API | ||
@@ -197,237 +39,7 @@ var spyApi = { | ||
resetHistory: function() { | ||
if (this.invoking) { | ||
var err = new Error( | ||
"Cannot reset Sinon function while invoking it. " + | ||
"Move the call to .resetHistory outside of the callback." | ||
); | ||
err.name = "InvalidResetException"; | ||
throw err; | ||
} | ||
this.called = false; | ||
this.notCalled = true; | ||
this.calledOnce = false; | ||
this.calledTwice = false; | ||
this.calledThrice = false; | ||
this.callCount = 0; | ||
this.firstCall = null; | ||
this.secondCall = null; | ||
this.thirdCall = null; | ||
this.lastCall = null; | ||
this.args = []; | ||
this.returnValues = []; | ||
this.thisValues = []; | ||
this.exceptions = []; | ||
this.callIds = []; | ||
this.errorsWithCallStack = []; | ||
if (this.fakes) { | ||
forEach(this.fakes, function(fake) { | ||
if (fake.resetHistory) { | ||
fake.resetHistory(); | ||
} else { | ||
fake.reset(); | ||
} | ||
}); | ||
} | ||
return this; | ||
}, | ||
create: function create(func, spyLength) { | ||
var name; | ||
var funk = func; | ||
if (typeof funk !== "function") { | ||
funk = function() { | ||
return; | ||
}; | ||
} else { | ||
name = functionName(funk); | ||
} | ||
var length = spyLength || funk.length; | ||
var proxy = createProxy(funk, length); | ||
extend.nonEnum(proxy, spy); | ||
delete proxy.create; | ||
extend(proxy, funk); | ||
proxy.resetHistory(); | ||
proxy.prototype = funk.prototype; | ||
extend.nonEnum(proxy, { | ||
displayName: name || "spy", | ||
toString: functionToString, | ||
instantiateFake: spy.create, | ||
id: "spy#" + uuid++ | ||
}); | ||
return proxy; | ||
}, | ||
invoke: function invoke(func, thisValue, args) { | ||
var matchings = this.matchingFakes(args); | ||
var currentCallId = callId++; | ||
var exception, returnValue; | ||
incrementCallCount.call(this); | ||
push(this.thisValues, thisValue); | ||
push(this.args, args); | ||
push(this.callIds, currentCallId); | ||
forEach(matchings, function(matching) { | ||
incrementCallCount.call(matching); | ||
push(matching.thisValues, thisValue); | ||
push(matching.args, args); | ||
push(matching.callIds, currentCallId); | ||
}); | ||
// Make call properties available from within the spied function: | ||
createCallProperties.call(this); | ||
forEach(matchings, function(matching) { | ||
createCallProperties.call(matching); | ||
}); | ||
try { | ||
this.invoking = true; | ||
var thisCall = this.getCall(this.callCount - 1); | ||
if (thisCall.calledWithNew()) { | ||
// Call through with `new` | ||
returnValue = new (bind.apply(this.func || func, concat([thisValue], args)))(); | ||
if (typeof returnValue !== "object") { | ||
returnValue = thisValue; | ||
} | ||
} else { | ||
returnValue = (this.func || func).apply(thisValue, args); | ||
} | ||
} catch (e) { | ||
exception = e; | ||
} finally { | ||
delete this.invoking; | ||
} | ||
push(this.exceptions, exception); | ||
push(this.returnValues, returnValue); | ||
forEach(matchings, function(matching) { | ||
push(matching.exceptions, exception); | ||
push(matching.returnValues, returnValue); | ||
}); | ||
var err = new ErrorConstructor(); | ||
// 1. Please do not get stack at this point. It may be so very slow, and not actually used | ||
// 2. PhantomJS does not serialize the stack trace until the error has been thrown: | ||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack | ||
try { | ||
throw err; | ||
} catch (e) { | ||
/* empty */ | ||
} | ||
push(this.errorsWithCallStack, err); | ||
forEach(matchings, function(matching) { | ||
push(matching.errorsWithCallStack, err); | ||
}); | ||
// Make return value and exception available in the calls: | ||
createCallProperties.call(this); | ||
forEach(matchings, function(matching) { | ||
createCallProperties.call(matching); | ||
}); | ||
if (exception !== undefined) { | ||
throw exception; | ||
} | ||
return returnValue; | ||
}, | ||
named: function named(name) { | ||
this.displayName = name; | ||
var nameDescriptor = Object.getOwnPropertyDescriptor(this, "name"); | ||
if (nameDescriptor && nameDescriptor.configurable) { | ||
// IE 11 functions don't have a name. | ||
// Safari 9 has names that are not configurable. | ||
nameDescriptor.value = name; | ||
Object.defineProperty(this, "name", nameDescriptor); | ||
} | ||
return this; | ||
}, | ||
getCall: function getCall(i) { | ||
if (i < 0 || i >= this.callCount) { | ||
return null; | ||
} | ||
return spyCall( | ||
this, | ||
this.thisValues[i], | ||
this.args[i], | ||
this.returnValues[i], | ||
this.exceptions[i], | ||
this.callIds[i], | ||
this.errorsWithCallStack[i] | ||
); | ||
}, | ||
getCalls: function() { | ||
var calls = []; | ||
var i; | ||
for (i = 0; i < this.callCount; i++) { | ||
push(calls, this.getCall(i)); | ||
} | ||
return calls; | ||
}, | ||
calledBefore: function calledBefore(spyFn) { | ||
if (!this.called) { | ||
return false; | ||
} | ||
if (!spyFn.called) { | ||
return true; | ||
} | ||
return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1]; | ||
}, | ||
calledAfter: function calledAfter(spyFn) { | ||
if (!this.called || !spyFn.called) { | ||
return false; | ||
} | ||
return this.callIds[this.callCount - 1] > spyFn.callIds[0]; | ||
}, | ||
calledImmediatelyBefore: function calledImmediatelyBefore(spyFn) { | ||
if (!this.called || !spyFn.called) { | ||
return false; | ||
} | ||
return this.callIds[this.callCount - 1] === spyFn.callIds[spyFn.callCount - 1] - 1; | ||
}, | ||
calledImmediatelyAfter: function calledImmediatelyAfter(spyFn) { | ||
if (!this.called || !spyFn.called) { | ||
return false; | ||
} | ||
return this.callIds[this.callCount - 1] === spyFn.callIds[spyFn.callCount - 1] + 1; | ||
}, | ||
withArgs: function() { | ||
var args = slice(arguments); | ||
if (this.fakes) { | ||
var matching = pop(this.matchingFakes(args, true)); | ||
if (matching) { | ||
return matching; | ||
} | ||
} else { | ||
extend.nonEnum(this, { fakes: [] }); | ||
var matching = pop(this.matchingFakes(args, true)); | ||
if (matching) { | ||
return matching; | ||
} | ||
@@ -441,7 +53,2 @@ | ||
if (original.defaultBehavior && original.defaultBehavior.promiseLibrary) { | ||
fake.defaultBehavior = fake.defaultBehavior || createBehavior(fake); | ||
fake.defaultBehavior.promiseLibrary = original.defaultBehavior.promiseLibrary; | ||
} | ||
fake.withArgs = function() { | ||
@@ -452,7 +59,7 @@ return original.withArgs.apply(original, arguments); | ||
forEach(original.args, function(arg, i) { | ||
if (!fake.matches(arg)) { | ||
if (!matches(fake, arg)) { | ||
return; | ||
} | ||
incrementCallCount.call(fake); | ||
proxyCallUtil.incrementCallCount(fake); | ||
push(fake.thisValues, original.thisValues[i]); | ||
@@ -465,3 +72,3 @@ push(fake.args, arg); | ||
createCallProperties.call(fake); | ||
proxyCallUtil.createCallProperties(fake); | ||
@@ -471,18 +78,9 @@ return fake; | ||
// Override proxy default implementation | ||
matchingFakes: function(args, strict) { | ||
return filter.call(this.fakes || [], function(fake) { | ||
return fake.matches(args, strict); | ||
return filter.call(this.fakes, function(fake) { | ||
return matches(fake, args, strict); | ||
}); | ||
}, | ||
matches: function(args, strict) { | ||
var margs = this.matchingArguments; | ||
if (margs.length <= args.length && deepEqual(slice(args, 0, margs.length), margs)) { | ||
return !strict || margs.length === args.length; | ||
} | ||
return undefined; | ||
}, | ||
printf: function(format) { | ||
@@ -507,74 +105,16 @@ var spyInstance = this; | ||
function delegateToCalls(method, matchAny, actual, returnsValues, notCalled, totalCallCount) { | ||
spyApi[method] = function() { | ||
if (!this.called) { | ||
if (notCalled) { | ||
return notCalled.apply(this, arguments); | ||
} | ||
return false; | ||
} | ||
if (totalCallCount !== undefined && this.callCount !== totalCallCount) { | ||
return false; | ||
} | ||
var currentCall; | ||
var matches = 0; | ||
var returnValues = []; | ||
for (var i = 0, l = this.callCount; i < l; i += 1) { | ||
currentCall = this.getCall(i); | ||
var returnValue = currentCall[actual || method].apply(currentCall, arguments); | ||
push(returnValues, returnValue); | ||
if (returnValue) { | ||
matches += 1; | ||
if (matchAny) { | ||
return true; | ||
} | ||
} | ||
} | ||
if (returnsValues) { | ||
return returnValues; | ||
} | ||
return matches === this.callCount; | ||
}; | ||
} | ||
delegateToCalls("calledOn", true); | ||
delegateToCalls("alwaysCalledOn", false, "calledOn"); | ||
delegateToCalls("calledWith", true); | ||
delegateToCalls("calledOnceWith", true, "calledWith", false, undefined, 1); | ||
delegateToCalls("calledWithMatch", true); | ||
delegateToCalls("alwaysCalledWith", false, "calledWith"); | ||
delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch"); | ||
delegateToCalls("calledWithExactly", true); | ||
delegateToCalls("calledOnceWithExactly", true, "calledWithExactly", false, undefined, 1); | ||
delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly"); | ||
delegateToCalls("neverCalledWith", false, "notCalledWith", false, function() { | ||
return true; | ||
}); | ||
delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch", false, function() { | ||
return true; | ||
}); | ||
delegateToCalls("threw", true); | ||
delegateToCalls("alwaysThrew", false, "threw"); | ||
delegateToCalls("returned", true); | ||
delegateToCalls("alwaysReturned", false, "returned"); | ||
delegateToCalls("calledWithNew", true); | ||
delegateToCalls("alwaysCalledWithNew", false, "calledWithNew"); | ||
/* eslint-disable local-rules/no-prototype-methods */ | ||
delegateToCalls("callArg", false, "callArgWith", true, function() { | ||
var delegateToCalls = proxyCallUtil.delegateToCalls; | ||
delegateToCalls(spyApi, "callArg", false, "callArgWith", true, function() { | ||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked."); | ||
}); | ||
spyApi.callArgWith = spyApi.callArg; | ||
delegateToCalls("callArgOn", false, "callArgOnWith", true, function() { | ||
delegateToCalls(spyApi, "callArgOn", false, "callArgOnWith", true, function() { | ||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked."); | ||
}); | ||
spyApi.callArgOnWith = spyApi.callArgOn; | ||
delegateToCalls("throwArg", false, "throwArg", false, function() { | ||
delegateToCalls(spyApi, "throwArg", false, "throwArg", false, function() { | ||
throw new Error(this.toString() + " cannot throw arg since it was not yet invoked."); | ||
}); | ||
delegateToCalls("yield", false, "yield", true, function() { | ||
delegateToCalls(spyApi, "yield", false, "yield", true, function() { | ||
throw new Error(this.toString() + " cannot yield since it was not yet invoked."); | ||
@@ -584,6 +124,6 @@ }); | ||
spyApi.invokeCallback = spyApi.yield; | ||
delegateToCalls("yieldOn", false, "yieldOn", true, function() { | ||
delegateToCalls(spyApi, "yieldOn", false, "yieldOn", true, function() { | ||
throw new Error(this.toString() + " cannot yield since it was not yet invoked."); | ||
}); | ||
delegateToCalls("yieldTo", false, "yieldTo", true, function(property) { | ||
delegateToCalls(spyApi, "yieldTo", false, "yieldTo", true, function(property) { | ||
throw new Error( | ||
@@ -593,3 +133,3 @@ this.toString() + " cannot yield to '" + valueToString(property) + "' since it was not yet invoked." | ||
}); | ||
delegateToCalls("yieldToOn", false, "yieldToOn", true, function(property) { | ||
delegateToCalls(spyApi, "yieldToOn", false, "yieldToOn", true, function(property) { | ||
throw new Error( | ||
@@ -601,4 +141,63 @@ this.toString() + " cannot yield to '" + valueToString(property) + "' since it was not yet invoked." | ||
function createSpy(func) { | ||
var name; | ||
var funk = func; | ||
if (typeof funk !== "function") { | ||
funk = function() { | ||
return; | ||
}; | ||
} else { | ||
name = functionName(funk); | ||
} | ||
var proxy = createProxy(funk, funk); | ||
// Inherit spy API: | ||
extend.nonEnum(proxy, spyApi); | ||
extend.nonEnum(proxy, { | ||
displayName: name || "spy", | ||
fakes: [], | ||
instantiateFake: createSpy, | ||
id: "spy#" + uuid++ | ||
}); | ||
return proxy; | ||
} | ||
function spy(object, property, types) { | ||
var descriptor, methodDesc; | ||
if (isEsModule(object)) { | ||
throw new TypeError("ES Modules cannot be spied"); | ||
} | ||
if (!property && typeof object === "function") { | ||
return createSpy(object); | ||
} | ||
if (!property && typeof object === "object") { | ||
return walkObject(spy, object); | ||
} | ||
if (!object && !property) { | ||
return createSpy(function() { | ||
return; | ||
}); | ||
} | ||
if (!types) { | ||
return wrapMethod(object, property, createSpy(object[property])); | ||
} | ||
descriptor = {}; | ||
methodDesc = getPropertyDescriptor(object, property); | ||
forEach(types, function(type) { | ||
descriptor[type] = createSpy(methodDesc[type]); | ||
}); | ||
return wrapMethod(object, property, descriptor); | ||
} | ||
extend(spy, spyApi); | ||
spy.spyCall = spyCall; | ||
module.exports = spy; |
@@ -6,2 +6,4 @@ "use strict"; | ||
var behaviors = require("./default-behaviors"); | ||
var createProxy = require("./proxy"); | ||
var functionName = require("@sinonjs/commons").functionName; | ||
var hasOwnProperty = require("@sinonjs/commons").prototypes.object.hasOwnProperty; | ||
@@ -11,9 +13,8 @@ var isNonExistentOwnProperty = require("./util/core/is-non-existent-own-property"); | ||
var extend = require("./util/core/extend"); | ||
var functionToString = require("./util/core/function-to-string"); | ||
var getPropertyDescriptor = require("./util/core/get-property-descriptor"); | ||
var isEsModule = require("./util/core/is-es-module"); | ||
var wrapMethod = require("./util/core/wrap-method"); | ||
var stubEntireObject = require("./stub-entire-object"); | ||
var throwOnFalsyObject = require("./throw-on-falsy-object"); | ||
var valueToString = require("@sinonjs/commons").valueToString; | ||
var walkObject = require("./util/core/walk-object"); | ||
@@ -25,2 +26,39 @@ var forEach = arrayProto.forEach; | ||
var uuid = 0; | ||
function createStub(originalFunc) { | ||
var proxy; | ||
function functionStub() { | ||
var args = slice(arguments); | ||
var matchings = proxy.matchingFakes(args); | ||
var fnStub = | ||
pop( | ||
sort(matchings, function(a, b) { | ||
return a.matchingArguments.length - b.matchingArguments.length; | ||
}) | ||
) || proxy; | ||
return getCurrentBehavior(fnStub).invoke(this, arguments); | ||
} | ||
proxy = createProxy(functionStub, originalFunc || functionStub); | ||
// Inherit spy API: | ||
extend.nonEnum(proxy, spy); | ||
// Inherit stub API: | ||
extend.nonEnum(proxy, stub); | ||
var name = originalFunc ? functionName(originalFunc) : null; | ||
extend.nonEnum(proxy, { | ||
fakes: [], | ||
instantiateFake: createStub, | ||
displayName: name || "stub", | ||
defaultBehavior: null, | ||
behaviors: [], | ||
id: "stub#" + uuid++ | ||
}); | ||
return proxy; | ||
} | ||
function stub(object, property) { | ||
@@ -50,17 +88,13 @@ if (arguments.length > 2) { | ||
typeof descriptor === "undefined"; | ||
var isStubbingExistingMethod = | ||
typeof object === "object" && | ||
typeof actualDescriptor !== "undefined" && | ||
typeof actualDescriptor.value === "function"; | ||
var arity = isStubbingExistingMethod ? object[property].length : 0; | ||
if (isStubbingEntireObject) { | ||
return stubEntireObject(stub, object); | ||
return walkObject(stub, object); | ||
} | ||
if (isCreatingNewStub) { | ||
return stub.create(); | ||
return createStub(); | ||
} | ||
var s = stub.create(arity); | ||
var func = typeof actualDescriptor.value === "function" ? actualDescriptor.value : null; | ||
var s = createStub(func); | ||
@@ -120,44 +154,4 @@ extend.nonEnum(s, { | ||
var uuid = 0; | ||
var proto = { | ||
create: function create(stubLength) { | ||
var functionStub = function() { | ||
var args = slice(arguments); | ||
var matchings = functionStub.matchingFakes(args); | ||
var fnStub = | ||
pop( | ||
sort(matchings, function(a, b) { | ||
return a.matchingArguments.length - b.matchingArguments.length; | ||
}) | ||
) || functionStub; | ||
return getCurrentBehavior(fnStub).invoke(this, arguments); | ||
}; | ||
var orig = functionStub; | ||
functionStub = spy.create(functionStub, stubLength); | ||
extend.nonEnum(functionStub, { | ||
id: "stub#" + uuid++, | ||
func: orig | ||
}); | ||
extend(functionStub, stub); | ||
extend.nonEnum(functionStub, { | ||
instantiateFake: stub.create, | ||
displayName: "stub", | ||
toString: functionToString, | ||
defaultBehavior: null, | ||
behaviors: [] | ||
}); | ||
return functionStub; | ||
}, | ||
resetBehavior: function() { | ||
var fakes = this.fakes || []; | ||
this.defaultBehavior = null; | ||
@@ -174,3 +168,3 @@ this.behaviors = []; | ||
forEach(fakes, function(fake) { | ||
forEach(this.fakes, function(fake) { | ||
fake.resetBehavior(); | ||
@@ -180,4 +174,2 @@ }); | ||
resetHistory: spy.resetHistory, | ||
reset: function() { | ||
@@ -206,2 +198,11 @@ this.resetHistory(); | ||
return this.onCall(2); | ||
}, | ||
withArgs: function withArgs() { | ||
var fake = spy.withArgs.apply(this, arguments); | ||
if (this.defaultBehavior && this.defaultBehavior.promiseLibrary) { | ||
fake.defaultBehavior = fake.defaultBehavior || behavior.create(fake); | ||
fake.defaultBehavior.promiseLibrary = this.defaultBehavior.promiseLibrary; | ||
} | ||
return fake; | ||
} | ||
@@ -215,3 +216,2 @@ }; | ||
method !== "create" && | ||
method !== "withArgs" && | ||
method !== "invoke" | ||
@@ -218,0 +218,0 @@ ) { |
"use strict"; | ||
var globalObject = require("@sinonjs/commons").global; | ||
var getNextTick = require("./get-next-tick"); | ||
/* istanbul ignore next */ | ||
var root = typeof window !== "undefined" ? window : global; | ||
module.exports = getNextTick(root.process, root.setImmediate); | ||
module.exports = getNextTick(globalObject.process, globalObject.setImmediate); |
@@ -112,2 +112,4 @@ "use strict"; | ||
wrappedMethod: wrappedMethod, | ||
// Set up an Error object for a stack trace which can be used later to find what line of | ||
@@ -147,4 +149,2 @@ // code the original method was created on. | ||
method.wrappedMethod = wrappedMethod; | ||
method.restore.sinon = true; | ||
@@ -151,0 +151,0 @@ |
@@ -5,2 +5,3 @@ "use strict"; | ||
var llx = require("lolex"); | ||
var globalObject = require("@sinonjs/commons").global; | ||
@@ -17,2 +18,9 @@ function createClock(config, globalCtx) { | ||
function addIfDefined(obj, globalPropName) { | ||
var globalProp = globalObject[globalPropName]; | ||
if (typeof globalProp !== "undefined") { | ||
obj[globalPropName] = globalProp; | ||
} | ||
} | ||
/** | ||
@@ -56,7 +64,5 @@ * @param {number|Date|Object} dateOrConfig The unix epoch value to install with (default 0) | ||
exports.timers = { | ||
var timers = { | ||
setTimeout: setTimeout, | ||
clearTimeout: clearTimeout, | ||
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : undefined, | ||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : undefined, | ||
setInterval: setInterval, | ||
@@ -66,1 +72,5 @@ clearInterval: clearInterval, | ||
}; | ||
addIfDefined(timers, "setImmediate"); | ||
addIfDefined(timers, "clearImmediate"); | ||
exports.timers = timers; |
{ | ||
"name": "sinon", | ||
"description": "JavaScript test spies, stubs and mocks.", | ||
"version": "7.5.0", | ||
"version": "8.0.0", | ||
"homepage": "https://sinonjs.org/", | ||
@@ -12,5 +12,8 @@ "author": "Christian Johansen", | ||
"bugs": { | ||
"mail": "christian@cjohansen.no", | ||
"url": "http://github.com/sinonjs/sinon/issues" | ||
}, | ||
"funding": { | ||
"type": "opencollective", | ||
"url": "https://opencollective.com/sinon" | ||
}, | ||
"license": "BSD-3-Clause", | ||
@@ -20,6 +23,6 @@ "scripts": { | ||
"test-dev": "npm run test-node -- --watch -R min", | ||
"test-headless": "mochify --recursive -R dot --grep WebWorker --invert --plugin [ proxyquire-universal ] \"test/**/*-test.js\"", | ||
"test-headless": "mochify --no-detect-globals --recursive -R dot --grep WebWorker --invert --plugin [ proxyquire-universal ] \"test/**/*-test.js\"", | ||
"test-coverage": "nyc npm run test-headless -- --transform [ babelify --ignore [ test ] --plugins [ babel-plugin-istanbul ] ]", | ||
"test-cloud": "npm run test-headless -- --wd", | ||
"test-webworker": "mochify --https-server 8080 test/webworker/webworker-support-assessment.js", | ||
"test-webworker": "mochify --no-detect-globals --https-server 8080 --no-request-interception test/webworker/webworker-support-assessment.js", | ||
"test-esm": "mocha -r esm test/es2015/module-support-assessment-test.es6", | ||
@@ -29,6 +32,4 @@ "test-esm-bundle": "node test/es2015/check-esm-bundle-is-runnable.js", | ||
"test": "run-s test-node test-headless test-webworker test-esm", | ||
"check-dependencies": "dependency-check package.json --unused --no-dev --ignore-module coveralls --ignore-module esm", | ||
"build": "run-p build-esm build-bundle", | ||
"build-bundle": "node ./build.js", | ||
"build-esm": "rollup -c", | ||
"check-dependencies": "dependency-check package.json --no-dev --ignore-module esm", | ||
"build": "node ./build.js", | ||
"build-docs": "cd docs; bundle exec jekyll build", | ||
@@ -39,6 +40,5 @@ "serve-docs": "cd docs; bundle exec jekyll serve --incremental --verbose", | ||
"lint-markdown": "find docs -type f -name '*.md' ! -name 'changelog.md' | xargs markdownlint", | ||
"precommit": "lint-staged", | ||
"pretest-webworker": "npm run build", | ||
"prebuild": "rimraf pkg && npm run check-dependencies", | ||
"postbuild": "run-s test-esm-bundle", | ||
"postbuild": "npm run test-esm-bundle", | ||
"prepublishOnly": "npm run build", | ||
@@ -64,18 +64,18 @@ "prettier": "prettier lib/**/*.js test/**/*.js", | ||
"@sinonjs/commons": "^1.4.0", | ||
"@sinonjs/formatio": "^3.2.1", | ||
"@sinonjs/samsam": "^3.3.3", | ||
"diff": "^3.5.0", | ||
"lolex": "^4.2.0", | ||
"nise": "^1.5.2", | ||
"supports-color": "^5.5.0" | ||
"@sinonjs/formatio": "^4.0.1", | ||
"@sinonjs/samsam": "^4.0.1", | ||
"diff": "^4.0.1", | ||
"lolex": "^5.1.2", | ||
"nise": "^3.0.0", | ||
"supports-color": "^7.1.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.5.5", | ||
"@sinonjs/referee": "^3.2.0", | ||
"@sinonjs/referee": "^4.0.0", | ||
"babel-plugin-istanbul": "^5.2.0", | ||
"babelify": "^10.0.0", | ||
"browserify": "^16.2.3", | ||
"dependency-check": "^2.9.1", | ||
"browserify": "^16.5.0", | ||
"dependency-check": "^4.1.0", | ||
"eslint": "^6.2.2", | ||
"eslint-config-prettier": "^3.6.0", | ||
"eslint-config-prettier": "^6.3.0", | ||
"eslint-config-sinon": "^3.0.0", | ||
@@ -87,21 +87,15 @@ "eslint-plugin-ie11": "^1.0.0", | ||
"esm": "^3.2.25", | ||
"husky": "^0.14.2", | ||
"lint-staged": "^6.0.0", | ||
"markdownlint-cli": "^0.8.2", | ||
"husky": "^3.0.8", | ||
"lint-staged": "^9.4.1", | ||
"markdownlint-cli": "^0.18.0", | ||
"mocha": "^6.2.0", | ||
"mochify": "^6.3.0", | ||
"native-promise-only": "^0.8.1", | ||
"mochify": "^6.6.0", | ||
"npm-run-all": "^4.1.5", | ||
"nyc": "^14.1.1", | ||
"prettier": "^1.18.2", | ||
"proxyquire": "^1.8.0", | ||
"proxyquire-universal": "^1.0.8", | ||
"proxyquire": "^2.1.3", | ||
"proxyquire-universal": "^2.1.0", | ||
"proxyquireify": "^3.2.1", | ||
"puppeteer": "^1.19.0", | ||
"rimraf": "^2.6.3", | ||
"rollup": "^0.59.3", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-node-builtins": "^2.1.2", | ||
"rollup-plugin-node-globals": "^1.4.0", | ||
"rollup-plugin-node-resolve": "^3.4.0" | ||
"rimraf": "^3.0.0" | ||
}, | ||
@@ -129,3 +123,8 @@ "files": [ | ||
"mode": "auto" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
} | ||
} |
@@ -17,4 +17,4 @@ <h1 align=center> | ||
<a href="http://travis-ci.org/sinonjs/sinon"><img src="https://secure.travis-ci.org/sinonjs/sinon.svg?branch=master" alt="Build status"></a> | ||
<a href="https://saucelabs.com/u/sinonjs"><img src="https://saucelabs.com/buildstatus/sinonjs" alt="Sauce Test Status"</a> | ||
<a href="https://coveralls.io/github/sinonjs/sinon"><img src="https://coveralls.io/repos/github/sinonjs/sinon/badge.svg" alt="Coverage Status"></a> | ||
<a href="https://saucelabs.com/u/sinonjs"><img src="https://saucelabs.com/buildstatus/sinonjs" alt="Sauce Test Status"/></a> | ||
<a href="https://codecov.io/gh/sinonjs/sinon"><img src="https://codecov.io/gh/sinonjs/sinon/branch/master/graph/badge.svg" alt="Codecov status"></a> | ||
<a href="#backers"><img src="https://opencollective.com/sinon/backers/badge.svg" alt="OpenCollective"></a> | ||
@@ -21,0 +21,0 @@ <a href="#sponsors"><img src="https://opencollective.com/sinon/sponsors/badge.svg" alt="OpenCollective"></a> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance 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
27
52
1890954
35507
6
7
2
+ Added@sinonjs/formatio@4.0.1(transitive)
+ Added@sinonjs/samsam@4.2.2(transitive)
+ Addeddiff@4.0.2(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedlodash.get@4.4.2(transitive)
+ Addednise@3.0.1(transitive)
+ Addedsupports-color@7.2.0(transitive)
- Removed@sinonjs/formatio@3.2.2(transitive)
- Removed@sinonjs/samsam@3.3.3(transitive)
- Removedarray-from@2.1.1(transitive)
- Removeddiff@3.5.0(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlolex@4.2.0(transitive)
- Removednise@1.5.3(transitive)
- Removedsupports-color@5.5.0(transitive)
Updated@sinonjs/formatio@^4.0.1
Updated@sinonjs/samsam@^4.0.1
Updateddiff@^4.0.1
Updatedlolex@^5.1.2
Updatednise@^3.0.0
Updatedsupports-color@^7.1.0