Skip to content

Commit ae5c37d

Browse files
Ahad690claude
andcommitted
Fix catalog render: escaped newline in the JS template killed the whole script
The aiPrompt helper's lines.join('\n') sat inside build_catalog.py's Python template string, so Python interpreted the escape and emitted a literal newline inside a JS string literal - a syntax error that silently blanked every gig card (header still rendered). Now emits \n; added a regression test that extracts the embedded <script> and validates it (node --check when available) plus asserts the escape survives intact. Regenerated the README demo screenshot, which had captured the broken empty render. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c62c35d commit ae5c37d

3 files changed

Lines changed: 20 additions & 1 deletion

File tree

assets/demo-catalog.png

104 KB
Loading

skills/fiverr-gig-optimizer/scripts/build_catalog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
'Style: flat, modern, minimal tech aesthetic; strong contrast; crisp typography; plenty of negative space.',
144144
'Do NOT include: photos of people, stock-photo textures, watermarks, logos, or any text other than the strings quoted above. All quoted text must be spelled exactly as written.'
145145
);
146-
return lines.join('\n');
146+
return lines.join('\\n');
147147
}
148148
149149
const app = document.getElementById('app');

tests/test_build_catalog.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ def test_canvas_thumbnail_still_present(self):
4545
self.assertIn("canvas", self.html)
4646
self.assertIn("Download PNG", self.html)
4747

48+
def test_embedded_script_is_valid_javascript(self):
49+
"""Regression: a Python-interpreted escape (e.g. '\\n' in the template)
50+
once emitted a literal newline inside a JS string, silently killing the
51+
whole render script (header showed, zero gig cards). Validate the
52+
embedded <script> parses — with node when available, else by checking
53+
no string literal is broken across a line."""
54+
import re
55+
m = re.search(r"<script>(.*)</script>", self.html, re.S)
56+
self.assertIsNotNone(m)
57+
js = m.group(1)
58+
self.assertIn(r"lines.join('\n')", js) # the once-broken escape, intact
59+
import shutil
60+
if shutil.which("node"):
61+
js_path = os.path.join(self.dir, "catalog.js")
62+
with open(js_path, "w", encoding="utf-8") as fh:
63+
fh.write(js)
64+
r = subprocess.run(["node", "--check", js_path], capture_output=True, text=True)
65+
self.assertEqual(r.returncode, 0, r.stderr)
66+
4867
def test_ai_prompt_ui_present(self):
4968
self.assertIn("Copy AI image prompt", self.html)
5069
self.assertIn("aiPrompt(", self.html)

0 commit comments

Comments
 (0)