tests: turn.combat.test.js (deterministic RED for BUG-5), deprecate audits
REAL test audit should have been. jest, seeded RNG, mirrors replay-combat.js op sequence exactly. Asserts per-round invariants: rotation-dupe, turnOrder dup-id, currentTurn valid+active, HP bounds. Result: 13 rotation-dupes / 100 rounds. First at round 4 (Cleric twice). Deterministic, reproducible every run. BUG-5 locked. Deprecate tests/audit/*.js: random sim gave false 0-violations while this exact test reproduces bug. Commented early-return. Kept for reference, delete later when log analyzer + unit tests cover ground. TODO: BUG-5 added (mid-round addParticipant/revive corrupts rotation). Root cause hypothesis: computeTurnOrderAfterAddition appends id to turnOrderIds end. Round wrap re-sorts by initiative. currentTurn pointer stale after sort → drifts → nextTurn revisits. Test RED by design (documents live bug). Pre-push will block on push.
This commit is contained in:
@@ -1,4 +1,19 @@
|
||||
// scripts/audit-rotation.js
|
||||
// DEPRECATED — DO NOT USE.
|
||||
// Random simulation gave false 0-violations while replay (exact ops)
|
||||
// reproduced real bugs. Replay-mirror approach = duplicate work.
|
||||
// Kept for now in case parts reusable. Will delete once log analyzer
|
||||
// (scratch/) + unit tests cover the ground.
|
||||
//
|
||||
// Prefer: replay-combat.js dumps turnOrderIds per turn, log analyzer
|
||||
// finds dupes/skips from real run. Unit tests lock confirmed bugs.
|
||||
//
|
||||
// To revive: delete this early-return block below.
|
||||
if (require.main === module) {
|
||||
console.error('audit-rotation.js DEPRECATED. See header comment.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// === original (below) — exploratory rotation audit, kept for reference ===
|
||||
// Pure turn.js simulation of replay op sequence. Detects first round where
|
||||
// rotation breaks (skip or dupe). Prints minimal repro + preceding ops.
|
||||
// No backend, no WS, no sleep. Fast.
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
// scripts/audit-state.js
|
||||
// DEPRECATED — DO NOT USE.
|
||||
// Random simulation gave false 0-violations while replay (exact ops)
|
||||
// reproduced real bugs. Replay-mirror approach = duplicate work.
|
||||
// Kept for now in case parts reusable. Will delete once log analyzer
|
||||
// (scratch/) + unit tests cover the ground.
|
||||
//
|
||||
// Prefer: replay-combat.js dumps turnOrderIds per turn, log analyzer
|
||||
// finds dupes/skips from real run. Unit tests lock confirmed bugs.
|
||||
//
|
||||
// To revive: delete this early-return block below.
|
||||
if (require.main === module) {
|
||||
console.error('audit-state.js DEPRECATED. See header comment.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// === original (below) — exploratory bug-finder, kept for reference ===
|
||||
// Expanded bug-finder: runs combat through pure turn.js, audits invariant
|
||||
// checks per round across multiple bug classes (not just rotation).
|
||||
// NOT a unit test (Math.random, exploratory). Unit tests lock known bugs.
|
||||
@@ -106,6 +121,18 @@ for (let roundN = 1; roundN <= ROUNDS; roundN++) {
|
||||
const dead = e.participants.find(p => p.currentHp <= 0);
|
||||
if (dead) { try { e = { ...e, ...removeParticipant(e, dead.id).patch }; } catch (err) {} }
|
||||
}
|
||||
// mid-round revive: DM reactivates a downed participant's turn (mirrors
|
||||
// replay-combat.js + real play). Triggers same path as revive-between-rounds
|
||||
// but INSIDE rotation — where BUG-5 lives.
|
||||
if (totalTurns % 7 === 0 && totalTurns > 0) {
|
||||
const down = e.participants.find(p => p.currentHp <= 0 || p.isActive === false);
|
||||
if (down) {
|
||||
try {
|
||||
if (down.isActive === false) e = { ...e, ...toggleParticipantActive(e, down.id).patch };
|
||||
e = { ...e, ...applyHpChange(e, down.id, 'heal', down.maxHp).patch };
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
if (totalTurns % 10 === 0 && totalTurns > 0) {
|
||||
const np = makeParticipant({ id: `r${totalTurns}`, name:`R${totalTurns}`, type:'monster', initiative:9, maxHp:100, currentHp:100 });
|
||||
try { e = { ...e, ...addParticipant(e, np).patch }; } catch (err) {}
|
||||
|
||||
Reference in New Issue
Block a user