Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
describe("cache", () => { beforeEach(() => { vi.resetModules(); });
afterEach(() => { vi.useRealTimers(); }); it("bypasses cache when not in browser", async () => { vi.doMock("$app/environment", () => ({ browser: false })); const { cached } = await import("./cache");
const fn = vi.fn().mockResolvedValue("result-1"); const res1 = await cached("test-key", 30_000, fn); const res2 = await cached("test-key", 30_000, fn);
expect(res1).toBe("result-1"); expect(res2).toBe("result-1"); expect(fn).toHaveBeenCalledTimes(2); });
it("caches value in browser and serves from cache before ttl expires", async () => { vi.doMock("$app/environment", () => ({ browser: true })); const { cached } = await import("./cache");
const fn = vi.fn().mockResolvedValue({ hello: "world" }); const res1 = await cached("test-key", 30_000, fn); const res2 = await cached("test-key", 30_000, fn);
expect(res1).toEqual({ hello: "world" }); expect(res2).toEqual({ hello: "world" }); expect(fn).toHaveBeenCalledTimes(1); });
it("refetches after ttl expires", async () => { vi.useFakeTimers(); vi.doMock("$app/environment", () => ({ browser: true })); const { cached } = await import("./cache");
let count = 0; const fn = vi.fn().mockImplementation(async () => ++count);
const res1 = await cached("test-key", 30_000, fn); expect(res1).toBe(1);
vi.advanceTimersByTime(29_999); const res2 = await cached("test-key", 30_000, fn); expect(res2).toBe(1); expect(fn).toHaveBeenCalledTimes(1);
vi.advanceTimersByTime(2); const res3 = await cached("test-key", 30_000, fn); expect(res3).toBe(2); expect(fn).toHaveBeenCalledTimes(2); });
it("cleans up cache and rethrows when loader rejects", async () => { vi.doMock("$app/environment", () => ({ browser: true })); const { cached } = await import("./cache");
const err = new Error("network error"); const fn = vi.fn().mockRejectedValue(err);
await expect(cached("err-key", 30_000, fn)).rejects.toThrow("network error");
fn.mockResolvedValueOnce("recovered"); const res = await cached("err-key", 30_000, fn); expect(res).toBe("recovered"); });
it("clears every key", async () => { vi.doMock("$app/environment", () => ({ browser: true })); const { cached, clear } = await import("./cache");
const fnIssues = vi.fn().mockResolvedValue("issues-data"); const fnPulls = vi.fn().mockResolvedValue("pulls-data");
await cached("issues:did:plc:repo:open:", 30_000, fnIssues); await cached("pulls:did:plc:repo:open:", 30_000, fnPulls);
clear();
await cached("issues:did:plc:repo:open:", 30_000, fnIssues); await cached("pulls:did:plc:repo:open:", 30_000, fnPulls);
expect(fnIssues).toHaveBeenCalledTimes(2); expect(fnPulls).toHaveBeenCalledTimes(2); });
it("invalidate drops one key so the next call reloads", async () => { vi.doMock("$app/environment", () => ({ browser: true })); const { cached, invalidate } = await import("./cache");
const fn = vi.fn().mockResolvedValueOnce("stale").mockResolvedValue("fresh"); await expect(cached("k", 30_000, fn)).resolves.toBe("stale"); invalidate("k"); await expect(cached("k", 30_000, fn)).resolves.toBe("fresh"); expect(fn).toHaveBeenCalledTimes(2); });});