package gallery import ( "html" "io/fs" "regexp" "strings" "testing" xhtml "golang.org/x/net/html" "amadan.net/rastrillo/fiesta" "amadan.net/rastrillo/fiesta/example" ) // The frame document: what every frame carries in its head, the stage // under the sign-in card, the links a shell demo needs to work as the // app it stands for, and the attribute that lets a document opened in // a tab of its own remember the reader's scheme. // The rules every frame's style carries, as written: a component // sample gets breathing room, a whole-page sample fills the frame, by // its markup or by the manifest's word. const ( paddingRule = `body { padding: 1rem; }` fillRule = `body:is([rst-stage], [rst-shell-topbar], [rst-shell-sidebar], [rst-shell-console]), body:has(> [rst-shell-topbar], > [rst-shell-sidebar], > [rst-shell-console], > [rst-backdrop], > [rst-stage]) { padding: 0; }` documentRule = `body[data-gallery-document] { padding: 0; }` ) // frameDocs is every frame document of the tree, by path. func frameDocs(t *testing.T, files map[string][]byte) map[string][]byte { t.Helper() out := map[string][]byte{} for name, body := range files { if isFrame(name) { out[name] = body } } if len(out) == 0 { t.Fatal("the render wrote no frame document; the check that follows would read nothing") } return out } // elementChildren is the element children of n, in order. func elementChildren(n node) []node { var out []node for c := n.n.FirstChild; c != nil; c = c.NextSibling { if c.Type == xhtml.ElementNode { out = append(out, node{c}) } } return out } // TestEveryFrameDocumentCarriesNoindexAndItsPaddingRule: every frame // document has one robots meta saying noindex, right after the // viewport meta, and one style, the last element of its head, with the // padding rule, the fill rule and the document rule each exactly once, // every selector present as written. func TestEveryFrameDocumentCarriesNoindexAndItsPaddingRule(t *testing.T) { frames := frameDocs(t, render(t, "")) for name, body := range frames { doc := parse(t, body) head, ok := doc.first(func(n node) bool { return n.n.Data == "head" }) if !ok { t.Errorf("%s has no ", name) continue } kids := elementChildren(head) robots := -1 for i, k := range kids { if k.n.Data != "meta" { continue } if v, _ := k.attr("name"); v == "robots" { if robots >= 0 { t.Errorf("%s carries two robots metas", name) } robots = i if c, _ := k.attr("content"); c != "noindex" { t.Errorf("%s says robots %q, want noindex", name, c) } } } if robots < 0 { t.Errorf("%s carries no robots meta", name) } else if robots == 0 { t.Errorf("%s: the robots meta is the head's first element; it follows the viewport meta", name) } else if prev := kids[robots-1]; prev.n.Data != "meta" || func() bool { v, _ := prev.attr("name"); return v != "viewport" }() { t.Errorf("%s: the robots meta does not follow the viewport meta", name) } if last := kids[len(kids)-1]; last.n.Data != "style" { t.Errorf("%s: the last element of the head is <%s>, want the frame's