panel — open-source game server manager (public release)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 19:19:43 -07:00
commit 658bda1d24
2160 changed files with 300413 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
package module
import (
"path/filepath"
"regexp"
"testing"
)
// TestAllManifestsLoadAndEventRegexesCompile is the repo-wide consistency
// gate for module manifests: every modules/<id>/module.yaml must LoadDir
// cleanly, and every declared events regex must compile under Go's RE2
// engine (AMPTemplates uses .NET (?<n>) syntax — these must have been
// converted to (?P<n>)) and carry at least one named capture group the
// agent's tracker actually reads (see agent/internal/state/tracker.go
// OnLogLine: name/player_name, id-family, msg/detail/reason).
func TestAllManifestsLoadAndEventRegexesCompile(t *testing.T) {
dir := filepath.Join("..", "..", "modules")
manifests, err := LoadDir(dir)
if err != nil {
t.Fatalf("LoadDir(%s): %v", dir, err)
}
if len(manifests) < 20 {
t.Fatalf("expected >=20 manifests, got %d — wrong dir?", len(manifests))
}
// Group names the tracker extracts (tracker.go firstGroup calls).
known := map[string]bool{
"name": true, "player_name": true,
"platform_id": true, "owner": true, "cross_id": true, "id": true, "player_id": true,
"msg": true, "detail": true, "reason": true,
}
validKinds := map[string]bool{"join": true, "leave": true, "chat": true, "death": true, "custom": true}
for _, m := range manifests {
m := m
t.Run(m.ID, func(t *testing.T) {
for evName, ev := range m.Events {
re, err := regexp.Compile(ev.Pattern)
if err != nil {
t.Errorf("event %q: pattern does not compile: %v", evName, err)
continue
}
if !validKinds[ev.Kind] {
t.Errorf("event %q: unknown kind %q", evName, ev.Kind)
}
// Every event must expose at least one group the tracker
// knows how to read, otherwise the event emits empty
// PlayerName/PlayerId/Detail and is a silently-useless knob.
got := false
for _, g := range re.SubexpNames() {
if known[g] {
got = true
}
}
if !got {
t.Errorf("event %q: no tracker-known named group (want one of name/id/msg families); groups=%v", evName, re.SubexpNames())
}
// join/leave should identify the player by name or id.
if ev.Kind == "join" || ev.Kind == "leave" {
hasIdent := false
for _, g := range re.SubexpNames() {
if g == "name" || g == "player_name" || g == "id" || g == "platform_id" || g == "player_id" || g == "owner" || g == "cross_id" {
hasIdent = true
}
}
if !hasIdent {
t.Errorf("event %q (kind %s): no player-identifying named group", evName, ev.Kind)
}
}
}
})
}
}