Socket
Socket
Sign inDemoInstall

sinon

Package Overview
Dependencies
Maintainers
4
Versions
208
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sinon - npm Package Compare versions

Comparing version 15.2.0 to 17.0.1

lib/create-sinon-api.js

18

CONTRIBUTING.md

@@ -107,2 +107,18 @@ # Contributing to Sinon.JS

### Tooling
To transparently handle all issues with different tool versions we recommend using [_ASDF: The Multiple Runtime Manager_][asdf]. You would then need the Ruby and Node plugins.
<details>
```
asdf plugin add ruby
asdf plugin add nodejs
asdf install
```
</details>
[asdf]: https://asdf-vm.com
### Run the tests

@@ -137,2 +153,2 @@

$ node build.js
$ node build.cjs

47

lib/sinon.js
"use strict";
const behavior = require("./sinon/behavior");
const createSandbox = require("./sinon/create-sandbox");
const extend = require("./sinon/util/core/extend");
const fakeTimers = require("./sinon/util/fake-timers");
const nise = require("nise");
const Sandbox = require("./sinon/sandbox");
const stub = require("./sinon/stub");
const promise = require("./sinon/promise");
const createApi = require("./create-sinon-api");
const apiMethods = {
createSandbox: createSandbox,
assert: require("./sinon/assert"),
match: require("@sinonjs/samsam").createMatcher,
restoreObject: require("./sinon/restore-object"),
expectation: require("./sinon/mock-expectation"),
defaultConfig: require("./sinon/util/core/default-config"),
// fake timers
timers: fakeTimers.timers,
// fake XHR
xhr: nise.fakeXhr.xhr,
FakeXMLHttpRequest: nise.fakeXhr.FakeXMLHttpRequest,
// fake server
fakeServer: nise.fakeServer,
fakeServerWithClock: nise.fakeServerWithClock,
createFakeServer: nise.fakeServer.create.bind(nise.fakeServer),
createFakeServerWithClock: nise.fakeServerWithClock.create.bind(
nise.fakeServerWithClock
),
addBehavior: function (name, fn) {
behavior.addBehavior(stub, name, fn);
},
// fake promise
promise: promise,
};
const sandbox = new Sandbox();
const api = extend(sandbox, apiMethods);
module.exports = api;
module.exports = createApi();
"use strict";
/** @module */

@@ -18,3 +19,32 @@ const arrayProto = require("@sinonjs/commons").prototypes.array;

function createAssertObject() {
function applyDefaults(obj, defaults) {
for (const key of Object.keys(defaults)) {
const val = obj[key];
if (val === null || typeof val === "undefined") {
obj[key] = defaults[key];
}
}
}
/**
* @typedef {object} CreateAssertOptions
* @global
*
* @property {boolean} [shouldLimitAssertionLogs] default is false
* @property {number} [assertionLogLimit] default is 10K
*/
/**
* Create an assertion object that exposes several methods to invoke
*
* @param {CreateAssertOptions} [opts] options bag
* @returns {object} object with multiple assertion methods
*/
function createAssertObject(opts) {
const cleanedAssertOptions = opts || {};
applyDefaults(cleanedAssertOptions, {
shouldLimitAssertionLogs: false,
assertionLogLimit: 1e4,
});
const assert = {

@@ -24,3 +54,10 @@ failException: "AssertError",

fail: function fail(message) {
const error = new Error(message);
let msg = message;
if (cleanedAssertOptions.shouldLimitAssertionLogs) {
msg = message.substring(
0,
cleanedAssertOptions.assertionLogLimit,
);
}
const error = new Error(msg);
error.name = this.failException || assert.failException;

@@ -57,3 +94,3 @@

this,
`expected ${expected} to be called in order but were called as ${actual}`
`expected ${expected} to be called in order but were called as ${actual}`,
);

@@ -157,3 +194,3 @@ } else {

assertionArgs.length + 1
} arguments`
} arguments`,
);

@@ -203,4 +240,4 @@ }

fake,
concat([msg], args)
)
concat([msg], args),
),
);

@@ -223,3 +260,3 @@ } else {

"called",
"expected %n to have been called at least once but was never called"
"expected %n to have been called at least once but was never called",
);

@@ -231,23 +268,23 @@ mirrorPropAsAssertion(

},
"expected %n to not have been called but was called %c%C"
"expected %n to not have been called but was called %c%C",
);
mirrorPropAsAssertion(
"calledOnce",
"expected %n to be called once but was called %c%C"
"expected %n to be called once but was called %c%C",
);
mirrorPropAsAssertion(
"calledTwice",
"expected %n to be called twice but was called %c%C"
"expected %n to be called twice but was called %c%C",
);
mirrorPropAsAssertion(
"calledThrice",
"expected %n to be called thrice but was called %c%C"
"expected %n to be called thrice but was called %c%C",
);
mirrorPropAsAssertion(
"calledOn",
"expected %n to be called with %1 as this but was called with %t"
"expected %n to be called with %1 as this but was called with %t",
);
mirrorPropAsAssertion(
"alwaysCalledOn",
"expected %n to always be called with %1 as this but was called with %t"
"expected %n to always be called with %1 as this but was called with %t",
);

@@ -257,43 +294,43 @@ mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");

