package eino import "testing" func TestParseOps(t *testing.T) { got := parseOps("```json\n[{\"op\":\"ADD\",\"key\":\"称呼\",\"value\":\"Dexter\",\"importance\":7},{\"op\":\"DELETE\",\"key\":\"旧公司\"}]\n```") if len(got) != 2 || got[0].Op != "ADD" || got[0].Key != "称呼" || got[0].Importance != 7 || got[1].Op != "DELETE" { t.Fatalf("parseOps 解析错: %+v", got) } if parseOps("不是 JSON") != nil { t.Error("非 JSON 应返回 nil") } } func TestSanitizeOps(t *testing.T) { existing := map[string]string{"语言": "中文", "旧公司": "A厂"} in := []memOp{ {Op: "add", Key: "重要事", Value: "X", Importance: 99}, // 大小写规范 + importance 夹到 10 {Op: "UPDATE", Key: "语言", Value: "英文", Importance: 0}, // importance 提到 1 {Op: "ADD", Key: "空值", Value: ""}, // 无 value → 丢 {Op: "DELETE", Key: "旧公司"}, // 命中已有 → 留 {Op: "DELETE", Key: "不存在"}, // 未命中 → 丢(防幻删) {Op: "NOOP", Key: "语言"}, // NOOP → 丢(不覆盖已收的 UPDATE) {Op: "ADD", Key: "称呼", Value: "Dexter", Importance: 7}, {Op: "ADD", Key: "称呼", Value: "Dex", Importance: 3}, // 同 key 重复 → 保留末个(值+importance) } out := sanitizeOps(in, existing) if len(out) != 4 { t.Fatalf("应剩 4 条(重要事/语言/删旧公司/称呼),得 %d: %+v", len(out), out) } byKey := map[string]memOp{} for _, o := range out { byKey[o.Key] = o } if byKey["重要事"].Importance != 10 { t.Errorf("重要事 importance 应夹到 10: %+v", byKey["重要事"]) } if byKey["语言"].Op != "UPDATE" || byKey["语言"].Importance != 1 { t.Errorf("语言 应为 UPDATE 且 importance 提到 1: %+v", byKey["语言"]) } if byKey["旧公司"].Op != "DELETE" { t.Errorf("旧公司 应保留 DELETE: %+v", byKey["旧公司"]) } if byKey["称呼"].Value != "Dex" || byKey["称呼"].Importance != 3 { t.Errorf("称呼 应取末个 op(Dex/3): %+v", byKey["称呼"]) } } func TestParseProfile(t *testing.T) { m := parseProfile("- 称呼:Dexter\n- 语言: 中文\n\n- 职业:律师") if m["称呼"] != "Dexter" || m["语言"] != "中文" || m["职业"] != "律师" { t.Errorf("画像解析错: %v", m) } if len(parseProfile("")) != 0 { t.Error("空画像应得空 map") } }