The roadmap lives in the knowledge base: an idea is listed, never served as in force; propose refuses a further active effort. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
93 lines
3.8 KiB
Go
93 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// effort accepts a new research effort at the status, under a number reserved for it.
|
|
func (w *world) effort(t *testing.T, status string) int {
|
|
t.Helper()
|
|
r, err := w.k.ReserveNumber("author@g14", KindResearch, "an effort")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w.accepted(t, "author@g14", effortAsk(r.Number, status, Section{Name: "00-overview.md", Text: "What a roadmap entry would be."}))
|
|
return r.Number
|
|
}
|
|
|
|
// ADR 0629 §1, §4: at most three efforts are active; a fourth, new or taken up from an idea, is refused and the
|
|
// refusal names the active ones; the limit is the setting's.
|
|
func TestAtMostThreeResearchEffortsAreActive(t *testing.T) {
|
|
w := imported(t, newMemStore())
|
|
var active []int
|
|
for i := 0; i < 3; i++ {
|
|
active = append(active, w.effort(t, StatusActive))
|
|
}
|
|
idea := w.effort(t, StatusIdea)
|
|
if got := mustGet(t, w.k.Store, Key{KindResearch, idea}).Current.Status; got != StatusIdea {
|
|
t.Fatalf("an effort proposed as an idea is %s", got)
|
|
}
|
|
r, err := w.k.ReserveNumber("author@g14", KindResearch, "a fourth")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for name, ask := range map[string]ProposeAsk{
|
|
"a new effort": effortAsk(r.Number, StatusActive, Section{Name: "00-overview.md", Text: "A fourth."}),
|
|
"an idea taken up": effortAsk(idea, StatusActive, Section{Name: "00-overview.md", Text: "Taken up."}),
|
|
"a new effort, as idea": effortAsk(r.Number, StatusIdea, Section{Name: "00-overview.md", Text: "A fourth."}),
|
|
} {
|
|
_, err := w.k.Propose("author@g14", ask)
|
|
refused := err != nil && strings.Contains(err.Error(), "research-active-at-most")
|
|
if want := name != "a new effort, as idea"; refused != want {
|
|
t.Errorf("%s: refused %v, want %v (%v)", name, refused, want, err)
|
|
}
|
|
if refused {
|
|
for _, n := range active {
|
|
if !strings.Contains(err.Error(), Key{KindResearch, n}.String()) {
|
|
t.Errorf("%s: the refusal does not name research %d: %v", name, n, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// An active effort takes a new version at the limit; the setting raises the limit, and an idea taken up and
|
|
// still waiting for its review counts as active.
|
|
if _, err := w.k.Propose("author@g14", effortAsk(active[0], StatusActive, Section{Name: "00-overview.md", Text: "More."})); err != nil {
|
|
t.Fatalf("an active effort refused a new version at the limit: %v", err)
|
|
}
|
|
w.k.Settings = func() (Settings, error) { return Settings{ResearchActiveAtMost: 4}, nil }
|
|
if _, err := w.k.Propose("author@g14", effortAsk(idea, StatusActive, Section{Name: "00-overview.md", Text: "Taken up."})); err != nil {
|
|
t.Fatalf("an idea taken up under a limit of 4: %v", err)
|
|
}
|
|
if _, err := w.k.Propose("author@g14", effortAsk(r.Number, StatusActive, Section{Name: "00-overview.md", Text: "A fifth."})); err == nil ||
|
|
!strings.Contains(err.Error(), "research-active-at-most") {
|
|
t.Fatalf("a fifth active (three accepted, one waiting) was not refused: %v", err)
|
|
}
|
|
}
|
|
|
|
// ADR 0629 §1, §2: list at idea is the roadmap; ask, holds and get never answer an idea as a record in force.
|
|
func TestAnIdeaIsListedAndNeverServedAsTruth(t *testing.T) {
|
|
w := imported(t, newMemStore())
|
|
n := w.effort(t, StatusIdea)
|
|
got, err := w.k.List(ListAsk{Kind: KindResearch, Status: StatusIdea})
|
|
if err != nil || len(got.Rows) != 1 {
|
|
t.Fatalf("list at idea: %+v, %v", got, err)
|
|
}
|
|
asked, err := w.k.Ask("roadmap entry inference layer", 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, r := range asked.Records {
|
|
if r.Record == (Key{KindResearch, n}).String() {
|
|
t.Errorf("ask answered from an idea: %+v", r)
|
|
}
|
|
}
|
|
g, err := w.k.Get(GetAsk{Kind: KindResearch, Number: n})
|
|
if err != nil || !strings.Contains(g.Idea, "research it again") {
|
|
t.Fatalf("get does not say an idea: %+v, %v", g, err)
|
|
}
|
|
if Served(mustGet(t, w.k.Store, Key{KindResearch, n}).Current, Clause{Status: ClauseInForce}) {
|
|
t.Errorf("a clause of an idea is served")
|
|
}
|
|
}
|