import { describe, expect, it, vi } from "vitest"; import { ResourceCache } from "./resource-cache"; describe("login-owned resource cache", () => { it("shares in-flight work, retains fresh values and retries after expiry", async () => { const clock = vi.spyOn(Date, "now").mockReturnValue(100); const cache = new ResourceCache(); const fetch = vi.fn(async () => ["project-a"]); const first = cache.load("projects", fetch, 60_000); expect(cache.load("projects", fetch, 60_000)).toBe(first); await first; for (let i = 0; i < 10; i++) await cache.load("projects", fetch, 60_000); expect(fetch).toHaveBeenCalledTimes(1); clock.mockReturnValue(60_101); await cache.load("projects", fetch, 60_000); expect(fetch).toHaveBeenCalledTimes(2); clock.mockRestore(); }); it("retains the last content after refresh failure and briefly caches failures", async () => { const cache = new ResourceCache(); cache.set("suggestions", ["原有问题"], 0); const fail = vi.fn(async () => { throw new Error("offline"); }); await expect(cache.load("suggestions", fail, 60_000, { errorTtl: 30_000 })).rejects.toThrow("offline"); await expect(cache.load("suggestions", fail, 60_000)).rejects.toThrow("offline"); expect(cache.peek("suggestions")?.value).toEqual(["原有问题"]); expect(fail).toHaveBeenCalledTimes(1); cache.clear(); expect(cache.peek("suggestions")).toBeUndefined(); }); });