Run index.py as Go tests: the reading order's topics are written and no list of records is stored (issue 1296)

This commit is contained in:
2026-10-23 15:07:48 +02:00
parent 0ad95768b6
commit 9339e953b8
+93
View File
@@ -0,0 +1,93 @@
package checks
import (
"fmt"
"io/fs"
"regexp"
"strings"
"testing"
"testing/fstest"
)
// The reading order of the decision records (index.py until ADR 0527): its topics are written in
// 02-DECISIONS/README.md, its records are not. The knowledge base reads these lines and refuses a record whose
// topic is not one of them, so the form is a contract; a topic's records are `knowledge-base.holds` with that
// topic, never stored here (ADR 0248, issue 297).
const readmeOfDecisions = "02-DECISIONS/README.md"
// A topic line: `1. **Label** — `topic: name`. ...`
var topicLineRx = regexp.MustCompile(`(?m)^\d+\.\s+\*\*([^*]+)\*\*\s+—\s+` + "`topic:\\s*([^`]+)`")
// What a stored list looks like: the old markers, or a line of the list index.py used to print.
var storedLists = []struct {
rx *regexp.Regexp
what string
}{
{regexp.MustCompile(`<!--\s*index:(start|end)\s*-->`), "an index marker"},
{regexp.MustCompile(`(?m)^- \*\*\d{4}\*\* — \[`), "a line of a generated list"},
}
func readingOrder(text string) []string {
var topics []string
for _, m := range topicLineRx.FindAllStringSubmatch(text, -1) {
topics = append(topics, strings.TrimSpace(m[2]))
}
return topics
}
func checkIndex(fsys fs.FS) []string {
text := readFile(fsys, readmeOfDecisions)
topics := readingOrder(text)
var out []string
if len(topics) == 0 {
out = append(out, "index: "+readmeOfDecisions+" writes no reading order: no line of the form '1. **Label** — `topic: name`. ...'; "+
"the knowledge base refuses every record without it")
}
seen := map[string]bool{}
for _, topic := range topics {
if seen[topic] {
out = append(out, fmt.Sprintf("index: %s names a topic twice in its reading order: %s", readmeOfDecisions, topic))
break
}
seen[topic] = true
}
for _, s := range storedLists {
if s.rx.MatchString(text) {
out = append(out, fmt.Sprintf("index: %s stores a list of records (%s). The records live in the knowledge base, and a topic's list is "+
"`knowledge-base.holds` with that topic", readmeOfDecisions, s.what))
}
}
return out
}
func TestIndexReadingOrderIsWrittenAndStoresNoList(t *testing.T) {
expectNone(t, checkIndex(rootFS()))
if n := len(readingOrder(readFile(rootFS(), readmeOfDecisions))); n == 0 {
t.Error("the reading order has no topic")
}
}
const sound = "1. **One** — `topic: one`. x\n2. **Two** — `topic: two`. y\n"
func TestIndexCatchesAMissingReadingOrder(t *testing.T) {
expectProblem(t, checkIndex(fstest.MapFS{readmeOfDecisions: doc("nothing written here\n")}), "writes no reading order")
}
func TestIndexCatchesADuplicateTopic(t *testing.T) {
broken := fstest.MapFS{readmeOfDecisions: doc(sound + "3. **Again** — `topic: one`. z\n")}
expectProblem(t, checkIndex(broken), "names a topic twice")
}
func TestIndexCatchesAStoredList(t *testing.T) {
for what, stored := range map[string]string{
"an index marker": "<!-- index:start -->\n",
"a line of a generated list": "- **0001** — [a title](x.md)\n",
} {
expectProblem(t, checkIndex(fstest.MapFS{readmeOfDecisions: doc(sound + stored)}), what)
}
}
func TestIndexAcceptsASoundReadme(t *testing.T) {
expectNone(t, checkIndex(fstest.MapFS{readmeOfDecisions: doc(sound)}))
}