carlos / platform Public

moves: the serve() wiring test checks the config identity and call order

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev b8c547f79e81526abdda6c2f58dbe9f84215665c parent b09e1d3
1 file changed, +53 −21
  • cmd/console/movesswitch_test.go +53 −21
diff --git a/cmd/console/movesswitch_test.go b/cmd/console/movesswitch_test.go
index 3240f12fd..5fc3f903d 100644
--- a/cmd/console/movesswitch_test.go
+++ b/cmd/console/movesswitch_test.go
@@ -33,36 +33,68 @@ func TestApplyMovesSwitchSetsTheConfigField(t *testing.T) {
}
// serve() is not callable from a test (it opens a database, a bucket and a
-// listener), so this parses main.go and checks that it applies the switch to
-// the config it hands console.NewServer, reading the real environment.
+// listener), so this parses main.go and checks three things: serve() calls
+// applyMovesSwitch(&X, os.Getenv); the same X is the config handed to
+// console.NewServer; and the switch call comes before the NewServer call.
func TestServeAppliesTheMovesSwitchFromTheEnvironment(t *testing.T) {
f, err := parser.ParseFile(token.NewFileSet(), "main.go", nil, 0)
if err != nil {
t.Fatal(err)
}
- found := false
+ var serve *ast.FuncDecl
for _, d := range f.Decls {
- fn, ok := d.(*ast.FuncDecl)
- if !ok || fn.Name.Name != "serve" {
- continue
+ if fn, ok := d.(*ast.FuncDecl); ok && fn.Name.Name == "serve" {
+ serve = fn
}
- ast.Inspect(fn.Body, func(n ast.Node) bool {
- call, ok := n.(*ast.CallExpr)
- if !ok {
- return true
- }
- if id, ok := call.Fun.(*ast.Ident); !ok || id.Name != "applyMovesSwitch" || len(call.Args) != 2 {
- return true
+ }
+ if serve == nil {
+ t.Fatal("no serve() in main.go")
+ }
+ var applies, news []*ast.CallExpr
+ ast.Inspect(serve.Body, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+ switch fun := call.Fun.(type) {
+ case *ast.Ident:
+ if fun.Name == "applyMovesSwitch" {
+ applies = append(applies, call)
}
- if sel, ok := call.Args[1].(*ast.SelectorExpr); ok {
- if pkg, ok := sel.X.(*ast.Ident); ok && pkg.Name == "os" && sel.Sel.Name == "Getenv" {
- found = true
- }
+ case *ast.SelectorExpr:
+ if pkg, ok := fun.X.(*ast.Ident); ok && pkg.Name == "console" && fun.Sel.Name == "NewServer" {
+ news = append(news, call)
}
- return true
- })
+ }
+ return true
+ })
+ if len(applies) != 1 || len(news) != 1 {
+ t.Fatalf("serve() has %d applyMovesSwitch calls and %d console.NewServer calls, want one of each", len(applies), len(news))
}
- if !found {
- t.Fatal("serve() does not call applyMovesSwitch(&cfg, os.Getenv); the switch would never reach the console")
+ apply, ns := applies[0], news[0]
+ if len(apply.Args) != 2 || len(ns.Args) < 1 {
+ t.Fatal("applyMovesSwitch wants (&cfg, os.Getenv) and console.NewServer wants (cfg, store)")
}
+ if sel, ok := apply.Args[1].(*ast.SelectorExpr); !ok || !isIdent(sel.X, "os") || sel.Sel.Name != "Getenv" {
+ t.Fatal("applyMovesSwitch is not given os.Getenv; the switch would not read the real environment")
+ }
+ addr, ok := apply.Args[0].(*ast.UnaryExpr)
+ if !ok || addr.Op != token.AND {
+ t.Fatal("applyMovesSwitch's first argument is not &X")
+ }
+ x, ok := addr.X.(*ast.Ident)
+ if !ok {
+ t.Fatal("applyMovesSwitch's first argument is not the address of a plain variable")
+ }
+ if !isIdent(ns.Args[0], x.Name) {
+ t.Fatalf("console.NewServer is not handed %s, the config applyMovesSwitch changed", x.Name)
+ }
+ if apply.Pos() >= ns.Pos() {
+ t.Fatal("applyMovesSwitch runs after console.NewServer; the server would be built with the switch off")
+ }
+}
+
+func isIdent(e ast.Expr, name string) bool {
+ id, ok := e.(*ast.Ident)
+ return ok && id.Name == name
}