"alwaysCalledWithNew",
"expected %n to always be called with new"
"expected %n to always be called with new",
);
mirrorPropAsAssertion(
"calledWith",
"expected %n to be called with arguments %D"
"expected %n to be called with arguments %D",
);
mirrorPropAsAssertion(
"calledWithMatch",
"expected %n to be called with match %D"
"expected %n to be called with match %D",
);
mirrorPropAsAssertion(
"alwaysCalledWith",
"expected %n to always be called with arguments %D"
"expected %n to always be called with arguments %D",
);
mirrorPropAsAssertion(
"alwaysCalledWithMatch",
"expected %n to always be called with match %D"
"expected %n to always be called with match %D",
);
mirrorPropAsAssertion(
"calledWithExactly",
"expected %n to be called with exact arguments %D"
"expected %n to be called with exact arguments %D",
);
mirrorPropAsAssertion(
"calledOnceWithExactly",
"expected %n to be called once and with exact arguments %D"
"expected %n to be called once and with exact arguments %D",
);
mirrorPropAsAssertion(
"calledOnceWithMatch",
"expected %n to be called once and with match %D"
"expected %n to be called once and with match %D",
);
mirrorPropAsAssertion(
"alwaysCalledWithExactly",
"expected %n to always be called with exact arguments %D"
"expected %n to always be called with exact arguments %D",
);
mirrorPropAsAssertion(
"neverCalledWith",
"expected %n to never be called with arguments %*%C"
"expected %n to never be called with arguments %*%C",
);
mirrorPropAsAssertion(
"neverCalledWithMatch",
"expected %n to never be called with match %*%C"
"expected %n to never be called with match %*%C",
);

@@ -300,0 +337,0 @@ mirrorPropAsAssertion("threw", "%n did not throw exception%C");

@@ -60,9 +60,9 @@ "use strict";

msg = `${functionName(
behavior.stub
behavior.stub,
)} expected to yield to '${valueToString(
behavior.callArgProp
behavior.callArgProp,
)}', but no object with such a property was passed.`;
} else {
msg = `${functionName(
behavior.stub
behavior.stub,
)} expected to yield, but no callback was passed.`;

@@ -91,3 +91,3 @@ }

args.length
} present`
} present`,
);

@@ -110,3 +110,3 @@ }

behavior.callbackContext,
behavior.callbackArguments
behavior.callbackArguments,
);

@@ -117,3 +117,3 @@ });

behavior.callbackContext,
behavior.callbackArguments
behavior.callbackArguments,
);

@@ -185,3 +185,3 @@ }

return (this.promiseLibrary || Promise).resolve(
args[this.resolveArgAt]
args[this.resolveArgAt],
);

@@ -206,3 +206,3 @@ } else if (this.resolveThis) {

WrappedClass,
concat([null], argsArray)
concat([null], argsArray),
);

@@ -248,3 +248,3 @@ return new F();

'is not supported. Use "stub.withArgs(...).onCall(...)" ' +
"to define sequential behavior for calls with certain arguments."
"to define sequential behavior for calls with certain arguments.",
);

@@ -259,3 +259,3 @@ },

this.defaultBehavior,
arguments
arguments,
);

@@ -262,0 +262,0 @@ return this;

@@ -10,3 +10,3 @@ "use strict";

function prepareSandboxFromConfig(config) {
const sandbox = new Sandbox();
const sandbox = new Sandbox({ assertOptions: config.assertOptions });

@@ -45,2 +45,39 @@ if (config.useFakeServer) {

/**
* Options to customize a sandbox
*
* The sandbox's methods can be injected into another object for
* convenience. The `injectInto` configuration option can name an
* object to add properties to.
*
* @typedef {object} SandboxConfig
* @property {string[]} properties The properties of the API to expose on the sandbox. Examples: ['spy', 'fake', 'restore']
* @property {object} injectInto an object in which to inject properties from the sandbox (a facade). This is mostly an integration feature (sinon-test being one).
* @property {boolean} useFakeTimers whether timers are faked by default
* @property {boolean|object} useFakeServer whether XHR's are faked and the server feature enabled by default. It could also be a different default fake server implementation to use
* @property {object} [assertOptions] see CreateAssertOptions in ./assert
*
* This type def is really suffering from JSDoc not having standardized
* how to reference types defined in other modules :(
*/
/**
* A configured sinon sandbox (private type)
*
* @typedef {object} ConfiguredSinonSandboxType
* @private
* @augments Sandbox
* @property {string[]} injectedKeys the keys that have been injected (from config.injectInto)
* @property {*[]} args the arguments for the sandbox
*/
/**
* Create a sandbox
*
* As of Sinon 5 the `sinon` instance itself is a Sandbox, so you
* hardly ever need to create additional instances for the sake of testing
*
* @param config {SandboxConfig}
* @returns {Sandbox}
*/
function createSandbox(config) {

@@ -47,0 +84,0 @@ if (!config) {

@@ -31,3 +31,3 @@ "use strict";

throw new Error(
`Cannot stub ${propertyName}. Property does not exist!`
`Cannot stub ${propertyName}. Property does not exist!`,
);

@@ -34,0 +34,0 @@ }

@@ -18,3 +18,5 @@ "use strict";

fake.exceptionCreator = function () {
const newException = new Error(message || "");
const newException = new Error(
message || `Sinon-provided ${error}`,
);
newException.name = error;

@@ -32,7 +34,44 @@ return newException;

const SKIP_OPTIONS_FOR_YIELDS = {
skipReturn: true,
skipThrows: true,
};
function clear(fake, options) {
fake.fakeFn = undefined;
fake.callsThrough = undefined;
fake.callsThroughWithNew = undefined;
if (!options || !options.skipThrows) {
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.throwArgAt = undefined;
}
fake.callArgAt = undefined;
fake.callbackArguments = undefined;
fake.callbackContext = undefined;
fake.callArgProp = undefined;
fake.callbackAsync = undefined;
if (!options || !options.skipReturn) {
fake.returnValue = undefined;
fake.returnValueDefined = undefined;
fake.returnArgAt = undefined;
fake.returnThis = undefined;
}
fake.resolve = undefined;
fake.resolveThis = undefined;
fake.resolveArgAt = undefined;
fake.reject = undefined;
}
const defaultBehaviors = {
callsFake: function callsFake(fake, fn) {
clear(fake);
fake.fakeFn = fn;
fake.exception = undefined;
fake.exceptionCreator = undefined;
},

@@ -44,8 +83,6 @@

}
clear(fake);
fake.callArgAt = index;
fake.callbackArguments = [];
fake.callbackContext = undefined;
fake.callArgProp = undefined;
fake.callbackAsync = false;
},

@@ -57,2 +94,3 @@

}
clear(fake);

@@ -62,4 +100,2 @@ fake.callArgAt = index;

fake.callbackContext = context;
fake.callArgProp = undefined;
fake.callbackAsync = false;
},

@@ -71,8 +107,6 @@

}
clear(fake);
fake.callArgAt = index;
fake.callbackArguments = slice(arguments, 2);
fake.callbackContext = undefined;
fake.callArgProp = undefined;
fake.callbackAsync = false;
},

