dither-alt (3878B)
1 #!/usr/bin/env python3 2 """Exercise migration and cleanup with fake external commands, without AI calls.""" 3 4 import os 5 from pathlib import Path 6 import subprocess 7 import tempfile 8 9 ROOT = Path(__file__).resolve().parent.parent 10 11 with tempfile.TemporaryDirectory(prefix="check-dither-alt-") as directory: 12 root = Path(directory) 13 commands = root / "commands" 14 commands.mkdir() 15 temporary = root / "temporary" 16 temporary.mkdir() 17 post = root / "index.md" 18 image = root / "photo with spaces.jpg.enc" 19 image.write_text("encrypted fixture") 20 plaintext = root / "photo with spaces.jpg" 21 plaintext.write_text("original image must survive") 22 log = root / "calls" 23 24 def command(name, source): 25 path = commands / name 26 path.write_text("#!/usr/bin/env python3\n" + source) 27 path.chmod(0o755) 28 29 command("openssl", """ 30 import os, sys 31 from pathlib import Path 32 args = sys.argv[1:] 33 assert args[:2] == ['aes-256-cbc', '-d'] 34 assert args[args.index('-iter') + 1] == '1000000' 35 assert Path(args[args.index('-in') + 1]).read_text() == 'encrypted fixture' 36 Path(args[args.index('-out') + 1]).write_text('decrypted fixture') 37 if os.environ.get('FAIL_DECRYPT'): 38 sys.exit(1) 39 """) 40 command("codex", """ 41 import os, sys 42 from pathlib import Path 43 args = sys.argv[1:] 44 assert 'accessibility alt text' in args[-1] 45 assert 'Avoid jokes' in args[-1] 46 assert args[args.index('--sandbox') + 1] == 'read-only' 47 assert Path(args[args.index('--image') + 1]).read_text() == 'decrypted fixture' 48 log = Path(os.environ['CALL_LOG']) 49 log.write_text(log.read_text() + 'call\\n' if log.exists() else 'call\\n') 50 if os.environ.get('FAIL_CODEX') and len(log.read_text().splitlines()) == 2: 51 sys.exit(1) 52 result = '' if os.environ.get('EMPTY_CODEX') else 'A child in a blue coat.\\nStanding beside a bicycle.' 53 Path(args[args.index('--output-last-message') + 1]).write_text(result) 54 print('Diagnostic output that must not become alt text') 55 """) 56 env = dict(os.environ, PATH=f"{commands}:{os.environ['PATH']}", 57 TMPDIR=str(temporary), CALL_LOG=str(log)) 58 59 def run(*args, **overrides): 60 result = subprocess.run( 61 [str(ROOT / "bin/refresh-dither-alt"), *args, str(post)], 62 env=dict(env, **overrides), capture_output=True, text=True) 63 leaked = [path for path in temporary.iterdir() 64 if path.name.startswith(("dither-alt-", "image-alt-text-"))] 65 assert not leaked, f"Temporary files leaked: {leaked}; {result.stderr}" 66 assert plaintext.read_text() == "original image must survive" 67 if image.exists(): 68 assert image.read_text() == "encrypted fixture" 69 return result 70 71 original = '''Before. 72 {{<dither unused.jpg "20x20" />}} 73 {{<dither "photo with spaces.jpg" "782x600">}}Cheeky caption.{{</dither>}} 74 Between. 75 {{% dither `photo with spaces.jpg` %}}Multiline 76 caption.{{% /dither %}} 77 {{<dither no-alt.jpg>}} {{</dither>}} 78 After. 79 ''' 80 post.write_text(original) 81 result = run("--dry-run") 82 assert result.returncode == 0, result.stderr 83 assert 'Found 2 shortcode(s)' in result.stdout 84 assert post.read_text() == original and not log.exists() 85 86 result = run() 87 assert result.returncode == 0, result.stderr 88 alt = "A child in a blue coat. Standing beside a bicycle." 89 assert post.read_text() == original.replace("Cheeky caption.", alt).replace("Multiline\ncaption.", alt) 90 91 for failure in ("FAIL_CODEX", "FAIL_DECRYPT", "EMPTY_CODEX"): 92 log.unlink(missing_ok=True) 93 post.write_text(original) 94 result = run(**{failure: "1"}) 95 assert result.returncode == 1, result.stdout 96 assert post.read_text() == original, "Failure partially rewrote a post" 97 98 image.unlink() 99 result = run() 100 assert result.returncode == 1 101 assert post.read_text() == original 102 103 print("Dither alt-text migration checks passed.")