Artifact 67094907b2a7726ec5d0ceb3b6385253c5865d050deadf5d9e42ac66b1129f72:
- File
internal/index/supersede_test.go
— part of check-in
[4832508615]
at
2026-08-26 23:13:58
on branch protect-3
— RFC 0007 phase 3: the merge is the fact; accept asks MayJoin
The fold reads accepted from the DAG, for every landing: the earliest target check-in after opening whose non-primary parent is on the proposed branch. A reply asserting acceptance with nothing merged leaves the record open and is recorded as a claim; the page says so, the timeline files it as conversation. Rejection has no DAG fact and stays the reply's to say. Re-derived after every branch recompute — which now also invalidates the count memo, since it can settle a landing — so a merge pushed from a clone with no reply settles.
landing.accept refuses a non-owner on a protected target before writing, naming the owners. landing.get reports MayLand beside CanAccept so the page shows a disabled control with the reason.
Fourteen existing tests settled records by reply alone, or asserted a by-hand merge does not count; each now carries the merge it announces or asserts the RFC's reading. Giving the web fixture real check-ins exposed checkin.diff dereferencing a nil store; it now refuses, after the lookups so not-found still wins. (user: dmestas, size: 5116) [annotate] [blame] [check-ins using] [more...]
package index import ( "testing" ) func landingOn(t *testing.T, ix *Index, root, branch, opened, title string) { t.Helper() foldForumBody(t, ix, root, "", title, opened, landingBody(branch, "trunk", "please")) } // zit#127 left one-open-landing-per-branch as "probably yes, refused by // name on the second" and neither side enforced it. Refusing at open // cannot be the whole answer: two people can open a landing for one // branch in separate clones, and both are ordinary forum threads that // are valid artifacts when they meet. So the readers agree instead. func TestSecondOpenLandingOnABranchIsSuperseded(t *testing.T) { ix := openIndex(t) landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "First try") landingOn(t, ix, "bbbb2222", "feat-x", "2026-01-05T10:00:00", "Second try") first := onlyOne(t, ix, "aaaa1111") second := onlyOne(t, ix, "bbbb2222") if second.SupersededBy != "" { t.Errorf("the newest landing was superseded by %q", second.SupersededBy) } if first.SupersededBy != "bbbb2222" { t.Errorf("the older landing defers to %q, want bbbb2222", first.SupersededBy) } // The open queue is a work list and shows one per branch... open, err := ix.Landings("open", 0) if err != nil { t.Fatal(err) } if len(open) != 1 || open[0].ID != "bbbb2222" { t.Fatalf("open queue holds %d landings, want just the current one", len(open)) } // ...and nothing is lost: the record and its discussion remain. all, _ := ix.Landings("", 0) if len(all) != 2 { t.Fatalf("the superseded record disappeared: %d listed, want 2", len(all)) } } func onlyOne(t *testing.T, ix *Index, id string) LandingSummary { t.Helper() l, ok, err := ix.Landing(id) if err != nil || !ok { t.Fatalf("landing %s: ok=%v err=%v", id, ok, err) } return l } // Recomputed every fold rather than accumulated, so a record can become // current again when the one that displaced it is settled. func TestSupersedingIsRecomputedNotAccumulated(t *testing.T) { ix := openIndex(t) landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "First try") landingOn(t, ix, "bbbb2222", "feat-x", "2026-01-05T10:00:00", "Second try") if l := onlyOne(t, ix, "aaaa1111"); l.SupersededBy != "bbbb2222" { t.Fatalf("precondition: %+v", l) } // The newer one is rejected, so it is no longer open. foldForumBody(t, ix, "cccc3333", "bbbb2222", "", "2026-01-06T10:00:00", landingState("rejected", "not this")) if l := onlyOne(t, ix, "aaaa1111"); l.SupersededBy != "" { t.Errorf("the surviving open landing is still marked superseded by %q", l.SupersededBy) } if open, _ := ix.Landings("open", 0); len(open) != 1 || open[0].ID != "aaaa1111" { t.Errorf("open queue is %+v, want the revived first landing", open) } } // A settled landing is history and its check-in is on the target. A // later proposal for the same branch is a new proposal, not a // correction of a finished one. func TestSettledLandingsAreNeverSuperseded(t *testing.T) { ix := openIndex(t) // Settled by the DAG (RFC 0007): the merge is the fact. A reply // alone would be a claim, and a claimed-but-open record is open. ci(t, ix, "t1", "trunk", "2026-01-01T09:00:00", "base") landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "Landed already") ci(t, ix, "f1", "feat-x", "2026-01-01T11:00:00", "work", "t1") ci(t, ix, "m1", "trunk", "2026-01-02T09:59:00", "land feat-x", "t1", "f1") foldForumBody(t, ix, "dddd4444", "aaaa1111", "", "2026-01-02T10:00:00", landingState("accepted", "in it goes")) landingOn(t, ix, "bbbb2222", "feat-x", "2026-01-05T10:00:00", "Round two") if l := onlyOne(t, ix, "aaaa1111"); l.SupersededBy != "" { t.Errorf("an ACCEPTED landing was superseded by %q", l.SupersededBy) } if l := onlyOne(t, ix, "bbbb2222"); l.SupersededBy != "" { t.Errorf("the new proposal was superseded by %q", l.SupersededBy) } } // One landing on a branch is the ordinary case and must stay untouched. func TestASingleLandingIsNeverMarked(t *testing.T) { ix := openIndex(t) landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "Only one") landingOn(t, ix, "bbbb2222", "feat-y", "2026-01-02T10:00:00", "Different branch") for _, id := range []string{"aaaa1111", "bbbb2222"} { if l := onlyOne(t, ix, id); l.SupersededBy != "" { t.Errorf("%s marked superseded by %q with no rival on its branch", id, l.SupersededBy) } } if open, _ := ix.Landings("open", 0); len(open) != 2 { t.Errorf("open queue holds %d, want both", len(open)) } } // The courtesy check the writer makes before opening a second. func TestOpenLandingOnFindsTheCurrentOne(t *testing.T) { ix := openIndex(t) if _, found, err := ix.OpenLandingOn("feat-x"); found || err != nil { t.Fatalf("empty index: found=%v err=%v", found, err) } landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "First try") landingOn(t, ix, "bbbb2222", "feat-x", "2026-01-05T10:00:00", "Second try") l, found, err := ix.OpenLandingOn("feat-x") if err != nil || !found { t.Fatalf("found=%v err=%v", found, err) } if l.ID != "bbbb2222" { t.Errorf("the check names %q, want the current landing", l.ID) } }