package review import ( "strings" "testing" ) func TestFormatMarkdown_EmptyFindings(t *testing.T) { result := &ReviewResult{ Verdict: "APPROVE", Summary: "All good, no issues.", Findings: []Finding{}, Recommendation: "Merge this PR.", } got := FormatMarkdown(result, "Sonnet") if !strings.Contains(got, "## Summary") { t.Error("expected Summary header") } if !strings.Contains(got, "All good, no issues.") { t.Error("expected summary text") } if strings.Contains(got, "## Findings") { t.Error("should not contain Findings header when empty") } if !strings.Contains(got, "**APPROVE**") { t.Error("expected verdict in recommendation") } if !strings.Contains(got, "Review by Sonnet") { t.Error("expected reviewer name") } } func TestFormatMarkdown_MultipleFindings(t *testing.T) { result := &ReviewResult{ Verdict: "REQUEST_CHANGES", Summary: "Several issues found.", Findings: []Finding{ {Severity: "MAJOR", File: "main.go", Line: 42, Finding: "Nil pointer dereference"}, {Severity: "MINOR", File: "util.go", Line: 7, Finding: "Unused variable"}, {Severity: "NIT", File: "doc.go", Line: 1, Finding: "Typo in comment"}, }, Recommendation: "Fix the nil pointer issue before merging.", } got := FormatMarkdown(result, "GPT") if !strings.Contains(got, "## Findings") { t.Error("expected Findings header") } if !strings.Contains(got, "| 1 | [MAJOR] | `main.go` | 42 | Nil pointer dereference |") { t.Error("expected first finding row") } if !strings.Contains(got, "| 2 | [MINOR] | `util.go` | 7 | Unused variable |") { t.Error("expected second finding row") } if !strings.Contains(got, "| 3 | [NIT] | `doc.go` | 1 | Typo in comment |") { t.Error("expected third finding row") } if !strings.Contains(got, "**REQUEST_CHANGES**") { t.Error("expected verdict in recommendation") } } func TestFormatMarkdown_NoReviewerName(t *testing.T) { result := &ReviewResult{ Verdict: "APPROVE", Summary: "Fine.", Findings: []Finding{}, Recommendation: "Go ahead.", } got := FormatMarkdown(result, "") if strings.Contains(got, "Review by") { t.Error("should not contain reviewer line when name is empty") } } func TestFormatMarkdown_SpecialChars(t *testing.T) { result := &ReviewResult{ Verdict: "REQUEST_CHANGES", Summary: "Issues with `fmt.Sprintf` usage.", Findings: []Finding{ {Severity: "MAJOR", File: "render.go", Line: 15, Finding: "Use `%v` instead of `%s` for interface{}"}, }, Recommendation: "Fix the format verb.", } got := FormatMarkdown(result, "Test") // Should contain the backtick content without breaking the table if !strings.Contains(got, "`render.go`") { t.Error("expected file in backticks") } if !strings.Contains(got, "Use `%v` instead of `%s` for interface{}") { t.Error("expected finding text with backticks preserved") } } func TestGiteaEvent(t *testing.T) { tests := []struct { verdict string expected string }{ {"APPROVE", "APPROVED"}, {"REQUEST_CHANGES", "REQUEST_CHANGES"}, {"UNKNOWN", "COMMENT"}, {"", "COMMENT"}, } for _, tc := range tests { got := GiteaEvent(tc.verdict) if got != tc.expected { t.Errorf("GiteaEvent(%q) = %q, want %q", tc.verdict, got, tc.expected) } } }