test: 添加文件操作工具测试,修复 glob 递归匹配
This commit is contained in:
parent
a41c4f3d08
commit
fd003638d6
@ -71,13 +71,35 @@ func (e *Executor) glob(args string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern := filepath.Join(e.workspaceDir, a.Pattern)
|
var result []string
|
||||||
files, err := filepath.Glob(pattern)
|
pattern := a.Pattern
|
||||||
|
|
||||||
|
if strings.HasPrefix(pattern, "**") {
|
||||||
|
baseDir := e.workspaceDir
|
||||||
|
ext := strings.TrimPrefix(pattern, "**/")
|
||||||
|
err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
matched, _ := filepath.Match(ext, info.Name())
|
||||||
|
if matched {
|
||||||
|
abs, _ := filepath.Abs(path)
|
||||||
|
rel, _ := filepath.Rel(e.workspaceDir, abs)
|
||||||
|
result = append(result, rel)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
files, err := filepath.Glob(filepath.Join(e.workspaceDir, pattern))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []string
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
abs, err := filepath.Abs(f)
|
abs, err := filepath.Abs(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -89,6 +111,7 @@ func (e *Executor) glob(args string) (string, error) {
|
|||||||
rel, _ := filepath.Rel(e.workspaceDir, abs)
|
rel, _ := filepath.Rel(e.workspaceDir, abs)
|
||||||
result = append(result, rel)
|
result = append(result, rel)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(result) == 0 {
|
if len(result) == 0 {
|
||||||
return "未找到匹配的文件", nil
|
return "未找到匹配的文件", nil
|
||||||
|
|||||||
118
internal/room/tools/executor_test.go
Normal file
118
internal/room/tools/executor_test.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGlob(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "test.go"), []byte("package test"), 0644)
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "test.ts"), []byte("const x = 1"), 0644)
|
||||||
|
os.MkdirAll(filepath.Join(tmpDir, "sub"), 0755)
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "sub", "nested.go"), []byte("package sub"), 0644)
|
||||||
|
|
||||||
|
exec := NewExecutor(tmpDir)
|
||||||
|
|
||||||
|
result, err := exec.glob(`{"pattern": "*.go"}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !contains(result, "test.go") {
|
||||||
|
t.Errorf("expected test.go in result, got: %s", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err = exec.glob(`{"pattern": "**/*.go"}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !contains(result, "test.go") || !contains(result, "sub/nested.go") {
|
||||||
|
t.Errorf("expected test.go and sub/nested.go, got: %s", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFile(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
content := "line1\nline2\nline3\nline4\nline5"
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte(content), 0644)
|
||||||
|
|
||||||
|
exec := NewExecutor(tmpDir)
|
||||||
|
|
||||||
|
result, err := exec.readFile(`{"filename": "test.txt"}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !contains(result, "line1") {
|
||||||
|
t.Errorf("expected line1 in result, got: %s", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err = exec.readFile(`{"filename": "test.txt", "offset": 1, "limit": 2}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !contains(result, "line2") || !contains(result, "line3") {
|
||||||
|
t.Errorf("expected line2 and line3, got: %s", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEditFile(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "test.txt"), []byte("hello world"), 0644)
|
||||||
|
|
||||||
|
exec := NewExecutor(tmpDir)
|
||||||
|
|
||||||
|
result, err := exec.editFile(`{"filename": "test.txt", "old_string": "world", "new_string": "opencode"}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := os.ReadFile(filepath.Join(tmpDir, "test.txt"))
|
||||||
|
if string(data) != "hello opencode" {
|
||||||
|
t.Errorf("expected 'hello opencode', got: %s", string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = result
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteFile(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
exec := NewExecutor(tmpDir)
|
||||||
|
|
||||||
|
result, err := exec.writeFile(`{"filename": "new.txt", "content": "new content"}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := os.ReadFile(filepath.Join(tmpDir, "new.txt"))
|
||||||
|
if string(data) != "new content" {
|
||||||
|
t.Errorf("expected 'new content', got: %s", string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = result
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListWorkspace(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "a.txt"), []byte("a"), 0644)
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "b.txt"), []byte("b"), 0644)
|
||||||
|
os.MkdirAll(filepath.Join(tmpDir, "sub"), 0755)
|
||||||
|
os.WriteFile(filepath.Join(tmpDir, "sub", "c.txt"), []byte("c"), 0644)
|
||||||
|
|
||||||
|
exec := NewExecutor(tmpDir)
|
||||||
|
|
||||||
|
result, err := exec.listWorkspace()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !contains(result, "a.txt") || !contains(result, "b.txt") || !contains(result, "sub/c.txt") {
|
||||||
|
t.Errorf("expected all files, got: %s", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func contains(s, substr string) bool {
|
||||||
|
return len(s) > 0 && strings.Contains(s, substr)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user