Fix undo/redo forward-state restore, harden test infra, skip-guard

Root cause: mutation writers stored oldValues only. Redo rebuilt from
current state via derived logic — wrong order, wrong content, or no-op.
Undo patched fields in place but ignored roster/array order changes.

Writers now store forward arrays (shared/turn.js):
- addParticipant: newTurnOrderIds, newCurrentTurnParticipantId
- removeParticipant: newTurnOrderIds, newCurrentTurnParticipantId
- updateParticipant: oldTurnOrderIds + newTurnOrderIds (initiative re-slot)
- reorderParticipants: newParticipants + newTurnOrderIds
- damage/heal/deathSave/stabilize/revive/deactivate_dead_monster:
  oldValues + newValues both capture full death state incl conditions

expandUndo redo uses stored forward state instead of deriving:
- add/remove: order via newTurnOrderIds
- update: initiative change re-orders both directions
- reorder: re-applies newParticipants
- death ops: restore via newValues (was HP-only, dropped status/conditions)

Missing expandUndo cases added: stabilize, revive, deactivate_dead_monster
(were default:null -> undo no-op).

Test infra (shared/tests/_helpers.js):
- Mock storage undo() real now: applies patch + flips undone flag (was no-op)
- addDoc persists log entries, getCollection returns them
- undoLast/redoLast harness helpers exercise real mechanism
- Undo tests assert against actual persisted doc, not expandUndo output

turn.undo.test.js rewritten: every op tested as undo->deepEqual before,
redo->deepEqual after-op (12 cases). Was undo-only, redo untested.
turn.deathsave.undo.test.js added: 11 death-path roundtrips.

Dead code removed:
- round-trip.test.js: skipped suite testing deleted replay-from-logs.js
  (5 skipped tests rotting). Coverage gap acknowledged in TODO.

Skip-guard added (scripts/run-tests.sh): pre-flight grep refuses to run
if any .skip/xdescribe/xit found in test dirs. No CI; this is the gate.
This commit is contained in:
david raistrick
2026-07-06 18:09:28 -04:00
parent c80ac6882f
commit 2c997de0da
7 changed files with 556 additions and 202 deletions
+17
View File
@@ -30,6 +30,23 @@ run_suite () {
fi
}
# Pre-flight: refuse to run if any test is skipped/disabled.
# Skipped tests rot silently. Catch them before they hide coverage gaps.
check_for_skips () {
echo "=== skip-guard ==="
local hits
hits=$(grep -rnE '\.(skip|todo)\(|xdescribe\(|xit\(' src/tests shared/tests server/tests 2>/dev/null || true)
if [ -n "$hits" ]; then
echo "FAIL: skipped/disabled tests found:" >&2
echo "$hits" >&2
echo "" >&2
echo "Fix or delete. Do not skip." >&2
exit 1
fi
echo "=== skip-guard: PASS ==="
}
check_for_skips
run_suite "app" "CI=true npx react-scripts test --watchAll=false" 60
run_suite "shared" "npm test --workspace shared" 30
run_suite "server" "npm test --workspace server" 30