Skip to content
go-libfossil Artifact [229d78a1a5]
Login

Artifact [229d78a1a5]

Artifact 229d78a1a590be3a6f9b26852afde224cf04ea812150529ac087428a92d8d996:


package conformance

// Derived-state cases for branch membership (Section 6) and the leaf table
// (Section 7).

func branchCases() []rsCase {
	return []rsCase{{
		// b2 inherits feat, and c2 trunk, each from its branch's root.
		Case:   Case{ID: "repostate.5.4.branch-inherited", Req: "RS-5.4-5"},
		arts:   branched(),
		tables: []string{"tagxref"},
		tags:   []string{"branch", "sym-feat", "sym-trunk"},
		want: rows("tagxref",
			"branch c1 2 c1 c1 'trunk' @1", "branch b1 2 b1 b1 'feat' @2",
			"branch b2 2 0 b1 'feat' @2", "branch c2 2 0 c1 'trunk' @1",
			"sym-trunk c1 2 c1 c1 NULL @1", "sym-trunk b1 0 b1 b1 NULL @2",
			"sym-trunk c2 2 0 c1 NULL @1",
			"sym-feat b1 2 b1 b1 NULL @2", "sym-feat b2 2 0 b1 NULL @2"),
		ignoring: []string{"-tagxref: branch b2 2 0 b1 'feat' @2",
			"+tagxref: branch b2 2 0 c1 'trunk' @1"},
		rebuild: true,
	}}
}

// leaves is a case comparing only the leaf table.
func leaves(id, req string, arts []rsArt, want []string, ignoring ...string) rsCase {
	return rsCase{
		Case:     Case{ID: id, Req: req},
		arts:     arts,
		tables:   []string{"leaf"},
		want:     rows("leaf", want...),
		ignoring: ignoring,
		rebuild:  true,
	}
}

// mergedIntoTrunk is c1 with b1 and b2 on feat and c2 on trunk; x, moved
// back to trunk, has primary parent b1 and merge parent c2. c2's only
// child is x, on its own branch through a merge link, so c2 is no leaf.
func mergedIntoTrunk() []rsArt {
	return []rsArt{
		checkin("c1", 1, nil, rsRoot...),
		checkin("b1", 2, of("c1"), rsFeat...),
		checkin("c2", 3, of("c1")),
		checkin("b2", 4, of("b1")),
		checkin("x", 5, of("b1", "c2"), "*branch * trunk", "*sym-trunk *", "-sym-feat *"),
	}
}

func leafCases() []rsCase {
	// Section 7.3 makes a parentless check-in with no same-branch child a
	// leaf; fossil(1) never makes an untagged one a leaf. The case follows
	// the draft, and go-libfossil's crosslink, following fossil, is marked
	// as a deviation.
	untagged := leaves("repostate.7.3.parentless-untagged", "RS-7.3-1",
		[]rsArt{checkin("c1", 1, nil)}, []string{"c1"}, "-leaf: c1")
	untagged.fossil = "fossil 2.28 never makes an untagged parentless check-in a leaf; " +
		"erratum candidate against Section 7.3"
	// c4 carries its own trunk tag, so retagging c3 feat leaves c3 with no
	// same-branch child: re-evaluating c3 itself makes it a leaf.
	ownTrunk := with(chain()[:3], checkin("c4", 4, of("c3"), "*branch * trunk"),
		control("t", 9, "*branch {c3} feat", "*sym-feat {c3}", "-sym-trunk {c3}"))
	// c4 gains feat by propagation from c3 and so stops being the merge
	// parent of a same-branch check-in: m stays on trunk.
	retagged := with(chain(), checkin("m", 5, of("c1", "c4")),
		control("t", 9, "*branch {c3} feat", "*sym-feat {c3}", "-sym-trunk {c3}"))
	// c1's cancelled feat row is not active, so c1 is on trunk, the
	// default branch, with c2: no leaf.
	cancelled := leaves("repostate.6.4.cancelled-branch-leaf", "RS-6.4-1", cancelledBranch(),
		[]string{"c2"}, "+leaf: c1")
	cancelled.fossil = "fossil 2.28's leaf_check reads the branch value without tagtype > 0 " +
		"(src/leaf.c), so c1's cancelled feat row keeps it a leaf; fossil-bug candidate " +
		"against Section 6.4"
	// Crosslinking c2 rechecks c2, a leaf, and c1, which c2 joins on trunk.
	childRecheck := leaves("repostate.7.3.recheck-untagged-child", "RS-7.3-3",
		untaggedChild(), []string{"c2"}, "-leaf: c2", "+leaf: c1")
	childRecheck.fossil = "fossil 2.28 rechecks leaves only when a branch tag lands, so c2, " +
		"which carries none, is never checked: per-artifact keeps c1, rebuild neither; the " +
		"informative note of Section 7.3 records this"
	// Crosslinking c1, alone, untagged and parentless, rechecks it: the
	// trigger half of the RS-7.3-1 deviation.
	lone := leaves("repostate.7.3.recheck-lone-untagged", "RS-7.3-3",
		[]rsArt{checkin("c1", 1, nil)}, []string{"c1"}, "-leaf: c1")
	lone.each, lone.rebuild, lone.fossil = true, false, untagged.fossil
	return []rsCase{
		leaves("repostate.7.2.branch-leaves", "RS-7.2-1", merged(),
			[]string{"b1", "m"}, "-leaf: b1"),
		leaves("repostate.7.2.merge-child-leaf", "RS-7.2-1", mergedIntoTrunk(),
			[]string{"b2", "x"}, "+leaf: c2"),
		untagged,
		leaves("repostate.7.3.sole-root", "RS-7.3-1",
			[]rsArt{checkin("c1", 1, nil, rsRoot...)}, []string{"c1"}, "-leaf: c1"),
		leaves("repostate.7.6.retag-branch", "RS-7.6-1", ownTrunk,
			[]string{"c2", "c3", "c4"}, "-leaf: c3"),
		leaves("repostate.7.6.propagated-branch", "RS-7.6-2", retagged,
			[]string{"c2", "c4", "m"}, "-leaf: c4"),
		cancelled, childRecheck,
		// Crosslinking b1 rechecks c1, its parent, which has no tag and no
		// parent: b1 is on feat, so c1, on the default branch, is a leaf.
		leaves("repostate.7.3.recheck-untagged-root", "RS-7.3-3",
			[]rsArt{checkin("c1", 1, nil), checkin("b1", 2, of("c1"), rsFeat...)},
			[]string{"b1", "c1"}, "-leaf: c1"),
		lone,
	}
}