Files
my-pi/pi-permission-system/test/async-cache.test.ts

49 lines
1.7 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { memoizeAsyncWithRetry } from "#src/async-cache";
describe("memoizeAsyncWithRetry", () => {
it("invokes the factory once and shares the resolved value across calls", async () => {
const factory = vi.fn<() => Promise<number>>().mockResolvedValue(42);
const memoized = memoizeAsyncWithRetry(factory);
const results = await Promise.all([memoized(), memoized(), memoized()]);
expect(results).toEqual([42, 42, 42]);
expect(factory).toHaveBeenCalledTimes(1);
});
it("caches the same promise instance on success", async () => {
const factory = vi.fn<() => Promise<string>>().mockResolvedValue("parser");
const memoized = memoizeAsyncWithRetry(factory);
await memoized();
await memoized();
expect(factory).toHaveBeenCalledTimes(1);
});
it("surfaces the rejection to the caller each time the factory fails", async () => {
const error = new Error("init failed");
const factory = vi.fn<() => Promise<number>>().mockRejectedValue(error);
const memoized = memoizeAsyncWithRetry(factory);
await expect(memoized()).rejects.toThrow("init failed");
await expect(memoized()).rejects.toThrow("init failed");
});
it("drops a rejected result so the next call re-invokes the factory", async () => {
const factory = vi
.fn<() => Promise<number>>()
.mockRejectedValueOnce(new Error("transient"))
.mockResolvedValue(7);
const memoized = memoizeAsyncWithRetry(factory);
await expect(memoized()).rejects.toThrow("transient");
const recovered = await memoized();
expect(recovered).toBe(7);
expect(factory).toHaveBeenCalledTimes(2);
});
});