@@ -84,2 +118,3 @@

}
clear(fake);

@@ -89,4 +124,2 @@ fake.callArgAt = index;

fake.callbackContext = context;
fake.callArgProp = undefined;
fake.callbackAsync = false;
},

@@ -99,38 +132,34 @@

yields: function (fake) {
clear(fake, SKIP_OPTIONS_FOR_YIELDS);
fake.callArgAt = useLeftMostCallback;
fake.callbackArguments = slice(arguments, 1);
fake.callbackContext = undefined;
fake.callArgProp = undefined;
fake.callbackAsync = false;
fake.fakeFn = undefined;
},
yieldsRight: function (fake) {
clear(fake, SKIP_OPTIONS_FOR_YIELDS);
fake.callArgAt = useRightMostCallback;
fake.callbackArguments = slice(arguments, 1);
fake.callbackContext = undefined;
fake.callArgProp = undefined;
fake.callbackAsync = false;
fake.fakeFn = undefined;
},
yieldsOn: function (fake, context) {
clear(fake, SKIP_OPTIONS_FOR_YIELDS);
fake.callArgAt = useLeftMostCallback;
fake.callbackArguments = slice(arguments, 2);
fake.callbackContext = context;
fake.callArgProp = undefined;
fake.callbackAsync = false;
fake.fakeFn = undefined;
},
yieldsTo: function (fake, prop) {
clear(fake, SKIP_OPTIONS_FOR_YIELDS);
fake.callArgAt = useLeftMostCallback;
fake.callbackArguments = slice(arguments, 2);
fake.callbackContext = undefined;
fake.callArgProp = prop;
fake.callbackAsync = false;
fake.fakeFn = undefined;
},
yieldsToOn: function (fake, prop, context) {
clear(fake, SKIP_OPTIONS_FOR_YIELDS);
fake.callArgAt = useLeftMostCallback;

@@ -140,4 +169,2 @@ fake.callbackArguments = slice(arguments, 3);

fake.callArgProp = prop;
fake.callbackAsync = false;
fake.fakeFn = undefined;
},

@@ -149,9 +176,6 @@

returns: function returns(fake, value) {
clear(fake);
fake.returnValue = value;
fake.resolve = false;
fake.reject = false;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},

@@ -163,2 +187,3 @@

}
clear(fake);

@@ -172,2 +197,3 @@ fake.returnArgAt = index;

}
clear(fake);

@@ -178,2 +204,4 @@ fake.throwArgAt = index;

returnsThis: function returnsThis(fake) {
clear(fake);
fake.returnThis = true;

@@ -183,10 +211,7 @@ },

resolves: function resolves(fake, value) {
clear(fake);
fake.returnValue = value;
fake.resolve = true;
fake.resolveThis = false;
fake.reject = false;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},

@@ -198,11 +223,6 @@

}
clear(fake);
fake.resolveArgAt = index;
fake.returnValue = undefined;
fake.resolve = true;
fake.resolveThis = false;
fake.reject = false;
fake.returnValueDefined = false;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},

@@ -220,10 +240,7 @@

}
clear(fake);
fake.returnValue = reason;
fake.resolve = false;
fake.resolveThis = false;
fake.reject = true;
fake.returnValueDefined = true;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;

@@ -234,13 +251,10 @@ return fake;

resolvesThis: function resolvesThis(fake) {
fake.returnValue = undefined;
fake.resolve = false;
clear(fake);
fake.resolveThis = true;
fake.reject = false;
fake.returnValueDefined = false;
fake.exception = undefined;
fake.exceptionCreator = undefined;
fake.fakeFn = undefined;
},
callThrough: function callThrough(fake) {
clear(fake);
fake.callsThrough = true;

@@ -250,2 +264,4 @@ },

