70 lines
2.3 KiB
TypeScript
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);
|
|
});
|
|
});
|