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", "