A Metamask fork with Infura removed and default networks editable
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ciphermask/test/lib/wait-until-called.js

67 lines
1.8 KiB

const DEFAULT_TIMEOUT = 10000
/**
* A function that wraps a sinon stub and returns an asynchronous function
* that resolves if the stubbed function was called enough times, or throws
* if the timeout is exceeded.
*
* The stub that has been passed in will be setup to call the wrapped function
* directly.
*
* WARNING: Any existing `callsFake` behavior will be overwritten.
*
* @param {import('sinon').stub} stub - A sinon stub of a function
* @param {unknown} [wrappedThis] - The object the stubbed function was called
* on, if any (i.e. the `this` value)
* @param {Object} [options] - Optional configuration
* @param {number} [options.callCount] - The number of calls to wait for.
* @param {number|null} [options.timeout] - The timeout, in milliseconds. Pass
* in `null` to disable the timeout.
* @returns {Function} An asynchronous function that resolves when the stub is
* called enough times, or throws if the timeout is reached.
*/
function waitUntilCalled(
stub,
wrappedThis = null,
{ callCount = 1, timeout = DEFAULT_TIMEOUT } = {},
) {
let numCalls = 0
let resolve
let timeoutHandle
const stubHasBeenCalled = new Promise((_resolve) => {
resolve = _resolve
if (timeout !== null) {
timeoutHandle = setTimeout(
() => resolve(new Error('Timeout exceeded')),
timeout,
)
}
})
stub.callsFake((...args) => {
try {
if (stub.wrappedMethod) {
stub.wrappedMethod.call(wrappedThis, ...args)
}
} finally {
if (numCalls < callCount) {
numCalls += 1
if (numCalls === callCount) {
if (timeoutHandle) {
clearTimeout(timeoutHandle)
}
resolve()
}
}
}
})
return async () => {
const error = await stubHasBeenCalled
if (error) {
throw error
}
}
}
module.exports = waitUntilCalled