from app.services.math_structure_scanner import ( MathStructureKind, scan_math_structures, ) def test_scanner_preserves_composite_assign_set_as_single_match() -> None: text = "S = {3} et x = 3 et 3 noyés dans le texte, aussi {3} ici" matches = scan_math_structures(text) assert [item.kind for item in matches] == [ MathStructureKind.ASSIGN_SET, MathStructureKind.ASSIGN_NUM, MathStructureKind.BARE_NUMBER, MathStructureKind.SET_LITERAL, ] assert matches[0].text == "S = {3}" assert matches[0].normalized_text == "S={3}" assert matches[0].children == { "target": "S", "value": "{3}", "elements": ["3"], } assert matches[0].ambiguous is False assert matches[1].text == "x = 3" assert matches[1].children == { "target": "x", "value": "3", } assert matches[1].ambiguous is False assert matches[2].text == "3" assert matches[2].ambiguous is True assert matches[3].text == "{3}" assert matches[3].children == {"elements": ["3"]} assert matches[3].ambiguous is False def test_scanner_handles_negative_and_multi_value_sets() -> None: text = "Après calcul, on obtient S={-2, 4}." matches = scan_math_structures(text) assert len(matches) == 1 assert matches[0].kind == MathStructureKind.ASSIGN_SET assert matches[0].text == "S={-2, 4}" assert matches[0].normalized_text == "S={-2,4}" assert matches[0].children == { "target": "S", "value": "{-2,4}", "elements": ["-2", "4"], } assert matches[0].ambiguous is False def test_scanner_handles_embedded_variable_assignment() -> None: text = "La solution finale est x=-2." matches = scan_math_structures(text) assert len(matches) == 1 assert matches[0].kind == MathStructureKind.ASSIGN_NUM assert matches[0].text == "x=-2" assert matches[0].children == { "target": "x", "value": "-2", } assert matches[0].ambiguous is False def test_scanner_marks_bare_number_as_ambiguous() -> None: text = "Donc 3 est la solution." matches = scan_math_structures(text) assert len(matches) == 1 assert matches[0].kind == MathStructureKind.BARE_NUMBER assert matches[0].text == "3" assert matches[0].children == {} assert matches[0].ambiguous is True