package main import ( "bytes" "go/ast" "go/doc" "go/parser" "go/token" "io/fs" "os" "os/exec" "path/filepath" "slices" "strconv" "strings" "testing" "github.com/alecthomas/chroma/v2/lexers" "git.golem15.com/golem15/summercms/internal/docsite" "git.golem15.com/golem15/summercms/modules/bonfire" ) // TestPhase11_1Acceptance asserts the Phase 11.1 success criteria on the // real tree, one subtest per ROADMAP criterion. func TestPhase11_1Acceptance(t *testing.T) { opts := docsite.Options{Root: repoRoot, Commands: docsCommands()} pages, loadProblems, err := docsite.Pages(opts) if err != nil { t.Fatal(err) } problems, err := docsite.Check(opts) if err != nil { t.Fatal(err) } out, _ := buildRealTree(t) // SC1: docs/ holds Markdown pages with frontmatter in the // Winter-mirroring sections, and every framework module is reachable // from the sidebar. t.Run("SC1", func(t *testing.T) { site, err := docsite.LoadSite(filepath.Join(repoRoot, "docs", "site.yaml")) if err != nil { t.Fatal(err) } var names []string for _, s := range site.Sections { names = append(names, s.Name) } if !slices.Equal(names, sectionOrder) { t.Errorf("site.yaml sections = %v, want %v", names, sectionOrder) } for _, p := range append(slices.Clone(loadProblems), problems...) { switch p.Rule { case "frontmatter", "section", "site", "page", "readme": t.Errorf("load problem: %s", p) } } guides := 0 for _, p := range pages { if p.Module != "" { continue } guides++ if p.Title == "" || p.Description == "" || !strings.HasPrefix(p.Source, "docs/") || !strings.HasSuffix(p.Source, ".md") { t.Errorf("page %s has incomplete frontmatter: %+v", p.URL, p) } if p.Section != "index" && (!slices.Contains(sectionOrder, p.Section) || p.Section == "api") { t.Errorf("page %s is in section %q", p.URL, p.Section) } } for _, sec := range sectionOrder[:len(sectionOrder)-1] { if !slices.ContainsFunc(pages, func(p docsite.Page) bool { return p.Section == sec }) { t.Errorf("section %s has no pages", sec) } } if guides < len(requiredPages) { t.Errorf("%d guide pages, want at least %d", guides, len(requiredPages)) } sidebar := sidebarOf(t, out, "setup/installation.html") for _, m := range frameworkModules(t) { if !slices.ContainsFunc(pages, func(p docsite.Page) bool { return p.URL == "api/"+m && p.Module == m }) { t.Errorf("module %s has no api/%s page", m, m) } if !strings.Contains(sidebar, `href="/api/`+m+`.html"`) { t.Errorf("the sidebar does not link api/%s", m) } } }) // SC2: summer builds a self-contained static site with the UI-SPEC // theme parts, search and dark mode, with no Node toolchain. t.Run("SC2", func(t *testing.T) { guide := readFile(t, filepath.Join(out, "setup", "installation.html")) for _, marker := range []string{ `
`, `