Files
suaveplan/packages/foundation/flow/undo/tests/properties/compress.prop.test.ts
2026-05-27 23:47:53 +01:00

46 lines
1.7 KiB
TypeScript

import { describe, it } from "@suaveplan/testing/runner";
import * as fc from "fast-check";
import { createCommand } from "../../src/command/command.js";
import { compressHistory } from "../../src/compression/history-compressor.js";
import { UndoStack } from "../../src/stack/stack.js";
interface Counter {
value: number;
}
describe("property: compressHistory idempotency", () => {
it("re-compressing does not change state or exceed original size", {
timeout: 30000,
}, () => {
fc.assert(
fc.property(
fc.integer({ min: 0, max: 50 }),
fc.integer({ min: 1, max: 20 }),
(pushCount, depth) => {
const s = new UndoStack<Counter>({ value: 0 });
for (let i = 0; i < pushCount; i++) {
s.push(
createCommand(
"Inc",
(st) => ({ value: st.value + 1 }),
(st) => ({ value: st.value - 1 })
)
);
}
const r1 = compressHistory(s, { compressionDepth: depth });
const r2 = compressHistory(r1.stack, {
compressionDepth: depth,
});
// State preserved
if (r1.stack.current.value !== r2.stack.current.value)
return false;
// Second compression adds no new squashes (all same-label entries already merged)
// Size should not increase
return r2.newSize <= r1.newSize;
}
),
{ numRuns: 200 }
);
});
});