52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import { describe, it } from "@suaveplan/testing/runner";
|
|
import * as fc from "fast-check";
|
|
import { createCommand, executeCommand } from "../../src/command/command.js";
|
|
import { CommandMerger } from "../../src/merge/command-merger.js";
|
|
|
|
interface Counter {
|
|
value: number;
|
|
}
|
|
|
|
describe("property: CommandMerger merge associativity", () => {
|
|
it("merged command executes to same state as executing individually", {
|
|
timeout: 30000,
|
|
}, () => {
|
|
fc.assert(
|
|
fc.property(
|
|
fc.array(fc.integer({ min: 1, max: 10 }), {
|
|
minLength: 1,
|
|
maxLength: 15,
|
|
}),
|
|
(deltas) => {
|
|
const commands = deltas.map((d) =>
|
|
createCommand<Counter>(
|
|
"Inc",
|
|
(s) => ({ value: s.value + d }),
|
|
(s) => ({ value: s.value - d })
|
|
)
|
|
);
|
|
|
|
// Execute individually
|
|
let individual: Counter = { value: 0 };
|
|
for (const cmd of commands) {
|
|
individual = executeCommand(individual, cmd);
|
|
}
|
|
|
|
// Merge all then execute
|
|
const m = new CommandMerger<Counter>({
|
|
maxCount: commands.length + 1,
|
|
});
|
|
for (const cmd of commands) m.add(cmd);
|
|
const merged = m.flush();
|
|
const mergedResult = merged
|
|
? executeCommand({ value: 0 }, merged)
|
|
: { value: 0 };
|
|
|
|
return mergedResult.value === individual.value;
|
|
}
|
|
),
|
|
{ numRuns: 200 }
|
|
);
|
|
});
|
|
});
|