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) }