"""Guards on the stylesheet that the browser will not give us.

An undefined custom property does not fail loudly — the declaration is invalid
at computed-value time, so the element quietly inherits instead. A colour typed
as `var(--ink-soft)` when the token is `--ink-3` therefore looks *almost* right
on most elements and is easy to ship.
"""
import re

from django.conf import settings
from django.test import SimpleTestCase

CSS = (settings.BASE_DIR / "static" / "portal.css").read_text()

# Set per element from a template rather than declared in the stylesheet.
SET_INLINE = {"--cat"}
# Supplied by the branding context processor into an inline :root block.
SET_PER_INSTANCE = {"--masthead"}


class StylesheetTokenTests(SimpleTestCase):
    def test_every_custom_property_used_is_defined_somewhere(self):
        """Only fallback-less uses count.

        `var(--arrow-x, 50%)` is deliberate — the property is set from script
        on some elements and the fallback covers the rest. It is `var(--x)`
        with nothing behind it that silently inherits.
        """
        defined = set(re.findall(r"^\s*(--[a-z0-9-]+)\s*:", CSS, re.M))
        bare = set(re.findall(r"var\(\s*(--[a-z0-9-]+)\s*\)", CSS))
        missing = bare - defined - SET_INLINE - SET_PER_INSTANCE
        self.assertEqual(missing, set(), "undefined custom properties: %s" % sorted(missing))

    def test_the_per_instance_tokens_are_actually_consumed(self):
        """Branding is config, so the stylesheet must read it, not hardcode it."""
        self.assertIn("var(--masthead)", CSS)
        self.assertIn("var(--accent)", CSS)

    def test_the_masthead_is_not_given_a_hardcoded_colour(self):
        header = CSS[CSS.index(".site-header {"):CSS.index(".header-inner {")]
        self.assertIn("var(--masthead)", header)
