type StubGlobal = (name: PropertyKey, value: unknown) => void; interface GlobalMockParams { fn: unknown>(implementation?: T) => T; stubGlobal?: StubGlobal; } const defaultStubGlobal: StubGlobal = (name, value) => { Object.defineProperty(globalThis, name, { value, writable: true, enumerable: true, configurable: true, }); }; export function mockMatchMedia({ fn, stubGlobal = defaultStubGlobal }: GlobalMockParams) { stubGlobal( 'matchMedia', fn((query) => { const matches = /^\(min-width: (\d+)px\)$/u.exec(query); const minWidth = matches != null ? Number(matches[1]) : undefined; return { matches: minWidth != null ? window.innerWidth >= minWidth : false, media: query, onchange: null, addListener: fn(), removeListener: fn(), addEventListener: fn(), removeEventListener: fn(), dispatchEvent: fn(), }; }), ); } export function mockResizeObserver({ fn, stubGlobal = defaultStubGlobal }: GlobalMockParams) { stubGlobal( 'ResizeObserver', fn( (): ResizeObserver => ({ observe: fn(), unobserve: fn(), disconnect: fn(), }), ), ); } export function mockRequestAnimationFrame() { global.requestAnimationFrame = (callback: (time: number) => void): number => { callback(performance.now()); return 0; }; }