ai_xiaopei
2 days ago ada154418fb223e742112e58ef169193e588eafb
internal/index/fts_test.go
@@ -52,3 +52,81 @@
      t.Errorf("result count = %d, want >= 1", len(results))
   }
}
// TestKeywordSearchASCII 覆盖 KeywordSearch 的 FTS 通道(ASCII 词 MATCH + rank 排序)
func TestKeywordSearchASCII(t *testing.T) {
   store, err := Open(filepath.Join(t.TempDir(), "test.db"))
   if err != nil {
      t.Fatalf("Open failed: %v", err)
   }
   defer store.Close()
   // 两个节点都含 "pump",但 node1 标题也含(title 权重高 → rank 更靠前)
   store.InsertNode(&graph.Node{
      ID:      1,
      Path:    "知识/001-pump.md",
      Title:   "pump failure",
      Section: "知识",
      Content: "pump failure troubleshooting guide",
   })
   store.InsertNode(&graph.Node{
      ID:      2,
      Path:    "知识/002-valve.md",
      Title:   "valve config",
      Section: "知识",
      Content: "the pump is configured here",
   })
   if err := store.CreateFTS(); err != nil {
      t.Fatalf("CreateFTS failed: %v", err)
   }
   if err := store.PopulateFTS(); err != nil {
      t.Fatalf("PopulateFTS failed: %v", err)
   }
   results, err := store.KeywordSearch([]string{"pump"}, 10)
   if err != nil {
      t.Fatalf("KeywordSearch failed: %v", err)
   }
   if len(results) != 2 {
      t.Fatalf("result count = %d, want 2 (FTS 通道应命中两节点)", len(results))
   }
   // FTS 通道 rank 排序:标题含 pump 的 node1 应排第一
   if results[0].ID != 1 {
      t.Errorf("FTS rank 排序: 首位 = %d, want 1", results[0].ID)
   }
}
// TestKeywordSearchMixed 覆盖双通道混合(ASCII 走 FTS + CJK 走 LIKE,seen 去重)
func TestKeywordSearchMixed(t *testing.T) {
   store, err := Open(filepath.Join(t.TempDir(), "test.db"))
   if err != nil {
      t.Fatalf("Open failed: %v", err)
   }
   defer store.Close()
   store.InsertNode(&graph.Node{
      ID:      1,
      Path:    "FAQ/001-pump.md",
      Title:   "pump 补气",
      Section: "FAQ",
      Content: "pump 补气失败排查",
   })
   if err := store.CreateFTS(); err != nil {
      t.Fatalf("CreateFTS failed: %v", err)
   }
   if err := store.PopulateFTS(); err != nil {
      t.Fatalf("PopulateFTS failed: %v", err)
   }
   // 同一节点被两个通道命中 → 去重后只出现一次
   results, err := store.KeywordSearch([]string{"pump", "补气"}, 10)
   if err != nil {
      t.Fatalf("KeywordSearch failed: %v", err)
   }
   if len(results) != 1 {
      t.Fatalf("双通道去重: count = %d, want 1", len(results))
   }
   if results[0].ID != 1 {
      t.Errorf("命中节点 = %d, want 1", results[0].ID)
   }
}