1import { describe, expect, it, vi } from "vite-plus/test";
2
3import { clearChunkReloadGuard, reloadOnceForChunkLoadError } from "./chunkReloadGuard";
4
5function createStorageStub(): Storage {
6 const store = new Map<string, string>();
7 return {
8 getItem: (key) => store.get(key) ?? null,
9 setItem: (key, value) => {
10 store.set(key, value);
11 },
12 removeItem: (key) => {
13 store.delete(key);
14 },
15 clear: () => store.clear(),
16 key: (index) => [...store.keys()][index] ?? null,
17 get length() {
18 return store.size;
19 },
20 };
21}
22
23describe("reloadOnceForChunkLoadError", () => {
24 it("reloads on the first failure and lets the second one surface", () => {
25 const storage = createStorageStub();
26 const reload = vi.fn();
27
28 expect(reloadOnceForChunkLoadError(() => storage, reload)).toBe(true);
29 expect(reload).toHaveBeenCalledTimes(1);
30
31 expect(reloadOnceForChunkLoadError(() => storage, reload)).toBe(false);
32 expect(reload).toHaveBeenCalledTimes(1);
33 });
34
35 it("reloads again after a successful boot cleared the guard", () => {
36 const storage = createStorageStub();
37 const reload = vi.fn();
38
39 reloadOnceForChunkLoadError(() => storage, reload);
40 clearChunkReloadGuard(() => storage);
41
42 expect(reloadOnceForChunkLoadError(() => storage, reload)).toBe(true);
43 expect(reload).toHaveBeenCalledTimes(2);
44 });
45
46 it("never reloads when storage is blocked, so a persistent failure cannot loop", () => {
47 const reload = vi.fn();
48 const blocked = () => {
49 throw new DOMException("blocked", "SecurityError");
50 };
51
52 expect(reloadOnceForChunkLoadError(blocked, reload)).toBe(false);
53 expect(reload).not.toHaveBeenCalled();
54 expect(() => clearChunkReloadGuard(blocked)).not.toThrow();
55 });
56});