3c536c42d5
- gitea/client_test.go: mock HTTP tests for all API methods + error cases - llm/client_test.go: mock tests for completion, errors, timeouts - review/parser_test.go: JSON parsing, markdown fences, validation - review/formatter_test.go: markdown output, empty/multiple findings - review/prompt_test.go: system/user prompt construction - integration_test.go: full end-to-end flow (build tag: integration) - .gitea/workflows/ci.yml: test + vet + build on push, dual LLM review on PRs - CONVENTIONS.md: coding standards for self-review dogfooding - README.md: usage docs, env vars, architecture
119 lines
3.2 KiB
Go
119 lines
3.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|