from drawing_intelligence.normalization import ( enrich_characteristic, infer_category, records_from_ocr_text, validate_characteristics, ) from drawing_intelligence.schema import Category, Characteristic, ReviewStatus def test_bilateral_dimension_is_normalized_without_standard_lookup() -> None: item = enrich_characteristic( Characteristic( balloon_id="12", requirement="4X ⌀12.00 ±0.05 THRU", source_text="4X ⌀12.00 ±0.05 THRU", ) ) assert item.category == Category.DIAMETER assert item.nominal == "12.00" assert item.upper_tolerance == "0.05" assert item.lower_tolerance == "-0.05" assert item.upper_limit == "12.05" assert item.lower_limit == "11.95" assert item.quantity == 4 def test_thread_and_surface_finish_categories() -> None: assert infer_category("M14×1.5-6H") == Category.THREAD assert infer_category("Ra 1.6") == Category.SURFACE_FINISH assert infer_category("⌖ ⌀0.10 M | A | B | C") == Category.GD_AND_T def test_ocr_fallback_does_not_fabricate_balloon_mapping() -> None: rows = records_from_ocr_text("Ø12 H7\n27: M14×1.5-6H", page=1) assert rows[0].balloon_id.startswith("UNASSIGNED") assert rows[0].status == ReviewStatus.NEEDS_MAPPING assert rows[1].balloon_id == "27" def test_ai_verified_status_is_reset_for_human_review() -> None: item = Characteristic( balloon_id="9", requirement="R5 ±0.2", source_text="R5 ±0.2", status=ReviewStatus.VERIFIED, ) validated = validate_characteristics([item]) assert validated[0].status == ReviewStatus.NEEDS_REVIEW