#!/usr/bin/env python3 """Compile elements rejection cases against this checkout's runtime.""" from pathlib import Path import os import subprocess import tempfile ROOT = Path(__file__).resolve().parents[1] NODE_CASES = [ ('polar element,element inner radius=2cm,element outer radius=1cm', 'element outer radius must exceed inner radius'), ('polar element,element delta angle=0', 'element delta angle must be greater than zero'), ('polar element,element delta angle=361', 'element delta angle must not exceed 360 degrees'), ('polar element,element delta angle=1cm', 'element delta angle must be unitless'), ('polar element,element start angle=1cm', 'element start angle must be unitless'), ('unwrapped ring,element inner radius=0cm', 'unwrapped ring requires a positive inner radius'), ] PIC_CASES = [ (r'\pic {sphere slice diagram={element position=1}};', 'sphere-slice position must lie between -1 and 1'), (r'\pic {sphere slice diagram={element axial thickness=3cm}};', 'sphere-slice thickness is too large'), (r'\pic {sphere slice diagram={element position=.98}};', 'sphere slice extends beyond the sphere body'), (r'\pic {cylinder slice diagram={element position=0}};', 'cylinder slice extends beyond the cylinder body'), (r'\pic {cylinder slice diagram={element axial thickness=4cm}};', 'cylinder-slice thickness must be smaller than body height'), (r'\pic {cylinder shell diagram={element inner radius=2cm}};', 'cylindrical shell must lie inside the cylinder body'), (r'\pic {cone slice diagram={element position=0}};', 'cone-slice position must be greater than zero'), (r'\pic {cone slice diagram={element position=.99}};', 'cone slice extends beyond the base'), (r'\pic {cone slice diagram={element projection ratio=1.5}};', 'element projection ratio must not exceed one'), (r'\pic {sheet element diagram={element width=6cm}};', 'rectangular element must be narrower than its sheet'), (r'\pic {sheet element diagram={element height=4cm}};', 'rectangular element must be shorter than its sheet'), (r'\pic {sheet element diagram={element transverse position=1.5}};', 'element transverse position must not exceed one'), ] def main(): env = os.environ.copy() env['TEXINPUTS'] = str(ROOT) + os.pathsep cases = [(r'\node[' + options + r'] (N) {};', diagnostic) for options, diagnostic in NODE_CASES] + PIC_CASES with tempfile.TemporaryDirectory(prefix='tikzphysics-elements-') as folder: work = Path(folder) for index, (body, diagnostic) in enumerate(cases): source = (r'\documentclass{article}\usepackage{tikzphysics}\begin{document}' r'\begin{tikzpicture}' + body + r'\end{tikzpicture}\end{document}') (work / 'case.tex').write_text(source) proc = subprocess.run( ['pdflatex', '-interaction=nonstopmode', '-halt-on-error', 'case.tex'], cwd=work, env=env, capture_output=True, text=True, timeout=60) # TeX may hard-wrap a diagnostic inside a word. normalized = ''.join(proc.stdout.split()) if proc.returncode == 0 or ''.join(diagnostic.split()) not in normalized: raise SystemExit(f'FAIL case {index}: {body}\n{proc.stdout[-2500:]}') print(f'PASS: rejected {body}') print(f'All {len(cases)} invalid-input cases rejected with the intended diagnostic.') if __name__ == '__main__': main()