package index import ( "os" "path/filepath" "testing" ) func TestRetryUnresolved(t *testing.T) { dir := t.TempDir() os.MkdirAll(filepath.Join(dir, "FAQ"), 0755) os.WriteFile(filepath.Join(dir, "FAQ", "001-旧文档.md"), []byte("---\ntitle: 旧文档\n---\n提到 [[补气失败]]\n"), 0644) store, _ := Open(filepath.Join(t.TempDir(), "kb.db")) defer store.Close() Reconcile(store, dir) // 验证悬空链接入表 var n int store.db.QueryRow(`SELECT COUNT(*) FROM unresolved_links WHERE link_text='补气失败'`).Scan(&n) if n != 1 { t.Fatalf("悬空链接未入表: %d", n) } // 新文档入库:标题正好是 "补气失败" os.WriteFile(filepath.Join(dir, "FAQ", "002-补气失败.md"), []byte("---\ntitle: 补气失败\n---\n补气失败排查\n"), 0644) res, err := Reconcile(store, dir) if err != nil { t.Fatal(err) } if res.Added != 1 { t.Fatalf("新增: %+v", res) } // 悬空链接应被解析:行删除 + 边建立 store.db.QueryRow(`SELECT COUNT(*) FROM unresolved_links WHERE link_text='补气失败'`).Scan(&n) if n != 0 { t.Errorf("悬空行未清除: %d", n) } store.db.QueryRow(`SELECT COUNT(*) FROM edges WHERE relation='wikilink' AND label='补气失败'`).Scan(&n) if n != 1 { t.Errorf("wikilink 边未建立: %d", n) } var prov string store.db.QueryRow(`SELECT provenance FROM edges WHERE relation='wikilink' AND label='补气失败'`).Scan(&prov) if prov != "exact" { t.Errorf("补全边应为 exact: %s", prov) } } func TestResolveWikilinkEmptyLink(t *testing.T) { dir := t.TempDir() os.MkdirAll(filepath.Join(dir, "FAQ"), 0755) os.WriteFile(filepath.Join(dir, "FAQ", "001-文档.md"), []byte("---\ntitle: 文档\n---\n提到 [[|别名]]\n"), 0644) store, _ := Open(filepath.Join(t.TempDir(), "kb.db")) defer store.Close() Reconcile(store, dir) // 空 link 不应 fuzzy 误建边(Contains 空串恒真) var n int store.db.QueryRow(`SELECT COUNT(*) FROM edges WHERE relation='wikilink' AND label='|别名'`).Scan(&n) if n != 0 { t.Errorf("空 link 不应建 wikilink 边: %d", n) } // 悬空行应入表且只入一行 store.db.QueryRow(`SELECT COUNT(*) FROM unresolved_links WHERE link_text='|别名'`).Scan(&n) if n != 1 { t.Errorf("悬空行应为 1: %d", n) } } func TestTagEntityEdgeProvenance(t *testing.T) { dir := t.TempDir() os.MkdirAll(filepath.Join(dir, "FAQ"), 0755) os.WriteFile(filepath.Join(dir, "FAQ", "001-文档.md"), []byte("---\ntitle: 文档\ntags: [t1]\nentities: [张三]\n---\n内容\n"), 0644) store, _ := Open(filepath.Join(t.TempDir(), "kb.db")) defer store.Close() Reconcile(store, dir) // tag/entity 边的 provenance 应为 relation 本身(Minor 1 修复) var prov string store.db.QueryRow(`SELECT provenance FROM edges WHERE relation='tag' AND label='t1'`).Scan(&prov) if prov != "tag" { t.Errorf("tag 边 provenance: %q", prov) } store.db.QueryRow(`SELECT provenance FROM edges WHERE relation='entity' AND label='张三'`).Scan(&prov) if prov != "entity" { t.Errorf("entity 边 provenance: %q", prov) } }