Spaces:
Sleeping
Sleeping
| import pytest | |
| from solver.dsl_parser import DSLParser | |
| from solver.engine import GeometryEngine | |
| from solver.models import Point, Constraint | |
| def test_solve_square_pyramid(): | |
| """ | |
| Test solving for a square pyramid S.ABCD. | |
| Base ABCD is a square with side 10. | |
| Height SO = 15, where O is the center of ABCD. | |
| """ | |
| dsl = """ | |
| POINT(A, 0, 0, 0) | |
| POINT(B, 10, 0, 0) | |
| POINT(C, 10, 10, 0) | |
| POINT(D, 0, 10, 0) | |
| POINT(S) | |
| POINT(O) | |
| MIDPOINT(M1, AB) | |
| MIDPOINT(M2, AC) | |
| SECTION(O, A, C, 0.5) | |
| LENGTH(SO, 15) | |
| PERPENDICULAR(SO, AC) | |
| PERPENDICULAR(SO, AB) | |
| PYRAMID(S_ABCD) | |
| """ | |
| parser = DSLParser() | |
| engine = GeometryEngine() | |
| points, constraints, is_3d = parser.parse(dsl) | |
| result = engine.solve(points, constraints, is_3d) | |
| assert result is not None | |
| coords = result["coordinates"] | |
| # Check base points | |
| assert coords["A"] == [0.0, 0.0, 0.0] | |
| assert coords["B"] == [10.0, 0.0, 0.0] | |
| assert coords["C"] == [10.0, 10.0, 0.0] | |
| assert coords["D"] == [0.0, 10.0, 0.0] | |
| # Check center O (should be (5, 5, 0)) | |
| assert coords["O"][0] == pytest.approx(5.0) | |
| assert coords["O"][1] == pytest.approx(5.0) | |
| assert coords["O"][2] == pytest.approx(0.0) | |
| # Check apex S (should be (5, 5, 15) or (5, 5, -15)) | |
| assert coords["S"][0] == pytest.approx(5.0) | |
| assert coords["S"][1] == pytest.approx(5.0) | |
| assert abs(coords["S"][2]) == pytest.approx(15.0) | |
| def test_solve_prism(): | |
| """ | |
| Triangular prism ABC_DEF. | |
| Base ABC is right triangle at A. AB=3, AC=4. | |
| Height AD=10. | |
| """ | |
| dsl = """ | |
| POINT(A, 0, 0, 0) | |
| POINT(B, 3, 0, 0) | |
| POINT(C, 0, 4, 0) | |
| POINT(D) | |
| POINT(E) | |
| POINT(F) | |
| LENGTH(AD, 10) | |
| PERPENDICULAR(AD, AB) | |
| PERPENDICULAR(AD, AC) | |
| PRISM(ABC_DEF) | |
| """ | |
| parser = DSLParser() | |
| engine = GeometryEngine() | |
| points, constraints, is_3d = parser.parse(dsl) | |
| result = engine.solve(points, constraints, is_3d) | |
| assert result is not None | |
| coords = result["coordinates"] | |
| # D should be (0, 0, 10) | |
| assert coords["D"][0] == pytest.approx(0.0, abs=1e-3) | |
| assert coords["D"][1] == pytest.approx(0.0, abs=1e-3) | |
| assert abs(coords["D"][2]) == pytest.approx(10.0, rel=1e-4, abs=1e-3) | |
| def test_explicit_z_zero_on_xy_plane_does_not_force_is_3d(): | |
| """POINT with z=0 must not flip is_3d; 2D triangle stays 2D (regression vs POINT(A,x,y,0) bug).""" | |
| dsl = """ | |
| POINT(A, 0, 0, 0) | |
| POINT(B, 3, 0, 0) | |
| POINT(C, 0, 4, 0) | |
| TRIANGLE(ABC) | |
| """ | |
| parser = DSLParser() | |
| points, constraints, is_3d = parser.parse(dsl) | |
| assert is_3d is False | |
| assert len(points) >= 3 | |
| if __name__ == "__main__": | |
| pytest.main([__file__]) | |