Study/src/lib/progressNormalization.test.ts

70 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { normalizeProgress } from "./progressNormalization";
const isGrade = (value: unknown): value is "correct" | "missed" =>
value === "correct" || value === "missed";
function normalize(order: string[], currentIndex: number, liveIds: string[]) {
return normalizeProgress({
orderJson: JSON.stringify(order),
currentIndex,
dataJson: JSON.stringify({ a: "correct", deleted: "missed" }),
liveIds,
isValidValue: isGrade,
});
}
describe("normalizeProgress", () => {
it("preserves the logical current card when a prior card was deleted", () => {
expect(normalize(["a", "b", "c"], 1, ["b", "c"]).currentIndex).toBe(0);
});
it("uses the next survivor when the current card was deleted", () => {
expect(normalize(["a", "b", "c"], 1, ["a", "c"]).currentIndex).toBe(1);
});
it("uses the previous survivor when no later card remains", () => {
expect(normalize(["a", "b", "c"], 2, ["a", "b"]).currentIndex).toBe(1);
});
it("preserves completed state after stale IDs are removed", () => {
const result = normalize(["a", "b", "c"], 3, ["a", "c"]);
expect(result.currentIndex).toBe(2);
expect(result.completed).toBe(true);
});
it("recovers malformed JSON and filters stale result keys", () => {
const result = normalizeProgress({
orderJson: "not-json",
currentIndex: -1,
dataJson: '{"a":"correct","b":"invalid"}',
liveIds: ["a", "b"],
isValidValue: isGrade,
});
expect(result).toMatchObject({
order: ["a", "b"],
currentIndex: 0,
data: { a: "correct" },
completed: false,
wasRecovered: true,
});
});
it("returns a clear completed state when all saved cards were deleted", () => {
const result = normalize(["deleted"], 0, []);
expect(result).toMatchObject({ order: [], currentIndex: 0, completed: true });
});
it("lets content-specific validation reject a value owned by another item", () => {
const result = normalizeProgress({
orderJson: '["q1","q2"]',
currentIndex: 0,
dataJson: '{"q1":["q2-option"]}',
liveIds: ["q1", "q2"],
isValidValue: (value, id): value is string[] =>
Array.isArray(value) && value.every((optionId) => optionId === `${id}-option`),
});
expect(result.data).toEqual({});
expect(result.wasRecovered).toBe(true);
});
});