Files
Memoh/internal/memory/storefs/service_test.go
T
晨苒 627b673a5c refactor: multi-provider memory adapters with scan-based builtin (#227)
* refactor: restructure memory into multi-provider adapters, remove manifest.json dependency

- Rename internal/memory/provider to internal/memory/adapters with per-provider subdirectories (builtin, mem0, openviking)
- Replace manifest.json-based delete/update with scan-based index from daily files
- Add mem0 and openviking provider adapters with HTTP client, chat hooks, MCP tools, and CRUD
- Wire provider lifecycle into registry (auto-instantiate on create, evict on update/delete)
- Split docker-compose into base stack + optional overlays (qdrant, browser, mem0, openviking)
- Update admin UI to support dynamic provider config schema rendering

* chore(lint): fix all golangci-lint issues for clean CI

* refactor(docker): replace compose overlay files with profiles

* feat(memory): add built-in memory multi modes

* fix(ci): golangci lint

* feat(memory): edit built-in memory sparse design
2026-03-14 06:04:13 +08:00

108 lines
2.7 KiB
Go

package storefs
import (
"strings"
"testing"
)
func TestFormatAndParseMemoryDayMD_Roundtrip(t *testing.T) {
items := []MemoryItem{
{
ID: "mem_2",
Memory: "second record",
Hash: "h2",
CreatedAt: "2026-03-01T11:15:00Z",
Metadata: map[string]any{"topic": "Notes"},
},
{
ID: "mem_1",
Memory: "first record",
Hash: "h1",
CreatedAt: "2026-03-01T09:40:00Z",
Metadata: map[string]any{"topic": "Decision"},
},
}
md := formatMemoryDayMD("2026-03-01", items)
if !strings.Contains(md, "# Memory 2026-03-01") {
t.Fatalf("expected header in markdown: %s", md)
}
if !strings.Contains(md, "## Entry mem_1") {
t.Fatalf("expected entry heading in markdown: %s", md)
}
if !strings.Contains(md, "```yaml") {
t.Fatalf("expected yaml block in markdown: %s", md)
}
parsed, err := parseMemoryDayMD(md)
if err != nil {
t.Fatalf("parseMemoryDayMD error: %v", err)
}
if len(parsed) != 2 {
t.Fatalf("expected 2 parsed items, got %d", len(parsed))
}
// formatMemoryDayMD sorts by created_at ascending.
if parsed[0].ID != "mem_1" || parsed[1].ID != "mem_2" {
t.Fatalf("unexpected order after roundtrip: %#v", parsed)
}
if got := parsed[0].Metadata["topic"]; got != "Decision" {
t.Fatalf("expected metadata preserved, got %#v", parsed[0].Metadata)
}
}
func TestParseJSONMemoryItems(t *testing.T) {
raw := `[
{
"id": "mem_json",
"topic": "Decision",
"memory": "Choose provider architecture."
}
]`
items, err := parseJSONMemoryItems(raw)
if err != nil {
t.Fatalf("parseJSONMemoryItems error: %v", err)
}
if len(items) != 1 {
t.Fatalf("expected 1 item, got %d", len(items))
}
if items[0].ID != "mem_json" {
t.Fatalf("unexpected id: %#v", items[0])
}
if got := items[0].Metadata["topic"]; got != "Decision" {
t.Fatalf("expected topic metadata, got %#v", items[0].Metadata)
}
if items[0].Memory != "Choose provider architecture." {
t.Fatalf("unexpected memory body: %#v", items[0])
}
}
func TestParseJSONMemoryItemsCanBeFormattedToCanonicalMarkdown(t *testing.T) {
raw := `[
{
"id": "mem_json",
"topic": "Decision",
"memory": "Choose provider architecture."
}
]`
items, err := parseJSONMemoryItems(raw)
if err != nil {
t.Fatalf("parseJSONMemoryItems error: %v", err)
}
md := formatMemoryDayMD("2026-03-01", items)
if !strings.Contains(md, "## Entry mem_json") {
t.Fatalf("expected canonical heading, got: %s", md)
}
if !strings.Contains(md, "topic: Decision") {
t.Fatalf("expected yaml metadata topic, got: %s", md)
}
parsed, err := parseMemoryDayMD(md)
if err != nil {
t.Fatalf("parseMemoryDayMD error: %v", err)
}
if len(parsed) != 1 || parsed[0].ID != "mem_json" {
t.Fatalf("unexpected parsed canonical items: %#v", parsed)
}
}