#!/usr/bin/env python3 """Compile rejection cases for native components; no third-party Python modules.""" from pathlib import Path import os import subprocess import tempfile ROOT = Path(__file__).resolve().parents[1] CASES = [ ('beam,beam length=0', '', 'Beam dimensions must be positive'), ('damper,damper position=1.2', '', 'Damper dimensions must be positive'), ('compound pulley,compound pulley inner radius=2', '', 'Pulley radii must satisfy'), ('physical pendulum,physical pendulum pivot=-.1', '', 'Pendulum dimensions must be positive'), ('piston cylinder,piston position=.95', '', 'Cylinder dimensions must be positive'), ('capillary tube,capillary sag=2', '', 'Invalid capillary dimensions'), ('nozzle,nozzle throat diameter=2', '', 'Flow dimensions must satisfy'), ('layered tank,layered tank interface=.9', '', 'Tank dimensions must be positive'), ('solid frustum,solid frustum top ratio=1.5', '', 'Top ratio must be between'), ('conical shell,conical shell thickness=2', '', 'Shell thickness must be between'), ('track,track rough start=80,track rough end=20', '', 'Rough interval must satisfy'), ('standing wave,standing wave lobes=2.5', '', 'Standing wave lobes must be an integer'), ('longitudinal wave,wave compression=1', '', 'Longitudinal wave requires integer'), ('closed pipe,pipe mode=0', '', 'Pipe dimensions must be positive'), ('closed pipe', r'\draw (N.node-1)--(N.center);', 'closed pipe node index out of range'), ] def main(): env = os.environ.copy() env['TEXINPUTS'] = str(ROOT) + os.pathsep with tempfile.TemporaryDirectory(prefix='tikzphysics-components-') as folder: work = Path(folder) for index, (options, extra, diagnostic) in enumerate(CASES): source = (r'\documentclass{article}\usepackage{tikzphysics}\begin{document}' r'\begin{tikzpicture}\node[' + options + r'] (N) {};' + extra + 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) normalized = ' '.join(proc.stdout.split()) if proc.returncode == 0 or diagnostic not in normalized: raise SystemExit(f'FAIL case {index}: {options}\n{proc.stdout[-2500:]}') print(f'PASS: rejected {options}') print(f'All {len(CASES)} invalid-input cases rejected with the intended diagnostic.') if __name__ == '__main__': main()