callThroughWithNew: function callThroughWithNew(fake) {
clear(fake);
fake.callsThroughWithNew = true;

@@ -261,3 +277,3 @@ },

rootStub.rootObj,
rootStub.propName
rootStub.propName,
),

@@ -280,5 +296,5 @@ });

rootStub.rootObj,
rootStub.propName
rootStub.propName,
),
}
},
);

@@ -285,0 +301,0 @@

@@ -151,3 +151,3 @@ "use strict";

mockExpectation.fail(
`${this.method} already called ${timesInWords(this.maxCalls)}`
`${this.method} already called ${timesInWords(this.maxCalls)}`,
);

@@ -159,4 +159,4 @@ }

`${this.method} called with ${valueToString(
thisValue
)} as thisValue, expected ${valueToString(this.expectedThis)}`
thisValue,
)} as thisValue, expected ${valueToString(this.expectedThis)}`,
);

@@ -172,4 +172,4 @@ }

`${this.method} received no arguments, expected ${inspect(
expectedArguments
)}`
expectedArguments,
)}`,
);

@@ -181,4 +181,4 @@ }

`${this.method} received too few arguments (${inspect(
args
)}), expected ${inspect(expectedArguments)}`
args,
)}), expected ${inspect(expectedArguments)}`,
);

@@ -193,4 +193,4 @@ }

`${this.method} received too many arguments (${inspect(
args
)}), expected ${inspect(expectedArguments)}`
args,
)}), expected ${inspect(expectedArguments)}`,
);

@@ -205,4 +205,4 @@ }

`${this.method} received wrong arguments ${inspect(
args
)}, didn't match ${String(expectedArguments)}`
args,
)}, didn't match ${String(expectedArguments)}`,
);

@@ -214,8 +214,8 @@ }

`${this.method} received wrong arguments ${inspect(
args
)}, expected ${inspect(expectedArguments)}`
args,
)}, expected ${inspect(expectedArguments)}`,
);
}
},
this
this,
);

@@ -296,3 +296,3 @@ },

", [...",
"[, ..."
"[, ...",
)} ${expectedCallCountInWords(this)}`;

@@ -299,0 +299,0 @@

@@ -146,5 +146,5 @@ "use strict";

currentArgs,
expectation.expectsExactArgCount
expectation.expectsExactArgCount,
);
}
},
);

@@ -159,3 +159,3 @@

);
}
},
);

@@ -191,3 +191,3 @@

args: args,
})}`
})}`,
);

@@ -210,3 +210,3 @@

stack: err.stack,
})}`
})}`,
);

@@ -213,0 +213,0 @@

@@ -28,3 +28,3 @@ "use strict";

notCalled,
totalCallCount
totalCallCount,
) {

@@ -51,3 +51,3 @@ proxy[method] = function () {

currentCall,
arguments
arguments,
);

@@ -54,0 +54,0 @@ push(returnValues, returnValue);

@@ -51,3 +51,3 @@ "use strict";

},
true
true,
);

@@ -71,3 +71,3 @@ },

},
true
true,
);

@@ -136,3 +136,3 @@ },

this,
concat([pos, null], slice(arguments, 1))
concat([pos, null], slice(arguments, 1)),
);

@@ -150,3 +150,3 @@ },

throw new TypeError(
`Not enough arguments: ${pos} required but only ${this.args.length} present`
`Not enough arguments: ${pos} required but only ${this.args.length} present`,
);

@@ -172,3 +172,3 @@ }

" cannot yield since no callback was passed.",
args
args,
);

@@ -183,3 +183,3 @@ }

this,
concat([prop, null], slice(arguments, 1))
concat([prop, null], slice(arguments, 1)),
);

@@ -199,5 +199,5 @@ },

` cannot yield to '${valueToString(
prop
prop,
)}' since no callback was passed.`,
args
args,
);

@@ -237,3 +237,3 @@ }

/^\s*(?:at\s+|@)?/,
" at "
" at ",
);

@@ -249,3 +249,3 @@ }

