test(11.1-07): planted fixtures and unit tests for fence, execution and name-form holes

- eighteen violation plants pin nested src=, Go aliases, unrun examples, build membership and command forms
- unit tests cover fence collection, captions, goLang, go doc -c, commandWord and Sync
This commit is contained in:
Jakub Zych
2026-10-01 08:45:34 +02:00
parent efc3161c3f
commit 9ba5530ca7
48 changed files with 890 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package docsite
import (
"os"
"path/filepath"
"runtime"
"slices"
"strings"
"testing"
@@ -320,3 +321,160 @@ func TestSnippetTestGraph(t *testing.T) {
t.Errorf("Extract with an unparsable sibling test = %v", err)
}
}
func TestSnippetRootsAndBuild(t *testing.T) {
other := "windows"
if runtime.GOOS == "windows" {
other = "linux"
}
root := writeTree(t, map[string]string{
"p/p.go": "package p\n",
"p/p_test.go": `package p
import "testing"
func Test(t *testing.T) { fromTest() }
func Test_x(t *testing.T) { fromTestX() }
func TestMain(m *testing.M) { fromMain() }
func Testable() { fromTestable() }
func fromTest() {}
func fromTestX() {}
func fromMain() {}
func fromTestable() {}
func onlyFromIgnored() {}
func ExampleOut() {
fromOut()
// Output: out
}
func ExampleEmpty() {
fromEmpty()
// Output:
}
func ExampleNone() {
fromNone()
}
func fromOut() {}
func fromEmpty() {}
func fromNone() {}
`,
"p/ignored_test.go": "//go:build ignore\n\npackage p\n\nimport \"testing\"\n\nfunc TestIgnored(t *testing.T) { onlyFromIgnored() }\n",
"p/broken.go": "//go:build ignore\n\npackage p\n\nfunc Broken() {}\n",
"p/broken_test.go": "//go:build ignore\n\npackage p\n\nfunc IgnoredTestTarget() {}\n",
"p/only_" + other + ".go": "package p\n\nfunc OnlyOS() {}\n",
"p/testdata/skip.go": "package p\n\nfunc Skip() {}\n",
"p/_old/old.go": "package p\n\nfunc Old() {}\n",
"p/testdata/app.yaml": "# docs:start db\nhost: localhost\n# docs:end db\n",
})
g, err := loadTestGraph(filepath.Join(root, "p"))
if err != nil {
t.Fatal(err)
}
for _, name := range []string{"Test", "Test_x", "TestMain", "ExampleOut", "ExampleEmpty", "fromTest", "fromTestX", "fromMain", "fromOut", "fromEmpty"} {
if !g.reachable[name] {
t.Errorf("%s is not a root or reachable from one", name)
}
}
for _, name := range []string{"Testable", "ExampleNone", "fromTestable", "fromNone", "onlyFromIgnored", "TestIgnored"} {
if g.reachable[name] {
t.Errorf("%s is reachable, want it not run", name)
}
}
mustExtract := func(ref Ref, wantErr string) {
t.Helper()
_, err := Extract(root, ref)
if wantErr == "" {
if err != nil {
t.Errorf("Extract(%s) = %v, want nil", ref, err)
}
return
}
if err == nil || !strings.Contains(err.Error(), wantErr) {
t.Errorf("Extract(%s) = %v, want %q", ref, err, wantErr)
}
}
skipped := "file is in a directory go test ./... skips"
excluded := "file is excluded from the default build"
mustExtract(Ref{"p/p_test.go", "fromOut"}, "")
mustExtract(Ref{"p/p_test.go", "fromEmpty"}, "")
mustExtract(Ref{"p/p_test.go", "fromNone"}, notRunMessage)
mustExtract(Ref{"p/p_test.go", "fromTestable"}, notRunMessage)
mustExtract(Ref{"p/p_test.go", "onlyFromIgnored"}, notRunMessage)
mustExtract(Ref{"p/broken.go", "Broken"}, excluded)
mustExtract(Ref{"p/broken_test.go", "IgnoredTestTarget"}, excluded)
mustExtract(Ref{"p/only_" + other + ".go", "OnlyOS"}, excluded)
mustExtract(Ref{"p/testdata/skip.go", "Skip"}, skipped)
mustExtract(Ref{"p/_old/old.go", "Old"}, skipped)
got, err := Extract(root, Ref{"p/testdata/app.yaml", "db"})
if err != nil || got != "host: localhost" {
t.Fatalf("Extract yaml = %q, %v", got, err)
}
}
func TestSyncParsedFences(t *testing.T) {
callout := "> [!NOTE]\n> Keep this callout text.\n"
doc := page("Start", "setup", 10, "Intro.\n\n```go src=pkg/lib.go#Greeting\nfunc stale() {}\n```\n\n"+callout+"\nOutro.\n")
root := snippetTree(t, map[string]string{"docs/setup/start.md": doc})
path := filepath.Join(root, "docs/setup/start.md")
res, problems, err := Sync(Options{Root: root})
if err != nil || len(problems) > 0 {
t.Fatalf("Sync: %v %v", err, problems)
}
if res.Files != 1 || res.Snippets != 1 {
t.Fatalf("Sync = %+v, want 1 snippet in 1 file", res)
}
got, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
wantDoc := strings.Replace(doc, "func stale() {}\n",
"// Greeting returns a greeting.\nfunc Greeting(name string) string {\n\treturn \"Hello, \" + name\n}\n", 1)
if string(got) != wantDoc {
t.Fatalf("synced file =\n%s\nwant\n%s", got, wantDoc)
}
if !strings.HasPrefix(string(got), "---\ntitle: Start\n") || !strings.Contains(string(got), callout) {
t.Fatal("frontmatter or callout text changed")
}
nested := page("Start", "setup", 10, "Intro.\n\n> [!NOTE]\n> ```go src=pkg/lib.go#Greeting\n> func stale() {}\n> ```\n\nOutro.\n")
root = snippetTree(t, map[string]string{"docs/setup/start.md": nested})
before := map[string]string{}
err = filepath.WalkDir(root, func(p string, d os.DirEntry, err error) error {
if err != nil || d.IsDir() {
return err
}
b, err := os.ReadFile(p)
if err != nil {
return err
}
before[p] = string(b)
return nil
})
if err != nil {
t.Fatal(err)
}
res, problems, err = Sync(Options{Root: root})
if err != nil || res != (SyncResult{}) || len(problems) != 1 || !strings.Contains(problems[0].Message, nestedSrcMessage) {
t.Fatalf("nested Sync = %+v %q %v", res, problemLines(problems), err)
}
err = filepath.WalkDir(root, func(p string, d os.DirEntry, err error) error {
if err != nil || d.IsDir() {
return err
}
b, err := os.ReadFile(p)
if err != nil {
return err
}
if string(b) != before[p] {
t.Errorf("Sync changed %s", p)
}
return nil
})
if err != nil {
t.Fatal(err)
}
}