diff options
Diffstat (limited to 'scripts/theme-studio/test_generate.py')
| -rw-r--r-- | scripts/theme-studio/test_generate.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/scripts/theme-studio/test_generate.py b/scripts/theme-studio/test_generate.py new file mode 100644 index 00000000..e76acdad --- /dev/null +++ b/scripts/theme-studio/test_generate.py @@ -0,0 +1,84 @@ +"""Tests for the theme-studio page generator (generate.py). + +The generator's risky logic is the export-strip and the placeholder substitution +that inline colormath.js and the sample/palette data into the page. A bug there +ships a broken theme-studio.html that the JS unit tests can't see. These tests +exercise the strip in isolation and assert the assembled page has every +placeholder filled and carries the colormath body verbatim. + +Run: python3 -m unittest test_generate (from scripts/theme-studio/) +""" +import os +import unittest + +import generate # importable without side effects: the file write is __main__-guarded + + +class StripExports(unittest.TestCase): + def test_removes_the_export_line_keeps_the_body(self): + src = "function f(){return 1;}\nexport { f };" + self.assertEqual(generate.strip_exports(src), "function f(){return 1;}") + + def test_preserves_multiline_body_and_rstrips_trailing_blanks(self): + src = "const a=1;\nconst b=2;\nexport { a, b };\n\n" + self.assertEqual(generate.strip_exports(src), "const a=1;\nconst b=2;") + + def test_no_export_line_returns_body_rstripped(self): + self.assertEqual(generate.strip_exports("let x=1;\n"), "let x=1;") + + def test_removes_every_export_line_not_just_the_last(self): + src = "export const a=1;\ncode();\nexport { a };" + self.assertEqual(generate.strip_exports(src), "code();") + + def test_matches_the_js_side_strip_so_integrity_holds(self): + # test-colormath.mjs strips with the same rule: drop lines starting with + # 'export', then trim trailing whitespace. Keep the two in lockstep. + src = "x();\nexport { x };\n" + js_equivalent = "\n".join( + l for l in src.split("\n") if not l.startswith("export") + ).rstrip() + self.assertEqual(generate.strip_exports(src), js_equivalent) + + +class ColormathInlining(unittest.TestCase): + def setUp(self): + self.cm_src = open(os.path.join(generate.HERE, "colormath.js")).read() + + def test_colormath_export_is_a_single_line(self): + # The strip is line-based, so a multi-line `export { ... }` would leave the + # continuation lines behind as a dangling block (a real bug this caught). + export_lines = [l for l in self.cm_src.splitlines() if l.startswith("export")] + self.assertEqual(len(export_lines), 1, "colormath.js must have one export line") + + def test_stripped_body_has_no_export_line_and_ends_cleanly(self): + # "export" can still appear inside a comment; what must be gone is any line + # that *starts* with export (and the dangling continuation lines a + # multi-line export would leave). + body = generate.strip_exports(self.cm_src) + for line in body.splitlines(): + self.assertFalse(line.startswith("export"), f"export line survived: {line!r}") + self.assertTrue(body.endswith("}"), "body should end at the last function") + + +class AssembledPage(unittest.TestCase): + PLACEHOLDERS = [ + "COLORMATH_J", "SAMPLES_J", "PALETTE_J", "CATS_J", + "UIFACES_J", "UIMAP_J", "APPS_J", "BOLD_J", "MAP_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_is_a_single_script_document(self): + self.assertEqual(generate.HTML.count("<script>"), 1) + self.assertEqual(generate.HTML.count("</script>"), 1) + + +if __name__ == "__main__": + unittest.main() |
