from pathlib import Path import re PROJECT_DIR = Path(__file__).resolve().parents[1] def iter_app_dirs(): for p in PROJECT_DIR.iterdir(): if not p.is_dir(): continue if p.name.startswith('_'): continue if (p / '__init__.py').exists(): yield p TEMPLATE_EXPR = re.compile(r"{{\s*([^}]*)\s*}}") def extract_exprs(html_path: Path): text = html_path.read_text(encoding='utf-8', errors='ignore') return TEMPLATE_EXPR.findall(text) def test_results_templates_have_next_button(): missing = [] for app_dir in iter_app_dirs(): results = app_dir / 'Results.html' if results.exists(): text = results.read_text(encoding='utf-8', errors='ignore') if '{{ next_button }}' not in text: missing.append(app_dir.name) assert not missing, ( "Missing '{{ next_button }}' in Results.html for apps: " + ", ".join(missing) ) def test_no_arithmetic_in_any_app_templates(): offenders = [] control = { 'extends', 'block', 'endblock', 'include', 'include_sibling', 'if', 'elif', 'else', 'endif', 'for', 'endfor', 'formfields', 'next_button', 'chat', 'load', 'static' } for app_dir in iter_app_dirs(): for html in app_dir.glob('*.html'): for expr in extract_exprs(html): head = expr.strip().split()[0] if expr.strip() else '' if head in control: continue if any(op in expr for op in ('-', '*', '/', '+')): offenders.append(f"{app_dir.name}/{html.name}: {expr.strip()}") assert not offenders, ( 'Unsupported arithmetic in template expressions found: ' + '; '.join(offenders) )