You've already forked agentic-coding-workflow
130 lines
3.7 KiB
Go
130 lines
3.7 KiB
Go
package run
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func readFixture(t *testing.T, name string) []byte {
|
|
t.Helper()
|
|
b, err := os.ReadFile(filepath.Join("testdata", name))
|
|
if err != nil {
|
|
t.Fatalf("read fixture %s: %v", name, err)
|
|
}
|
|
return b
|
|
}
|
|
|
|
func TestParseGoTestJSON(t *testing.T) {
|
|
sum, err := parseGoTestJSON(readFixture(t, "gotest.jsonl"))
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if sum.Framework != "gotest" {
|
|
t.Fatalf("framework = %q", sum.Framework)
|
|
}
|
|
if sum.Passed != 1 || sum.Failed != 1 || sum.Skipped != 1 || sum.Total != 3 {
|
|
t.Fatalf("counts p=%d f=%d s=%d t=%d", sum.Passed, sum.Failed, sum.Skipped, sum.Total)
|
|
}
|
|
if len(sum.Failures) != 1 || sum.Failures[0].Name != "TestFail" || sum.Failures[0].Package != "example/pkg" {
|
|
t.Fatalf("failures = %+v", sum.Failures)
|
|
}
|
|
if sum.Failures[0].Message == "" {
|
|
t.Fatal("failure message should not be empty")
|
|
}
|
|
}
|
|
|
|
func TestParseJUnitXML(t *testing.T) {
|
|
sum, err := parseJUnitXML(readFixture(t, "junit.xml"))
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if sum.Framework != "junit" {
|
|
t.Fatalf("framework = %q", sum.Framework)
|
|
}
|
|
if sum.Passed != 1 || sum.Failed != 1 || sum.Skipped != 1 || sum.Total != 3 {
|
|
t.Fatalf("counts p=%d f=%d s=%d t=%d", sum.Passed, sum.Failed, sum.Skipped, sum.Total)
|
|
}
|
|
if len(sum.Failures) != 1 || sum.Failures[0].Name != "testFails" {
|
|
t.Fatalf("failures = %+v", sum.Failures)
|
|
}
|
|
if sum.Failures[0].Message != "expected true but was false" {
|
|
t.Fatalf("failure message = %q", sum.Failures[0].Message)
|
|
}
|
|
}
|
|
|
|
func TestParseVitestJSON(t *testing.T) {
|
|
sum, err := parseVitestJSON(readFixture(t, "vitest.json"))
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if sum.Framework != "vitest" {
|
|
t.Fatalf("framework = %q", sum.Framework)
|
|
}
|
|
if sum.Passed != 1 || sum.Failed != 1 || sum.Skipped != 1 || sum.Total != 3 {
|
|
t.Fatalf("counts p=%d f=%d s=%d t=%d", sum.Passed, sum.Failed, sum.Skipped, sum.Total)
|
|
}
|
|
if len(sum.Failures) != 1 || sum.Failures[0].Name != "sum > subtracts" {
|
|
t.Fatalf("failures = %+v", sum.Failures)
|
|
}
|
|
if sum.Failures[0].Message != "expected 1 to be 2" {
|
|
t.Fatalf("failure message = %q", sum.Failures[0].Message)
|
|
}
|
|
}
|
|
|
|
// TestParseTestOutput_Auto 验证 auto 嗅探把各格式路由到正确解析器。
|
|
func TestParseTestOutput_Auto(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
fixture string
|
|
want string
|
|
}{
|
|
{"gotest", "gotest.jsonl", "gotest"},
|
|
{"junit", "junit.xml", "junit"},
|
|
{"vitest", "vitest.json", "vitest"},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
sum, err := parseTestOutput("auto", string(readFixture(t, tc.fixture)), "")
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if sum.Framework != tc.want {
|
|
t.Fatalf("framework = %q, want %q", sum.Framework, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestParseTestOutput_Malformed 验证解析失败返回 error(由 RunTests 折成 ParseError),
|
|
// 永不 panic。
|
|
func TestParseTestOutput_Malformed(t *testing.T) {
|
|
cases := []struct {
|
|
format string
|
|
in string
|
|
}{
|
|
{"gotest", "not json at all"},
|
|
{"junit", "<broken><xml"},
|
|
{"vitest", "{not valid"},
|
|
{"auto", ""},
|
|
{"auto", "random text with no structure"},
|
|
}
|
|
for _, tc := range cases {
|
|
_, err := parseTestOutput(tc.format, tc.in, "")
|
|
if err == nil {
|
|
t.Fatalf("format %q input %q: expected parse error, got nil", tc.format, tc.in)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestParseGoTestJSON_StderrFallback 验证 stdout 为空时退回 stderr。
|
|
func TestParseTestOutput_StderrFallback(t *testing.T) {
|
|
sum, err := parseTestOutput("auto", "", string(readFixture(t, "gotest.jsonl")))
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if sum.Framework != "gotest" || sum.Total != 3 {
|
|
t.Fatalf("got %+v", sum)
|
|
}
|
|
}
|