94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|