From e0c82440b39b11bc6523ce1998176c45a2e396fa Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 21 Sep 2026 18:36:31 +0200 Subject: [PATCH] Hold every source file to a README Layout line --- doc_test.go | 9 +++++++-- readme_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/doc_test.go b/doc_test.go index 55d8b1a..4952312 100644 --- a/doc_test.go +++ b/doc_test.go @@ -47,15 +47,20 @@ func namesAPass(t *testing.T, where, text string, declared, funcs map[string]boo } } -func sourceFiles(t *testing.T) (*token.FileSet, []*ast.File) { +func goFiles(t *testing.T) []string { t.Helper() pkg, err := build.ImportDir(".", 0) if err != nil { t.Fatalf("read the package directory: %v", err) } + return pkg.GoFiles +} + +func sourceFiles(t *testing.T) (*token.FileSet, []*ast.File) { + t.Helper() fset := token.NewFileSet() var files []*ast.File - for _, name := range pkg.GoFiles { + for _, name := range goFiles(t) { f, err := parser.ParseFile(fset, name, nil, parser.ParseComments) if err != nil { t.Fatalf("parse %s: %v", name, err) diff --git a/readme_test.go b/readme_test.go index c253170..a8238f8 100644 --- a/readme_test.go +++ b/readme_test.go @@ -4,12 +4,14 @@ import ( "encoding/json" "os" "regexp" + "slices" "strings" "testing" ) var ( jsonBlock = regexp.MustCompile("(?s)```json\n(.*?)```") + plainBlock = regexp.MustCompile("(?s)```\n(.*?)```") tsvBlock = regexp.MustCompile("(?s)```tsv\n(.*?)```") rowsFile = regexp.MustCompile(`"rows":\s*"([^"]+)"`) parentName = regexp.MustCompile(`"parent":\s*"([^"]+)"`) @@ -191,3 +193,38 @@ func TestReadmeTableExample(t *testing.T) { t.Fatalf("README table example as a record: %q, %v", r.CSVHeader(), err) } } + +// TestLayoutNamesEverySourceFile holds an added, renamed or split file to its Layout +// line, so the list a reader picks a file from stays the list on disk. +func TestLayoutNamesEverySourceFile(t *testing.T) { + src := readme(t) + i := strings.Index(src, "## Layout") + if i < 0 { + t.Fatal("README lost the Layout section") + } + block := plainBlock.FindStringSubmatch(src[i:]) + if block == nil { + t.Fatal("README Layout section has no block") + } + listed := map[string]bool{} + for _, line := range strings.Split(block[1], "\n") { + name, _, _ := strings.Cut(strings.TrimSpace(line), " ") + if strings.HasSuffix(name, ".go") { + listed[name] = true + } + } + for _, name := range goFiles(t) { + if !listed[name] { + t.Errorf("the README Layout names no %s, so nothing says what it holds", name) + } + delete(listed, name) + } + stale := make([]string, 0, len(listed)) + for name := range listed { + stale = append(stale, name) + } + slices.Sort(stale) + for _, name := range stale { + t.Errorf("the README Layout names %s, which the package does not hold", name) + } +}