package webui import ( "os" "path/filepath" "regexp" "sort" "strings" "testing" "kjol/wasmruntime/vdom" ) // An unregistered icon name renders as an empty box: right size, no glyph. Nothing // errors, nothing logs — the icons just quietly aren't there. That is exactly how // this broke, so scan our own source for every name we ask for and assert the // registry has it. func TestEveryIconTheKitUsesIsRegistered(t *testing.T) { // Icon("name", …), IconInline("name", …), and the Icon: "name" struct field. calls := regexp.MustCompile(`\bIcon(?:Inline|Success|Error)?\("([a-z0-9-]+)"`) fields := 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") || f == "icons.go" { continue // icons.go is the registry itself } src, err := os.ReadFile(f) if err != nil { t.Fatal(err) } for _, re := range []*regexp.Regexp{calls, fields} { for _, m := range re.FindAllStringSubmatch(string(src), -1) { if m[1] == "" { continue } used[m[1]] = append(used[m[1]], f) } } } // Icon names also reach Icon() through lookup tables. Those cannot be found by // scanning call sites, so add them from the tables themselves. for _, name := range toastTypeIcons { if name != "" { used[name] = append(used[name], "toast.go (toastTypeIcons)") } } if len(used) == 0 { t.Fatal("scanned no icon usages — the regexes have rotted") } var missing []string for name, where := range used { if _, ok := iconRegistry[name]; !ok { missing = append(missing, name+" (used in "+strings.Join(dedupe(where), ", ")+")") } } sort.Strings(missing) for _, m := range missing { t.Errorf("icon not registered, renders as an empty box: %s", m) } } // A registered icon must actually draw something. An entry with empty content is // the same silent failure as a missing one. func TestRegisteredIconsHaveContent(t *testing.T) { for name, def := range iconRegistry { if strings.TrimSpace(def.content) == "" { t.Errorf("icon %q is registered with no SVG content", name) } if !strings.Contains(def.content, ": %q", name, def.content) } if def.viewBox == "" { t.Errorf("icon %q has no viewBox", name) } } } func TestIconRendersRegisteredContent(t *testing.T) { html := renderNode(Icon("check", 20, "text-red-500")) if !strings.Contains(html, "