mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-09 01:46:46 +08:00
MUL-6291. Vitest's own breakdown for `@multica/views` showed the shape of the problem: environment 633s and import 644s against only 508s of actual test execution. Two thirds of a cold frontend-test run went on building a jsdom per file and importing its module graph, not on running assertions. - 94 pure-logic `.test.ts` files across views/web/desktop now declare `// @vitest-environment node`. Measured on the 45 converted views files: environment 53.15s -> 4ms, wall 8.72s -> 2.03s. Candidates were picked by module-graph analysis (skipping type-only imports) and rejected when the code under test branches on `typeof window`/`document`, where node would silently take the SSR path and still pass; the remainder were verified empirically and reverted where they failed. - The three jsdom setup files bail out when there is no DOM, so a node-env suite can share them. - schedule-editor: the pure state transitions (isFullDay, displayWindow, timeAnchorOf, defaultAtTime, defaultEveryTime, clampWindow, toggleDay) move out of the component into transitions.ts, with the full combination matrix as a table-driven node-env suite. 34 cases in 3ms, replacing four DOM mounts. - Cross-layer duplicates removed where a canonical layer already owns the matrix: originSourceUrl (skills/lib/origin.test.ts) was re-run through the refresh dialog and the detail page; needsSourceBackfill (core/onboarding/needs-backfill.test.ts) through the backfill modal. Each component keeps one wiring case naming the canonical file. No behaviour change: the transitions extraction is a pure move, and every removal names where the same contract is still covered. Co-authored-by: Bohan-J <[email protected]> Co-authored-by: multica-agent <[email protected]>
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import "@testing-library/jest-dom/vitest";
|
|
import { vi } from "vitest";
|
|
|
|
// Everything below patches gaps in jsdom. Pure-logic suites opt out of jsdom
|
|
// with `// @vitest-environment node` and share this file, so there is no DOM to
|
|
// patch there — bail out rather than guard each stub.
|
|
if (typeof window !== "undefined") {
|
|
// jsdom doesn't provide ResizeObserver; stub it so components that rely on it
|
|
// (e.g. input-otp) can render in tests.
|
|
if (typeof globalThis.ResizeObserver === "undefined") {
|
|
globalThis.ResizeObserver = class ResizeObserver {
|
|
observe() {}
|
|
unobserve() {}
|
|
disconnect() {}
|
|
} as unknown as typeof ResizeObserver;
|
|
}
|
|
|
|
// jsdom doesn't implement elementFromPoint; input-otp uses it internally.
|
|
if (typeof document.elementFromPoint !== "function") {
|
|
document.elementFromPoint = () => null;
|
|
}
|
|
|
|
// jsdom 29 / Node.js 22+ may not provide a proper Web Storage API.
|
|
// Create a proper localStorage mock if methods are missing.
|
|
if (
|
|
typeof globalThis.localStorage === "undefined" ||
|
|
typeof globalThis.localStorage.getItem !== "function"
|
|
) {
|
|
const store: Record<string, string> = {};
|
|
const localStorageMock = {
|
|
getItem: vi.fn((key: string) => store[key] ?? null),
|
|
setItem: vi.fn((key: string, value: string) => {
|
|
store[key] = value;
|
|
}),
|
|
removeItem: vi.fn((key: string) => {
|
|
delete store[key];
|
|
}),
|
|
clear: vi.fn(() => {
|
|
for (const key of Object.keys(store)) {
|
|
delete store[key];
|
|
}
|
|
}),
|
|
get length() {
|
|
return Object.keys(store).length;
|
|
},
|
|
key: vi.fn((index: number) => Object.keys(store)[index] ?? null),
|
|
};
|
|
Object.defineProperty(globalThis, "localStorage", {
|
|
value: localStorageMock,
|
|
writable: true,
|
|
});
|
|
}
|
|
}
|