From 62a9f6223745c0df42be1f4226f31dfb10c83ea8 Mon Sep 17 00:00:00 2001
From: ax_rd <ax_rd@aisim.cn>
Date: Thu, 03 Sep 2026 13:53:11 +0800
Subject: [PATCH] fix: e2e-verify.sh 退出码处理(FAILS 计数 + pipefail,CI 可凭退出码判定)

---
 internal/search/engine_test.go |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/internal/search/engine_test.go b/internal/search/engine_test.go
index 6aeeb1e..06b511f 100644
--- a/internal/search/engine_test.go
+++ b/internal/search/engine_test.go
@@ -147,6 +147,48 @@
 	}
 }
 
+// TestSearchLongCJKBigram 回归(审查遗留):单复合 CJK 词「电子秤补气失败」
+// 在内容中不连续出现时,整串 LIKE 匹配不到,search 必须对长 CJK 词做 bigram
+// 展开后检索才能命中(RED 证据:未下沉前该查询 0 结果)。
+func TestSearchLongCJKBigram(t *testing.T) {
+	tmpDir := t.TempDir()
+	dbPath := filepath.Join(tmpDir, "test.db")
+	store, err := index.Open(dbPath)
+	if err != nil {
+		t.Fatalf("Open failed: %v", err)
+	}
+	defer store.Close()
+
+	// content 含「电子秤补气」「补气失败」片段,但不含完整的连续「电子秤补气失败」
+	n := &graph.Node{
+		ID:      1,
+		Path:    "FAQ/称重/001-test.md",
+		Title:   "称重故障排查",
+		Section: "FAQ",
+		Content: "电子秤补气 时先检查阀门,补气失败后断电重启。",
+	}
+	if err := store.UpsertNode(n, 100, 1, "x"); err != nil {
+		t.Fatalf("UpsertNode failed: %v", err)
+	}
+	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 := Search(store, []string{"电子秤补气失败"}, SearchOptions{})
+	if err != nil {
+		t.Fatalf("Search failed: %v", err)
+	}
+	if len(results) != 1 {
+		t.Fatalf("expected 1 result (bigram 展开命中), got %d", len(results))
+	}
+	if results[0].Path != "FAQ/称重/001-test.md" {
+		t.Errorf("expected hit FAQ/称重/001-test.md, got %q", results[0].Path)
+	}
+}
+
 func TestIsGenericWord(t *testing.T) {
 	tests := []struct {
 		word     string

--
Gitblit v1.10.0