Skip to content
quarry Artifact [55c1b0c6b5]
Login

Artifact [55c1b0c6b5]

Artifact 55c1b0c6b5db779cf030afd2c2ed5d465b7701906a0e84081210c0f406dba89d:


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)
	landingOn(t, ix, "aaaa1111", "feat-x", "2026-01-01T10:00:00", "Landed already")
	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)
	}
}