"""Разбор дат из OCR-текста (§11.1 п. 2): дословный перенос `date_utils` старого ядра, вход — после `fix_lookalikes`.""" from datetime import date import pytest from src.normalizer.ocr.dates import parse_date from src.normalizer.ocr.text import fix_lookalikes LOOKALIKES = {"О": "0", "о": "0", "З": "3", "l": "1", "I": "1", "|": "1", "б": "6", "S": "5", "Ч": "4"} @pytest.mark.parametrize( ("raw", "expected"), [ ("на 30 сентября 2025 г.", date(2025, 9, 30)), ("На 30 июня\n2025 г", date(2025, 6, 30)), ("31 декабря 2024 года", date(2024, 12, 31)), ("30 сентября 2025 r.", date(2025, 9, 30)), # латинская r вместо г ("с 01.01.2025 по 30.09.2025", date(2025, 9, 30)), # диапазон — конец ("I квартал 2026", date(2026, 3, 31)), ("1-й кв. 2026", date(2026, 3, 31)), ("первый квартал 2025 г.", date(2025, 3, 31)), ("1 полугодие 2026", date(2026, 6, 30)), ("1 п/г 2026", date(2026, 6, 30)), ("9 месяцев 2025", date(2025, 9, 30)), ("9 мес. 2025", date(2025, 9, 30)), ("За январь - июнь\n2025 г.", date(2025, 6, 30)), ("январь – сентябрь 2025", date(2025, 9, 30)), ("за 2025 г.", date(2025, 12, 31)), ("2024 год", date(2024, 12, 31)), ("30.09.2025", date(2025, 9, 30)), ("2025 03 31", date(2025, 3, 31)), ("30/09/25", date(2025, 9, 30)), ("2 0 2 4", date(2024, 12, 31)), ("30 09 2 0 2 5", date(2025, 9, 30)), ("30092025", date(2025, 9, 30)), ("20250930", date(2025, 9, 30)), ("30 09 25", date(2025, 9, 30)), ("30.09.2025 0:00:00", date(2025, 9, 30)), ("2|0|2|4|", date(2024, 12, 31)), # через fix_lookalikes ("3l.12.2О24", date(2024, 12, 31)), ], ) def test_parses_real_forms(raw: str, expected: date) -> None: assert parse_date(fix_lookalikes(raw, LOOKALIKES)) == expected @pytest.mark.parametrize( "raw", [ "Общество с ограниченной ответственностью", # Review Focus 3: название организации — не дата "ЗАКРЫТОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО", "", "+", "тыс. руб.", "1999999999999", # 13 цифр — ни одна форма ], ) def test_organization_name_is_not_a_date(raw: str) -> None: assert parse_date(fix_lookalikes(raw, LOOKALIKES)) is None def test_non_string_is_none() -> None: assert parse_date(None) is None assert parse_date(20250930) is None def test_year_out_of_range_is_none() -> None: assert parse_date("1 2 3 4") is None # 1234 вне 1990–2100