Unit test coverage: wands/staves (game/sticks.go, 534 lines, one test) #6
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
game/sticks.gois the largest under-tested file in the repo: 534 lines,23 functions, and exactly one test (
TestZapSlowMonster). Every other zapeffect, the bolt-bouncing geometry, and the level-drain logic are untested.
Second of three units splitting the
TODO.mdNext Step into commit-sizedpieces.
Untested surface
Per-effect handlers, all unexercised except speed/slow:
zapLight,zapDrainLife,zapInvisibility,zapPolymorph,zapCancellation,zapTeleport,zapMagicMissile,zapBolt.Supporting logic, all unexercised:
fireBolt— bolt propagation, the highest-risk code here.boltDirChar/boltBounces— the/,\,|,-glyph selection andthe wall-bounce reflection rules. Pure geometry over a direction vector;
cheap to test exhaustively and easy to get subtly wrong.
boltStrikesMonster/boltStrikesHero— including the case where abounced bolt hits the player who fired it.
drain/drainReaches— which monsters are in range for drain-life,including the in-passage and cross-room cases.
fixStick,chargeStr— charge accounting and display.Definition of done
game/sticks_test.gocovering, at minimum:boltDirCharfor all eight direction vectors.boltBouncesfor the reflection cases in both wall orientations,including a corner.
fireBoltthrough a constructed level assertingthe path taken and the final resting position.
drainReachesfor: same room, different room, in-passage.(e.g.
zapPolymorphreplaces the monster type;zapCancellationclearsthe monster's special flags;
zapTeleportmoves the target).fixStickcharge accounting andchargeStroutput for a known and anunknown stick.
existing tests' pattern.
make checkfully green.TODO.mdupdated in the same commit (narrow the Next Step; do not mark itcomplete — the wizard-command third remains).
(closes #N).Implementation requirements
(
git show origin/c-master:sticks.c). Do NOT check out or modifyorigin/c-master. Do not simply assert current Go behavior — the value ofthese tests is catching divergence from C, and a test written by reading the
Go code proves nothing.
gameplay in a test-coverage commit and do not encode the bug as expected.
calls
os.Exit, which would kill the test binary. Use the existingfortify()-style HP-pinning pattern from the playtest tests where needed.t.Parallel(); keep the lint run at 0 issues.//nolint:testpackage // white-box tests reach unexported state (approved 2026-07-07)header.
maketargets only. Do NOT modify.golangci.yml. No game behavior changes.file is acceptable — but keep it to this one commit.
Implemented in PR #35 (branch
test/sticks-coverage, commitdda90bf).game/sticks_test.goandgame/bolt_test.gocover every item in the definition of done:boltDirCharfor all eight directions,boltBouncesin both wall orientations plus a corner (and diagonally off a wall, which is what separates C's negate-both-components rule from a surface reflection), an end-to-endfireBoltasserting the path and resting square, a bounced bolt striking the hero who fired it,drainReachesfor same-room / other-room / in-passage / door-under-hero, every remaining zap handler with its characteristic state change, andfixStick/chargeStr.TODO.mdhas the Completed Steps entry; theNext Stepwas not rotated, since the wizard-command third (#7) remains.Expectations were read from
git show origin/c-master:sticks.c, not from the Go code. No divergence from C was found, so no game code changed. Two pieces of C archaeology are recorded in the test comments:fire_bolt'sch != 'M'guard on the miss message is a tautology (winatist_disguisewhen a monster stands there,rogue.h57), andzapCancellation'st_disguise = t_typeis an identity for every monster a zap ray can stop on, because a xeroc's item disguise isstep_okand the ray walks past it.Verification:
make checkgreen (fmt-check, golangci-lint 0 issues with a private lint cache,go test -timeout 30s -race -cover), and 27 mutations ofgame/sticks.gowere each shown to make the targeted test fail — including the door-under-hero guard, whose loss makes the test hang rather than fail, which is the only signal it can have. The full breakdown is in the PR comment.