Files
Agent-System/internal/archtest/arch_test.go
T
weichenandCursor 2a75abb39e refactor(bizdev): delete eight locator getters
Composition roots already hold Snapshot ports; the interface and archtest now forbid putting Pool/DocGov/DocRevision/ContextManager/CAS/ProjectWorkflow/FreeformDoc/KB back on Service.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 13:08:25 +00:00

109 lines
2.6 KiB
Go

package archtest
import (
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestArchitectureBoundaries(t *testing.T) {
root, err := ModuleRoot()
if err != nil {
t.Fatal(err)
}
b, err := LoadBoundaries(DefaultBoundariesPath(root))
if err != nil {
t.Fatal(err)
}
findings, err := Scan(ScanOptions{Root: root}, b)
if err != nil {
t.Fatal(err)
}
ev := Evaluate(findings, b, time.Now())
if os.Getenv("ARCHTEST_DUMP") != "" {
t.Log(ev.Report())
}
if ev.Failed() {
t.Fatal(ev.Report())
}
if os.Getenv("ARCHTEST_STRICT") == "" {
return
}
if len(b.BlockKinds) == 0 {
if len(ev.Excepted) > 0 {
t.Fatalf("strict/block mode: %d baseline exceptions remain\n%s", len(ev.Excepted), ev.Report())
}
return
}
for _, f := range ev.Excepted {
for _, kind := range b.BlockKinds {
if f.Kind == kind {
t.Fatalf("strict/block mode: cleared kind %s still has exception %s\n%s", kind, f.Key(), ev.Report())
}
}
}
for _, kind := range b.BlockKinds {
if ev.Counts[kind] > 0 {
t.Fatalf("strict/block mode: cleared kind %s count=%d\n%s", kind, ev.Counts[kind], ev.Report())
}
}
}
var forbiddenBizdevLocators = []string{
"Pool", "DocGov", "DocRevision", "ContextManager", "CAS", "ProjectWorkflow", "FreeformDoc", "KB",
}
func TestBizdevNoLocatorGetters(t *testing.T) {
root, err := ModuleRoot()
if err != nil {
t.Fatal(err)
}
dir := filepath.Join(root, "internal", "bizdev")
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, dir, func(info os.FileInfo) bool {
name := info.Name()
return strings.HasSuffix(name, ".go") && !strings.HasSuffix(name, "_test.go")
}, parser.SkipObjectResolution)
if err != nil {
t.Fatal(err)
}
forbidden := make(map[string]struct{}, len(forbiddenBizdevLocators))
for _, name := range forbiddenBizdevLocators {
forbidden[name] = struct{}{}
}
for _, pkg := range pkgs {
for path, file := range pkg.Files {
for _, decl := range file.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok || fn.Recv == nil || fn.Name == nil {
continue
}
if _, hit := forbidden[fn.Name.Name]; !hit {
continue
}
if !recvIsBizdevService(fn.Recv) {
continue
}
t.Errorf("locator getter %s must not exist on *bizdev.Service (%s)", fn.Name.Name, relFile(root, path))
}
}
}
}
func recvIsBizdevService(recv *ast.FieldList) bool {
if recv == nil || len(recv.List) == 0 {
return false
}
expr := recv.List[0].Type
if star, ok := expr.(*ast.StarExpr); ok {
expr = star.X
}
ident, ok := expr.(*ast.Ident)
return ok && ident.Name == "Service"
}