Archived
81 lines
3.3 KiB
TypeScript
81 lines
3.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { createPiWebReleaseLookupCache } from "./piWebReleaseLookupCache.js";
|
|
|
|
describe("createPiWebReleaseLookupCache", () => {
|
|
it("serves a fresh cached release lookup", async () => {
|
|
let now = 1_000;
|
|
const load = vi.fn(() => Promise.resolve("1.0.0"));
|
|
const cache = createPiWebReleaseLookupCache(load, { ttlMs: 100, now: () => now });
|
|
|
|
await expect(cache.get("0.9.0")).resolves.toMatchObject({ latestVersion: "1.0.0", checkedAtMs: 1_000 });
|
|
now = 1_050;
|
|
await expect(cache.get("0.9.1")).resolves.toMatchObject({ latestVersion: "1.0.0", checkedAtMs: 1_000 });
|
|
|
|
expect(load).toHaveBeenCalledOnce();
|
|
expect(load).toHaveBeenCalledWith("0.9.0");
|
|
});
|
|
|
|
it("bypasses a fresh lookup when forced", async () => {
|
|
let now = 1_000;
|
|
const load = vi.fn()
|
|
.mockResolvedValueOnce("1.0.0")
|
|
.mockResolvedValueOnce("1.1.0");
|
|
const cache = createPiWebReleaseLookupCache(load, { ttlMs: 100, now: () => now });
|
|
|
|
await cache.get("0.9.0");
|
|
now = 1_050;
|
|
|
|
await expect(cache.get("0.9.0", { force: true })).resolves.toMatchObject({ latestVersion: "1.1.0", checkedAtMs: 1_050 });
|
|
await expect(cache.get("0.9.0")).resolves.toMatchObject({ latestVersion: "1.1.0", checkedAtMs: 1_050 });
|
|
expect(load).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it.each(["forced-first", "regular-first"] as const)("does not let an older regular lookup replace a forced result when %s completes", async (completionOrder) => {
|
|
const regular = createDeferred<string>();
|
|
const forced = createDeferred<string>();
|
|
const load = vi.fn()
|
|
.mockImplementationOnce(() => regular.promise)
|
|
.mockImplementationOnce(() => forced.promise);
|
|
const cache = createPiWebReleaseLookupCache(load);
|
|
|
|
const regularLookup = cache.get("0.9.0");
|
|
const forcedLookup = cache.get("0.9.0", { force: true });
|
|
if (completionOrder === "forced-first") {
|
|
forced.resolve("2.0.0");
|
|
await expect(forcedLookup).resolves.toMatchObject({ latestVersion: "2.0.0" });
|
|
regular.resolve("1.0.0");
|
|
await expect(regularLookup).resolves.toMatchObject({ latestVersion: "1.0.0" });
|
|
} else {
|
|
regular.resolve("1.0.0");
|
|
await expect(regularLookup).resolves.toMatchObject({ latestVersion: "1.0.0" });
|
|
forced.resolve("2.0.0");
|
|
await expect(forcedLookup).resolves.toMatchObject({ latestVersion: "2.0.0" });
|
|
}
|
|
|
|
await expect(cache.get("0.9.0")).resolves.toMatchObject({ latestVersion: "2.0.0" });
|
|
expect(load).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it("makes regular callers join a pending forced lookup", async () => {
|
|
const forced = createDeferred<string>();
|
|
const load = vi.fn(() => forced.promise);
|
|
const cache = createPiWebReleaseLookupCache(load);
|
|
|
|
const forcedLookup = cache.get("0.9.0", { force: true });
|
|
const regularLookup = cache.get("0.9.0");
|
|
|
|
expect(regularLookup).toBe(forcedLookup);
|
|
forced.resolve("2.0.0");
|
|
await expect(regularLookup).resolves.toMatchObject({ latestVersion: "2.0.0" });
|
|
expect(load).toHaveBeenCalledOnce();
|
|
});
|
|
});
|
|
|
|
function createDeferred<T>(): { promise: Promise<T>; resolve: (value: T) => void } {
|
|
let resolve: (value: T) => void = () => undefined;
|
|
const promise = new Promise<T>((innerResolve) => {
|
|
resolve = innerResolve;
|
|
});
|
|
return { promise, resolve };
|
|
}
|