mesh/merge-gate pass: builds new: modules/mesh-knowledge, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compo…
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery superseded: a newer head of the same pull request
A revision came from anyone and a review was refused only to the first author, so a co-writer could approve, and a record proposed before callers are proven would later be reviewable by its own unproven author. Now a revision is taken only from the proven author, a reserved number only from whoever reserved it, and a review is refused from any writer of any version or for any record with an unproven writer. The rules held records from no date, so a correction to an older record was refused by rules hq never held it to; each dated rule now holds from hq's own start date, and a new record cannot be dated before its reservation. history and the question to ask are bounded like the other answers.
152 lines
5.3 KiB
Go
152 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// to-be 55 §10: "Every version is kept and comparable — the module's test: three versions, history lists them,
|
|
// the difference of the first and third is exact."
|
|
func TestThreeVersionsAreKeptAndTheFirstAndThirdCompareExactly(t *testing.T) {
|
|
eachStore(t, func(t *testing.T, s Store) {
|
|
w := imported(t, s)
|
|
n := w.reserved(t, "author@g14") // version 1: the reservation
|
|
p := valid(n)
|
|
if _, err := w.k.Propose("author@g14", p); err != nil { // version 2
|
|
t.Fatal(err)
|
|
}
|
|
p.Clauses[1] = "**A batch is delivered by one walk.** At most one commit per repository."
|
|
p.Why = "the bound named"
|
|
if _, err := w.k.Propose("author@g14", p); err != nil { // version 3
|
|
t.Fatal(err)
|
|
}
|
|
h, err := w.k.History(Key{KindDecision, n}, 0, 0, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(h.Versions) != 3 || h.Versions[0].Status != StatusReserved || h.Versions[1].Why != "proposed" ||
|
|
h.Versions[2].Why != "the bound named" || !h.Versions[2].Served || h.Versions[0].By != "author@g14" {
|
|
t.Fatalf("history: %+v", h.Versions)
|
|
}
|
|
d, err := w.k.History(Key{KindDecision, n}, 1, 3, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
vs, _ := s.Versions(t.Context(), Key{KindDecision, n})
|
|
// Exact: applying the difference to the first version's text gives the third's, line for line.
|
|
if got := applyDiff(Render(vs[0].Record), d.Diff); got != Render(vs[2].Record) {
|
|
t.Fatalf("the difference does not turn version 1 into version 3:\n%s\n---\n%s", got, Render(vs[2].Record))
|
|
}
|
|
// And it is the difference: what changed between the reservation and the revised proposal, nothing else.
|
|
want := []string{"-status: reserved", "+status: proposed", "+topic: the mesh", "+date: 2026-10-11"}
|
|
for _, line := range want {
|
|
if !containsLine(d.Diff, line) {
|
|
t.Errorf("the difference lacks %q: %v", line, d.Diff)
|
|
}
|
|
}
|
|
if containsLine(d.Diff, "-# "+strings.TrimPrefix(itoaKey(n), "ADR ")+". a test record") == false {
|
|
t.Errorf("the title's change is not in the difference: %v", d.Diff)
|
|
}
|
|
// Versions 2 and 3 differ in clause 2 alone.
|
|
d23, _ := w.k.History(Key{KindDecision, n}, 2, 3, 0)
|
|
var changed []string
|
|
for _, l := range d23.Diff {
|
|
if !strings.HasPrefix(l, "@@") {
|
|
changed = append(changed, l)
|
|
}
|
|
}
|
|
if !reflect.DeepEqual(changed, []string{"-2. **A batch is delivered by one walk.** One commit per repository.",
|
|
"+2. **A batch is delivered by one walk.** At most one commit per repository."}) {
|
|
t.Fatalf("2 to 3: %v", d23.Diff)
|
|
}
|
|
if d22, _ := w.k.History(Key{KindDecision, n}, 2, 2, 0); !d22.Same || len(d22.Diff) != 0 {
|
|
t.Fatalf("a version against itself: %+v", d22)
|
|
}
|
|
})
|
|
}
|
|
|
|
func containsLine(lines []string, s string) bool {
|
|
for _, l := range lines {
|
|
if l == s {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// applyDiff applies a difference as Diff writes it to the text it was taken from.
|
|
func applyDiff(a string, diff []string) string {
|
|
src := strings.Split(a, "\n")
|
|
var out []string
|
|
at := 0
|
|
for i := 0; i < len(diff); i++ {
|
|
var oa, ca, ob, cb int
|
|
if _, err := fmt.Sscanf(diff[i], "@@ -%d,%d +%d,%d @@", &oa, &ca, &ob, &cb); err != nil {
|
|
continue
|
|
}
|
|
for at < oa-1 {
|
|
out = append(out, src[at])
|
|
at++
|
|
}
|
|
for i+1 < len(diff) && !strings.HasPrefix(diff[i+1], "@@") {
|
|
i++
|
|
if strings.HasPrefix(diff[i], "-") {
|
|
at++
|
|
} else {
|
|
out = append(out, diff[i][1:])
|
|
}
|
|
}
|
|
}
|
|
out = append(out, src[at:]...)
|
|
return strings.Join(out, "\n")
|
|
}
|
|
|
|
func TestDiffIsExactOnSmallTexts(t *testing.T) {
|
|
for _, c := range [][2]string{{"a\nb\nc", "a\nc"}, {"a", "b"}, {"", "x\ny"}, {"x\ny", ""}, {"a\nb\nc\nd", "b\nc\nd\ne"}} {
|
|
if got := applyDiff(c[0], Diff(c[0], c[1])); got != c[1] {
|
|
t.Errorf("%q to %q: %q (%v)", c[0], c[1], got, Diff(c[0], c[1]))
|
|
}
|
|
}
|
|
}
|
|
|
|
// history is bounded like the other answers: its work, and its answer, with a cut notice (the review of #206).
|
|
func TestHistoryIsBounded(t *testing.T) {
|
|
w := imported(t, newMemStore())
|
|
n := w.reserved(t, "author@g14")
|
|
p := valid(n)
|
|
big := strings.Repeat("A line of reasoning that is long enough to count.\n", 3000)
|
|
p.Sections[0].Text = big
|
|
if _, err := w.k.Propose("author@g14", p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p.Sections[0].Text = strings.ReplaceAll(big, "long enough", "longer than")
|
|
if _, err := w.k.Propose("author@g14", p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
h, err := w.k.History(Key{KindDecision, n}, 2, 3, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if size(h) > DefaultBound || h.Cut == "" {
|
|
t.Fatalf("a large difference: %d bytes, cut %q", size(h), h.Cut)
|
|
}
|
|
// The difference stays exact when it is not cut, however large: its work is bounded, not its truth.
|
|
whole, _ := w.k.History(Key{KindDecision, n}, 2, 3, MostBound)
|
|
vs, _ := w.k.Store.Versions(t.Context(), Key{KindDecision, n})
|
|
if whole.Cut == "" && applyDiff(Render(vs[1].Record), whole.Diff) != Render(vs[2].Record) {
|
|
t.Fatal("the bounded difference is not exact")
|
|
}
|
|
if d := Diff(strings.Repeat("a\n", 5000)+"x", strings.Repeat("b\n", 5000)+"y"); applyDiff(strings.Repeat("a\n", 5000)+"x", d) != strings.Repeat("b\n", 5000)+"y" {
|
|
t.Fatal("a difference past the work bound is not exact")
|
|
}
|
|
}
|
|
|
|
func TestAQuestionIsBounded(t *testing.T) {
|
|
w := imported(t, newMemStore())
|
|
if _, err := w.k.Ask(strings.Repeat("merge window ", 200), 0); err == nil || !strings.Contains(err.Error(), "at most") {
|
|
t.Fatalf("a question of 2600 characters: %v", err)
|
|
}
|
|
}
|