Files
Cyrene_v2/internal/runtime/memory/extract_test.go
T
AskaEth 61cf80d5ee
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
docs(comments): 注释中文化 · internal/runtime/memory(31 文件,纯替换)
- 只翻注释/文档字符串:820 增 / 820 删 严格 1:1;剥掉整行注释与行尾注释尾巴后,
  逐文件与 HEAD 比对「代码部分差异 = 0」;裁决/design 编号计数逐项与 HEAD 一致
- 保留可执行 SQL 样例、SQLite 报错原文、pgvector/HNSW/ANN/BLOB 等技术词原文
- 复核:go build 绿 + memory/projectindex/vector 三包测试绿;gofmt 仅剩 2 个既有未格式化文件(改动前即如此,未顺手修)
2026-10-04 13:32:54 +08:00

110 lines
3.4 KiB
Go

package memory
import (
"context"
"errors"
"testing"
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
func TestManualExtractor_Extract_ParseRemember_正常(t *testing.T) {
t.Parallel()
ex := NewManualExtractor("persona.a", "role.1")
conversation := []model.Message{
model.TextMessage(model.RoleUser, "记住她喜欢喝冰美式"),
model.TextMessage(model.RoleAssistant, "好的,我记住了"),
model.TextMessage(model.RoleUser, "今天天气不错"), // 无指令
model.TextMessage(model.RoleUser, "请记住周三下午有项目会"),
}
items, err := ex.Extract(context.Background(), conversation)
if err != nil {
t.Fatalf("Extract: %v", err)
}
if len(items) != 2 {
t.Fatalf("got %d items, want 2", len(items))
}
if items[0].Content != "她喜欢喝冰美式" {
t.Errorf("items[0].Content = %q, want the stripped directive", items[0].Content)
}
if items[0].PersonaID != "persona.a" || items[0].RoleID != "role.1" {
t.Errorf("items[0] persona/role = %q/%q, want persona.a/role.1", items[0].PersonaID, items[0].RoleID)
}
if items[1].Content != "周三下午有项目会" {
t.Errorf("items[1].Content = %q, want the 请记住 content", items[1].Content)
}
}
func TestManualExtractor_Extract_NoRemember_正常(t *testing.T) {
t.Parallel()
ex := NewManualExtractor("persona.a", "role.1")
conversation := []model.Message{
model.TextMessage(model.RoleUser, "今天天气不错"),
model.TextMessage(model.RoleUser, "记得带伞吗"),
model.TextMessage(model.RoleAssistant, "记住是记忆"), // 非用户角色跳过
}
items, err := ex.Extract(context.Background(), conversation)
if err != nil {
t.Fatalf("Extract: %v", err)
}
if len(items) != 0 {
t.Fatalf("got %d items, want 0", len(items))
}
}
func TestManualExtractor_Extract_Canceled_异常(t *testing.T) {
t.Parallel()
ex := NewManualExtractor("persona.a", "role.1")
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := ex.Extract(ctx, []model.Message{model.TextMessage(model.RoleUser, "记住x")}); !errors.Is(err, context.Canceled) {
t.Fatalf("Extract with canceled ctx err = %v, want context.Canceled", err)
}
}
func TestStore_RememberManual_正常(t *testing.T) {
t.Parallel()
ctx := context.Background()
s := newTestStore(t)
item, err := s.RememberManual(ctx, "persona.a", "role.1", "记住她喜欢喝咖啡")
if err != nil {
t.Fatalf("RememberManual: %v", err)
}
// 落库内容保留指令原文;这是手动单条目
// 路径,与会剥离指令的提取器不同。
if item.Content != "记住她喜欢喝咖啡" {
t.Fatalf("RememberManual content = %q, want the passed text", item.Content)
}
if item.PersonaID != "persona.a" || item.Scope != ScopePersona || item.Kind != KindRelationship {
t.Fatalf("item persona/scope/kind = %q/%q/%q, want persona.a/persona/relationship",
item.PersonaID, item.Scope, item.Kind)
}
got, err := s.Get(ctx, item.ID)
if err != nil {
t.Fatalf("Get: %v", err)
}
if got.Content != item.Content {
t.Fatalf("persisted content = %q, want %q", got.Content, item.Content)
}
}
func TestStore_RememberManual_Empty_异常(t *testing.T) {
t.Parallel()
ctx := context.Background()
s := newTestStore(t)
for _, text := range []string{"", " "} {
if _, err := s.RememberManual(ctx, "persona.a", "role.1", text); !errors.Is(err, ErrMissingContent) {
t.Fatalf("RememberManual(%q) err = %v, want ErrMissingContent", text, err)
}
}
}