mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Tests: catch up stale assertions to current prod UX
Two tests had been failing on -short for several phases; the
comfortable "pre-existing failures" framing was masking that both
were stale, not flaky — each test predated a deliberate UX rewire
that nobody updated the assertion against.
TestMageSpellbookLineInRender — commit 8bf7d35 (UX S7 jargon sweep)
reshaped the spellbook line to "**Spellbook:** N / M leveled spells
learned" and intentionally dropped the redundant "(can learn N more)"
trailer. Test was still asserting "2/10" (no spaces) and the dropped
hint. Updated to track the live "N / M leveled spells learned"
format; comment cites the sweep commit.
TestAdv2Scenario_ZoneRunGoblinWarrens — commit 886eb5a (turn-based
elite/boss combat) moved Elite/Boss rooms off the auto-resolve
SimulateCombat path onto the manual !fight + !attack engine; !zone
advance now stops at the doorway and only progresses past a won
CombatSession. The scenario test was only calling !advance, so it
spun in place at room 4 (the elite). Loop now detects Elite/Boss
prev-rooms, opens with !fight if the session doesn't exist, drains
!attack rounds until the session terminates, then falls through to
!advance to clear the room (won → walk graph; lost/fled → terminate
next pass). maxSteps doubled to absorb the fight-then-advance pairs;
inner !attack cap at 60 rounds covers RNG tail.
Both -short tests now pass; full -short suite green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -76,10 +76,17 @@ func TestAdv2Scenario_ZoneRunGoblinWarrens(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Drive !zone advance until the run terminates (cleared, died, or
|
// Drive !zone advance until the run terminates (cleared, died, or
|
||||||
// abandoned). When a fork is pending (Phase G branching graphs) auto-pick
|
// abandoned). Branches the test handles:
|
||||||
// the first option via `!zone go 1` so the test doesn't stall on a
|
// - Fork queued (Phase G branching graphs): commit with `!zone go 1`.
|
||||||
// diamond. Doubled iteration cap covers fork-then-advance pairs.
|
// - Elite/Boss doorway (commit 886eb5a moved these off auto-resolve):
|
||||||
maxSteps := (run.TotalRooms + 4) * 2
|
// !advance now stops at the door and the player engages with
|
||||||
|
// !fight, then resolves one round per !attack. The test mirrors
|
||||||
|
// that: call !fight to open the session, !attack until the session
|
||||||
|
// closes, then the next !advance clears the room and walks the
|
||||||
|
// graph. Cap the per-fight !attack loop generously — a real fight
|
||||||
|
// resolves in <20 rounds, but RNG can drag.
|
||||||
|
maxSteps := (run.TotalRooms + 4) * 4
|
||||||
|
const maxAttacksPerFight = 60
|
||||||
clearedRoomTypes := []RoomType{}
|
clearedRoomTypes := []RoomType{}
|
||||||
for step := 0; step < maxSteps; step++ {
|
for step := 0; step < maxSteps; step++ {
|
||||||
before, _ := getActiveZoneRun(uid)
|
before, _ := getActiveZoneRun(uid)
|
||||||
@@ -101,6 +108,31 @@ func TestAdv2Scenario_ZoneRunGoblinWarrens(t *testing.T) {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Elite/Boss doorway: !advance won't progress past the door
|
||||||
|
// without a won CombatSession for the encounter. Open the fight
|
||||||
|
// if it isn't already open, then attack until the session
|
||||||
|
// terminates. After the loop, fall through to !advance — the
|
||||||
|
// won session lets advance clear the room and walk the graph;
|
||||||
|
// a lost/fled session terminates the run on the next pass.
|
||||||
|
if prevType == RoomElite || prevType == RoomBoss {
|
||||||
|
sess, _ := getCombatSessionForEncounter(before.RunID, encounterIDForRoom(before.CurrentRoom))
|
||||||
|
if sess == nil {
|
||||||
|
if err := p.handleFightCmd(MessageContext{Sender: uid}); err != nil {
|
||||||
|
t.Fatalf("zone fight step %d: %v", step, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drain the round loop. handleAttackCmd no-ops if there's no
|
||||||
|
// active session, so the inner loop self-terminates either way.
|
||||||
|
for atk := 0; atk < maxAttacksPerFight; atk++ {
|
||||||
|
active, _ := getActiveCombatSession(uid)
|
||||||
|
if active == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err := p.handleAttackCmd(MessageContext{Sender: uid}); err != nil {
|
||||||
|
t.Fatalf("attack step %d.%d: %v", step, atk, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := p.handleDnDZoneCmd(MessageContext{Sender: uid}, "advance"); err != nil {
|
if err := p.handleDnDZoneCmd(MessageContext{Sender: uid}, "advance"); err != nil {
|
||||||
t.Fatalf("zone advance step %d: %v", step, err)
|
t.Fatalf("zone advance step %d: %v", step, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,11 +175,14 @@ func TestMageSpellbookLineInRender(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out := renderSpellsList(c)
|
out := renderSpellsList(c)
|
||||||
// L3 cap = 10, count = 2.
|
// L3 cap = 10, count = 2. UX S7 jargon sweep (8bf7d35) reshaped
|
||||||
if !strings.Contains(out, "Spellbook:") || !strings.Contains(out, "2/10") {
|
// the line to "**Spellbook:** N / M leveled spells learned" and
|
||||||
|
// dropped the redundant "(can learn N more)" trailer — the
|
||||||
|
// "N / M" already conveys remaining capacity. Assertion tracks
|
||||||
|
// the live format; if the line ever loses the count or the cap
|
||||||
|
// the substrings still pin the regression.
|
||||||
|
if !strings.Contains(out, "**Spellbook:**") ||
|
||||||
|
!strings.Contains(out, "2 / 10 leveled spells learned") {
|
||||||
t.Errorf("renderSpellsList missing/wrong Spellbook line; got\n%s", out)
|
t.Errorf("renderSpellsList missing/wrong Spellbook line; got\n%s", out)
|
||||||
}
|
}
|
||||||
if !strings.Contains(out, "can learn 8 more") {
|
|
||||||
t.Errorf("renderSpellsList missing headroom hint; got\n%s", out)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user