fix: 验收对照表按子项记结果不再虚报通过

This commit is contained in:
Nixevol
2026-09-30 16:24:56 +08:00
parent c72d1f0427
commit cb9512fe11
11 changed files with 1138 additions and 93 deletions
+111 -1
View File
@@ -56,11 +56,80 @@ func TestWriteMarkdownSample(t *testing.T) {
if !strings.Contains(out, "未测") {
t.Fatalf("expected 未测:\n%s", out)
}
if !strings.Contains(out, "通过 0,失败 0,未测 23") {
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()
@@ -81,6 +150,47 @@ func TestEmptyResultsRoundTrip(t *testing.T) {
}
}
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 {