from __future__ import annotations from core.csv_utils import merge_verbatim_long_strings, set_at_path def test_merge_replaces_truncated_string_same_path() -> None: raw = { "Notas": ( "Las retenciones son informativas. Paciente: 1 - NOMBRE " "Contrato No. X. Valor en Letras: MIL PESOS Fecha ingreso 01/01/2024" ), } norm = {"Notas": "Las retenciones son informativas. Paciente: 1 - NOMBRE "} merge_verbatim_long_strings(raw, norm, ["Notas"]) assert norm["Notas"] == raw["Notas"] def test_merge_nested_path() -> None: raw = {"cabecera": {"Notas": "A" * 200}} norm = {"cabecera": {"Notas": "A" * 40}} merge_verbatim_long_strings(raw, norm, ["cabecera/Notas"]) assert norm["cabecera"]["Notas"] == "A" * 200 def test_merge_resolves_by_unique_last_segment() -> None: raw = {"Notas": "texto completo desde raĆ­z cuando el normalizado usa cabecera/Notas"} norm = {"cabecera": {"Notas": "texto completo"}} merge_verbatim_long_strings(raw, norm, ["cabecera/Notas"]) assert norm["cabecera"]["Notas"] == raw["Notas"] def test_merge_skips_ambiguous_same_last_segment() -> None: raw = { "a": {"Notas": "primera nota " + "x" * 50}, "b": {"Notas": "segunda nota " + "y" * 50}, } norm = {"cabecera": {"Notas": "primera nota"}} merge_verbatim_long_strings(raw, norm, ["cabecera/Notas"]) assert norm["cabecera"]["Notas"] == "primera nota" def test_merge_skips_when_normalized_not_prefix_of_raw() -> None: raw = {"Notas": "completamente distinto " + "z" * 80} norm = {"Notas": "otro texto corto"} merge_verbatim_long_strings(raw, norm, ["Notas"]) assert norm["Notas"] == "otro texto corto" def test_merge_skips_paths_with_wildcard() -> None: raw = {"items": [{"x": "long " * 20}]} norm = {"items": [{"x": "long "}]} merge_verbatim_long_strings(raw, norm, ["items/*/x"]) assert norm["items"][0]["x"] == "long " def test_set_at_path_creates_intermediates() -> None: root: dict = {} set_at_path(root, "a/b/c", 1) assert root == {"a": {"b": {"c": 1}}}