#!/usr/bin/env python3 from __future__ import annotations import importlib.util import tempfile import unittest from pathlib import Path from PIL import Image, ImageDraw MODULE_PATH = Path(__file__).with_name("verify_visual_fidelity.py") SPEC = importlib.util.spec_from_file_location("verify_visual_fidelity", MODULE_PATH) assert SPEC is not None and SPEC.loader is not None VERIFY = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(VERIFY) class VisualFidelityTests(unittest.TestCase): def _image(self, box: tuple[int, int, int, int] | None = None) -> Image.Image: image = Image.new("RGB", (200, 100), "white") if box is not None: ImageDraw.Draw(image).rectangle(box, fill="black") return image def _contract(self) -> dict: return { "approved_master": {"aspect": 2.0}, "runtime_canvas": {"bounds": "auto_centered"}, "defaults": { "analysis_width": 200, "aspect_ratio_delta": 0.01, "anchor_delta": 0.02, "focal_scale_delta": 0.02, "occupancy_delta": 0.05, "static_region_mean_error": 0.01, "dynamic_detection": { "difference_threshold": 0.1, "minimum_component_area_px": 4, }, }, "regions": [ { "id": "subject", "mode": "runtime_replacement", "search_bounds": [0.0, 0.0, 1.0, 1.0], "runtime_bounds": [0.2, 0.2, 0.2, 0.4], } ], } def _run(self, runtime_box: tuple[int, int, int, int]) -> dict: with tempfile.TemporaryDirectory() as directory: return VERIFY.run_verification( self._image((40, 20, 80, 60)), self._image(runtime_box), self._image(), self._contract(), Path(directory), Path("approved.png"), Path("runtime.png"), Path("static.png"), ) def test_matching_rendered_dynamic_bounds_pass(self) -> None: report = self._run((40, 20, 80, 60)) subject = report["checks"][1] self.assertEqual("PASS", report["result"]) self.assertEqual([0.2, 0.2, 0.205, 0.41], subject["runtime_measurement"]["bounds"]) self.assertIn("declared_runtime_bounds_ignored", subject) def test_copied_runtime_bounds_cannot_hide_shifted_pixels(self) -> None: report = self._run((110, 30, 180, 80)) subject = report["checks"][1] self.assertEqual("FAIL_VISUAL_FIDELITY", report["result"]) self.assertEqual([0.55, 0.3, 0.355, 0.51], subject["runtime_measurement"]["bounds"]) self.assertGreater(subject["anchor_delta"], subject["anchor_tolerance"]) self.assertGreater(subject["size_delta"], subject["size_tolerance"]) if __name__ == "__main__": unittest.main()