Ports main.py's _combat_session_delta / _combat_merge_into_lifetime (incl. the documented "offense/defense use latest, additively" quirk) and the combat_stats handler (session delta -> DB-backed lifetime merge -> delete-then-insert of combat_stats + combat_stats_sessions). Read handlers gain the live combat overlay (union live + DB), like Python. Validation: - combat.go `combat-merge` CLI folds snapshots through the accumulator; diffed against the Python functions on identical input -> byte-IDENTICAL. - combat_test.go golden test runs in the build (go test now part of the tracker Dockerfile). - Live: 40 combat lifetime rows + 40 session snapshots + rare_events flowing in dereth_go via the shadow consumer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2 KiB
Go
54 lines
2 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
// Golden values cross-checked against the Python _combat_session_delta /
|
|
// _combat_merge_into_lifetime on identical input (see compare run). Folds two
|
|
// cumulative snapshots; the first is treated as the whole delta.
|
|
func TestCombatMerge(t *testing.T) {
|
|
snap1 := map[string]any{
|
|
"total_damage_given": 100.0, "total_kills": 2.0,
|
|
"monsters": map[string]any{
|
|
"Drudge": map[string]any{
|
|
"name": "Drudge", "kill_count": 2.0, "damage_given": 100.0,
|
|
"offense": map[string]any{"melee": map[string]any{"slashing": map[string]any{
|
|
"total_attacks": 10.0, "max_normal_damage": 15.0,
|
|
}}},
|
|
},
|
|
},
|
|
}
|
|
snap2 := map[string]any{
|
|
"total_damage_given": 250.0, "total_kills": 5.0,
|
|
"monsters": map[string]any{
|
|
"Drudge": map[string]any{
|
|
"name": "Drudge", "kill_count": 4.0, "damage_given": 200.0,
|
|
"offense": map[string]any{"melee": map[string]any{"slashing": map[string]any{
|
|
"total_attacks": 20.0, "max_normal_damage": 18.0,
|
|
}}},
|
|
},
|
|
},
|
|
}
|
|
|
|
lifetime := map[string]any{}
|
|
lifetime = combatMergeIntoLifetime(lifetime, snap1) // first = whole delta
|
|
lifetime = combatMergeIntoLifetime(lifetime, combatSessionDelta(snap2, snap1))
|
|
|
|
if got := num(lifetime["total_kills"]); got != 5 {
|
|
t.Errorf("total_kills = %v, want 5", got)
|
|
}
|
|
if got := num(lifetime["total_damage_given"]); got != 250 {
|
|
t.Errorf("total_damage_given = %v, want 250", got)
|
|
}
|
|
drudge := asMap(asMap(lifetime["monsters"])["Drudge"])
|
|
if got := num(drudge["kill_count"]); got != 4 {
|
|
t.Errorf("Drudge.kill_count = %v, want 4", got)
|
|
}
|
|
slashing := asMap(asMap(asMap(drudge["offense"])["melee"])["slashing"])
|
|
// offense uses the latest snapshot additively (the documented quirk): 10 + 20.
|
|
if got := num(slashing["total_attacks"]); got != 30 {
|
|
t.Errorf("offense slashing total_attacks = %v, want 30 (latest-additive quirk)", got)
|
|
}
|
|
if got := num(slashing["max_normal_damage"]); got != 18 {
|
|
t.Errorf("offense slashing max_normal_damage = %v, want 18 (max)", got)
|
|
}
|
|
}
|