rastrillo / fiesta Public

Clone
git clone https://amadan.net/rastrillo/fiesta

Plain git — no account needed to clone.

Download

Download this file

1package gallery
2
3import (
4 "strings"
5 "testing"
6
7 "amadan.net/rastrillo/fiesta"
8)
9
10// The integration gate: what holds only with the four streams in
11// together, the shell's rail over Getting started's rows, the URL gate
12// over the demo, the modal and the shells in the rail, and the widget
13// count with the Overview's demo in it. Each is a preservation of a
14// stream's own gate, extended to what another stream added, and each
15// was already passing when written; the comment on each names the
16// mutation that turns it red.
17
18// TestTheSidebarLinksGettingStartedExactlyOnce extends
19// TestTheSidebarLinksEverythingOnThePageExactlyOnce to Getting started,
20// whose rows are another stream's: in every theme and locale the rail's
21// fragments into getting-started.html are the page's anchored rows, in
22// order, one per file the release ships and the page lists. Mutation:
23// assetNav dropping its first item reports the rail one row short on
24// every Getting started page.
25func TestTheSidebarLinksGettingStartedExactlyOnce(t *testing.T) {
26 files := render(t, "")
27 s := newTestSite(t, fiesta.FS(), "")
28 file := s.fileOf("getting-started")
29 read := 0
30 for _, dir := range dirs() {
31 theme, locale, _ := strings.Cut(strings.TrimSuffix(dir, "/"), "/")
32 name := dir + file
33 page := kindPage(t, files, theme, locale, file)
34 rail := railOf(t, name, page)
35 self := s.href(theme, locale, file)
36 var anchors, fragments []string
37 for _, m := range anchorMarker.FindAllStringSubmatch(page, -1) {
38 anchors = append(anchors, m[1])
39 }
40 for _, m := range navHref.FindAllStringSubmatch(rail, -1) {
41 if strings.HasPrefix(m[1], self+"#") {
42 fragments = append(fragments, strings.TrimPrefix(m[1], self+"#"))
43 }
44 }
45 view, err := s.buildAssets(s.newPage(theme, locale, "getting-started", file, ""))
46 if err != nil {
47 t.Fatal(err)
48 }
49 if len(view.List) == 0 {
50 t.Fatalf("%s lists no file", name)
51 }
52 if len(fragments) != len(view.List) || strings.Join(fragments, " ") != strings.Join(anchors, " ") {
53 t.Errorf("%s: the rail links %d rows %v, the page anchors %v and lists %d files", name, len(fragments), fragments, anchors, len(view.List))
54 }
55 read++
56 }
57 if read != len(dirs()) {
58 t.Fatalf("read %d Getting started pages, want %d", read, len(dirs()))
59 }
60}
61
62// TestEveryDemoInTheRailResolves extends TestEveryGalleryURLResolves
63// to the Demos the rail and the phone index carry, which three streams
64// wrote: at a mount, on every page of every directory, the rail's Demos
65// are the five shells, the modal route and the demo application, each
66// a file the render wrote under that directory, and the Overview's
67// phone index lists the same seven; and every link the demo's
68// documents and the modal route mark as the gallery's resolves too.
69// Mutation: demoHref writing "demo.htm" reports the demo application
70// as a file the render did not write, here and in the URL gate.
71func TestEveryDemoInTheRailResolves(t *testing.T) {
72 const mount = "/x"
73 files := render(t, mount)
74 s := newTestSite(t, fiesta.FS(), mount)
75 checked := 0
76 for _, dir := range dirs() {
77 theme, locale, _ := strings.Cut(strings.TrimSuffix(dir, "/"), "/")
78 want := demoHrefs(t, s, theme, locale)
79 for _, pk := range s.pageKinds() {
80 name := dir + pk.File
81 page := kindPage(t, files, theme, locale, pk.File)
82 groups := railSections(railOf(t, name, page))
83 if len(groups) == 0 {
84 t.Fatalf("%s: no rail", name)
85 }
86 demos := groups[len(groups)-1]
87 got := map[string]bool{}
88 for _, m := range navHref.FindAllStringSubmatch(demos.Body, -1) {
89 got[m[1]] = true
90 path := strings.TrimPrefix(m[1], mount+"/")
91 if _, ok := files[path]; !ok || !strings.HasPrefix(path, dir) {
92 t.Errorf("%s: the Demos link %q, which is not a file of %s", name, m[1], dir)
93 }
94 checked++
95 }
96 if !sameKeys(got, want) {
97 t.Errorf("%s: the Demos are %v, want %v", name, keysOf(got), keysOf(want))
98 }
99 if pk.Kind == "overview" {
100 m := indexNav.FindStringSubmatch(page)
101 if m == nil {
102 t.Fatalf("%s: no phone index", name)
103 }
104 rows := map[string]bool{}
105 for _, l := range navHref.FindAllStringSubmatch(m[2], -1) {
106 if want[l[1]] {
107 rows[l[1]] = true
108 }
109 }
110 if !sameKeys(rows, want) {
111 t.Errorf("%s: the phone index lists the Demos %v, want %v", name, keysOf(rows), keysOf(want))
112 }
113 }
114 }
115 for _, extra := range s.extraDocumentNames() {
116 for _, u := range galleryURLs(t, files[dir+extra]) {
117 path, _, _ := strings.Cut(strings.TrimPrefix(u, mount+"/"), "#")
118 if _, ok := files[path]; !ok || !strings.HasPrefix(u, mount+"/") {
119 t.Errorf("%s%s links %q, which the render did not write", dir, extra, u)
120 }
121 checked++
122 }
123 }
124 }
125 if checked == 0 {
126 t.Fatal("no link was checked")
127 }
128}
129
130// TestEveryWidgetIsFramedAsItsKindSays extends
131// TestEveryExampleIsFramedDesktopMobileAndHTML to the Overview's demo,
132// another stream's widget in the first stream's markup: on day/en the
133// example pages hold one widget per state or per grouped example, each
134// with Desktop, Mobile and HTML and its panel, and in every directory
135// the Overview holds exactly one more, the demo, at the page width with
136// Desktop and Mobile and no HTML; every widget's radios carry a name of
137// their own on the page. Mutation: the demo's widget given a Source
138// (an HTML panel) reports the Overview's widget as an example's.
139func TestEveryWidgetIsFramedAsItsKindSays(t *testing.T) {
140 files := render(t, "")
141 s := newTestSite(t, fiesta.FS(), "")
142 theme := fiesta.ThemeNames()[0]
143 examples, overviews := 0, 0
144 for _, e := range s.m.Examples {
145 for _, w := range widgetsOf(examplePage(t, files, theme, "en", e.Name)) {
146 examples++
147 var order string
148 for _, m := range tabClass.FindAllStringSubmatch(w, -1) {
149 order += m[1]
150 }
151 if order != "dmh" || panelOf(w) == "" {
152 t.Errorf("%s: a widget with tabs %q and panel %v, want Desktop, Mobile, HTML and its panel", e.Name, order, panelOf(w) != "")
153 }
154 }
155 }
156 for _, dir := range dirs() {
157 name := dir + "index.html"
158 page := string(files[name])
159 widgets := widgetsOf(page)
160 if len(widgets) != 1 {
161 t.Errorf("%s: %d widgets, want the demo alone", name, len(widgets))
162 continue
163 }
164 overviews++
165 w := widgets[0]
166 var order string
167 for _, m := range tabClass.FindAllStringSubmatch(w, -1) {
168 order += m[1]
169 }
170 if order != "dm" || panelOf(w) != "" || !strings.Contains(page, `<div class="ds-view ds-view--page" style="`) {
171 t.Errorf("%s: the demo's widget has tabs %q and panel %v, want a page-width widget with Desktop and Mobile and no HTML", name, order, panelOf(w) != "")
172 }
173 names := map[string]int{}
174 for _, r := range radioInput.FindAllStringSubmatch(page, -1) {
175 names[r[1]]++
176 }
177 if len(names) != 1 || names["demo-app-0"] != 2 {
178 t.Errorf("%s: the radios are %v, want the demo's two under its own name", name, names)
179 }
180 }
181 if examples < 100 || overviews != len(dirs()) {
182 t.Fatalf("%d example widgets and %d Overview widgets read; the walk read too little", examples, overviews)
183 }
184 t.Logf("%d example widgets on day/en and the demo on %d Overviews", examples, overviews)
185}
186