83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package app
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
ui "kjol/webui"
|
|
)
|
|
|
|
// Every icon name this app names must actually resolve.
|
|
//
|
|
// An unregistered name renders an empty, correctly-sized box. That is the right thing
|
|
// at runtime — a missing icon should not collapse the layout — but it means a typo is
|
|
// invisible: the icon is simply absent, and nothing says why. Two of them (shapes,
|
|
// layer-group, which the kit calls squares and layers) shipped in the sidebar looking
|
|
// like blank squares before this test existed.
|
|
//
|
|
// It scans the SOURCE rather than a hand-kept list, so an icon added to a page tomorrow
|
|
// is checked tomorrow, without anyone remembering to add it here.
|
|
func TestEveryIconNameResolves(t *testing.T) {
|
|
// ui.Icon("x", …) / ui.IconInline("x", …), and the Icon: "x" field on the props
|
|
// structs (buttons, menu items, docs nav).
|
|
patterns := []*regexp.Regexp{
|
|
regexp.MustCompile(`Icon(?:Inline)?\("([a-z0-9-]+)"`),
|
|
regexp.MustCompile(`\bIcon:\s*"([a-z0-9-]+)"`),
|
|
}
|
|
|
|
files, err := filepath.Glob("*.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
used := map[string][]string{} // icon name -> files that ask for it
|
|
for _, f := range files {
|
|
if strings.HasSuffix(f, "_test.go") {
|
|
continue
|
|
}
|
|
src, err := os.ReadFile(f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, re := range patterns {
|
|
for _, m := range re.FindAllStringSubmatch(string(src), -1) {
|
|
used[m[1]] = append(used[m[1]], f)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(used) == 0 {
|
|
t.Fatal("scanned the package and found no icon names at all — the patterns have gone stale")
|
|
}
|
|
|
|
names := make([]string, 0, len(used))
|
|
for n := range used {
|
|
names = append(names, n)
|
|
}
|
|
sort.Strings(names)
|
|
|
|
for _, n := range names {
|
|
if !ui.HasIcon(n) {
|
|
t.Errorf("icon %q is not registered (used in %s) — it will render as an empty box",
|
|
n, strings.Join(dedupe(used[n]), ", "))
|
|
}
|
|
}
|
|
t.Logf("checked %d icon names", len(names))
|
|
}
|
|
|
|
func dedupe(in []string) []string {
|
|
seen := map[string]bool{}
|
|
out := in[:0:0]
|
|
for _, s := range in {
|
|
if !seen[s] {
|
|
seen[s] = true
|
|
out = append(out, s)
|
|
}
|
|
}
|
|
return out
|
|
}
|