| 1 | package check |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "amadan.net/rastrillo/fiesta" |
| 8 | "amadan.net/rastrillo/fiesta/internal/markup" |
| 9 | ) |
| 10 | |
| 11 | // The seeded spelling fixture, held to the class spelling as text. The |
| 12 | // browser drive (markup_v3_browser_test.go) compares the fixture |
| 13 | // against markup.Respell of it; a fixture that already carried the |
| 14 | // attribute spelling in places would compare those elements against |
| 15 | // themselves and prove nothing about them, which is what rastrillo's own |
| 16 | // fixture did before it was translated back to classes. |
| 17 | |
| 18 | // mappedAttributes is every rst- attribute name the grammar writes for |
| 19 | // a class tokens.css styles: the set a class-spelled page must not |
| 20 | // carry. |
| 21 | func mappedAttributes(t *testing.T) map[string]bool { |
| 22 | t.Helper() |
| 23 | out := map[string]bool{} |
| 24 | for class := range styledClasses(t, string(fiesta.TokensCSS())) { |
| 25 | if name, _, ok := markup.Attribute(class); ok { |
| 26 | out[name] = true |
| 27 | } |
| 28 | } |
| 29 | if len(out) < 20 { |
| 30 | t.Fatalf("the grammar maps %d attribute names from tokens.css's classes; the reader is broken", len(out)) |
| 31 | } |
| 32 | return out |
| 33 | } |
| 34 | |
| 35 | // rstAttributesIn lists every rst- attribute in the open tags of html |
| 36 | // whose name the grammar maps, each with the tag it sits in. The class |
| 37 | // attribute comes out of the tag before the scan: its tokens follow |
| 38 | // whitespace exactly as an attribute does, and rst-btn in class="rst-btn" |
| 39 | // is a class, not an attribute. |
| 40 | func rstAttributesIn(html string, mapped map[string]bool) []string { |
| 41 | var found []string |
| 42 | for _, tag := range openTagInFixture.FindAllString(html, -1) { |
| 43 | for _, m := range rstAttrInFixture.FindAllStringSubmatch(classInMarkup.ReplaceAllString(tag, ""), -1) { |
| 44 | if mapped[m[1]] { |
| 45 | found = append(found, m[1]+" in "+tag) |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | return found |
| 50 | } |
| 51 | |
| 52 | // mappedClassesIn lists every rst- class token in html that the |
| 53 | // grammar maps to an attribute, each with the class attribute it sits |
| 54 | // in. Only rst- tokens: the grammar is defined on the vocabulary, and |
| 55 | // Attribute answers for any name handed to it (.icon, an app's own |
| 56 | // class), which are not the stylesheet's to respell. |
| 57 | func mappedClassesIn(html string) []string { |
| 58 | var found []string |
| 59 | for _, m := range classInMarkup.FindAllStringSubmatch(html, -1) { |
| 60 | for _, token := range strings.Fields(m[1]) { |
| 61 | if !strings.HasPrefix(token, "rst-") { |
| 62 | continue |
| 63 | } |
| 64 | if _, _, ok := markup.Attribute(token); ok { |
| 65 | found = append(found, token+" in "+m[0]) |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | return found |
| 70 | } |
| 71 | |
| 72 | // TestTheClassFixtureIsGenuinelyClassSpelled: the seeded class page |
| 73 | // holds no rst- attribute the grammar maps, its markup.Respell twin |
| 74 | // holds no class="rst-…" token the grammar maps, and the two differ. |
| 75 | // rastrillo's fixture was the partials and the styleguide, which write |
| 76 | // attributes, behind a hand-written block in classes; the seed is that |
| 77 | // fixture translated back whole, and this is what says the translation |
| 78 | // reached all of it. |
| 79 | func TestTheClassFixtureIsGenuinelyClassSpelled(t *testing.T) { |
| 80 | class := fixture(t, "markup_v3_browser_test.go", "classFixture", "") |
| 81 | mapped := mappedAttributes(t) |
| 82 | if found := rstAttributesIn(class, mapped); len(found) > 0 { |
| 83 | t.Errorf("the class page carries %d rst- attributes the grammar maps; it is not in the class spelling. The first: %s", len(found), found[0]) |
| 84 | } |
| 85 | attr, notes := markup.Respell([]byte(class)) |
| 86 | for _, n := range notes { |
| 87 | t.Errorf("respelling the class page: %s", n) |
| 88 | } |
| 89 | if found := mappedClassesIn(string(attr)); len(found) > 0 { |
| 90 | t.Errorf("the attribute twin still carries %d classes the grammar maps; the translation did not reach them. The first: %s", len(found), found[0]) |
| 91 | } |
| 92 | if string(attr) == class { |
| 93 | t.Error("the attribute twin is identical to the class page; the translation did nothing") |
| 94 | } |
| 95 | } |
| 96 | |