import pytest import asyncio from domain.math_validator import MathPolygraph, _latex_to_sympy_str import sympy @pytest.mark.asyncio async def test_blind_stripping_and_regex(): # Test that mixed text is preserved and math is extracted text = "נציב $x=5$ ונקבל $y=2$. התוצאה היא $$z=7$$." # _validate_single should return True because all math segments are valid ok, reason = await MathPolygraph._validate_single(text, 1) assert ok, f"Failed mixed text: {reason}" @pytest.mark.asyncio async def test_multiline_display_math(): # Test re.DOTALL with multi-line display math text = """הנה משוואה: $$ x = 5 + 3 y = 10 $$ סוף.""" ok, reason = await MathPolygraph._validate_single(text, 1) assert ok, f"Failed multiline display math: {reason}" @pytest.mark.asyncio async def test_multi_equal_guard(): # x=y=5 should not crash unpacking text = "נתון $x = y = 5$." ok, reason = await MathPolygraph._validate_single(text, 1) assert ok, f"Failed multi-equal check: {reason}" @pytest.mark.asyncio async def test_empty_string_guard(): # $$$$ should be ignored text = "ריק $$$$ וגם $ $." ok, reason = await MathPolygraph._validate_single(text, 1) assert ok, f"Failed empty string guard: {reason}" @pytest.mark.asyncio async def test_arithmetic_exception_handling(): # $1/0$ should not crash the server text = "חלוקה באפס $1/0$." ok, reason = await MathPolygraph._validate_single(text, 1) assert not ok assert "SYMPY_PARSE_ERROR" in reason @pytest.mark.asyncio async def test_variable_trap_in_equivalence(): # Algebraic equivalence should pass syntax check but skip numerical identity # x=5 is validated segment by segment (LHS: x, RHS: 5) # are_equivalent for x=5 and x=5 should return True res = MathPolygraph.are_equivalent("x=5", "x=5") assert res is True @pytest.mark.asyncio async def test_numerical_identity_check(): # Valid identity assert MathPolygraph.are_equivalent("2+3", "5") is True # Hallucination assert MathPolygraph.are_equivalent("2+3", "6") is False @pytest.mark.asyncio async def test_inequality_guard(): # x > 0 should not crash simplify(LHS - RHS) # It should skip identity check and return True because strings are same assert MathPolygraph.are_equivalent("x > 0", "x > 0") is True @pytest.mark.asyncio async def test_rce_protection(): # Malicious string that would execute if sympify was used without evaluate=False # However, parse_expr(evaluate=False) just builds the tree. # We just want to ensure it doesn't crash or execute. # Note: testing "exec" in a string is hard without side effects, # but we can verify it doesn't crash on standard malicious patterns. text = "__import__('os').system('echo hello')" # This should definitely fail parsing or at least not execute ok, reason = await MathPolygraph._check_segment(text, 1) assert not ok assert "SYMPY_PARSE_ERROR" in reason if __name__ == "__main__": import pytest pytest.main([__file__])