diff options
Diffstat (limited to 'scripts/theme-studio/test_generate.py')
| -rw-r--r-- | scripts/theme-studio/test_generate.py | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/scripts/theme-studio/test_generate.py b/scripts/theme-studio/test_generate.py index e20e90b3e..974fca68a 100644 --- a/scripts/theme-studio/test_generate.py +++ b/scripts/theme-studio/test_generate.py @@ -10,6 +10,7 @@ Run: python3 -m unittest test_generate (from scripts/theme-studio/) """ import os import io +import json import tempfile import runpy import unittest @@ -82,38 +83,36 @@ class AssembledPage(unittest.TestCase): "PALETTE_ACTIONS_J", "BROWSER_GATES_J", "COLORMATH_J", "SAMPLES_J", "PALETTE_J", "CATS_J", "UIFACES_J", "UIMAP_J", "APPS_J", "SYNTAX_J", "MAP_J", - "COLOR_NAMES_J", + "COLOR_NAMES_J", "FACE_DOCS_J", "SYNTAX_DOCS_J", ] def test_every_placeholder_is_substituted(self): for token in self.PLACEHOLDERS: self.assertNotIn(token, generate.HTML, f"{token} left unsubstituted") - def test_page_carries_the_colormath_body_verbatim(self): - # Python-side inline-integrity: the same guarantee the JS test asserts, but - # checked at the point the page is built rather than after a round-trip. - self.assertIn(generate.COLORMATH_BODY, generate.HTML) - - def test_page_carries_the_app_core_body_verbatim(self): - # app-core.js inlines verbatim (no data placeholders), so the inlined copy - # and the unit-tested module cannot drift. - self.assertIn(generate.APP_CORE_BODY, generate.HTML) - - def test_page_carries_the_app_util_body_verbatim(self): - # app-util.js inlines verbatim after its import line is stripped. - self.assertIn(generate.APP_UTIL_BODY, generate.HTML) - - def test_page_carries_palette_generator_core_verbatim(self): - self.assertIn(generate.PALETTE_GENERATOR_CORE_BODY, generate.HTML) - - def test_page_carries_palette_generator_ui_verbatim(self): - self.assertIn(generate.PALETTE_GENERATOR_UI_BODY, generate.HTML) - - def test_page_carries_palette_actions_verbatim(self): - self.assertIn(generate.PALETTE_ACTIONS_BODY, generate.HTML) - - def test_page_carries_browser_gates_verbatim(self): - self.assertIn(generate.BROWSER_GATES_BODY, generate.HTML) + def test_face_docs_maps_embed_a_known_docstring(self): + # The face/syntax docstring maps inline so element hovers can show them. + # default is always present; its first line is stable across Emacs builds. + self.assertIn("Basic default face.", generate.FACE_DOCS["default"]) + self.assertIn(json.dumps(generate.FACE_DOCS), generate.HTML) + + def test_syntax_docs_resolve_categories_to_face_docstrings(self): + # The syntax table is keyed by category (kw, doc, ...); each resolves to + # its font-lock face's docstring via build-theme's canonical map. + self.assertIn("keyword", generate.SYNTAX_DOCS["kw"].lower()) + self.assertIn(json.dumps(generate.SYNTAX_DOCS), generate.HTML) + + def test_page_carries_each_inlined_body_verbatim(self): + # Python-side inline-integrity: every verbatim-inlined module (no data + # placeholders, exports/imports stripped) must appear in the page byte for + # byte, so the inlined copy and the unit-tested module cannot drift. Checked + # at build time rather than after a round-trip. app-util.js's import line is + # already stripped in APP_UTIL_BODY. + for name in ("COLORMATH_BODY", "APP_CORE_BODY", "APP_UTIL_BODY", + "PALETTE_GENERATOR_CORE_BODY", "PALETTE_GENERATOR_UI_BODY", + "PALETTE_ACTIONS_BODY", "BROWSER_GATES_BODY"): + with self.subTest(body=name): + self.assertIn(getattr(generate, name), generate.HTML) def test_app_util_inlined_body_has_no_import_line(self): # The `import rl` line must be gone, or the page <script> is invalid. @@ -164,6 +163,20 @@ class LanguageSamples(unittest.TestCase): self.assertIn("@import", text) self.assertIn("error.MissingColor", text) + def test_expanded_language_set_is_registered_and_renders(self): + # Every added language is selectable and renders a non-trivial sample that + # exercises keywords and carries a comment. + added = ["Racket", "Scheme", "Haskell", "OCaml", "Scala", "Kotlin", + "Swift", "Lua", "Ruby", "Perl", "R", "Erlang", "SQL", "PHP", + "Ada", "Fortran", "MATLAB", "Assembly"] + for lang in added: + self.assertIn(lang, generate.SAMPLES, f"{lang} not in the language selector") + tokens = self._tokens(lang) + cats = {k for k, _ in tokens} + self.assertGreater(len(tokens), 40, f"{lang} sample is too short") + self.assertIn("kw", cats, f"{lang} sample has no keywords") + self.assertIn("cmd", cats, f"{lang} sample has no comment") + class FacesHelper(unittest.TestCase): def test_strips_prefix_and_derives_label_and_merges_seed(self): @@ -421,6 +434,16 @@ class DefaultFaceAdapter(unittest.TestCase): }, "effectiveGuiLight": {}, }, + "rich": { + "chosenGuiLight": { + "distantForeground": "black", + "distantForegroundHex": "#000000", + "overline": "t", + "inverseVideo": "t", + "extend": "t", + }, + "effectiveGuiLight": {}, + }, } }) @@ -435,6 +458,19 @@ class DefaultFaceAdapter(unittest.TestCase): "box": {"style": "released", "width": 2, "color": None}, }) + def test_seed_emits_the_additive_attrs_when_the_snapshot_has_them(self): + self.assertEqual(self.defaults.seed("rich", effective=False), { + "distant-fg": "#000000", + "overline": {"color": None}, + "inverse": True, + "extend": True, + }) + + def test_seed_omits_additive_attrs_when_the_snapshot_lacks_them(self): + seeded = self.defaults.seed("sample", effective=False) + for key in ("distant-fg", "overline", "inverse", "extend"): + self.assertNotIn(key, seeded) + def test_color_reads_effective_hex_by_default(self): self.assertEqual(self.defaults.color("sample"), "#000000") |
