package search import ( "path/filepath" "testing" "verstak/internal/core/storage" ) func openTestDB(t *testing.T) *storage.DB { t.Helper() dir := t.TempDir() db, err := storage.Open(filepath.Join(dir, "test.db")) if err != nil { t.Fatalf("open db: %v", err) } t.Cleanup(func() { db.Close() }) return db } func TestRebuild(t *testing.T) { db := openTestDB(t) svc := NewService(db) // Rebuild should not fail even without FTS5 (virtual table may not exist). err := svc.Rebuild() // If FTS5 is available, this will create the table. // If not, the CREATE VIRTUAL will be silently ignored. _ = err } func TestSearchFallback(t *testing.T) { db := openTestDB(t) svc := NewService(db) // Index a document directly (only works if FTS5 is available). // If not, Search should return empty results gracefully. _ = svc.Index("n1", "Hello world", "some content", "/path", "tag1", "case") _ = svc.Index("n2", "Goodbye world", "other content", "/path2", "tag2", "note") results, err := svc.Search("hello") if err != nil { t.Fatalf("Search: %v", err) } // Results will be non-empty only if FTS5 is compiled in. // The test passes either way — we just verify no crash. _ = results } func TestSearchEmpty(t *testing.T) { db := openTestDB(t) svc := NewService(db) results, err := svc.Search("") if err != nil { t.Fatalf("Search empty: %v", err) } if len(results) != 0 { t.Errorf("expected 0 results, got %d", len(results)) } // Single char query should also return empty. results, err = svc.Search("a") if err != nil { t.Fatalf("Search short: %v", err) } if len(results) != 0 { t.Errorf("expected 0 results, got %d", len(results)) } } func TestRemove(t *testing.T) { db := openTestDB(t) svc := NewService(db) _ = svc.Index("n1", "Test doc", "content", "", "tag", "case") svc.Remove("n1") // Should not error. } func TestSanitizeFTS(t *testing.T) { cases := []struct{ in, want string }{ {`hello world`, `"hello world"`}, {`test"quote`, `"test""quote"`}, {` spaced `, `"spaced"`}, } for _, c := range cases { got := sanitizeFTS(c.in) if got != c.want { t.Errorf("sanitizeFTS(%q) = %q, want %q", c.in, got, c.want) } } }