`Expected argument at position ${pos} to be a Function, but was ${typeof this
.args[pos]}`
.args[pos]}`,
);

@@ -273,2 +273,4 @@ }

* @param errorWithCallStack
*
* @returns {object} proxyCall
*/

@@ -282,3 +284,3 @@ function createProxyCall(

id,
errorWithCallStack
errorWithCallStack,
) {

@@ -285,0 +287,0 @@ if (typeof id !== "number") {

@@ -43,3 +43,3 @@ "use strict";

this.func || func,
concat([thisValue], args)
concat([thisValue], args),
))();

@@ -46,0 +46,0 @@

@@ -60,3 +60,3 @@ "use strict";

this.callIds[i],
this.errorsWithCallStack[i]
this.errorsWithCallStack[i],
);

@@ -141,3 +141,3 @@ },

"Cannot reset Sinon function while invoking it. " +
"Move the call to .resetHistory outside of the callback."
"Move the call to .resetHistory outside of the callback.",
);

@@ -188,3 +188,3 @@ err.name = "InvalidResetException";

undefined,
1
1,
);

@@ -202,3 +202,3 @@ delegateToCalls(proxyApi, "calledWithMatch", true);

undefined,
1
1,
);

@@ -212,3 +212,3 @@ delegateToCalls(

undefined,
1
1,
);

@@ -219,3 +219,3 @@ delegateToCalls(

false,
"calledWithExactly"
"calledWithExactly",
);

@@ -230,3 +230,3 @@ delegateToCalls(

return true;
}
},
);

@@ -241,3 +241,3 @@ delegateToCalls(

return true;
}
},
);

@@ -345,3 +345,3 @@ delegateToCalls(proxyApi, "threw", true);

originalFunc,
"name"
"name",
);

@@ -348,0 +348,0 @@ if (nameDescriptor && nameDescriptor.configurable) {

@@ -38,4 +38,46 @@ "use strict";

function Sandbox() {
function throwOnAccessors(descriptor) {
if (typeof descriptor.get === "function") {
throw new Error("Use sandbox.replaceGetter for replacing getters");
}
if (typeof descriptor.set === "function") {
throw new Error("Use sandbox.replaceSetter for replacing setters");
}
}
function verifySameType(object, property, replacement) {
if (typeof object[property] !== typeof replacement) {
throw new TypeError(
`Cannot replace ${typeof object[
property
]} with ${typeof replacement}`,
);
}
}
function checkForValidArguments(descriptor, property, replacement) {
if (typeof descriptor === "undefined") {
throw new TypeError(
`Cannot replace non-existent property ${valueToString(
property,
)}. Perhaps you meant sandbox.define()?`,
);
}
if (typeof replacement === "undefined") {
throw new TypeError("Expected replacement argument to be defined");
}
}
/**
* A sinon sandbox
*
* @param opts
* @param {object} [opts.assertOptions] see the CreateAssertOptions in ./assert
* @class
*/
function Sandbox(opts = {}) {
const sandbox = this;
const assertOptions = opts.assertOptions || {};
let fakeRestorers = [];

@@ -55,3 +97,3 @@ let promiseLib;

logger.printWarning(
"Potential memory leak detected; be sure to call restore() to clean up your sandbox. To suppress this warning, modify the leakThreshold property of your sandbox."
"Potential memory leak detected; be sure to call restore() to clean up your sandbox. To suppress this warning, modify the leakThreshold property of your sandbox.",
);

@@ -62,3 +104,3 @@ loggedLeakWarning = true;

sandbox.assert = sinonAssert.createAssertObject();
sandbox.assert = sinonAssert.createAssertObject(assertOptions);

@@ -72,7 +114,2 @@ sandbox.serverPrototype = fakeServer;

// this is for testing only
sandbox.getRestorers = function () {
return fakeRestorers;
};
sandbox.createStubInstance = function createStubInstance() {

@@ -113,2 +150,6 @@ const stubbed = sinonCreateStubInstance.apply(null, arguments);

obj.define = function () {
return sandbox.define.apply(null, arguments);
};
obj.replace = function () {

@@ -166,19 +207,3 @@ return sandbox.replace.apply(null, arguments);

forEach(collection, function (fake) {
if (typeof fake === "function") {
privateResetHistory(fake);
return;
}
const methods = [];
if (fake.get) {
push(methods, fake.get);
}
if (fake.set) {
push(methods, fake.set);
}
forEach(methods, privateResetHistory);
});
forEach(collection, privateResetHistory);
};

@@ -189,3 +214,3 @@

throw new Error(
"sandbox.restore() does not take any parameters. Perhaps you meant stub.restore()"
"sandbox.restore() does not take any parameters. Perhaps you meant stub.restore()",
);

@@ -207,21 +232,29 @@ }

sandbox.restoreContext = function restoreContext() {
let injectedKeys = sandbox.injectedKeys;
const injectInto = sandbox.injectInto;
if (!injectedKeys) {
if (!sandbox.injectedKeys) {
return;
}
forEach(injectedKeys, function (injectedKey) {
delete injectInto[injectedKey];
forEach(sandbox.injectedKeys, function (injectedKey) {
delete sandbox.injectInto[injectedKey];
});
injectedKeys = [];
sandbox.injectedKeys.length = 0;
};
function getFakeRestorer(object, property) {
/**
* Creates a restorer function for the property
*
* @param {object|Function} object
* @param {string} property
* @param {boolean} forceAssignment
* @returns {Function} restorer function
*/
function getFakeRestorer(object, property, forceAssignment = false) {
const descriptor = getPropertyDescriptor(object, property);
const value = object[property];
function restorer() {
if (descriptor.isOwn) {
if (forceAssignment) {
object[property] = value;
} else if (descriptor?.isOwn) {
Object.defineProperty(object, property, descriptor);

@@ -232,2 +265,3 @@ } else {

}
restorer.object = object;

@@ -245,3 +279,3 @@ restorer.property = property;

throw new TypeError(
`Attempted to replace ${property} which is already replaced`
`Attempted to replace ${property} which is already replaced`,
);

@@ -252,41 +286,68 @@ }

/**
* Replace an existing property
*
* @param {object|Function} object
* @param {string} property
* @param {*} replacement a fake, stub, spy or any other value
* @returns {*}
*/
sandbox.replace = function replace(object, property, replacement) {
const descriptor = getPropertyDescriptor(object, property);
checkForValidArguments(descriptor, property, replacement);
throwOnAccessors(descriptor);
verifySameType(object, property, replacement);
if (typeof descriptor === "undefined") {
throw new TypeError(
`Cannot replace non-existent property ${valueToString(
property
)}`
);
}
verifyNotReplaced(object, property);
if (typeof replacement === "undefined") {
throw new TypeError("Expected replacement argument to be defined");
}
// store a function for restoring the replaced property
push(fakeRestorers, getFakeRestorer(object, property));
if (typeof descriptor.get === "function") {
throw new Error("Use sandbox.replaceGetter for replacing getters");
}
object[property] = replacement;
if (typeof descriptor.set === "function") {
throw new Error("Use sandbox.replaceSetter for replacing setters");
}
return replacement;
};
if (typeof object[property] !== typeof replacement) {
sandbox.replace.usingAccessor = function replaceUsingAccessor(
object,
property,
replacement,
) {
const descriptor = getPropertyDescriptor(object, property);
checkForValidArguments(descriptor, property, replacement);
verifySameType(object, property, replacement);
verifyNotReplaced(object, property);
// store a function for restoring the replaced property
push(fakeRestorers, getFakeRestorer(object, property, true));
object[property] = replacement;
return replacement;
};
sandbox.define = function define(object, property, value) {
const descriptor = getPropertyDescriptor(object, property);
if (descriptor) {
throw new TypeError(
`Cannot replace ${typeof object[
property
]} with ${typeof replacement}`
`Cannot define the already existing property ${valueToString(
property,
)}. Perhaps you meant sandbox.replace()?`,
);
}
if (typeof value === "undefined") {
throw new TypeError("Expected value argument to be defined");
}
verifyNotReplaced(object, property);
// store a function for restoring the replaced property
// store a function for restoring the defined property
push(fakeRestorers, getFakeRestorer(object, property));
object[property] = replacement;
object[property] = value;
return replacement;
return value;
};

@@ -297,3 +358,3 @@

property,
replacement
replacement,
) {

@@ -305,4 +366,4 @@ const descriptor = getPropertyDescriptor(object, property);

`Cannot replace non-existent property ${valueToString(
property
)}`
property,
)}`,
);

