package check import ( "slices" "strings" "testing" xhtml "golang.org/x/net/html" "amadan.net/rastrillo/fiesta" "amadan.net/rastrillo/fiesta/internal/markup" "amadan.net/rastrillo/fiesta/internal/rowrule" ) // The Row Rule: a dropdown never sits on a line of its own. It sits in // a row beside what it acts on. A menu alone on a line reads as a // control for nothing in particular, and one above a page's title // pushes the title down and reads as the page's first action. DESIGN.md // states the rule, and internal/rowrule is its check, shared with the // site's landing page. This test holds every example to it, so a // gallery page can never teach the placement the rule forbids. // TestEveryDropdownSitsInARow: every state of every example, bodies and // layouts whole, keeps the Row Rule. The gallery is where a reader // learns where a menu goes, so a state that shows one alone teaches the // placement the rule forbids. func TestEveryDropdownSitsInARow(t *testing.T) { states := everyState(t, fiesta.FS()) menus := 0 for _, s := range states { if strings.Contains(s.Markup, "rst-dropdown") { menus++ } respelled, _ := markup.Respell([]byte(s.Markup)) doc, err := xhtml.Parse(strings.NewReader(string(respelled))) if err != nil { t.Errorf("%s/%s: the markup does not parse: %v", s.Name, s.State, err) continue } for _, msg := range rowrule.Breaches(doc, nil) { t.Errorf("%s/%s: %s", s.Name, s.State, msg) } } // A walk that finds no menus passes whatever the rule says. if menus < 10 { t.Fatalf("%d states hold a dropdown, want at least 10; the walk is reading the wrong markup", menus) } if t.Failed() { var rows []string for row, why := range rowrule.Rows { rows = append(rows, row+" ("+why+")") } slices.Sort(rows) t.Logf("put each menu in one of these rows: %s", strings.Join(rows, ", ")) } }