Files
AutoZero/tools/read_page_test.go
Sakurasan d5dac5a6fc feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)
llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
2026-10-26 00:54:46 +08:00

106 lines
2.6 KiB
Go

package tools
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)
func readIn(t *testing.T, input string, files map[string]string) (string, error) {
t.Helper()
dir := t.TempDir()
for name, content := range files {
p := filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(p, []byte(content), 0o644); err != nil {
t.Fatal(err)
}
}
reg := NewRegistry()
for _, tl := range BuiltinIn(dir, NewFence(), nil) {
if err := reg.Register(tl); err != nil {
t.Fatal(err)
}
}
r, _ := reg.Get("read")
res, err := r.Run(context.Background(), input)
return res.Text, err
}
// TestReadSmallFileUnchanged:不分页的小文件保持原样,不加头尾。
func TestReadSmallFileUnchanged(t *testing.T) {
got, err := readIn(t, `{"path":"f.txt"}`, map[string]string{"f.txt": "a\nb\nc\n"})
if err != nil {
t.Fatal(err)
}
if got != "a\nb\nc\n" {
t.Fatalf("got %q", got)
}
}
func TestReadOffsetLimit(t *testing.T) {
got, err := readIn(t, `{"path":"f.txt","offset":2,"limit":2}`,
map[string]string{"f.txt": "l1\nl2\nl3\nl4\nl5\n"})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(got, "lines 2-3 of 5") || !strings.Contains(got, "l2\nl3") {
t.Fatalf("got %q", got)
}
if !strings.Contains(got, "continue with offset: 4") {
t.Fatalf("missing continuation: %q", got)
}
if strings.Contains(got, "l1") || strings.Contains(got, "l4") {
t.Fatalf("paging leaked other lines: %q", got)
}
}
func TestReadBeyondEOF(t *testing.T) {
got, err := readIn(t, `{"path":"f.txt","offset":99}`, map[string]string{"f.txt": "a\nb\n"})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(got, "beyond EOF") {
t.Fatalf("got %q", got)
}
}
func TestReadDirectoryListing(t *testing.T) {
got, err := readIn(t, `{"path":".","offset":2,"limit":1}`, map[string]string{
"a.txt": "x",
"sub/b.go": "y",
})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(got, "entries 2-2 of 2") || !strings.Contains(got, "sub/") {
t.Fatalf("got %q", got)
}
if strings.Contains(got, "a.txt") {
t.Fatalf("paging leaked other entries: %q", got)
}
}
func TestReadRejectsBinary(t *testing.T) {
dir := t.TempDir()
p := filepath.Join(dir, "bin")
if err := os.WriteFile(p, []byte{'a', 0, 'b'}, 0o644); err != nil {
t.Fatal(err)
}
reg := NewRegistry()
for _, tl := range BuiltinIn(dir, NewFence(), nil) {
if err := reg.Register(tl); err != nil {
t.Fatal(err)
}
}
r, _ := reg.Get("read")
if _, err := r.Run(context.Background(), `{"path":"bin"}`); err == nil ||
!strings.Contains(err.Error(), "binary") {
t.Fatalf("want binary error, got %v", err)
}
}