@@ -313,3 +374,3 @@ }

throw new TypeError(
"Expected replacement argument to be a function"
"Expected replacement argument to be a function",
);

@@ -338,3 +399,3 @@ }

property,
replacement
replacement,
) {

@@ -346,4 +407,4 @@ const descriptor = getPropertyDescriptor(object, property);

`Cannot replace non-existent property ${valueToString(
property
)}`
property,
)}`,
);

@@ -354,3 +415,3 @@ }

throw new TypeError(
"Expected replacement argument to be a function"
"Expected replacement argument to be a function",
);

@@ -378,4 +439,3 @@ }

function commonPostInitSetup(args, spy) {
const object = args[0];
const property = args[1];
const [object, property, types] = args;

@@ -393,2 +453,7 @@ const isSpyingOnEntireObject =

usePromiseLibrary(promiseLib, ownMethods);
} else if (Array.isArray(types)) {
for (const accessorType of types) {
addToCollection(spy[accessorType]);
usePromiseLibrary(promiseLib, spy[accessorType]);
}
} else {

@@ -395,0 +460,0 @@ addToCollection(spy);

"use strict";
const arrayProto = require("@sinonjs/commons").prototypes.array;
const color = require("./color");
const Colorizer = require("./colorizer");
const colororizer = new Colorizer();
const match = require("@sinonjs/samsam").createMatcher;

@@ -15,2 +16,10 @@ const timesInWords = require("./util/core/times-in-words");

/**
*
* @param matcher
* @param calledArg
* @param calledArgMessage
*
* @returns {string} the colored text
*/
function colorSinonMatchText(matcher, calledArg, calledArgMessage) {

@@ -20,5 +29,5 @@ let calledArgumentMessage = calledArgMessage;

if (!matcher.test(calledArg)) {
matcherMessage = color.red(matcher.message);
matcherMessage = colororizer.red(matcher.message);
if (calledArgumentMessage) {
calledArgumentMessage = color.green(calledArgumentMessage);
calledArgumentMessage = colororizer.green(calledArgumentMessage);
}

@@ -29,2 +38,7 @@ }

/**
* @param diff
*
* @returns {string} the colored diff
*/
function colorDiffText(diff) {

@@ -34,5 +48,5 @@ const objects = map(diff, function (part) {

if (part.added) {
text = color.green(text);
text = colororizer.green(text);
} else if (part.removed) {
text = color.red(text);
text = colororizer.red(text);
}

@@ -47,2 +61,7 @@ if (diff.length === 2) {

/**
*
* @param value
* @returns {string} a quoted string
*/
function quoteStringValue(value) {

@@ -99,3 +118,3 @@ if (typeof value === "string") {

calledArg,
calledArgMessage
calledArgMessage,
);

@@ -107,3 +126,3 @@ } else {

calledArgMessage,
expectedArgMessage
expectedArgMessage,
);

@@ -148,5 +167,5 @@ message += colorDiffText(diff);

}),
", "
", ",
);
},
};

@@ -84,3 +84,3 @@ "use strict";

throw new Error(
`${this.toString()} cannot call arg since it was not yet invoked.`
`${this.toString()} cannot call arg since it was not yet invoked.`,
);

@@ -91,3 +91,3 @@ });

throw new Error(
`${this.toString()} cannot call arg since it was not yet invoked.`
`${this.toString()} cannot call arg since it was not yet invoked.`,
);

@@ -98,3 +98,3 @@ });

throw new Error(
`${this.toString()} cannot throw arg since it was not yet invoked.`
`${this.toString()} cannot throw arg since it was not yet invoked.`,
);

@@ -104,3 +104,3 @@ });

throw new Error(
`${this.toString()} cannot yield since it was not yet invoked.`
`${this.toString()} cannot yield since it was not yet invoked.`,
);

@@ -112,3 +112,3 @@ });

throw new Error(
`${this.toString()} cannot yield since it was not yet invoked.`
`${this.toString()} cannot yield since it was not yet invoked.`,
);

@@ -119,4 +119,4 @@ });

`${this.toString()} cannot yield to '${valueToString(
property
)}' since it was not yet invoked.`
property,
)}' since it was not yet invoked.`,
);

