mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
49 lines
1.7 KiB
TypeScript
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);
|
|
});
|
|
});
|