sinon-test
Version:
<a href="CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Contributor Covenant" /></a>
225 lines (186 loc) • 6.36 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.sinonTest = factory());
})(this, (function () { 'use strict';
/**
* Internal utilities for sinon-test
*/
/**
* From version 3.1 Sinon uses factory methods for sandboxes and deprecates
* sinon.sandbox. It - and its exports - will in time be removed/internalized, but
* we can still support backwards compatibility easily.
* See Sinon pull request #1515
*/
function isOlderSinonVersion(sinonObj) {
return (
typeof sinonObj.createSandbox === "undefined" &&
Boolean(sinonObj.sandbox) &&
typeof sinonObj.sandbox === "object" &&
typeof sinonObj.sandbox.create === "function"
);
}
var isPromise = function (object) {
return typeof object === "object" && typeof object.then === "function";
};
var isSinon = function (obj) {
var isObject = Boolean(obj) && typeof obj === "object";
return (
isObject &&
(isOlderSinonVersion(obj) || typeof obj.createSandbox === "function")
);
};
var utils = {
isPromise: isPromise,
isSinon: isSinon
};
var getConfig = function getConfig(defaultConfig, custom) {
var config = {};
var prop;
var internalCustom = custom || {};
for (prop in defaultConfig) {
if (defaultConfig.hasOwnProperty(prop)) {
config[prop] = internalCustom.hasOwnProperty(prop)
? internalCustom[prop]
: defaultConfig[prop];
}
}
return config;
};
var defaultConfig = {
injectInto: null,
injectIntoThis: true,
properties: [
"spy",
"stub",
"mock",
"clock",
"server",
"requests",
"fake",
"define",
"replace",
"replaceSetter",
"replaceGetter",
"createStubInstance",
],
useFakeTimers: true,
useFakeServer: true,
};
defaultConfig.injectInto;
defaultConfig.injectIntoThis;
defaultConfig.properties;
defaultConfig.useFakeTimers;
defaultConfig.useFakeServer;
const slice = Array.prototype.slice;
function finish(sandbox, error, dontThrow) {
if (error) {
sandbox.restore();
if (dontThrow) {
return;
}
throw error;
}
sandbox.verifyAndRestore();
}
function handleFn(sandbox, result) {
if (result && utils.isPromise(result)) {
return result.then(
function sinonHandlePromiseResolve(value) {
finish(sandbox);
return value;
},
function sinonHandlePromiseReject(error) {
finish(
sandbox,
error || new Error("Promise rejected with no/falsy error")
);
}
);
}
finish(sandbox);
return result;
}
function handleAsyncFn(sandbox, result, isAsync) {
if (result && utils.isPromise(result)) {
if (!isAsync) {
// # issue #75
return handleFn(sandbox, result);
}
finish(
sandbox,
new Error(
"Your test should take a callback *or* return a promise. " +
"It should not do both."
)
);
}
// the function had an arity of 1 or more, but it was not passed a callback
if (!isAsync) {
finish(sandbox);
}
return null;
}
function configure(sinon, config) {
if (!utils.isSinon(sinon)) {
throw new TypeError("expected sinon object");
}
var sandboxFactory = sinon.createSandbox || sinon.sandbox.create;
function callSandboxedFn(context, args, fn, handler) {
var internalConfig = getConfig(defaultConfig, config);
internalConfig.injectInto =
(internalConfig.injectIntoThis && context) ||
internalConfig.injectInto;
var sandbox = sandboxFactory(internalConfig);
var done = args.length && args[args.length - 1];
var result;
if (typeof done === "function") {
args[args.length - 1] = function sinonDone(error) {
finish(sandbox, error, true);
done(error);
};
}
try {
result = fn.apply(context, args.concat(sandbox.args));
} catch (e) {
finish(sandbox, e);
}
return handler(sandbox, result, typeof done === "function");
}
return function test(callback) {
var type = typeof callback;
if (type !== "function") {
throw new TypeError(
`sinon.test needs to wrap a test function, got ${type}`
);
}
return callback.length
? // eslint-disable-next-line no-unused-vars
function sinonAsyncSandboxedTest(_) {
return callSandboxedFn(
this,
slice.call(arguments),
callback,
handleAsyncFn
);
}
: function sinonSandboxedTest() {
return callSandboxedFn(
this,
slice.call(arguments),
callback,
handleFn
);
};
};
}
var configure_1 = configure;
var test = {
configure: configure_1
};
function sinonTest(sinon, config) {
return test.configure(sinon, config);
}
var lib = sinonTest;
return lib;
}));