Merge pull request 'Declare scanner.scan's apart argument, so several tickets on the glass can be filed apart (issue 1528)' (#401) from fix/1528-apart-argument into main
This commit was merged in pull request #401.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -277,6 +277,7 @@ func tools(settingsFile string, now func() time.Time) []stdio.Tool {
|
||||
"document": map[string]any{"type": "string", "description": "glass only, a document of several pages in one PDF: start opens one and scans its first page; the id of an open document scans the next page into it"},
|
||||
"finish": map[string]any{"type": "boolean", "description": "with document: the id of an open document: close it into one PDF, filed once (nothing is scanned)"},
|
||||
"duplex": map[string]any{"type": "boolean", "description": "feeder only: scan both sides of each sheet (default false)"},
|
||||
"apart": map[string]any{"type": "boolean", "description": "glass only: several documents lying apart on the glass are each filed as their own PDF (default false: one scan of the glass)"},
|
||||
}},
|
||||
Run: func(args map[string]any) (any, error) {
|
||||
s, err := service()
|
||||
|
||||
Reference in New Issue
Block a user