UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

89 lines (88 loc) 3.75 kB
import { describe, expect, it, vi } from "vitest"; import { isChunkLoadError, loadWithRetry } from "./dynamicImport.mjs"; const instantDelay = () => Promise.resolve(); const chunkError = () => new Error("Failed to fetch dynamically imported module: /assets/EditorPane.js"); const drain = () => new Promise(r => setTimeout(r, 0)); describe("isChunkLoadError", () => { it("matches the chrome / firefox / safari chunk-load messages, nothing else", () => { expect(isChunkLoadError(new Error("Failed to fetch dynamically imported module: /a"))).toBe(true); expect(isChunkLoadError(new Error("error loading dynamically imported module: /a"))).toBe(true); expect(isChunkLoadError(new Error("Importing a module script failed."))).toBe(true); expect(isChunkLoadError("Failed to fetch dynamically imported module")).toBe(true); expect(isChunkLoadError(new Error("TypeError: x is not a function"))).toBe(false); }); }); describe("loadWithRetry", () => { it("resolves on first success without retrying or recovering", async () => { const loader = vi.fn().mockResolvedValue({ default: "ok" }); const delay = vi.fn(instantDelay); const onChunkErrorExhausted = vi.fn(() => false); await expect(loadWithRetry(loader, { delay, onChunkErrorExhausted })).resolves.toEqual({ default: "ok" }); expect(loader).toHaveBeenCalledTimes(1); expect(delay).not.toHaveBeenCalled(); expect(onChunkErrorExhausted).not.toHaveBeenCalled(); }); it("retries a transient rejection then resolves, re-invoking the loader each attempt", async () => { const loader = vi.fn().mockRejectedValueOnce(chunkError()).mockRejectedValueOnce(chunkError()).mockResolvedValue({ default: "ok" }); const delay = vi.fn(instantDelay); const onChunkErrorExhausted = vi.fn(() => false); await expect(loadWithRetry(loader, { attempts: 3, delay, onChunkErrorExhausted })).resolves.toEqual({ default: "ok" }); expect(loader).toHaveBeenCalledTimes(3); expect(delay).toHaveBeenCalledTimes(2); expect(onChunkErrorExhausted).not.toHaveBeenCalled(); }); it("exhausts retries on a persistent chunk error, recovers once, and stays pending", async () => { const loader = vi.fn().mockRejectedValue(chunkError()); const delay = vi.fn(instantDelay); const onChunkErrorExhausted = vi.fn(() => true); const settled = vi.fn(); void loadWithRetry(loader, { attempts: 2, delay, onChunkErrorExhausted }).then(settled, settled); await drain(); expect(loader).toHaveBeenCalledTimes(3); expect(onChunkErrorExhausted).toHaveBeenCalledTimes(1); expect(settled).not.toHaveBeenCalled(); }); it("rethrows a non-chunk error without recovering", async () => { const loader = vi.fn().mockRejectedValue(new Error("boom: a real bug")); const delay = vi.fn(instantDelay); const onChunkErrorExhausted = vi.fn(() => true); await expect(loadWithRetry(loader, { attempts: 1, delay, onChunkErrorExhausted })).rejects.toThrow("boom: a real bug"); expect(loader).toHaveBeenCalledTimes(2); expect(onChunkErrorExhausted).not.toHaveBeenCalled(); }); it("rethrows a chunk error when the reload was debounced away", async () => { const loader = vi.fn().mockRejectedValue(chunkError()); const delay = vi.fn(instantDelay); const onChunkErrorExhausted = vi.fn(() => false); await expect(loadWithRetry(loader, { attempts: 1, delay, onChunkErrorExhausted })).rejects.toThrow("Failed to fetch dynamically imported module"); expect(onChunkErrorExhausted).toHaveBeenCalledTimes(1); }); }); //# sourceMappingURL=dynamicImport.test.mjs.map