test(11.1-06): branch-level tests for every docsite stage (94.8% coverage)

- load, render, emit, snippet, highlight, serve and checker branch tests;
  docs:build --check, docs:sync and docs:serve output tests in cmd/summer
- fix: a CRLF or BOM page is reported as such, not as a page without a
  frontmatter block (TestFrontmatterEncodingProblems)
- fix: src=#Type.Method finds a method with a parenthesised receiver
  (TestSnippetGenericsAndGroups, Box.Paren)
- fix: docs:serve adds its watches before announcing the server, so an
  edit made right after the serving line rebuilds (TestServeWatchRebuilds)
This commit is contained in:
Jakub Zych
2026-10-01 00:05:12 +02:00
parent 1d38e73f03
commit 28afd4d197
13 changed files with 2276 additions and 11 deletions

View File

@@ -379,3 +379,85 @@ func TestSyncRewritesDrift(t *testing.T) {
t.Errorf("start.md fences not reduced to the language word:\n%s", md)
}
}
func TestProblemString(t *testing.T) {
for _, tc := range []struct {
p Problem
want string
}{
{Problem{File: "docs/a.md", Line: 3, Rule: "link", Message: "x does not resolve"}, "docs/a.md:3: link: x does not resolve"},
{Problem{File: "modules/b", Rule: "readme", Message: "no README"}, "modules/b: readme: no README"},
} {
if got := tc.p.String(); got != tc.want {
t.Errorf("String() = %q, want %q", got, tc.want)
}
}
problems := []Problem{{File: "b", Line: 2}, {File: "a", Line: 9}, {File: "b", Line: 1}, {File: "a", Line: 9, Rule: "second"}}
sortProblems(problems)
if got := problemLines(problems); !slices.Equal(got, []string{"a:9: : ", "a:9: second: ", "b:1: : ", "b:2: : "}) {
t.Errorf("sortProblems = %q", got)
}
}
func TestPathHelpers(t *testing.T) {
sep := string(filepath.Separator)
for _, tc := range []struct {
p, dir string
want bool
}{
{"/a/b", "/a/b", true},
{"/a/b/c", "/a/b", true},
{"/a/bc", "/a/b", false},
{"/a", "/a/b", false},
{"/a/..b", "/a", true},
{"/x" + sep + "y", "/x", true},
} {
if got := within(filepath.FromSlash(tc.p), filepath.FromSlash(tc.dir)); got != tc.want {
t.Errorf("within(%s, %s) = %v, want %v", tc.p, tc.dir, got, tc.want)
}
}
dir := t.TempDir()
real := filepath.Join(dir, "real")
if err := os.Mkdir(real, 0o755); err != nil {
t.Fatal(err)
}
link := filepath.Join(dir, "link")
if err := os.Symlink(real, link); err != nil {
t.Fatal(err)
}
realResolved, err := filepath.EvalSymlinks(real)
if err != nil {
t.Fatal(err)
}
if got := resolved(filepath.Join(link, "not", "yet")); got != filepath.Join(realResolved, "not", "yet") {
t.Errorf("resolved(link/not/yet) = %s", got)
}
if got := resolved("/no-such-root-dir/x"); got != "/no-such-root-dir/x" {
t.Errorf("resolved(missing) = %s", got)
}
}
func TestWriteOutputs(t *testing.T) {
out := t.TempDir()
if err := writeOutputs(out, map[string][]byte{"a/b.html": []byte("x"), "c.txt": []byte("y")}); err != nil {
t.Fatal(err)
}
if got, err := os.ReadFile(filepath.Join(out, "a", "b.html")); err != nil || string(got) != "x" {
t.Fatalf("a/b.html = %q, %v", got, err)
}
if err := writeOutputs(out, map[string][]byte{"../escape.html": []byte("x")}); err == nil || !strings.Contains(err.Error(), "escapes") {
t.Fatalf("an escaping output path = %v", err)
}
if _, err := os.Stat(filepath.Join(filepath.Dir(out), "escape.html")); err == nil {
t.Fatal("an output escaped the directory")
}
// A file where a directory is needed fails the write.
if err := writeOutputs(out, map[string][]byte{"c.txt/d.html": []byte("z")}); err == nil {
t.Fatal("writing under a file succeeded")
}
// prepareOut refuses a path it cannot read as a directory.
file := filepath.Join(out, "c.txt")
if err := prepareOut(file); err == nil {
t.Fatal("prepareOut on a file succeeded")
}
}