Establishes frontend unit testing infra (jsdom env, RTL, jest-dom matchers, common Radix/jsdom polyfills) and seeds it with tests for lib/utils.ts, lib/photo-utils.ts, hooks/useFocusTrap.ts, and ThemeToggle.tsx (46 tests total).
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import '@testing-library/jest-dom/vitest';
|
|
|
|
// jsdom doesn't implement these, but Radix UI primitives (Tooltip, Popover,
|
|
// Select, etc.) call them during mount/positioning. Stub them out so
|
|
// component tests don't have to know about Radix's internals.
|
|
if (typeof window.matchMedia !== 'function') {
|
|
window.matchMedia = (query: string) => ({
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: () => {},
|
|
removeListener: () => {},
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
dispatchEvent: () => false,
|
|
}) as unknown as MediaQueryList;
|
|
}
|
|
|
|
if (typeof (globalThis as any).ResizeObserver === 'undefined') {
|
|
class ResizeObserverStub {
|
|
observe() {}
|
|
unobserve() {}
|
|
disconnect() {}
|
|
}
|
|
(globalThis as any).ResizeObserver = ResizeObserverStub;
|
|
}
|
|
|
|
for (const method of ['hasPointerCapture', 'setPointerCapture', 'releasePointerCapture'] as const) {
|
|
if (!(method in Element.prototype)) {
|
|
Object.defineProperty(Element.prototype, method, {
|
|
value: () => false,
|
|
writable: true,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (!('scrollIntoView' in Element.prototype)) {
|
|
Object.defineProperty(Element.prototype, 'scrollIntoView', {
|
|
value: () => {},
|
|
writable: true,
|
|
});
|
|
}
|
|
|
|
// jsdom never computes layout, so its native `offsetParent` getter always
|
|
// returns null. Code that uses it as a "is this element visible?" check
|
|
// (e.g. useFocusTrap's focusable-element filter) would otherwise treat
|
|
// everything as hidden. Override it to approximate "visible" as "attached
|
|
// to the document" instead.
|
|
Object.defineProperty(HTMLElement.prototype, 'offsetParent', {
|
|
get() {
|
|
return this.parentNode;
|
|
},
|
|
configurable: true,
|
|
});
|