@@ -133,6 +133,6 @@ });

`${this.toString()} cannot yield to '${valueToString(
property
)}' since it was not yet invoked.`
property,
)}' since it was not yet invoked.`,
);
}
},
);

@@ -139,0 +139,0 @@

@@ -42,3 +42,3 @@ "use strict";

);
})
}),
) || proxy;

@@ -72,3 +72,3 @@ return getCurrentBehavior(fnStub).invoke(this, arguments);

throw new TypeError(
"stub(obj, 'meth', fn) has been removed, see documentation"
"stub(obj, 'meth', fn) has been removed, see documentation",
);

@@ -85,3 +85,3 @@ }

throw new TypeError(
`Cannot stub non-existent property ${valueToString(property)}`
`Cannot stub non-existent property ${valueToString(property)}`,
);

@@ -142,3 +142,3 @@ }

throw new TypeError(
`Descriptor for property ${property} is non-configurable and non-writable`
`Descriptor for property ${property} is non-configurable and non-writable`,
);

@@ -148,3 +148,3 @@ }

throw new TypeError(
`Descriptor for accessor property ${property} is non-configurable`
`Descriptor for accessor property ${property} is non-configurable`,
);

@@ -154,3 +154,3 @@ }

throw new TypeError(
`Descriptor for data property ${property} is non-writable`
`Descriptor for data property ${property} is non-writable`,
);

@@ -157,0 +157,0 @@ }

@@ -8,3 +8,3 @@ "use strict";

throw new Error(
`Trying to stub property '${valueToString(property)}' of ${type}`
`Trying to stub property '${valueToString(property)}' of ${type}`,
);

@@ -11,0 +11,0 @@ }

@@ -13,2 +13,3 @@ "use strict";

"fake",
"define",
"replace",

@@ -15,0 +16,0 @@ "replaceSetter",

@@ -15,3 +15,3 @@ "use strict";

this,
arguments
arguments,
);

@@ -24,4 +24,4 @@ this.callbackAsync = true;

},
{}
{},
);
};

@@ -102,7 +102,7 @@ "use strict";

dest,
prop
prop,
);
const sourceOwnPropertyDescriptor = Object.getOwnPropertyDescriptor(
source,
prop
prop,
);

@@ -137,3 +137,3 @@

Object.defineProperty(dest, prop, descriptors);
}
},
);

@@ -161,4 +161,4 @@ };

});
}
},
);
};
"use strict";
module.exports = function getPropertyDescriptor(object, property) {
/* eslint-disable jsdoc/valid-types */
/*
* The following type def is strictly an illegal JSDoc, but the expression forms a
* legal Typescript union type and is understood by Visual Studio and the IntelliJ
* family of editors. The "TS" flavor of JSDoc is becoming the de-facto standard these
* days for that reason (and the fact that JSDoc is essentially unmaintained)
*/
/**
* @typedef {{isOwn: boolean} & PropertyDescriptor} SinonPropertyDescriptor
* a slightly enriched property descriptor
* @property {boolean} isOwn true if the descriptor is owned by this object, false if it comes from the prototype
*/
/* eslint-enable jsdoc/valid-types */
/**
* Returns a slightly modified property descriptor that one can tell is from the object or the prototype
*
* @param {*} object
* @param {string} property
* @returns {SinonPropertyDescriptor}
*/
function getPropertyDescriptor(object, property) {
let proto = object;
let descriptor;
const isOwn = Boolean(
object && Object.getOwnPropertyDescriptor(object, property)
object && Object.getOwnPropertyDescriptor(object, property),
);

@@ -22,2 +44,4 @@

return descriptor;
};
}
module.exports = getPropertyDescriptor;

@@ -10,3 +10,3 @@ "use strict";

return Boolean(
object && typeof property !== "undefined" && !(property in object)
object && typeof property !== "undefined" && !(property in object),
);

@@ -13,0 +13,0 @@ }

@@ -22,3 +22,3 @@ "use strict";

throw new Error(
`Trying to ${name} object but received ${String(object)}`
`Trying to ${name} object but received ${String(object)}`,
);

@@ -49,3 +49,3 @@ }

throw new Error(
`Found no methods on object to which we could apply mutations`
`Found no methods on object to which we could apply mutations`,
);

@@ -52,0 +52,0 @@ }

@@ -53,3 +53,3 @@ "use strict";

