返回 DeepSeek-Reasonix
md_cjk_test.go
根目录 / internal / cli / md_cjk_test.go
1 package cli
2
3 import (
4 "strings"
5 "testing"
6 )
7
8 func TestFixCJKEmphasis(t *testing.T) {
9 tests := []struct {
10 name string
11 input string
12 want string
13 }{
14 {
15 name: "cjk punctuation bold",
16 input: "**测试,**更多",
17 want: "**测试,** 更多",
18 },
19 {
20 name: "cjk punctuation bold with period",
21 input: "**测试。**更多",
22 want: "**测试。** 更多",
23 },
24 {
25 name: "cjk punctuation bold with exclamation",
26 input: "**好!**然后",
27 want: "**好!** 然后",
28 },
29 {
30 name: "non-punctuation cjk unchanged",
31 input: "**中文**词",
32 want: "**中文**词",
33 },
34 {
35 name: "english unchanged",
36 input: "**bold** text",
37 want: "**bold** text",
38 },
39 {
40 name: "cjk after opening unchanged",
41 input: "前**加粗**后",
42 want: "前**加粗**后",
43 },
44 {
45 name: "inline code untouched",
46 input: "`a**中文**b`",
47 want: "`a**中文**b`",
48 },
49 {
50 name: "fenced code untouched",
51 input: "```\n**测试,**更多\n```",
52 want: "```\n**测试,**更多\n```",
53 },
54 {
55 name: "code span with cjk punctuation",
56 input: "`**你好,**世界` and **真,**好",
57 want: "`**你好,**世界` and **真,** 好",
58 },
59 {
60 name: "multiple emphasis",
61 input: "**第一,**和**第二,**都",
62 want: "**第一,** 和**第二,** 都",
63 },
64 {
65 name: "cjk punct before opener stays untouched (colon)",
66 input: "注意:**重要**事项",
67 want: "注意:**重要**事项",
68 },
69 {
70 name: "cjk punct before opener stays untouched (comma)",
71 input: "他说,**重点**是",
72 want: "他说,**重点**是",
73 },
74 {
75 name: "opener after punct, closer after punct",
76 input: "他说:**注意,**然后",
77 want: "他说:**注意,** 然后",
78 },
79 {
80 name: "empty input",
81 input: "",
82 want: "",
83 },
84 }
85
86 for _, tt := range tests {
87 t.Run(tt.name, func(t *testing.T) {
88 got := fixCJKEmphasis(tt.input)
89 if got != tt.want {
90 t.Errorf("fixCJKEmphasis(%q)\n got: %q\n want: %q", tt.input, got, tt.want)
91 }
92 })
93 }
94 }
95
96 func TestFixCJKEmphasisRenderIntegration(t *testing.T) {
97 r := newMarkdownRenderer(80)
98
99 tests := []struct {
100 name string
101 input string
102 wantText string // rendered output must contain this text
103 }{
104 {
105 name: "cjk punctuation bold renders",
106 input: "**测试,**更多",
107 wantText: "测试,",
108 },
109 {
110 name: "non-punctuation cjk already renders",
111 input: "**中文**词",
112 wantText: "中文",
113 },
114 {
115 name: "inline code preserved",
116 input: "`a**中文**b`",
117 wantText: "a**中文**b",
118 },
119 }
120
121 for _, tt := range tests {
122 t.Run(tt.name, func(t *testing.T) {
123 rendered := r.Render(tt.input)
124 if rendered == "" {
125 t.Fatal("Render returned empty string")
126 }
127 if !strings.Contains(rendered, tt.wantText) {
128 t.Errorf("rendered output missing %q:\n%s", tt.wantText, rendered)
129 }
130 })
131 }
132 }
133
134 func TestFixCJKEmphasisPunctBeforeOpenerRendersBold(t *testing.T) {
135 r := newMarkdownRenderer(80)
136 for _, in := range []string{"注意:**重要**事项", "他说,**重点**是"} {
137 if rendered := r.Render(in); strings.Contains(rendered, "**") {
138 t.Errorf("punct before opener left literal ** (not bold):\n%s", rendered)
139 }
140 }
141 }
142
143 func TestIsCJKPunct(t *testing.T) {
144 tests := []struct {
145 r rune
146 want bool
147 }{
148 {',', false}, // ASCII comma
149 {'。', true}, // CJK period
150 {',', true}, // CJK comma
151 {'!', true}, // CJK exclamation
152 {'?', true}, // CJK question
153 {'中', false}, // CJK letter
154 {'文', false}, // CJK letter
155 {'a', false}, // ASCII letter
156 {'「', true}, // CJK bracket
157 {'」', true}, // CJK bracket
158 {'、', true}, // CJK ideographic comma
159 {'·', true}, // middle dot
160 }
161 for _, tt := range tests {
162 if got := isCJKPunct(tt.r); got != tt.want {
163 t.Errorf("isCJKPunct(%q) = %v, want %v", tt.r, got, tt.want)
164 }
165 }
166 }
167
167 lines GO