Files

91 lines
2.3 KiB
Go

package event
import (
"go/ast"
"go/parser"
"go/token"
"os"
"strings"
"testing"
)
// TestKnownTypes_ContainsAllTrackConstants is a build-time drift guard.
// It walks event.go's Analytics const block via go/parser + go/ast and
// asserts every `Track*` constant declared there appears in
// event.KnownTypes. Self-deriving means: adding TrackNew requires
// updating ONLY KnownTypes, not also the test. So the test cannot
// itself drift.
//
// If you add a new Track* constant and accidentally forget
// KnownTypes, this test fails. Update KnownTypes and re-run.
func TestKnownTypes_ContainsAllTrackConstants(t *testing.T) {
const srcPath = "event.go"
raw, err := os.ReadFile(srcPath)
if err != nil {
t.Skipf("cannot read %q (running under go test in a different layout) — drift check deferred: %v", srcPath, err)
}
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, srcPath, string(raw), parser.ParseComments)
if err != nil {
t.Fatalf("parser.ParseFile failed: %v", err)
}
var trackConsts []Type
ast.Inspect(file, func(n ast.Node) bool {
gen, ok := n.(*ast.GenDecl)
if !ok || gen.Tok != token.CONST {
return true
}
for _, spec := range gen.Specs {
vs, ok := spec.(*ast.ValueSpec)
if !ok {
continue
}
for i, name := range vs.Names {
if !strings.HasPrefix(name.Name, "Track") {
continue
}
if vs.Values == nil || i >= len(vs.Values) {
continue
}
bl, ok := vs.Values[i].(*ast.BasicLit)
if !ok || bl.Kind != token.STRING {
continue
}
trackConsts = append(trackConsts, Type(strings.Trim(bl.Value, `""`)))
}
}
return true
})
if len(trackConsts) == 0 {
t.Fatalf("AST scan did not find any Track* constants in event.go — check the AST walker or the file layout")
}
for _, c := range KnownTypes {
found := false
for _, tc := range trackConsts {
if tc == c {
found = true
break
}
}
if !found {
t.Errorf("KnownTypes contains %q but the const block in event.go does NOT declare a Track* with that value", string(c))
}
}
for _, tc := range trackConsts {
found := false
for _, c := range KnownTypes {
if c == tc {
found = true
break
}
}
if !found {
t.Errorf("event.go declares Track* = %q but KnownTypes is missing it — add it to KnownTypes and re-run", string(tc))
}
}
}