nandi/oripublic Fork 0
7895c1d1c9bb1048807dc04f7246dc456c47e025
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

search_test.go · 121 lines · 3.5 KBGo Blame HistoryRaw
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday1package files_test
2
3import (
4 "net/http"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "rickub.com/bots-garden/ori/internal/files"
10)
11
12// searchWorkspace extends the basic tree with nested and noisy directories.
13func searchWorkspace(t *testing.T) (string, http.Handler) {
14 t.Helper()
15 root, h := workspace(t)
16 for _, rel := range []string{
17 "src/server/main_test.go",
18 "docs/guide.md",
19 "node_modules/pkg/index.js",
20 ".git/HEAD",
21 } {
22 full := filepath.Join(root, rel)
23 if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
24 t.Fatal(err)
25 }
26 if err := os.WriteFile(full, []byte("x"), 0o644); err != nil {
27 t.Fatal(err)
28 }
29 }
30 return root, h
31}
32
33func relPaths(hits []files.Hit) []string {
34 out := make([]string, 0, len(hits))
35 for _, h := range hits {
36 out = append(out, h.RelPath)
37 }
38 return out
39}
40
41func TestSearchIsRecursiveAndSkipsNoise(t *testing.T) {
42 root, _ := searchWorkspace(t)
43 hits := files.New(root).Search("", 0)
44 got := relPaths(hits)
45 // Ranked: shorter relative paths first, alphabetical among equals.
46 want := []string{"README.md", "src/main.go", "docs/guide.md", "src/server/main_test.go"}
47 if len(got) != len(want) {
48 t.Fatalf("hits = %v, want %v", got, want)
49 }
50 for i := range want {
51 if got[i] != want[i] {
52 t.Errorf("hit[%d] = %q, want %q", i, got[i], want[i])
53 }
54 }
55 if hits[1].Path != filepath.Join(root, "src", "main.go") || hits[1].Name != "main.go" {
56 t.Errorf("hit = %+v, want absolute path and base name", hits[1])
57 }
58}
59
60func TestSearchFiltersCaseInsensitivelyAndRanksBaseNames(t *testing.T) {
61 root, _ := searchWorkspace(t)
62 cases := []struct {
63 query string
64 want []string
65 }{
66 {"MAIN", []string{"src/main.go", "src/server/main_test.go"}},
67 // "src" matches only through the directory: still found.
68 {"src/", []string{"src/main.go", "src/server/main_test.go"}},
69 {"guide", []string{"docs/guide.md"}},
70 {"nothing-here", []string{}},
71 }
72 for _, tc := range cases {
73 got := relPaths(files.New(root).Search(tc.query, 10))
74 if len(got) != len(tc.want) {
75 t.Errorf("Search(%q) = %v, want %v", tc.query, got, tc.want)
76 continue
77 }
78 for i := range tc.want {
79 if got[i] != tc.want[i] {
80 t.Errorf("Search(%q)[%d] = %q, want %q", tc.query, i, got[i], tc.want[i])
81 }
82 }
83 }
84}
85
86func TestSearchHonoursLimit(t *testing.T) {
87 root, _ := searchWorkspace(t)
88 if got := files.New(root).Search("", 2); len(got) != 2 {
89 t.Errorf("limit 2 returned %d hits", len(got))
90 }
91 if got := files.New(root).Search("", 100000); len(got) != 4 {
92 t.Errorf("oversized limit returned %d hits, want all 4", len(got))
93 }
94}
95
96func TestSearchEndpoint(t *testing.T) {
97 _, h := searchWorkspace(t)
98 rec := do(t, h, http.MethodGet, "/api/files/search?q=main&limit=1", "")
99 if rec.Code != http.StatusOK {
100 t.Fatalf("GET search = %d (%s)", rec.Code, rec.Body.String())
101 }
102 hits := decodeBody(t, rec)["files"].([]any)
103 if len(hits) != 1 || hits[0].(map[string]any)["relPath"] != "src/main.go" {
104 t.Errorf("files = %v, want [src/main.go]", hits)
105 }
106
107 rec = do(t, h, http.MethodGet, "/api/files/search?q=zzz", "")
108 if got := decodeBody(t, rec)["files"].([]any); len(got) != 0 {
109 t.Errorf("no-match search = %v, want an empty array", got)
110 }
111}
112
113func TestSearchEndpointOnMissingRootIs404(t *testing.T) {
114 mux := http.NewServeMux()
115 for pattern, handler := range files.New(filepath.Join(t.TempDir(), "gone")).Routes() {
116 mux.Handle(pattern, handler)
117 }
118 if rec := do(t, mux, http.MethodGet, "/api/files/search", ""); rec.Code != http.StatusNotFound {
119 t.Errorf("search on missing root = %d, want 404", rec.Code)
120 }
121}