Artifact 5e5288589bb02d4e5466e5e3ee74e6841e004824e909bc58a063ad9192eebf20:
- File
internal/index/verdict_test.go
— part of check-in
[1305bb9374]
at
2026-08-26 12:56:35
on branch landings-batch
— A landing's CI verdict: the branch tip's tag, nothing new minted
The ticket asked to decide the shape — forum reply or tag — before wiring the display. Neither is needed: a verdict is already a tag on a check-in, quarry already folds and reads them, and a landing proposes a branch whose tip is a check-in.
Better on its own terms too. The verdict stays attached to what was actually tested rather than to a discussion record, keeps the zit#127 invariant with no new vocabulary, and a retargeted or reopened landing inherits the right answer without anyone copying it across.
Read at render, never stored, so it cannot go stale against the branch it describes. No run leaves it empty, which reads as 'nothing has run' rather than as bad news. (user: dmestas, size: 2633) [annotate] [blame] [check-ins using] [more...]
package index import ( "testing" ) func tagCheckin(t *testing.T, ix *Index, checkin, name, date string) { t.Helper() if _, err := ix.db.Exec(`INSERT OR REPLACE INTO checkin_tag (checkin, name, sign, value, date, src) VALUES (?, ?, '+', '', ?, 'tagartifact')`, checkin, name, date); err != nil { t.Fatal(err) } } // The ticket asked which shape a landing verdict should take — forum // reply or tag — before wiring the display. Neither: a verdict is // already a tag on a CHECK-IN, and a landing proposes a branch whose // tip is one. Nothing new to mint, and the verdict stays attached to // the thing that was actually tested. func TestLandingVerdictComesFromTheBranchTip(t *testing.T) { ix := openIndex(t) ci(t, ix, "t1", "trunk", "2026-01-01T10:00:00", "base") ci(t, ix, "f1", "feat", "2026-01-02T10:00:00", "first", "t1") ci(t, ix, "f2", "feat", "2026-01-02T10:00:00", "tip", "f1") tagCheckin(t, ix, "f2", "ci-pass", "2026-01-02T11:00:00") got, err := ix.VerdictsForLandings([]string{"feat"}) if err != nil { t.Fatal(err) } if got["feat"] != "ci-pass" { t.Fatalf("verdict %q, want ci-pass", got["feat"]) } } // A verdict on an older commit is not the branch's verdict: the tip is // what a reviewer would land. func TestAVerdictOnAnOlderCommitIsNotTheBranchsVerdict(t *testing.T) { ix := openIndex(t) ci(t, ix, "t1", "trunk", "2026-01-01T10:00:00", "base") ci(t, ix, "f1", "feat", "2026-01-02T10:00:00", "first", "t1") ci(t, ix, "f2", "feat", "2026-01-02T10:00:00", "tip, untested", "f1") tagCheckin(t, ix, "f1", "ci-pass", "2026-01-02T11:00:00") got, _ := ix.VerdictsForLandings([]string{"feat"}) if got["feat"] != "" { t.Errorf("verdict %q — an untested tip inherited an older pass", got["feat"]) } } // A later run supersedes an earlier one, the same way the timeline // reads tags: newest wins. func TestTheLatestRunWins(t *testing.T) { ix := openIndex(t) ci(t, ix, "f1", "feat", "2026-01-02T10:00:00", "tip") tagCheckin(t, ix, "f1", "ci-fail", "2026-01-02T11:00:00") tagCheckin(t, ix, "f1", "ci-pass", "2026-01-02T12:00:00") if got, _ := ix.VerdictsForLandings([]string{"feat"}); got["feat"] != "ci-pass" { t.Errorf("verdict %q, want the later ci-pass", got["feat"]) } } // No run is not a failure. An empty verdict must read as "nothing has // run", never as bad news. func TestNoRunIsNotAVerdict(t *testing.T) { ix := openIndex(t) ci(t, ix, "f1", "feat", "2026-01-02T10:00:00", "tip") got, err := ix.VerdictsForLandings([]string{"feat", "", "never-heard-of-it"}) if err != nil { t.Fatal(err) } if len(got) != 0 { t.Fatalf("got %v, want nothing", got) } }