|
8 | 8 | "github.com/cluion/zh-finder/internal/classifier" |
9 | 9 | "github.com/cluion/zh-finder/internal/matcher" |
10 | 10 | "github.com/cluion/zh-finder/internal/output" |
| 11 | + "github.com/cluion/zh-finder/internal/scanner" |
11 | 12 | ) |
12 | 13 |
|
13 | 14 | func TestFormatTerminalOutput(t *testing.T) { |
@@ -40,6 +41,98 @@ func TestFormatTerminalOutput(t *testing.T) { |
40 | 41 | } |
41 | 42 | } |
42 | 43 |
|
| 44 | +func TestFormatTerminalWithColor(t *testing.T) { |
| 45 | + f := output.New(true, "term") |
| 46 | + |
| 47 | + results := map[string][]output.LineMatch{ |
| 48 | + "test.go": { |
| 49 | + { |
| 50 | + Line: 1, |
| 51 | + Content: "// 測試", |
| 52 | + Matches: []matcher.Match{ |
| 53 | + {Text: "測試", Type: classifier.Traditional, Start: 3, End: 5}, |
| 54 | + }, |
| 55 | + }, |
| 56 | + }, |
| 57 | + } |
| 58 | + |
| 59 | + var buf bytes.Buffer |
| 60 | + err := f.Format(&buf, results, nil) |
| 61 | + if err != nil { |
| 62 | + t.Fatalf("Format returned error: %v", err) |
| 63 | + } |
| 64 | + |
| 65 | + got := buf.String() |
| 66 | + if !strings.Contains(got, "test.go") { |
| 67 | + t.Error("Expected file name in colored output") |
| 68 | + } |
| 69 | + if !strings.Contains(got, "測試") { |
| 70 | + t.Error("Expected match text in colored output") |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | +func TestFormatTerminalSimplified(t *testing.T) { |
| 75 | + f := output.New(false, "term") |
| 76 | + |
| 77 | + results := map[string][]output.LineMatch{ |
| 78 | + "test.go": { |
| 79 | + { |
| 80 | + Line: 1, |
| 81 | + Content: "// 简体", |
| 82 | + Matches: []matcher.Match{ |
| 83 | + {Text: "简体", Type: classifier.Simplified, Start: 3, End: 5}, |
| 84 | + }, |
| 85 | + }, |
| 86 | + }, |
| 87 | + } |
| 88 | + |
| 89 | + var buf bytes.Buffer |
| 90 | + err := f.Format(&buf, results, nil) |
| 91 | + if err != nil { |
| 92 | + t.Fatalf("Format returned error: %v", err) |
| 93 | + } |
| 94 | + |
| 95 | + got := buf.String() |
| 96 | + if !strings.Contains(got, "简体 (simplified)") { |
| 97 | + t.Error("Expected simplified label in output") |
| 98 | + } |
| 99 | +} |
| 100 | + |
| 101 | +func TestFormatTerminalWithColorAndStats(t *testing.T) { |
| 102 | + f := output.New(true, "term") |
| 103 | + |
| 104 | + results := map[string][]output.LineMatch{ |
| 105 | + "test.go": { |
| 106 | + { |
| 107 | + Line: 1, |
| 108 | + Content: "// 測試", |
| 109 | + Matches: []matcher.Match{ |
| 110 | + {Text: "測試", Type: classifier.Traditional, Start: 3, End: 5}, |
| 111 | + }, |
| 112 | + }, |
| 113 | + }, |
| 114 | + } |
| 115 | + |
| 116 | + stats := &output.Stats{ |
| 117 | + ScannedFiles: 5, |
| 118 | + MatchedFiles: 1, |
| 119 | + TraditionalCount: 1, |
| 120 | + SimplifiedCount: 0, |
| 121 | + Duration: "0.01s", |
| 122 | + } |
| 123 | + |
| 124 | + var buf bytes.Buffer |
| 125 | + err := f.Format(&buf, results, stats) |
| 126 | + if err != nil { |
| 127 | + t.Fatalf("Format returned error: %v", err) |
| 128 | + } |
| 129 | + |
| 130 | + got := buf.String() |
| 131 | + if !strings.Contains(got, "Statistics") { |
| 132 | + t.Error("Expected statistics in colored output") |
| 133 | + } |
| 134 | +} |
| 135 | + |
43 | 136 | func TestFormatJSONOutput(t *testing.T) { |
44 | 137 | f := output.New(false, "json") |
45 | 138 |
|
@@ -70,6 +163,41 @@ func TestFormatJSONOutput(t *testing.T) { |
70 | 163 | } |
71 | 164 | } |
72 | 165 |
|
| 166 | +func TestFormatJSONWithStats(t *testing.T) { |
| 167 | + f := output.New(false, "json") |
| 168 | + |
| 169 | + results := map[string][]output.LineMatch{ |
| 170 | + "test.go": { |
| 171 | + { |
| 172 | + Line: 1, |
| 173 | + Content: "// 測試", |
| 174 | + Matches: []matcher.Match{ |
| 175 | + {Text: "測試", Type: classifier.Traditional, Start: 3, End: 5}, |
| 176 | + }, |
| 177 | + }, |
| 178 | + }, |
| 179 | + } |
| 180 | + |
| 181 | + stats := &output.Stats{ |
| 182 | + ScannedFiles: 5, |
| 183 | + MatchedFiles: 1, |
| 184 | + TraditionalCount: 1, |
| 185 | + SimplifiedCount: 0, |
| 186 | + Duration: "0.01s", |
| 187 | + } |
| 188 | + |
| 189 | + var buf bytes.Buffer |
| 190 | + err := f.Format(&buf, results, stats) |
| 191 | + if err != nil { |
| 192 | + t.Fatalf("Format returned error: %v", err) |
| 193 | + } |
| 194 | + |
| 195 | + got := buf.String() |
| 196 | + if !strings.Contains(got, `"summary"`) { |
| 197 | + t.Error("Expected summary field in JSON with stats") |
| 198 | + } |
| 199 | +} |
| 200 | + |
73 | 201 | func TestFormatJSONCompactOutput(t *testing.T) { |
74 | 202 | f := output.New(false, "json-compact") |
75 | 203 |
|
@@ -130,3 +258,63 @@ func TestFormatWithStats(t *testing.T) { |
130 | 258 | t.Error("Expected statistics in output") |
131 | 259 | } |
132 | 260 | } |
| 261 | + |
| 262 | +func TestScannerSetExcludeDirs(t *testing.T) { |
| 263 | + s := scanner.New() |
| 264 | + s.SetExcludeDirs([]string{"custom"}) |
| 265 | + if len(s.ExcludeDirs()) != 1 || s.ExcludeDirs()[0] != "custom" { |
| 266 | + t.Error("Expected custom exclude dir") |
| 267 | + } |
| 268 | +} |
| 269 | + |
| 270 | +func TestScannerAddExcludeDirs(t *testing.T) { |
| 271 | + s := scanner.New() |
| 272 | + original := len(s.ExcludeDirs()) |
| 273 | + s.AddExcludeDirs([]string{"extra"}) |
| 274 | + if len(s.ExcludeDirs()) != original+1 { |
| 275 | + t.Error("Expected additional exclude dir") |
| 276 | + } |
| 277 | +} |
| 278 | + |
| 279 | +func TestScannerSetMaxDepth(t *testing.T) { |
| 280 | + s := scanner.New() |
| 281 | + s.SetMaxDepth(5) |
| 282 | + if s.MaxDepth() != 5 { |
| 283 | + t.Error("Expected max depth 5") |
| 284 | + } |
| 285 | +} |
| 286 | + |
| 287 | +func TestScannerSetScanBinary(t *testing.T) { |
| 288 | + s := scanner.New() |
| 289 | + s.SetScanBinary(true) |
| 290 | + if !s.ScanBinary() { |
| 291 | + t.Error("Expected scan binary true") |
| 292 | + } |
| 293 | +} |
| 294 | + |
| 295 | +func TestMatcherMixedTraditionalSimplified(t *testing.T) { |
| 296 | + c := classifier.New("繁體", "简体") |
| 297 | + m := matcher.New(c) |
| 298 | + |
| 299 | + results := m.Find("繁體简体混合") |
| 300 | + if len(results) < 1 { |
| 301 | + t.Fatalf("Expected at least 1 match, got %d", len(results)) |
| 302 | + } |
| 303 | + // Mixed traditional + simplified in one sequence should be classified as Common |
| 304 | + if results[0].Type != classifier.Common { |
| 305 | + t.Errorf("Expected Common for mixed, got %v", results[0].Type) |
| 306 | + } |
| 307 | +} |
| 308 | + |
| 309 | +func TestMatcherSimplifiedOnly(t *testing.T) { |
| 310 | + c := classifier.New("", "简体") |
| 311 | + m := matcher.New(c) |
| 312 | + |
| 313 | + results := m.Find("这是简体") |
| 314 | + if len(results) < 1 { |
| 315 | + t.Fatalf("Expected at least 1 match, got %d", len(results)) |
| 316 | + } |
| 317 | + if results[0].Type != classifier.Simplified { |
| 318 | + t.Errorf("Expected Simplified, got %v", results[0].Type) |
| 319 | + } |
| 320 | +} |
0 commit comments