package theme
import (
"strings"
"testing"
)
// Every family resolves to a light theme and a dark one, under ids of
// its own, and a theme with no partner is offered nowhere.
func TestEveryFamilyHasBothSides(t *testing.T) {
if len(Families) != len(familyTable) {
t.Errorf("FAIL: %d of %d families resolved; a row names a theme the generator no longer makes", len(Families), len(familyTable))
}
seen := map[string]bool{}
for _, f := range Families {
if f.Light.Dark || !f.Dark.Dark {
t.Errorf("FAIL: %s pairs %s (dark=%v) with %s (dark=%v)", f.ID, f.Light.ID, f.Light.Dark, f.Dark.ID, f.Dark.Dark)
}
if seen[f.ID] {
t.Errorf("FAIL: family id %s twice", f.ID)
}
seen[f.ID] = true
}
for _, alone := range []string{"dracula", "monokai", "nord", "tokyo-night", "snazzy-light"} {
for _, f := range Families {
if f.Light.ID == alone || f.Dark.ID == alone {
t.Errorf("FAIL: %s has no partner but is offered in %s", alone, f.ID)
}
}
}
t.Logf("ok: %d families, each a light and a dark theme", len(Families))
}
// A choice saved as a single theme finds its family; an unknown id and
// an unpaired theme find none.
func TestOldChoicesFindTheirFamily(t *testing.T) {
for id, want := range map[string]string{"gruvbox-dark-hard": "gruvbox-hard", "catppuccin-latte": "catppuccin-mocha", "github": "github"} {
if f, ok := FamilyByID(id); !ok || f.ID != want {
t.Errorf("FAIL: %s found %q, want %q", id, f.ID, want)
}
}
for _, id := range []string{"nord", "no-such-theme", ""} {
if f, ok := FamilyByID(id); ok {
t.Errorf("FAIL: %q found family %s", id, f.ID)
}
}
}
// A family's sheets carry the light side plainly and the dark side under
// both of paletteCSS's dark conditions, so the page's own light/dark
// choice picks the side.
func TestFamilySheetsFollowLightAndDark(t *testing.T) {
f, _ := FamilyByID("gruvbox-hard")
site, code := FamilySiteCSS(f), FamilyCodeCSS(f)
lightBg, darkBg := f.Light.Value("--bg"), f.Dark.Value("--bg")
for _, want := range []string{
":root:root{--", "--bg:" + lightBg, "color-scheme:light",
`@media (prefers-color-scheme: dark){:root:root:not([data-theme="light"]){`,
`:root:root[data-theme="dark"]{`, "--bg:" + darkBg, "color-scheme:dark",
} {
if !strings.Contains(site, want) {
t.Errorf("FAIL: site sheet lacks %q", want)
}
}
for _, want := range []string{
codeSelector + "{",
`@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) :is(` + codeSelector + "){",
`:root[data-theme="dark"] :is(` + codeSelector + "){",
"--syn-kw:" + f.Light.Value("--syn-kw"), "--syn-kw:" + f.Dark.Value("--syn-kw"),
} {
if !strings.Contains(code, want) {
t.Errorf("FAIL: code sheet lacks %q", want)
}
}
if strings.Contains(code, "--bg:") {
t.Error("FAIL: the code sheet sets the page ground")
}
if strings.Count(site, "{") != strings.Count(site, "}") || strings.Count(code, "{") != strings.Count(code, "}") {
t.Error("FAIL: a family sheet's braces do not balance")
}
}