from __future__ import annotations import unittest from src.localization_quality import ( calculate_bbox_area_ratio, evaluate_localization_boxes, ) from src.schemas.detection import BBox as LocalizationBox def make_box(box_2d: list[int], label: str = "finding") -> LocalizationBox: return LocalizationBox(box_2d=box_2d, label=label) class TestLocalizationQualityGate(unittest.TestCase): def test_a_small_focal_nodule_box_accepted(self) -> None: box = make_box([388, 553, 403, 575], label="nodule") result = evaluate_localization_boxes("nodule", [box]) self.assertEqual(len(result.accepted_boxes), 1) self.assertEqual(result.rejection_reasons, []) self.assertAlmostEqual(calculate_bbox_area_ratio(box), 0.0003, places=4) def test_b_broad_fracture_box_rejected(self) -> None: box = make_box([100, 100, 700, 500], label="fracture") result = evaluate_localization_boxes("fracture", [box]) self.assertEqual(result.accepted_boxes, []) self.assertTrue( any("bbox_area_ratio=0.2400" in reason for reason in result.rejection_reasons) ) def test_c_large_diffuse_opacity_box_not_geometry_rejected(self) -> None: box = make_box([380, 250, 750, 750], label="opacity") result = evaluate_localization_boxes("opacity", [box]) self.assertEqual(len(result.accepted_boxes), 1) self.assertEqual(result.rejection_reasons, []) if __name__ == "__main__": unittest.main()