from app.schemas.cross_validation import AnswerKind, ValidationConfidence from app.services.math_answer_extractor import extract_student_math_answer def test_extractor_uses_scanner_for_set_literal() -> None: r = extract_student_math_answer( "La reponse est {3}.", expected_answer_kind=AnswerKind.SOLUTION_SET, ) assert r.extracted_value == "3" assert r.confidence == ValidationConfidence.CERTAIN assert r.needs_human_review is False assert r.reason == "deterministic_structure_scanner" def test_extractor_preserves_multi_value_solution_set() -> None: r = extract_student_math_answer( "On obtient S={-2, 4}.", expected_answer_kind=AnswerKind.SOLUTION_SET, ) assert r.extracted_value == "{-2,4}" assert r.confidence == ValidationConfidence.CERTAIN assert r.needs_human_review is False def test_extractor_marks_bare_number_as_semantic_residue() -> None: r = extract_student_math_answer( "Donc 3 est la solution.", expected_answer_kind=AnswerKind.SOLUTION_SET, ) assert r.extracted_value == "3" assert r.confidence == ValidationConfidence.PROBABLE assert r.needs_human_review is True assert r.reason == "bare_number_requires_semantic_confirmation"