200 lines
4.7 KiB
Go
200 lines
4.7 KiB
Go
package report
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeFillsMissingAsUntested(t *testing.T) {
|
|
t.Parallel()
|
|
items, err := Normalize(Results{Items: []Item{
|
|
{ID: "F01", Status: StatusPass, Note: "ok"},
|
|
{ID: "f08", Status: "失败", Note: "flaky"},
|
|
}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(items) != 23 {
|
|
t.Fatalf("len=%d", len(items))
|
|
}
|
|
if items[0].Status != StatusPass || items[0].Note != "ok" {
|
|
t.Fatalf("F01=%+v", items[0])
|
|
}
|
|
if items[7].Status != StatusFail {
|
|
t.Fatalf("F08=%+v", items[7])
|
|
}
|
|
if items[22].Status != StatusUntested {
|
|
t.Fatalf("F23=%+v", items[22])
|
|
}
|
|
}
|
|
|
|
func TestWriteMarkdownSample(t *testing.T) {
|
|
t.Parallel()
|
|
path := filepath.Join("testdata", "sample_results.json")
|
|
r, err := LoadResults(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
items, err := Normalize(r)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := WriteMarkdown(&buf, items); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
out := buf.String()
|
|
for _, id := range []string{"F01", "F12", "F23"} {
|
|
if !strings.Contains(out, id) {
|
|
t.Fatalf("missing %s in:\n%s", id, out)
|
|
}
|
|
}
|
|
if !strings.Contains(out, "未测") {
|
|
t.Fatalf("expected 未测:\n%s", out)
|
|
}
|
|
if !strings.Contains(out, "通过 0,部分通过 0,失败 0,未测 23") {
|
|
t.Fatalf("summary mismatch:\n%s", out)
|
|
}
|
|
}
|
|
|
|
func TestCatalogHonestSummary(t *testing.T) {
|
|
t.Parallel()
|
|
items := CatalogItems()
|
|
if len(items) != 23 {
|
|
t.Fatalf("len=%d", len(items))
|
|
}
|
|
var pass, partial, fail, untested int
|
|
for _, it := range items {
|
|
if it.Status == StatusPass && it.Total > 0 {
|
|
if it.Passed != it.Total {
|
|
t.Fatalf("%s pass but %d/%d", it.ID, it.Passed, it.Total)
|
|
}
|
|
}
|
|
if it.Status == StatusPartial {
|
|
if it.Passed == it.Total || it.Passed == 0 {
|
|
t.Fatalf("%s partial but %d/%d", it.ID, it.Passed, it.Total)
|
|
}
|
|
}
|
|
switch it.Status {
|
|
case StatusPass:
|
|
pass++
|
|
case StatusPartial:
|
|
partial++
|
|
case StatusFail:
|
|
fail++
|
|
default:
|
|
untested++
|
|
}
|
|
}
|
|
if pass != 19 || partial != 4 || fail != 0 || untested != 0 {
|
|
t.Fatalf("pass=%d partial=%d fail=%d untested=%d", pass, partial, fail, untested)
|
|
}
|
|
wantPartial := map[string]bool{"F03": true, "F08": true, "F21": true, "F22": true}
|
|
for _, it := range items {
|
|
if wantPartial[it.ID] && it.Status != StatusPartial {
|
|
t.Fatalf("%s want partial got %s", it.ID, it.Status)
|
|
}
|
|
if !wantPartial[it.ID] && it.Status != StatusPass {
|
|
t.Fatalf("%s want pass got %s", it.ID, it.Status)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReconcileLiveFailWins(t *testing.T) {
|
|
t.Parallel()
|
|
out := Reconcile([]Item{{ID: "F04", Status: StatusFail, Note: "probe failed"}})
|
|
var f04 Item
|
|
for _, it := range out {
|
|
if it.ID == "F04" {
|
|
f04 = it
|
|
break
|
|
}
|
|
}
|
|
if f04.Status != StatusFail || f04.Note != "probe failed" {
|
|
t.Fatalf("F04=%+v", f04)
|
|
}
|
|
}
|
|
|
|
func TestRollupPartial(t *testing.T) {
|
|
t.Parallel()
|
|
it := Rollup(Item{ID: "X", Subs: []SubItem{
|
|
{ID: "Xa", Status: StatusPass},
|
|
{ID: "Xb", Status: StatusUntested, Note: "skip"},
|
|
}})
|
|
if it.Status != StatusPartial || it.Passed != 1 || it.Total != 2 {
|
|
t.Fatalf("%+v", it)
|
|
}
|
|
}
|
|
|
|
func TestEmptyResultsRoundTrip(t *testing.T) {
|
|
t.Parallel()
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "empty.json")
|
|
raw, err := json.MarshalIndent(EmptyResults(), "", " ")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if writeErr := os.WriteFile(path, raw, 0o644); writeErr != nil {
|
|
t.Fatal(writeErr)
|
|
}
|
|
r, err := LoadResults(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(r.Items) != 23 {
|
|
t.Fatalf("items=%d", len(r.Items))
|
|
}
|
|
}
|
|
|
|
func TestWriteCatalogArtifacts(t *testing.T) {
|
|
if os.Getenv("NIXMSG_WRITE_ACCEPT_REPORT") != "1" {
|
|
t.Skip("set NIXMSG_WRITE_ACCEPT_REPORT=1 to rewrite ACCEPTANCE.md")
|
|
}
|
|
dir, wdErr := os.Getwd()
|
|
if wdErr != nil {
|
|
t.Fatal(wdErr)
|
|
}
|
|
for {
|
|
if _, stErr := os.Stat(filepath.Join(dir, "go.mod")); stErr == nil {
|
|
break
|
|
}
|
|
parent := filepath.Dir(dir)
|
|
if parent == dir {
|
|
t.Fatal("go.mod not found")
|
|
}
|
|
dir = parent
|
|
}
|
|
r := CatalogResults()
|
|
raw, marshErr := json.MarshalIndent(r, "", " ")
|
|
if marshErr != nil {
|
|
t.Fatal(marshErr)
|
|
}
|
|
jsonPath := filepath.Join(dir, "test", "report", "testdata", "q2_results.json")
|
|
if writeErr := os.WriteFile(jsonPath, append(raw, '\n'), 0o644); writeErr != nil {
|
|
t.Fatal(writeErr)
|
|
}
|
|
items, normErr := Normalize(r)
|
|
if normErr != nil {
|
|
t.Fatal(normErr)
|
|
}
|
|
var buf bytes.Buffer
|
|
if mdErr := WriteMarkdown(&buf, items); mdErr != nil {
|
|
t.Fatal(mdErr)
|
|
}
|
|
mdPath := filepath.Join(dir, "test", "accept", "ACCEPTANCE.md")
|
|
if writeMD := os.WriteFile(mdPath, buf.Bytes(), 0o644); writeMD != nil {
|
|
t.Fatal(writeMD)
|
|
}
|
|
}
|
|
|
|
func TestParseStatusRejectsUnknown(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := Normalize(Results{Items: []Item{{ID: "F01", Status: "maybe"}}}); err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
}
|