Files
gogobee/internal/plugin/dnd_spell_save_rounding_test.go
prosolis 3369d7d8fe gofmt: bring internal/ and cmd/ back to gofmt -l clean
Mechanical `gofmt -w ./internal ./cmd`. Mostly struct-field realignment that
had drifted, plus a few trailing-newline fixes. No behaviour change — gofmt is
semantics-preserving, and build/vet/test are green either side.

Split out from the code-review fixes that follow so those stay reviewable
instead of hiding inside a wall of realignment.
2026-07-10 07:18:07 -07:00

66 lines
1.8 KiB
Go

package plugin
import "testing"
// Phase 9 SP4 — save-half rounding edge cases.
func TestHalveSavedDamage_Boundaries(t *testing.T) {
cases := []struct{ in, want int }{
{0, 1}, // 0 dmg saved → 1 (floor kicks in even on no-damage spells)
{1, 1}, // 1 / 2 = 0 → floor 1
{2, 1}, // 2 / 2 = 1
{3, 1}, // 3 / 2 = 1 (rounds down)
{10, 5}, // even
{11, 5}, // odd rounds down
{99, 49}, // large odd
{100, 50},
}
for _, c := range cases {
if got := halveSavedDamage(c.in); got != c.want {
t.Errorf("halveSavedDamage(%d) = %d, want %d", c.in, got, c.want)
}
}
}
// TestEnemySpellSaveMod_Scales — heuristic save mod is enemy.AttackBonus / 2.
// Sanity-check that T1-ish (+2..+4) → +1..+2 and T5-ish (+10..+12) → +5..+6.
func TestEnemySpellSaveMod_Scales(t *testing.T) {
cases := []struct {
atk int
want int
}{
{0, 0}, // unstatted enemy
{2, 1}, // T1
{4, 2}, // T2
{6, 3}, // T3
{8, 4}, // T4
{10, 5}, // T5 floor
{12, 6}, // T5 boss
{20, 10}, // outsized boss
}
for _, c := range cases {
enemy := &CombatStats{AttackBonus: c.atk}
if got := enemySpellSaveMod(enemy); got != c.want {
t.Errorf("enemySpellSaveMod(atk=%d) = %d, want %d", c.atk, got, c.want)
}
}
// Monotonic non-decreasing across the range: a stronger enemy should never
// have a worse save mod than a weaker one.
prev := -1
for atk := 0; atk <= 20; atk++ {
got := enemySpellSaveMod(&CombatStats{AttackBonus: atk})
if got < prev {
t.Errorf("save mod regressed at atk=%d: %d < prev %d", atk, got, prev)
}
prev = got
}
}
// TestEnemySpellSaveMod_NilSafe — defensive: nil enemy yields 0 (callers
// should never pass nil, but the helper shouldn't panic).
func TestEnemySpellSaveMod_NilSafe(t *testing.T) {
if got := enemySpellSaveMod(nil); got != 0 {
t.Errorf("nil enemy save mod = %d, want 0", got)
}
}