package main import ( "go/ast" "go/parser" "go/token" "strconv" "testing" ) // Astra plan 6 R1 #9: every member-facing string `carlos apps set` adds is a // named constant, so the approved copy record can pin it. In apps_swap.go, the // help text of a flag and the text of an error it prints must be a constant, // never a bare literal. The only literals allowed there are the help // strings shared, word for word, with the other verbs' --account, // --account-id and --console flags: existing copy, not new. func TestAppsSetCopyIsNamedConstants(t *testing.T) { shared := map[string]bool{ "account (sqid or name) the app belongs to (default: your only account, or the configured/chosen one)": true, "account sqid, matched as a sqid ONLY — supersedes --account": true, "console to act through (default: the only logged-in one)": true, } fset := token.NewFileSet() f, err := parser.ParseFile(fset, "apps_swap.go", nil, parser.ParseComments) if err != nil { t.Fatal(err) } // copyArg is which argument of each call is member-facing text. copyArg := map[string]int{"fs.String": 2, "fs.Int": 2, "appFlag": 1, "consoleOption": 1, "fmt.Errorf": 0, "errors.New": 0, "log.Fatal": 0, "log.Fatalf": 0} checked := 0 ast.Inspect(f, func(n ast.Node) bool { call, ok := n.(*ast.CallExpr) if !ok { return true } name := "" switch fn := call.Fun.(type) { case *ast.Ident: name = fn.Name case *ast.SelectorExpr: if x, ok := fn.X.(*ast.Ident); ok { name = x.Name + "." + fn.Sel.Name } } i, ok := copyArg[name] if !ok || i >= len(call.Args) { return true } checked++ pos := fset.Position(call.Pos()) if a, ok := call.Args[i].(*ast.BasicLit); ok { if s, _ := strconv.Unquote(a.Value); !shared[s] { t.Errorf("%s: %s(%s): new copy as a bare literal; make it a named constant", pos, name, a.Value) } } return true }) if checked < 10 { t.Fatalf("only %d copy sites checked in apps_swap.go: the scan is broken", checked) } }