Add unit tests for role middleware
Some checks are pending
Docker Test / test (push) Waiting to run

This commit is contained in:
BibaBot 2026-03-17 07:07:36 +00:00
parent 7a9bf3199a
commit c294e2e9ae
5702 changed files with 465039 additions and 34 deletions

22
node_modules/@jest/fake-timers/LICENSE generated vendored Normal file
View file

@ -0,0 +1,22 @@
MIT License
Copyright (c) Meta Platforms, Inc. and affiliates.
Copyright Contributors to the Jest project.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

117
node_modules/@jest/fake-timers/build/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,117 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {Config} from '@jest/types';
import {StackTraceConfig} from 'jest-message-util';
import {ModuleMocker} from 'jest-mock';
declare type Callback = (...args: Array<unknown>) => void;
export declare class LegacyFakeTimers<TimerRef = unknown> {
#private;
private _cancelledTicks;
private readonly _config;
private _disposed;
private _fakeTimerAPIs;
private _fakingTime;
private readonly _global;
private _immediates;
private readonly _maxLoops;
private readonly _moduleMocker;
private _now;
private _ticks;
private readonly _timerAPIs;
private _timers;
private _uuidCounter;
private readonly _timerConfig;
constructor({
global,
moduleMocker,
timerConfig,
config,
maxLoops,
}: {
global: typeof globalThis;
moduleMocker: ModuleMocker;
timerConfig: TimerConfig<TimerRef>;
config: StackTraceConfig;
maxLoops?: number;
});
clearAllTimers(): void;
dispose(): void;
reset(): void;
now(): number;
runAllTicks(): void;
runAllImmediates(): void;
private _runImmediate;
runAllTimers(): void;
runOnlyPendingTimers(): void;
advanceTimersToNextTimer(steps?: number): void;
advanceTimersByTime(msToRun: number): void;
runWithRealTimers(cb: Callback): void;
useRealTimers(): void;
useFakeTimers(): void;
getTimerCount(): number;
private _checkFakeTimers;
private _createMocks;
private _fakeClearTimer;
private _fakeClearImmediate;
private _fakeNextTick;
private _fakeRequestAnimationFrame;
private _fakeSetImmediate;
private _fakeSetInterval;
private _fakeSetTimeout;
private _getNextTimerHandleAndExpiry;
private _runTimerHandle;
}
export declare class ModernFakeTimers {
private _clock;
private readonly _config;
private _fakingTime;
private readonly _global;
private readonly _fakeTimers;
constructor({
global,
config,
}: {
global: typeof globalThis;
config: Config.ProjectConfig;
});
clearAllTimers(): void;
dispose(): void;
runAllTimers(): void;
runAllTimersAsync(): Promise<void>;
runOnlyPendingTimers(): void;
runOnlyPendingTimersAsync(): Promise<void>;
advanceTimersToNextTimer(steps?: number): void;
advanceTimersToNextTimerAsync(steps?: number): Promise<void>;
advanceTimersByTime(msToRun: number): void;
advanceTimersByTimeAsync(msToRun: number): Promise<void>;
advanceTimersToNextFrame(): void;
runAllTicks(): void;
useRealTimers(): void;
useFakeTimers(fakeTimersConfig?: Config.FakeTimersConfig): void;
reset(): void;
setSystemTime(now?: number | Date): void;
setTimerTickMode(tickModeConfig: {
mode: 'interval' | 'manual' | 'nextAsync';
delta?: number;
}): void;
getRealSystemTime(): number;
now(): number;
getTimerCount(): number;
private _checkFakeTimers;
private _toSinonFakeTimersConfig;
}
declare type TimerConfig<Ref> = {
idToRef: (id: number) => Ref;
refToId: (ref: Ref) => number | void;
};
export {};

731
node_modules/@jest/fake-timers/build/index.js generated vendored Normal file
View file

