40 lines
1.4 KiB
JavaScript
40 lines
1.4 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { EventLog, ReplayTimeline, SnapshotStore, fnv1a64 } from "./replay.mjs";
|
|
|
|
function buildTimeline() {
|
|
const timeline = new ReplayTimeline();
|
|
timeline.appendEvent(1, 0, "SESSION_READY", {});
|
|
timeline.appendEvent(2, 5, "SIM_STEP", { cycles: 5 });
|
|
timeline.checkpoint(2, 5, { tick: 5, position: 5 });
|
|
timeline.appendEvent(3, 9, "SIM_STEP", { cycles: 4 });
|
|
const base = timeline.snapshots.latest().snapshot_id;
|
|
timeline.checkpoint(3, 9, { tick: 9, position: 9 }, base);
|
|
return timeline;
|
|
}
|
|
|
|
const first = buildTimeline();
|
|
const second = buildTimeline();
|
|
assert.deepEqual(first.export(), second.export());
|
|
const replay = first.replay({ tick: 0, position: 0 }, (state, event) => ({
|
|
tick: event.tick,
|
|
position: state.position + (event.payload.cycles ?? 0),
|
|
}));
|
|
assert.equal(replay.tick, 9);
|
|
assert.equal(replay.state.position, 9);
|
|
assert.equal(replay.state_hash, fnv1a64({ tick: 9, position: 9 }));
|
|
|
|
assert.throws(() => {
|
|
const log = new EventLog();
|
|
log.append(2, 0, "GAP", {});
|
|
}, /event_sequence_gap/);
|
|
|
|
assert.throws(() => {
|
|
const snapshots = new SnapshotStore();
|
|
snapshots.create(1, 1, { tick: 1 }, "snap:missing");
|
|
}, /snapshot_base_missing/);
|
|
|
|
const exported = first.export();
|
|
exported.snapshots.snapshots[0].state_hash = "fnv1a64:0000000000000000";
|
|
assert.throws(() => new ReplayTimeline(exported), /snapshot_hash_mismatch/);
|
|
console.log("replay=passed cursor=" + replay.cursor + " tick=" + replay.tick);
|