package graph import ( "testing" "github.com/aisim/kb-cli/internal/vault" ) func TestBuildGraphProvenance(t *testing.T) { files := []*vault.FileMeta{ {Path: "FAQ/001-补气失败.md", Title: "补气失败", Wikilinks: []string{"红绿闪", "不存在的链接"}}, {Path: "FAQ/002-红绿闪.md", Title: "红绿闪"}, {Path: "知识/003-称重原理详解.md", Title: "称重原理详解"}, // "称重原理" 是 "称重原理详解" 的子串 → fuzzy } files[0].Wikilinks = append(files[0].Wikilinks, "称重原理") g, unresolved := BuildGraph(files) // exact: 标题精确匹配 var exact, fuzzy int for _, e := range g.Edges { if e.Relation != "wikilink" { continue } switch e.Provenance { case "exact": exact++ case "fuzzy": fuzzy++ } } if exact != 1 || fuzzy != 1 { t.Errorf("provenance 分布: exact=%d fuzzy=%d (want 1/1)", exact, fuzzy) } // 悬空链接 if len(unresolved) != 1 || unresolved[0].LinkText != "不存在的链接" { t.Errorf("unresolved: %+v", unresolved) } if unresolved[0].NameTail != "不存在的链接" { t.Errorf("name_tail: %s", unresolved[0].NameTail) } } func TestBuildGraph(t *testing.T) { files := []*vault.FileMeta{ { Path: "FAQ/充装类/001-test.md", Title: "测试FAQ", Section: "FAQ", Tags: []string{"充装", "智能枪"}, Entities: []string{"YSP-35.5"}, Wikilinks: []string{}, Content: "测试内容", }, { Path: "知识/002-配置.md", Title: "充装规格配置", Section: "知识", Tags: []string{"充装"}, Entities: []string{}, Wikilinks: []string{}, Content: "配置内容", }, } g, _ := BuildGraph(files) if len(g.Nodes) != 2 { t.Errorf("node count = %d, want 2", len(g.Nodes)) } // 应该有 3 条边:2条 tag + 1条 entity tagEdges := 0 entityEdges := 0 for _, e := range g.Edges { if e.Relation == "tag" { tagEdges++ } if e.Relation == "entity" { entityEdges++ } } if tagEdges != 3 { // 充装 + 智能枪 + 充装(第二个文件) t.Errorf("tag edges = %d, want 3", tagEdges) } if entityEdges != 1 { t.Errorf("entity edges = %d, want 1", entityEdges) } }