package store import ( "context" "path/filepath" "testing" ) func newMemTestStore(t *testing.T) *Store { t.Helper() path := filepath.Join(t.TempDir(), "mem_test.db") st, err := Open(context.Background(), path) if err != nil { t.Fatalf("Open: %v", err) } t.Cleanup(func() { _ = st.Close() }) return st } func TestMemoryStoreInsertSearch(t *testing.T) { ctx := context.Background() m := newMemTestStore(t).VectorMemory() // three orthonormal-ish vectors; a query aligned with the second must rank it top. if err := m.Insert(ctx, "a", []float32{1, 0, 0}, map[string]string{"text": "вода"}); err != nil { t.Fatal(err) } if err := m.Insert(ctx, "b", []float32{0, 1, 0}, map[string]string{"text": "сон", "type": "fact"}); err != nil { t.Fatal(err) } if err := m.Insert(ctx, "c", []float32{0, 0, 1}, map[string]string{"text": "еда"}); err != nil { t.Fatal(err) } got, err := m.Search(ctx, []float32{0, 1, 0}, 2) if err != nil { t.Fatalf("Search: %v", err) } if len(got) != 2 { t.Fatalf("topK=2 returned %d results", len(got)) } if got[0].ID != "b" { t.Errorf("top hit = %q, want b", got[0].ID) } if got[0].Meta["text"] != "сон" || got[0].Meta["type"] != "fact" { t.Errorf("meta not round-tripped: %v", got[0].Meta) } if got[0].Score < 0.99 { t.Errorf("aligned vector score = %v, want ~1.0", got[0].Score) } } func TestMemoryStoreUpsertReplaces(t *testing.T) { ctx := context.Background() m := newMemTestStore(t).VectorMemory() if err := m.Insert(ctx, "x", []float32{1, 0}, map[string]string{"text": "старое"}); err != nil { t.Fatal(err) } if err := m.Insert(ctx, "x", []float32{0, 1}, map[string]string{"text": "новое"}); err != nil { t.Fatal(err) } got, err := m.Search(ctx, []float32{0, 1}, 10) if err != nil { t.Fatal(err) } if len(got) != 1 { t.Fatalf("re-inserting the same id produced %d rows, want 1 (upsert)", len(got)) } if got[0].Meta["text"] != "новое" { t.Errorf("upsert kept the old value: %q", got[0].Meta["text"]) } } func TestMemoryStorePersistsAcrossReopen(t *testing.T) { ctx := context.Background() path := filepath.Join(t.TempDir(), "persist.db") st, err := Open(ctx, path) if err != nil { t.Fatal(err) } if err := st.VectorMemory().Insert(ctx, "k", []float32{1, 0, 0}, map[string]string{"text": "запомни"}); err != nil { t.Fatal(err) } if err := st.Close(); err != nil { t.Fatal(err) } // reopen the same file — the in-memory floor would have lost this. st2, err := Open(ctx, path) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st2.Close() }) got, err := st2.VectorMemory().Search(ctx, []float32{1, 0, 0}, 1) if err != nil { t.Fatal(err) } if len(got) != 1 || got[0].Meta["text"] != "запомни" { t.Fatalf("memory did not survive reopen: %v", got) } }