@ -0,0 +1,731 @@
/*!
* /**
* * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* * This source code is licensed under the MIT license found in the
* * LICENSE file in the root directory of this source tree.
* * /
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/legacyFakeTimers.ts"
(__unused_webpack_module, exports) {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
function _util() {
const data = require("util");
_util = function () {
return data;
};
return data;
}
function _jestMessageUtil() {
const data = require("jest-message-util");
_jestMessageUtil = function () {
return data;
};
return data;
}
function _jestUtil() {
const data = require("jest-util");
_jestUtil = function () {
return data;
};
return data;
}
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/prefer-spread-eventually */
const MS_IN_A_YEAR = 31_536_000_000;
class FakeTimers {
_cancelledTicks;
_config;
_disposed;
_fakeTimerAPIs;
_fakingTime = false;
_global;
_immediates;
_maxLoops;
_moduleMocker;
_now;
_ticks;
_timerAPIs;
_timers;
_uuidCounter;
_timerConfig;
constructor({
global,
moduleMocker,
timerConfig,
config,
maxLoops
}) {
this._global = global;
this._timerConfig = timerConfig;
this._config = config;
this._maxLoops = maxLoops || 100_000;
this._uuidCounter = 1;
this._moduleMocker = moduleMocker;
// Store original timer APIs for future reference
this._timerAPIs = {
cancelAnimationFrame: global.cancelAnimationFrame,
clearImmediate: global.clearImmediate,
clearInterval: global.clearInterval,
clearTimeout: global.clearTimeout,
nextTick: global.process && global.process.nextTick,
requestAnimationFrame: global.requestAnimationFrame,
setImmediate: global.setImmediate,
setInterval: global.setInterval,
setTimeout: global.setTimeout
};
this._disposed = false;
this.reset();
}
clearAllTimers() {
this._immediates = [];
this._timers.clear();
}
dispose() {
this._disposed = true;
this.clearAllTimers();
}
reset() {
this._cancelledTicks = {};
this._now = 0;
this._ticks = [];
this._immediates = [];
this._timers = new Map();
}
now() {
if (this._fakingTime) {
return this._now;
}
return Date.now();
}
runAllTicks() {
this._checkFakeTimers();
// Only run a generous number of ticks and then bail.
// This is just to help avoid recursive loops
let i;
for (i = 0; i < this._maxLoops; i++) {
const tick = this._ticks.shift();
if (tick === undefined) {
break;
}
if (!Object.prototype.hasOwnProperty.call(this._cancelledTicks, tick.uuid)) {
// Callback may throw, so update the map prior calling.
this._cancelledTicks[tick.uuid] = true;
tick.callback();
}
}
if (i === this._maxLoops) {
throw new Error(`Ran ${this._maxLoops} ticks, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
}
}
runAllImmediates() {
this._checkFakeTimers();
// Only run a generous number of immediates and then bail.
let i;
for (i = 0; i < this._maxLoops; i++) {
const immediate = this._immediates.shift();
if (immediate === undefined) {
break;
}
this._runImmediate(immediate);
}
if (i === this._maxLoops) {
throw new Error(`Ran ${this._maxLoops} immediates, and there are still more! Assuming ` + "we've hit an infinite recursion and bailing out...");
}
}
_runImmediate(immediate) {
try {
immediate.callback();
} finally {
this._fakeClearImmediate(immediate.uuid);
}
}
runAllTimers() {
this._checkFakeTimers();
this.runAllTicks();
this.runAllImmediates();
// Only run a generous number of timers and then bail.
// This is just to help avoid recursive loops
let i;
for (i = 0; i < this._maxLoops; i++) {
const nextTimerHandleAndExpiry = this._getNextTimerHandleAndExpiry();
// If there are no more timer handles, stop!
if (nextTimerHandleAndExpiry === null) {
break;
}
const [nextTimerHandle, expiry] = nextTimerHandleAndExpiry;
this._now = expiry;
this._runTimerHandle(nextTimerHandle);
// Some of the immediate calls could be enqueued
// during the previous handling of the timers, we should
// run them as well.
if (this._immediates.length > 0) {
this.runAllImmediates();
}
if (this._ticks.length > 0) {
this.runAllTicks();
}
}
if (i === this._maxLoops) {
throw new Error(`Ran ${this._maxLoops} timers, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
}
}
runOnlyPendingTimers() {
// We need to hold the current shape of `this._timers` because existing
// timers can add new ones to the map and hence would run more than necessary.
// See https://github.com/jestjs/jest/pull/4608 for details
const timerEntries = [...this._timers.entries()];
this._checkFakeTimers();
for (const _immediate of this._immediates) this._runImmediate(_immediate);
for (const [timerHandle, timer] of timerEntries.sort(([, left], [, right]) => left.expiry - right.expiry)) {
this._now = timer.expiry;
this._runTimerHandle(timerHandle);
}
}
advanceTimersToNextTimer(steps = 1) {
if (steps < 1) {
return;
}
const nextExpiry = [...this._timers.values()].reduce((minExpiry, timer) => {
if (minExpiry === null || timer.expiry < minExpiry) return timer.expiry;
return minExpiry;
}, null);
if (nextExpiry !== null) {
this.advanceTimersByTime(nextExpiry - this._now);
this.advanceTimersToNextTimer(steps - 1);
}
}
advanceTimersByTime(msToRun) {
this._checkFakeTimers();
// Only run a generous number of timers and then bail.
// This is just to help avoid recursive loops
let i;
for (i = 0; i < this._maxLoops; i++) {
const timerHandleAndExpiry = this._getNextTimerHandleAndExpiry();
// If there are no more timer handles, stop!
if (timerHandleAndExpiry === null) {
break;
}
const [timerHandle, nextTimerExpiry] = timerHandleAndExpiry;
if (this._now + msToRun < nextTimerExpiry) {
// There are no timers between now and the target we're running to
break;
} else {
msToRun -= nextTimerExpiry - this._now;
this._now = nextTimerExpiry;
this._runTimerHandle(timerHandle);
}
}
// Advance the clock by whatever time we still have left to run
this._now += msToRun;
if (i === this._maxLoops) {
throw new Error(`Ran ${this._maxLoops} timers, and there are still more! ` + "Assuming we've hit an infinite recursion and bailing out...");
}
}
runWithRealTimers(cb) {
const prevClearImmediate = this._global.clearImmediate;
const prevClearInterval = this._global.clearInterval;
const prevClearTimeout = this._global.clearTimeout;
const prevNextTick = this._global.process.nextTick;
const prevSetImmediate = this._global.setImmediate;
const prevSetInterval = this._global.setInterval;
const prevSetTimeout = this._global.setTimeout;
this.useRealTimers();
let cbErr = null;
let errThrown = false;
try {
cb();
} catch (error) {
errThrown = true;
cbErr = error;
}
this._global.clearImmediate = prevClearImmediate;
this._global.clearInterval = prevClearInterval;
this._global.clearTimeout = prevClearTimeout;
this._global.process.nextTick = prevNextTick;
this._global.setImmediate = prevSetImmediate;
this._global.setInterval = prevSetInterval;
this._global.setTimeout = prevSetTimeout;
if (errThrown) {
throw cbErr;
}
}
useRealTimers() {
const global = this._global;
if (typeof global.cancelAnimationFrame === 'function') {
(0, _jestUtil().setGlobal)(global, 'cancelAnimationFrame', this._timerAPIs.cancelAnimationFrame);
}
if (typeof global.clearImmediate === 'function') {
(0, _jestUtil().setGlobal)(global, 'clearImmediate', this._timerAPIs.clearImmediate);
}
(0, _jestUtil().setGlobal)(global, 'clearInterval', this._timerAPIs.clearInterval);
(0, _jestUtil().setGlobal)(global, 'clearTimeout', this._timerAPIs.clearTimeout);
if (typeof global.requestAnimationFrame === 'function') {
(0, _jestUtil().setGlobal)(global, 'requestAnimationFrame', this._timerAPIs.requestAnimationFrame);
}
if (typeof global.setImmediate === 'function') {
(0, _jestUtil().setGlobal)(global, 'setImmediate', this._timerAPIs.setImmediate);
}
(0, _jestUtil().setGlobal)(global, 'setInterval', this._timerAPIs.setInterval);
(0, _jestUtil().setGlobal)(global, 'setTimeout', this._timerAPIs.setTimeout);
global.process.nextTick = this._timerAPIs.nextTick;
this._fakingTime = false;
}
useFakeTimers() {
this._createMocks();
const global = this._global;
if (typeof global.cancelAnimationFrame === 'function') {
(0, _jestUtil().setGlobal)(global, 'cancelAnimationFrame', this._fakeTimerAPIs.cancelAnimationFrame);
}
if (typeof global.clearImmediate === 'function') {
(0, _jestUtil().setGlobal)(global, 'clearImmediate', this._fakeTimerAPIs.clearImmediate);
}
(0, _jestUtil().setGlobal)(global, 'clearInterval', this._fakeTimerAPIs.clearInterval);
(0, _jestUtil().setGlobal)(global, 'clearTimeout', this._fakeTimerAPIs.clearTimeout);
if (typeof global.requestAnimationFrame === 'function') {
(0, _jestUtil().setGlobal)(global, 'requestAnimationFrame', this._fakeTimerAPIs.requestAnimationFrame);
}
if (typeof global.setImmediate === 'function') {
(0, _jestUtil().setGlobal)(global, 'setImmediate', this._fakeTimerAPIs.setImmediate);
}
(0, _jestUtil().setGlobal)(global, 'setInterval', this._fakeTimerAPIs.setInterval);
(0, _jestUtil().setGlobal)(global, 'setTimeout', this._fakeTimerAPIs.setTimeout);
global.process.nextTick = this._fakeTimerAPIs.nextTick;
this._fakingTime = true;
}
getTimerCount() {
this._checkFakeTimers();
return this._timers.size + this._immediates.length + this._ticks.length;
}
_checkFakeTimers() {
if (!this._fakingTime) {
this._global.console.warn('A function to advance timers was called but the timers APIs are not mocked ' + 'with fake timers. Call `jest.useFakeTimers({legacyFakeTimers: true})` ' + 'in this test file or enable fake timers for all tests by setting ' + "{'enableGlobally': true, 'legacyFakeTimers': true} in " + `Jest configuration file.\nStack Trace:\n${(0, _jestMessageUtil().formatStackTrace)(
// eslint-disable-next-line unicorn/error-message
new Error().stack, this._config, {
noStackTrace: false
})}`);
}
}
#createMockFunction(implementation) {
return this._moduleMocker.fn(implementation.bind(this));
}
_createMocks() {
const promisifiableFakeSetTimeout = this.#createMockFunction(this._fakeSetTimeout);
// @ts-expect-error: no index
promisifiableFakeSetTimeout[_util().promisify.custom] = (delay, arg) => new Promise(resolve => promisifiableFakeSetTimeout(resolve, delay, arg));
this._fakeTimerAPIs = {
cancelAnimationFrame: this.#createMockFunction(this._fakeClearTimer),
clearImmediate: this.#createMockFunction(this._fakeClearImmediate),
clearInterval: this.#createMockFunction(this._fakeClearTimer),
clearTimeout: this.#createMockFunction(this._fakeClearTimer),
nextTick: this.#createMockFunction(this._fakeNextTick),
requestAnimationFrame: this.#createMockFunction(this._fakeRequestAnimationFrame),
setImmediate: this.#createMockFunction(this._fakeSetImmediate),
setInterval: this.#createMockFunction(this._fakeSetInterval),
setTimeout: promisifiableFakeSetTimeout
};
}
_fakeClearTimer(timerRef) {
const uuid = this._timerConfig.refToId(timerRef);
if (uuid) {
this._timers.delete(String(uuid));
}
}
_fakeClearImmediate(uuid) {
this._immediates = this._immediates.filter(immediate => immediate.uuid !== uuid);
}
_fakeNextTick(callback, ...args) {
if (this._disposed) {
return;
}
const uuid = String(this._uuidCounter++);
this._ticks.push({
callback: () => callback.apply(null, args),
uuid
});
const cancelledTicks = this._cancelledTicks;
this._timerAPIs.nextTick(() => {
if (!Object.prototype.hasOwnProperty.call(cancelledTicks, uuid)) {
// Callback may throw, so update the map prior calling.
cancelledTicks[uuid] = true;
callback.apply(null, args);
}
});
}
_fakeRequestAnimationFrame(callback) {
return this._fakeSetTimeout(() => {
// TODO: Use performance.now() once it's mocked
callback(this._now);
}, 1000 / 60);
}
_fakeSetImmediate(callback, ...args) {
if (this._disposed) {
return null;
}
const uuid = String(this._uuidCounter++);
this._immediates.push({
callback: () => callback.apply(null, args),
uuid
});
this._timerAPIs.setImmediate(() => {
if (!this._disposed) {
if (this._immediates.some(x => x.uuid === uuid)) {
try {
callback.apply(null, args);
} finally {
this._fakeClearImmediate(uuid);
}
}
}
});
return uuid;
}
_fakeSetInterval(callback, intervalDelay, ...args) {
if (this._disposed) {
return null;
}
if (intervalDelay == null) {
intervalDelay = 0;
}
const uuid = this._uuidCounter++;
this._timers.set(String(uuid), {
callback: () => callback.apply(null, args),
expiry: this._now + intervalDelay,
interval: intervalDelay,
type: 'interval'
});
return this._timerConfig.idToRef(uuid);
}
_fakeSetTimeout(callback, delay, ...args) {
if (this._disposed) {
return null;
}
// eslint-disable-next-line no-bitwise,unicorn/prefer-math-trunc
delay = Number(delay) | 0;
const uuid = this._uuidCounter++;
this._timers.set(String(uuid), {
callback: () => callback.apply(null, args),
expiry: this._now + delay,
interval: undefined,
type: 'timeout'
});
return this._timerConfig.idToRef(uuid);
}
_getNextTimerHandleAndExpiry() {
let nextTimerHandle = null;
let soonestTime = MS_IN_A_YEAR;
for (const [uuid, timer] of this._timers.entries()) {
if (timer.expiry < soonestTime) {
soonestTime = timer.expiry;
nextTimerHandle = uuid;
}
}
if (nextTimerHandle === null) {
return null;
}
return [nextTimerHandle, soonestTime];
}
_runTimerHandle(timerHandle) {
const timer = this._timers.get(timerHandle);
if (!timer) {
// Timer has been cleared - we'll hit this when a timer is cleared within
// another timer in runOnlyPendingTimers
return;
}
switch (timer.type) {
case 'timeout':
this._timers.delete(timerHandle);
timer.callback();
break;
case 'interval':
timer.expiry = this._now + (timer.interval || 0);
timer.callback();
break;
default:
throw new Error(`Unexpected timer type: ${timer.type}`);
}
}
}
exports["default"] = FakeTimers;
/***/ },
/***/ "./src/modernFakeTimers.ts"
(__unused_webpack_module, exports) {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
function _fakeTimers() {
const data = require("@sinonjs/fake-timers");
_fakeTimers = function () {
return data;
};
return data;
}
function _jestMessageUtil() {
const data = require("jest-message-util");
_jestMessageUtil = function () {
return data;
};
return data;
}
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class FakeTimers {
_clock;
_config;
_fakingTime;
_global;
_fakeTimers;
constructor({
global,
config
}) {
this._global = global;
this._config = config;
this._fakingTime = false;
this._fakeTimers = (0, _fakeTimers().withGlobal)(global);
}
clearAllTimers() {
if (this._fakingTime) {
this._clock.reset();
}
}
dispose() {
this.useRealTimers();
}
runAllTimers() {
if (this._checkFakeTimers()) {
this._clock.runAll();
}
}
async runAllTimersAsync() {
if (this._checkFakeTimers()) {
await this._clock.runAllAsync();
}
}
runOnlyPendingTimers() {
if (this._checkFakeTimers()) {
this._clock.runToLast();
}
}
async runOnlyPendingTimersAsync() {
if (this._checkFakeTimers()) {
await this._clock.runToLastAsync();
}
}
advanceTimersToNextTimer(steps = 1) {
if (this._checkFakeTimers()) {
for (let i = steps; i > 0; i--) {
this._clock.next();
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
this._clock.tick(0);
if (this._clock.countTimers() === 0) {
break;
}
}
}
}
async advanceTimersToNextTimerAsync(steps = 1) {
if (this._checkFakeTimers()) {
for (let i = steps; i > 0; i--) {
await this._clock.nextAsync();
// Fire all timers at this point: https://github.com/sinonjs/fake-timers/issues/250
await this._clock.tickAsync(0);
if (this._clock.countTimers() === 0) {
break;
}
}
}
}
advanceTimersByTime(msToRun) {
if (this._checkFakeTimers()) {
this._clock.tick(msToRun);
}
}
async advanceTimersByTimeAsync(msToRun) {
if (this._checkFakeTimers()) {
await this._clock.tickAsync(msToRun);
}
}
advanceTimersToNextFrame() {
if (this._checkFakeTimers()) {
this._clock.runToFrame();
}
}
runAllTicks() {
if (this._checkFakeTimers()) {
// @ts-expect-error needs an upstream fix: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/73943
this._clock.runMicrotasks();
}
}
useRealTimers() {
if (this._fakingTime) {
this._clock.uninstall();
this._fakingTime = false;
}
}
useFakeTimers(fakeTimersConfig) {
if (this._fakingTime) {
this._clock.uninstall();
}
this._clock = this._fakeTimers.install(this._toSinonFakeTimersConfig(fakeTimersConfig));
this._fakingTime = true;
}
reset() {
if (this._checkFakeTimers()) {
const {
now
} = this._clock;
this._clock.reset();
this._clock.setSystemTime(now);
}
}
setSystemTime(now) {
if (this._checkFakeTimers()) {
this._clock.setSystemTime(now);
}
}
setTimerTickMode(tickModeConfig) {
if (this._checkFakeTimers()) {
this._clock.setTickMode(tickModeConfig);
}
}
getRealSystemTime() {
return Date.now();
}
now() {
if (this._fakingTime) {
return this._clock.now;
}
return Date.now();
}
getTimerCount() {
if (this._checkFakeTimers()) {
return this._clock.countTimers();
}
return 0;
}
_checkFakeTimers() {
if (!this._fakingTime) {
this._global.console.warn('A function to advance timers was called but the timers APIs are not replaced ' + 'with fake timers. Call `jest.useFakeTimers()` in this test file or enable ' + "fake timers for all tests by setting 'fakeTimers': {'enableGlobally': true} " + `in Jest configuration file.\nStack Trace:\n${(0, _jestMessageUtil().formatStackTrace)(
// eslint-disable-next-line unicorn/error-message
new Error().stack, this._config, {
noStackTrace: false
})}`);
}
return this._fakingTime;
}
_toSinonFakeTimersConfig(fakeTimersConfig = {}) {
fakeTimersConfig = {
...this._config.fakeTimers,
...fakeTimersConfig
};
const advanceTimeDelta = typeof fakeTimersConfig.advanceTimers === 'number' ? fakeTimersConfig.advanceTimers : undefined;
const toFake = new Set(Object.keys(this._fakeTimers.timers));
if (fakeTimersConfig.doNotFake) for (const nameOfFakeableAPI of fakeTimersConfig.doNotFake) {
toFake.delete(nameOfFakeableAPI);
}
return {
advanceTimeDelta,
loopLimit: fakeTimersConfig.timerLimit || 100_000,
now: fakeTimersConfig.now ?? Date.now(),
shouldAdvanceTime: Boolean(fakeTimersConfig.advanceTimers),
shouldClearNativeTimers: true,
toFake: [...toFake]
};
}
}
exports["default"] = FakeTimers;
/***/ }
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry needs to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;
Object.defineProperty(exports, "__esModule", ({
value: true
}));
Object.defineProperty(exports, "LegacyFakeTimers", ({
enumerable: true,
get: function () {
return _legacyFakeTimers.default;
}
}));
Object.defineProperty(exports, "ModernFakeTimers", ({
enumerable: true,
get: function () {
return _modernFakeTimers.default;
}
}));
var _legacyFakeTimers = _interopRequireDefault(__webpack_require__("./src/legacyFakeTimers.ts"));
var _modernFakeTimers = _interopRequireDefault(__webpack_require__("./src/modernFakeTimers.ts"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
})();
module.exports = __webpack_exports__;
/******/ })()
;

