new rpg mode
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { PendingSaveSyncRepository, SAVE_SYNC_RETRY_DELAYS_MS, SaveSyncRetryCoordinator } from "./saveSync";
|
||||
|
||||
function memoryStorage(initial = "[]") {
|
||||
const values = new Map([["i-want-to-heal:saves:pending-sync:v1", initial]]);
|
||||
return {
|
||||
getItem: (key: string) => values.get(key) ?? null,
|
||||
setItem: (key: string, value: string) => { values.set(key, value); },
|
||||
};
|
||||
}
|
||||
|
||||
describe("pending save sync", () => {
|
||||
it("persists unique dirty slots and tolerates corrupt state", () => {
|
||||
const storage = memoryStorage();
|
||||
const pending = new PendingSaveSyncRepository(storage);
|
||||
pending.mark(2);
|
||||
pending.mark(2);
|
||||
pending.mark(1);
|
||||
expect(pending.list()).toEqual([2, 1]);
|
||||
pending.clear(2);
|
||||
expect(pending.list()).toEqual([1]);
|
||||
expect(new PendingSaveSyncRepository(memoryStorage("not-json")).list()).toEqual([]);
|
||||
});
|
||||
|
||||
it("waits offline and caps automatic retries", async () => {
|
||||
const pending = new PendingSaveSyncRepository(memoryStorage());
|
||||
pending.mark(1);
|
||||
let online = false;
|
||||
const uploads: number[] = [];
|
||||
const tasks: Array<{ run: () => void; delay: number }> = [];
|
||||
const coordinator = new SaveSyncRetryCoordinator(
|
||||
pending,
|
||||
async (slotId) => { uploads.push(slotId); return false; },
|
||||
() => online,
|
||||
(run, delay) => {
|
||||
tasks.push({ run, delay });
|
||||
return tasks.length as unknown as ReturnType<typeof setTimeout>;
|
||||
},
|
||||
() => undefined,
|
||||
);
|
||||
|
||||
coordinator.flush();
|
||||
expect(uploads).toEqual([]);
|
||||
online = true;
|
||||
coordinator.flush(true);
|
||||
await Promise.resolve();
|
||||
expect(uploads).toEqual([1]);
|
||||
|
||||
for (const delay of SAVE_SYNC_RETRY_DELAYS_MS) {
|
||||
coordinator.failed(1);
|
||||
expect(tasks[0]?.delay).toBe(delay);
|
||||
tasks.shift()!.run();
|
||||
await Promise.resolve();
|
||||
}
|
||||
coordinator.failed(1);
|
||||
expect(tasks).toEqual([]);
|
||||
expect(uploads).toHaveLength(1 + SAVE_SYNC_RETRY_DELAYS_MS.length);
|
||||
coordinator.dispose();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user