throw new TypeError(
"Method wrapper should be a function or a property descriptor"
"Method wrapper should be a function or a property descriptor",
);

@@ -64,4 +64,4 @@ }

`Attempted to wrap ${typeof wrappedMethod} property ${valueToString(
property
)} as function`
property,
)} as function`,
);

@@ -71,4 +71,4 @@ } else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {

`Attempted to wrap ${valueToString(
property
)} which is already wrapped`
property,
)} which is already wrapped`,
);

@@ -79,4 +79,4 @@ } else if (wrappedMethod.calledBefore) {

`Attempted to wrap ${valueToString(
property
)} which is already ${verb}`
property,
)} which is already ${verb}`,
);

@@ -116,3 +116,3 @@ }

error = new TypeError(
`Attempted to wrap ${typeof wrappedMethod} property ${property} as function`
`Attempted to wrap ${typeof wrappedMethod} property ${property} as function`,
);

@@ -124,3 +124,3 @@ } else if (

error = new TypeError(
`Attempted to wrap ${property} which is already wrapped`
`Attempted to wrap ${property} which is already wrapped`,
);

@@ -127,0 +127,0 @@ }

@@ -11,2 +11,4 @@ "use strict";

* @param globalCtx
*
* @returns {object} the clock, after installing it on the global context, if given
*/

@@ -69,3 +71,3 @@ function createClock(config, globalCtx) {

throw new TypeError(
"useFakeTimers expected epoch or config object. See https://github.com/sinonjs/sinon"
"useFakeTimers expected epoch or config object. See https://github.com/sinonjs/sinon",
);

@@ -72,0 +74,0 @@ };

@@ -18,3 +18,3 @@ {

],
"version": "15.2.0",
"version": "17.0.1",
"homepage": "https://sinonjs.org/",

@@ -37,6 +37,6 @@ "author": "Christian Johansen",

"test-dev": "npm run test-node -- --watch -R min",
"test-headless": "mochify --no-detect-globals --recursive -R dot --grep WebWorker --invert --plugin [ proxyquire-universal ] \"test/**/*-test.js\"",
"test-headless": "mochify --no-detect-globals --recursive -R dot --grep WebWorker --invert \"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 --no-detect-globals --https-server 8080 --no-request-interception test/webworker/webworker-support-assessment.js",
"test-webworker": "mochify --no-detect-globals --https-server 0 --no-request-interception test/webworker/webworker-support-assessment.js",
"test-esm-support": "mocha test/es2015/module-support-assessment-test.mjs",

@@ -49,5 +49,6 @@ "check-esm-bundle-runs-in-browser": "node test/es2015/check-esm-bundle-is-runnable.js",

"build": "node ./build.cjs",
"dev-docs": "cd docs; rsync -r --delete release-source/ releases/dev; npm run serve-docs",
"build-docs": "cd docs; bundle exec jekyll build",
"serve-docs": "cd docs; bundle exec jekyll serve --incremental --verbose",
"lint": "eslint --max-warnings 99 '**/*.{js,cjs,mjs}'",
"serve-docs": "cd docs; bundle exec jekyll serve --incremental --verbose --livereload",
"lint": "eslint --max-warnings 0 '**/*.{js,cjs,mjs}'",
"unimported": "unimported .",

@@ -74,3 +75,3 @@ "pretest-webworker": "npm run build",

"lint-staged": {
"*.{js,css,md}": "prettier --check",
"**/*.{js,css,md}": "prettier --write",
"*.js": "eslint --quiet",

@@ -81,13 +82,13 @@ "*.mjs": "eslint --quiet --ext mjs --parser-options=sourceType:module"

"@sinonjs/commons": "^3.0.0",
"@sinonjs/fake-timers": "^10.3.0",
"@sinonjs/fake-timers": "^11.2.2",
"@sinonjs/samsam": "^8.0.0",
"diff": "^5.1.0",
"nise": "^5.1.4",
"nise": "^5.1.5",
"supports-color": "^7.2.0"
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@sinonjs/eslint-config": "^4.0.6",
"@babel/core": "^7.23.2",
"@sinonjs/eslint-config": "^4.1.0",
"@sinonjs/eslint-plugin-no-prototype-methods": "^0.1.1",
"@sinonjs/referee": "^10.0.0",
"@sinonjs/referee": "^10.0.1",
"@studio/changes": "^2.2.0",

@@ -99,16 +100,12 @@ "babel-plugin-istanbul": "^6.1.1",

"dependency-check": "^4.1.0",
"husky": "^6.0.0",
"lint-staged": "^13.2.0",
"lint-staged": "^15.0.2",
"mocha": "^10.2.0",
"mochify": "^9.2.0",
"nyc": "^15.1.0",
"prettier": "^2.8.4",
"proxyquire": "^2.1.3",
"proxyquire-universal": "^3.0.1",
"proxyquireify": "^3.2.1",
"puppeteer": "^19.7.4",
"rimraf": "^4.4.0",
"semver": "^7.3.8",
"prettier": "^3.0.3",
"puppeteer": "^21.4.0",
"rimraf": "^5.0.5",
"semver": "^7.5.4",
"shelljs": "^0.8.5",
"unimported": "^1.26.0"
"unimported": "^1.30.0"
},

@@ -145,8 +142,3 @@ "files": [

"mode": "auto"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc