Files
ttrpg-initiative-tracker/scripts
david raistrick 2c997de0da 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.
2026-07-06 18:09:28 -04:00
..

scripts/

Dev orchestration + manual demo tool. NOT test.

dev-start.sh / dev-stop.sh

Local dev stack: backend (:4001, sqlite) + frontend (:3999, server mode). One command. Writes env vars for you. Logs to tmp/server.log, tmp/fe.log.

./scripts/dev-start.sh   # start (idempotent: leaves running ports as-is)
./scripts/dev-stop.sh    # stop both

replay-combat.js

Live backend demo. Drives full combat via server adapter (same contract as App). Player display live-updates. Watch UI react to state changes.

# start backend + frontend first (see docs/DEVELOPMENT.md)
node scripts/replay-combat.js [rounds] [delayMs]
# defaults: 100 rounds, 200ms/step

Coverage per round: damage, heal, all 22 conditions, toggleActive, removeParticipant, addParticipant (reinforcements), updateParticipant, pause/resume, reorderParticipants, endEncounter. Revives dead each round to sustain full round count.

See also

  • tests/audit/ — exploratory bug-finders (manual run, non-deterministic)
  • {shared,server,src}/tests/ — jest unit/integration/characterization
  • scratch/ — gitignored throwaway