Files
mesh-catalog/modules/brother/cmd/brother/declared_test.go
T
jschoubben c4913dbbcb
mesh/merge-gate head c4913dbbcb35 merged into trunk 9daeab209ba4 — pass: builds brother → shanks; no bus step; every machine composes with the change as it…
mesh/repo-check head c4913dbbcb35 merged into trunk 9daeab209ba4 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
Declare scanner.scan's apart argument, so the console lets it through to the tool (issue 1528)
2026-10-21 09:26:11 +02:00

96 lines
2.2 KiB
Go

package main
import (
"go/ast"
"go/parser"
"go/token"
"sort"
"strconv"
"testing"
)
// 1528: a tool reads only arguments its input schema declares; the console refuses an undeclared
// one before it reaches the tool (scanner.scan read apart, which its schema never named).
func TestEveryArgumentAToolReadsIsDeclared(t *testing.T) {
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, "main.go", nil, 0)
if err != nil {
t.Fatal(err)
}
checked := 0
ast.Inspect(f, func(n ast.Node) bool {
lit, ok := n.(*ast.CompositeLit)
if !ok {
return true
}
var name string
var input, run ast.Expr
for _, e := range lit.Elts {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
continue
}
switch k, _ := kv.Key.(*ast.Ident); {
case k == nil:
case k.Name == "Name":
if b, ok := kv.Value.(*ast.BasicLit); ok {
name, _ = strconv.Unquote(b.Value)
}
case k.Name == "Input":
input = kv.Value
case k.Name == "Run":
run = kv.Value
}
}
if name == "" || input == nil || run == nil {
return true
}
declared := map[string]bool{}
ast.Inspect(input, func(m ast.Node) bool {
kv, ok := m.(*ast.KeyValueExpr)
if !ok {
return true
}
if k, ok := kv.Key.(*ast.BasicLit); ok && k.Value == `"properties"` {
if props, ok := kv.Value.(*ast.CompositeLit); ok {
for _, p := range props.Elts {
if pkv, ok := p.(*ast.KeyValueExpr); ok {
if b, ok := pkv.Key.(*ast.BasicLit); ok {
s, _ := strconv.Unquote(b.Value)
declared[s] = true
}
}
}
}
return false
}
return true
})
var missing []string
ast.Inspect(run, func(m ast.Node) bool {
ix, ok := m.(*ast.IndexExpr)
if !ok {
return true
}
if id, ok := ix.X.(*ast.Ident); ok && id.Name == "args" {
if b, ok := ix.Index.(*ast.BasicLit); ok && b.Kind == token.STRING {
s, _ := strconv.Unquote(b.Value)
if !declared[s] {
missing = append(missing, s)
}
}
}
return true
})
checked++
if len(missing) > 0 {
sort.Strings(missing)
t.Errorf("%s reads %v, which its input schema does not declare", name, missing)
}
return false
})
if checked < 5 {
t.Fatalf("checked %d tools; the test no longer finds the tool literals", checked)
}
}