Files
xinmi/internal/application/service/chat_pipeline/rerank_clean_test.go
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

181 lines
4.9 KiB
Go

package chatpipeline
import (
"context"
"encoding/json"
"strings"
"testing"
"github.com/Tencent/WeKnora/internal/types"
)
func TestGetEnrichedPassageKeepsQuestionsFromEarlierRevision(t *testing.T) {
metadata, err := json.Marshal(types.DocumentChunkMetadata{
GeneratedQuestionsRevision: 1,
GeneratedQuestions: []types.GeneratedQuestion{{
ID: "old", Question: "question generated before the edit",
}},
})
if err != nil {
t.Fatal(err)
}
passage := getEnrichedPassage(context.Background(), &types.SearchResult{
Content: "edited chunk body",
ChunkMetadata: types.JSON(metadata),
})
if !strings.Contains(passage, "question generated before the edit") {
t.Fatalf("earlier generated question was excluded from rerank passage: %q", passage)
}
}
func TestGetEnrichedPassageKeepsCodeAndMathCandidates(t *testing.T) {
tests := []struct {
name string
content string
want string
}{
{
name: "code only",
content: "```go\nfunc answer() int { return 42 }\n```",
want: "func answer() int { return 42 }",
},
{
name: "math only",
content: "$$\nE = mc^2\n$$",
want: "E = mc^2",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
passage := getEnrichedPassage(context.Background(), &types.SearchResult{Content: tt.content})
if strings.TrimSpace(passage) == "" {
t.Fatal("semantic-only candidate was removed from the rerank passage")
}
if !strings.Contains(passage, tt.want) {
t.Fatalf("rerank passage %q does not preserve %q", passage, tt.want)
}
})
}
}
func TestCleanPassageForRerank(t *testing.T) {
tests := []struct {
name string
input string
expect string
}{
{
name: "plain text unchanged",
input: "这是一段普通的文本内容",
expect: "这是一段普通的文本内容",
},
{
name: "remove markdown images",
input: "前文 ![图片说明](https://example.com/img.png) 后文",
expect: "前文 后文",
},
{
name: "convert markdown links to text",
input: "请参考 [官方文档](https://docs.example.com) 了解详情",
expect: "请参考 官方文档 了解详情",
},
{
name: "remove standalone URLs",
input: "访问 https://example.com/path?q=1&b=2 获取更多信息",
expect: "访问 获取更多信息",
},
{
name: "unwrap code blocks",
input: "示例代码:\n```python\nprint('hello')\n```\n以上是示例",
expect: "示例代码:\nprint('hello')\n以上是示例",
},
{
name: "unwrap LaTeX blocks",
input: "公式如下 $$E=mc^2$$ 其中E是能量",
expect: "公式如下 E=mc^2 其中E是能量",
},
{
name: "remove table separator rows and convert data rows",
input: "| 名称 | 值 |\n| --- | --- |\n| A | 1 |",
expect: "名称, 值\n\nA, 1",
},
{
name: "strip heading markers",
input: "## 第二章 概述\n### 2.1 背景",
expect: "第二章 概述\n2.1 背景",
},
{
name: "strip blockquote markers",
input: "> 这是一段引用\n> 第二行引用",
expect: "这是一段引用\n第二行引用",
},
{
name: "unwrap bold and italic",
input: "这是 **加粗** 和 *斜体* 以及 ***粗斜体*** 文本",
expect: "这是 加粗 和 斜体 以及 粗斜体 文本",
},
{
name: "strip list markers",
input: "- 项目一\n- 项目二\n1. 有序一\n2. 有序二",
expect: "项目一\n项目二\n有序一\n有序二",
},
{
name: "remove HTML tags",
input: "文本<br>换行<div class=\"test\">内容</div>结尾",
expect: "文本换行内容结尾",
},
{
name: "collapse excessive newlines",
input: "段落一\n\n\n\n\n段落二",
expect: "段落一\n\n段落二",
},
{
name: "combined real-world passage",
input: `## 产品介绍
这是一个 **重要的** 产品。详见 [产品页面](https://example.com/product)。
![产品截图](images/product.png)
> 用户评价:非常好用
- 功能一
- 功能二
` + "```json\n{\"key\": \"value\"}\n```",
expect: "产品介绍\n\n这是一个 重要的 产品。详见 产品页面。\n\n用户评价:非常好用\n\n功能一\n功能二\n\n{\"key\": \"value\"}",
},
{
name: "convert table data rows to plain text",
input: "| col1 | col2 | col3 |",
expect: "col1, col2, col3",
},
{
name: "multi-row table fully converted",
input: "| Header1 | Header2 |\n| --- | --- |\n| data1 | data2 |\n| data3 | data4 |",
expect: "Header1, Header2\n\ndata1, data2\ndata3, data4",
},
{
name: "table-only passage becomes empty after separator removal",
input: "| --- | --- |",
expect: "",
},
{
name: "whitespace-only after cleaning",
input: " \n\n ",
expect: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := cleanPassageForRerank(tt.input)
if got != tt.expect {
t.Errorf("cleanPassageForRerank():\ngot: %q\nexpect: %q", got, tt.expect)
}
})
}
}