4
node_modules/@jest/fake-timers/build/index.mjs generated vendored Normal file
View file

@ -0,0 +1,4 @@
import cjsModule from './index.js';
export const LegacyFakeTimers = cjsModule.LegacyFakeTimers;
export const ModernFakeTimers = cjsModule.ModernFakeTimers;

View file

@ -0,0 +1,11 @@
Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,423 @@
# `@sinonjs/fake-timers`
[![codecov](https://codecov.io/gh/sinonjs/fake-timers/branch/main/graph/badge.svg)](https://codecov.io/gh/sinonjs/fake-timers)
<a href="CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Contributor Covenant" /></a>
JavaScript implementation of the timer
APIs; `setTimeout`, `clearTimeout`, `setImmediate`, `clearImmediate`, `setInterval`, `clearInterval`, `requestAnimationFrame`, `cancelAnimationFrame`, `requestIdleCallback`,
and `cancelIdleCallback`, along with a clock instance that controls the flow of time. FakeTimers also provides a `Date`
implementation that gets its time from the clock.
In addition in browser environment `@sinonjs/fake-timers` provides a `performance` implementation that gets its time
from the clock. In Node environments FakeTimers provides a `nextTick` implementation that is synchronized with the
clock - and a `process.hrtime` shim that works with the clock.
`@sinonjs/fake-timers` can be used to simulate passing time in automated tests and other
situations where you want the scheduling semantics, but don't want to actually
wait.
`@sinonjs/fake-timers` is an integral part of [Sinon.JS](https://github.com/sinonjs/sinon.js) and targets
the [same runtimes](https://sinonjs.org/releases/latest#compatibility-and-supported-runtimes).
## Autocomplete, IntelliSense and TypeScript definitions
Version 7 introduced JSDoc to the codebase. This should provide autocomplete and type suggestions in supporting IDEs. If
you need more elaborate type support, TypeScript definitions for the Sinon projects are independently maintained by the
Definitely Types community:
```
npm install -D @types/sinonjs__fake-timers
```
## Installation
`@sinonjs/fake-timers` can be used in both Node and browser environments. Installation is as easy as
```sh
npm install @sinonjs/fake-timers
```
If you want to use `@sinonjs/fake-timers` in a browser you can either build your own bundle or
use [Skypack](https://www.skypack.dev).
## Usage
To use `@sinonjs/fake-timers`, create a new clock, schedule events on it using the timer
functions and pass time using the `tick` method.
```js
// In the browser distribution, a global `FakeTimers` is already available
var FakeTimers = require("@sinonjs/fake-timers");
var clock = FakeTimers.createClock();
clock.setTimeout(function () {
console.log(
"The poblano is a mild chili pepper originating in the state of Puebla, Mexico.",
);
}, 15);
// ...
clock.tick(15);
```
Upon executing the last line, an interesting fact about the
[Poblano](https://en.wikipedia.org/wiki/Poblano) will be printed synchronously to
the screen. If you want to simulate asynchronous behavior, please see the `async` function variants (
eg `clock.tick(time)` vs `await clock.tickAsync(time)`).
The `next`, `runAll`, `runToFrame`, and `runToLast` methods are available to advance the clock. See the
API Reference for more details.
### Faking the native timers
When using `@sinonjs/fake-timers` to test timers, you will most likely want to replace the native
timers such that calling `setTimeout` actually schedules a callback with your
clock instance, not the browser's internals.
Calling `install` with no arguments achieves this. You can call `uninstall`
later to restore things as they were again.
Note that in NodeJS the [timers](https://nodejs.org/api/timers.html)
and [timers/promises](https://nodejs.org/api/timers.html#timers-promises-api) modules will also receive fake timers when
using global scope.
```js
// In the browser distribution, a global `FakeTimers` is already available
var FakeTimers = require("@sinonjs/fake-timers");
var clock = FakeTimers.install();
// Equivalent to
// var clock = FakeTimers.install(typeof global !== "undefined" ? global : window);
setTimeout(fn, 15); // Schedules with clock.setTimeout
clock.uninstall();
// setTimeout is restored to the native implementation
```
To hijack timers in another context pass it to the `install` method.
```js
var FakeTimers = require("@sinonjs/fake-timers");
var context = {
setTimeout: setTimeout, // By default context.setTimeout uses the global setTimeout
};
var clock = FakeTimers.withGlobal(context).install();
context.setTimeout(fn, 15); // Schedules with clock.setTimeout
clock.uninstall();
// context.setTimeout is restored to the original implementation
```
Usually you want to install the timers onto the global object, so call `install`
without arguments.
#### Automatically incrementing mocked time
FakeTimers supports the possibility to attach the faked timers to any change
in the real system time. This means that there is no need to `tick()` the
clock in a situation where you won't know **when** to call `tick()`.
Please note that this is achieved using the original setImmediate() API at a certain
configurable interval `config.advanceTimeDelta` (default: 20ms). Meaning time would
be incremented every 20ms, not in real time.
An example would be:
```js
var FakeTimers = require("@sinonjs/fake-timers");
var clock = FakeTimers.install({
shouldAdvanceTime: true,
advanceTimeDelta: 40,
});
setTimeout(() => {
console.log("this just timed out"); //executed after 40ms
}, 30);
setImmediate(() => {
console.log("not so immediate"); //executed after 40ms
});
setTimeout(() => {
console.log("this timed out after"); //executed after 80ms
clock.uninstall();
}, 50);
```
In addition to the above, mocked time can be configured to advance more quickly
using `clock.setTickMode({ mode: "nextAsync" });`. With this mode, the clock
advances to the first scheduled timer and fires it, in a loop. Between each timer,
it will also break the event loop, allowing any scheduled promise
callbacks to execute _before_ running the next one.
## API Reference
### `var clock = FakeTimers.createClock([now[, loopLimit]])`
Creates a clock. The default
[epoch](https://en.wikipedia.org/wiki/Epoch_%28reference_date%29) is `0`.
The `now` argument may be a number (in milliseconds) or a Date object.
The `loopLimit` argument sets the maximum number of timers that will be run when calling `runAll()` before assuming that
we have an infinite loop and throwing an error. The default is `1000`.
### `var clock = FakeTimers.install([config])`
Installs FakeTimers using the specified config (otherwise with epoch `0` on the global scope).
Note that in NodeJS the [timers](https://nodejs.org/api/timers.html)
and [timers/promises](https://nodejs.org/api/timers.html#timers-promises-api) modules will also receive fake timers when
using global scope.
The following configuration options are available
| Parameter | Type | Default | Description |
| -------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config.now` | Number/Date | 0 | installs FakeTimers with the specified unix epoch |
| `config.toFake` | String[] | ["setTimeout", "clearTimeout", "setImmediate", "clearImmediate","setInterval", "clearInterval", "Date", "requestAnimationFrame", "cancelAnimationFrame", "requestIdleCallback", "cancelIdleCallback", "hrtime", "performance"] | an array with explicit function names (or objects, in the case of "performance") to hijack. \_When not set, FakeTimers will automatically fake all methods e.g., `FakeTimers.install({ toFake: ["setTimeout","nextTick"]})` will fake only `setTimeout` and `nextTick` |
| `config.loopLimit` | Number | 1000 | the maximum number of timers that will be run when calling runAll() |
| `config.shouldAdvanceTime` | Boolean | false | tells FakeTimers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change in the real system time) |
| `config.advanceTimeDelta` | Number | 20 | relevant only when using with `shouldAdvanceTime: true`. increment mocked time by `advanceTimeDelta` ms every `advanceTimeDelta` ms change in the real system time. |
| `config.shouldClearNativeTimers` | Boolean | false | tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their respective handlers. These are not cleared by default, leading to potentially unexpected behavior if timers existed prior to installing FakeTimers. |
| `config.ignoreMissingTimers` | Boolean | false | tells FakeTimers to ignore missing timers that might not exist in the given environment |
### `clock.setTickMode(mode)`
Allows configuring how the clock advances time, automatically or manually.
There are 3 different types of modes for advancing timers:
- `{mode: 'manual'}`: Timers do not advance without explicit, manual calls to the tick
APIs (`clock.nextAsync`, `clock.runAllAsync`, etc). This mode is equivalent to `false`.
- `{mode: 'nextAsync'}`: The clock will continuously break the event loop, then run the next timer until the mode changes.
As a result, tests can be written in a way that is independent from whether fake timers are installed.
Tests can always be written to wait for timers to resolve, even when using fake timers.
- `{mode: 'interval', delta?: <number>}`: This is the same as specifying `shouldAdvanceTime: true` with an `advanceTimeDelta`. If the delta is
not specified, 20 will be used by default.
The 'nextAsync' mode differs from `interval` in two key ways:
1. The microtask queue is allowed to empty between each timer execution,
as would be the case without fake timers installed.
1. It advances as quickly and as far as necessary. If the next timer in
the queue is at 1000ms, it will advance 1000ms immediately whereas interval,
without manually advancing time in the test, would take `1000 / advanceTimeDelta`
real time to reach and execute the timer.
### `var id = clock.setTimeout(callback, timeout)`
Schedules the callback to be fired once `timeout` milliseconds have ticked by.
In Node.js `setTimeout` returns a timer object. FakeTimers will do the same, however
its `ref()` and `unref()` methods have no effect.
In browsers a timer ID is returned.
### `clock.clearTimeout(id)`
Clears the timer given the ID or timer object, as long as it was created using
`setTimeout`.
### `var id = clock.setInterval(callback, timeout)`
Schedules the callback to be fired every time `timeout` milliseconds have ticked
by.
In Node.js `setInterval` returns a timer object. FakeTimers will do the same, however
its `ref()` and `unref()` methods have no effect.
In browsers a timer ID is returned.
### `clock.clearInterval(id)`
Clears the timer given the ID or timer object, as long as it was created using
`setInterval`.
### `var id = clock.setImmediate(callback)`
Schedules the callback to be fired once `0` milliseconds have ticked by. Note
that you'll still have to call `clock.tick()` for the callback to fire. If
called during a tick the callback won't fire until `1` millisecond has ticked
by.
In Node.js `setImmediate` returns a timer object. FakeTimers will do the same,
however its `ref()` and `unref()` methods have no effect.
In browsers a timer ID is returned.
### `clock.clearImmediate(id)`
Clears the timer given the ID or timer object, as long as it was created using
`setImmediate`.
### `clock.requestAnimationFrame(callback)`
Schedules the callback to be fired on the next animation frame, which runs every
16 ticks. Returns an `id` which can be used to cancel the callback. This is
available in both browser & node environments.
### `clock.cancelAnimationFrame(id)`
Cancels the callback scheduled by the provided id.
### `clock.requestIdleCallback(callback[, timeout])`
Queued the callback to be fired during idle periods to perform background and low priority work on the main event loop.
Callbacks which have a timeout option will be fired no later than time in milliseconds. Returns an `id` which can be
used to cancel the callback.
### `clock.cancelIdleCallback(id)`
Cancels the callback scheduled by the provided id.
### `clock.countTimers()`
Returns the number of waiting timers. This can be used to assert that a test
finishes without leaking any timers.
### `clock.hrtime(prevTime?)`
Only available in Node.js, mimicks process.hrtime().
### `clock.nextTick(callback)`
Only available in Node.js, mimics `process.nextTick` to enable completely synchronous testing flows.
### `clock.performance.now()`
Only available in browser environments, mimicks performance.now().
### `clock.tick(time)` / `await clock.tickAsync(time)`
Advance the clock, firing callbacks if necessary. `time` may be the number of
milliseconds to advance the clock by or a human-readable string. Valid string
formats are `"08"` for eight seconds, `"01:00"` for one minute and `"02:34:10"`
for two hours, 34 minutes and ten seconds.
The `tickAsync()` will also break the event loop, allowing any scheduled promise
callbacks to execute _before_ running the timers.
### `clock.next()` / `await clock.nextAsync()`
Advances the clock to the the moment of the first scheduled timer, firing it.
The `nextAsync()` will also break the event loop, allowing any scheduled promise
callbacks to execute _before_ running the timers.
### `clock.jump(time)`
Advance the clock by jumping forward in time, firing callbacks at most once.
`time` takes the same formats as [`clock.tick`](#clockticktime--await-clocktickasynctime).
This can be used to simulate the JS engine (such as a browser) being put to sleep and resumed later, skipping
intermediary timers.
### `clock.reset()`
Removes all timers and ticks without firing them, and sets `now` to `config.now`
that was provided to `FakeTimers.install` or to `0` if `config.now` was not provided.
Useful to reset the state of the clock without having to `uninstall` and `install` it.
### `clock.runAll()` / `await clock.runAllAsync()`
This runs all pending timers until there are none remaining. If new timers are added while it is executing they will be
run as well.
This makes it easier to run asynchronous tests to completion without worrying about the number of timers they use, or
the delays in those timers.
It runs a maximum of `loopLimit` times after which it assumes there is an infinite loop of timers and throws an error.
The `runAllAsync()` will also break the event loop, allowing any scheduled promise
callbacks to execute _before_ running the timers.
### `clock.runMicrotasks()`
This runs all pending microtasks scheduled with `nextTick` but none of the timers and is mostly useful for libraries
using FakeTimers underneath and for running `nextTick` items without any timers.
### `clock.runToFrame()`
Advances the clock to the next frame, firing all scheduled animation frame callbacks,
if any, for that frame as well as any other timers scheduled along the way.
### `clock.runToLast()` / `await clock.runToLastAsync()`
This takes note of the last scheduled timer when it is run, and advances the
clock to that time firing callbacks as necessary.
If new timers are added while it is executing they will be run only if they
would occur before this time.
This is useful when you want to run a test to completion, but the test recursively
sets timers that would cause `runAll` to trigger an infinite loop warning.
The `runToLastAsync()` will also break the event loop, allowing any scheduled promise
callbacks to execute _before_ running the timers.
### `clock.setSystemTime([now])`
This simulates a user changing the system clock while your program is running.
It affects the current time but it does not in itself cause e.g. timers to fire;
they will fire exactly as they would have done without the call to
setSystemTime().
### `clock.uninstall()`
Restores the original methods of the native timers or the methods on the object
that was passed to `FakeTimers.withGlobal`
### `Date`
Implements the `Date` object but using the clock to provide the correct time.
### `Performance`
Implements the `now` method of the [`Performance`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)
object but using the clock to provide the correct time. Only available in environments that support the Performance
object (browsers mostly).
### `FakeTimers.withGlobal`
In order to support creating clocks based on separate or sandboxed environments (such as JSDOM), FakeTimers exports a
factory method which takes single argument `global`, which it inspects to figure out what to mock and what features to
support. When invoking this function with a global, you will get back an object with `timers`, `createClock`
and `install` - same as the regular FakeTimers exports only based on the passed in global instead of the global
environment.
## Promises and fake time
If you use a Promise library like Bluebird, note that you should either call `clock.runMicrotasks()` or make sure to
_not_ mock `nextTick`.
## Running tests
FakeTimers has a comprehensive test suite. If you're thinking of contributing bug
fixes or suggesting new features, you need to make sure you have not broken any
tests. You are also expected to add tests for any new behavior.
### On node:
```sh
npm test
```
Or, if you prefer more verbose output:
```
$(npm bin)/mocha ./test/fake-timers-test.js
```
### In the browser
[Mochify](https://github.com/mochify-js) is used to run the tests in headless
Chrome.
```sh
npm test-headless
```
## License
BSD 3-clause "New" or "Revised" License (see LICENSE file)

View file

@ -0,0 +1,78 @@
{
"name": "@sinonjs/fake-timers",
"description": "Fake JavaScript timers",
"version": "15.1.1",
"homepage": "https://github.com/sinonjs/fake-timers",
"author": "Christian Johansen",
"repository": {
"type": "git",
"url": "git+https://github.com/sinonjs/fake-timers.git"
},
"bugs": {
"mail": "christian@cjohansen.no",
"url": "https://github.com/sinonjs/fake-timers/issues"
},
"license": "BSD-3-Clause",
"scripts": {
"lint": "eslint .",
"test-node": "mocha --timeout 200 test/ integration-test/ -R dot --check-leaks",
"test-headless": "mochify --driver puppeteer",
"test-check-coverage": "npm run test-coverage && nyc check-coverage",
"test-cloud": "npm run test-edge && npm run test-firefox && npm run test-safari",
"test-edge": "BROWSER_NAME=MicrosoftEdge mochify --config mochify.webdriver.js",
"test-firefox": "BROWSER_NAME=firefox mochify --config mochify.webdriver.js",
"test-safari": "BROWSER_NAME=safari mochify --config mochify.webdriver.js",
"test-coverage": "nyc -x mochify.webdriver.js -x coverage --all --reporter text --reporter html --reporter lcovonly npm run test-node",
"test": "npm run test-node && npm run test-headless",
"prettier:check": "prettier --check '**/*.{js,css,md}'",
"prettier:write": "prettier --write '**/*.{js,css,md}'",
"preversion": "./scripts/preversion.sh",
"version": "./scripts/version.sh",
"postversion": "./scripts/postversion.sh",
"prepare": "husky"
},
"lint-staged": {
"*.{js,css,md}": "prettier --check",
"*.js": "eslint"
},
"mochify": {
"reporter": "dot",
"timeout": 10000,
"bundle": "esbuild --bundle --sourcemap=inline --define:process.env.NODE_DEBUG=\"\"",
"bundle_stdin": "require",
"spec": "test/**/*-test.js"
},
"files": [
"src/"
],
"devDependencies": {
"@mochify/cli": "^1.0.0",
"@mochify/driver-puppeteer": "^1.0.1",
"@mochify/driver-webdriver": "^1.0.0",
"@sinonjs/eslint-config": "^5.0.4",
"@sinonjs/referee-sinon": "12.0.0",
"esbuild": "^0.27.3",
"husky": "^9.1.7",
"jsdom": "28.1.0",
"lint-staged": "16.3.1",
"mocha": "11.7.5",
"nyc": "18.0.0",
"prettier": "3.8.1"
},
"main": "./src/fake-timers-src.js",
"dependencies": {
"@sinonjs/commons": "^3.0.1"
},
"nyc": {
"branches": 85,
"lines": 92,
"functions": 92,
"statements": 92,
"exclude": [
"**/*-test.js",
"coverage/**",
"types/**",
"fake-timers.js"
]
}
}

File diff suppressed because it is too large Load diff

40
node_modules/@jest/fake-timers/package.json generated vendored Normal file
View file

@ -0,0 +1,40 @@
{
"name": "@jest/fake-timers",
"version": "30.3.0",
"repository": {
"type": "git",
"url": "https://github.com/jestjs/jest.git",
"directory": "packages/jest-fake-timers"
},
"license": "MIT",
"main": "./build/index.js",
"types": "./build/index.d.ts",
"exports": {
".": {
"types": "./build/index.d.ts",
"require": "./build/index.js",
"import": "./build/index.mjs",
"default": "./build/index.js"
},
"./package.json": "./package.json"
},
"dependencies": {
"@jest/types": "30.3.0",
"@sinonjs/fake-timers": "^15.0.0",
"@types/node": "*",
"jest-message-util": "30.3.0",
"jest-mock": "30.3.0",
"jest-util": "30.3.0"
},
"devDependencies": {
"@jest/test-utils": "30.3.0",
"@types/sinonjs__fake-timers": "15.0.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"publishConfig": {
"access": "public"
},
"gitHead": "efb59c2e81083f8dc941f20d6d20a3af2dc8d068"
}