go-rag/collections_test.go
Snider d8fd067a8c feat: Phase 3 enhancements — sentence splitting, collection helpers, keyword filter, benchmarks
3.1: Sentence-aware chunk splitting at ". ", "? ", "! " boundaries when
paragraphs exceed ChunkConfig.Size. Overlap now aligns to word boundaries
to avoid mid-word splits.

3.2: VectorStore interface gains ListCollections and CollectionInfo methods.
New collections.go with ListCollections, DeleteCollection, CollectionStats
helpers returning backend-agnostic CollectionInfo. Mock updated accordingly.

3.3: KeywordFilter re-ranks QueryResults by boosting scores for keyword
matches (case-insensitive, +10% per keyword). QueryConfig.Keywords flag
enables automatic extraction and filtering.

3.4: Mock-only benchmarks for chunking, query, ingest, formatting, and
keyword filtering.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-20 08:02:00 +00:00

127 lines
3.3 KiB
Go

package rag
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// --- ListCollections tests ---
func TestListCollections(t *testing.T) {
t.Run("returns collection names from store", func(t *testing.T) {
store := newMockVectorStore()
store.collections["alpha"] = 768
store.collections["bravo"] = 384
names, err := ListCollections(context.Background(), store)
require.NoError(t, err)
assert.Len(t, names, 2)
assert.Contains(t, names, "alpha")
assert.Contains(t, names, "bravo")
})
t.Run("empty store returns empty list", func(t *testing.T) {
store := newMockVectorStore()
names, err := ListCollections(context.Background(), store)
require.NoError(t, err)
assert.Empty(t, names)
})
t.Run("error from store propagates", func(t *testing.T) {
store := newMockVectorStore()
store.listErr = fmt.Errorf("connection lost")
_, err := ListCollections(context.Background(), store)
assert.Error(t, err)
assert.Contains(t, err.Error(), "connection lost")
})
}
// --- DeleteCollection tests ---
func TestDeleteCollectionHelper(t *testing.T) {
t.Run("deletes collection from store", func(t *testing.T) {
store := newMockVectorStore()
store.collections["to-delete"] = 768
store.points["to-delete"] = []Point{{ID: "p1"}}
err := DeleteCollection(context.Background(), store, "to-delete")
require.NoError(t, err)
_, exists := store.collections["to-delete"]
assert.False(t, exists)
assert.Empty(t, store.points["to-delete"])
})
t.Run("error from store propagates", func(t *testing.T) {
store := newMockVectorStore()
store.deleteErr = fmt.Errorf("permission denied")
err := DeleteCollection(context.Background(), store, "any")
assert.Error(t, err)
assert.Contains(t, err.Error(), "permission denied")
})
}
// --- CollectionStats tests ---
func TestCollectionStats(t *testing.T) {
t.Run("returns info for existing collection", func(t *testing.T) {
store := newMockVectorStore()
store.collections["my-col"] = 768
store.points["my-col"] = []Point{
{ID: "p1", Vector: []float32{0.1}},
{ID: "p2", Vector: []float32{0.2}},
{ID: "p3", Vector: []float32{0.3}},
}
info, err := CollectionStats(context.Background(), store, "my-col")
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, "my-col", info.Name)
assert.Equal(t, uint64(3), info.PointCount)
assert.Equal(t, uint64(768), info.VectorSize)
assert.Equal(t, "green", info.Status)
})
t.Run("nonexistent collection returns error", func(t *testing.T) {
store := newMockVectorStore()
_, err := CollectionStats(context.Background(), store, "missing")
assert.Error(t, err)
assert.Contains(t, err.Error(), "not found")
})
t.Run("error from store propagates", func(t *testing.T) {
store := newMockVectorStore()
store.collections["err-col"] = 768
store.infoErr = fmt.Errorf("internal error")
_, err := CollectionStats(context.Background(), store, "err-col")
assert.Error(t, err)
assert.Contains(t, err.Error(), "internal error")
})
t.Run("empty collection has zero point count", func(t *testing.T) {
store := newMockVectorStore()
store.collections["empty-col"] = 384
info, err := CollectionStats(context.Background(), store, "empty-col")
require.NoError(t, err)
assert.Equal(t, uint64(0), info.PointCount)
assert.Equal(t, uint64(384), info.VectorSize)
})
}