Files
cdsl-cad/backend/tests/test_engine_profile_contract.py
T

87 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import math
import sys
import tempfile
import unittest
from copy import deepcopy
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "backend"))
sys.path.insert(0, str(ROOT / "backend" / "engine"))
from cdsl_engine.sketch_solver import list_registered_shapes # noqa: E402
def _workplane() -> dict:
return {"origin_mm": [0, 0, 0], "x_dir": [1, 0, 0], "normal": [0, 0, 1]}
def _document(profile: dict) -> dict:
return {
"schema": "cad.cdsl.llm.v1", "schema_version": "1.1.0", "kind": "part", "part_id": "profile-chain",
"meta": {"unit": "mm"},
"geometry": {"sketches": [{
"id": "base", "workplane": _workplane(), "profile": profile,
}]},
"features": [{
"id": "base_add", "atomic_id": "extrude_add_blind", "depends_on": [],
"params": {"distance_mm": 10}, "sketch_id": "base",
}],
}
class EngineProfileContractTests(unittest.TestCase):
"""#10 Profile 链:annulus / circles 进入 CDSL-only 运行时与公开 schema。"""
def test_annulus_and_circles_are_registered_runtime_profiles(self) -> None:
registered = list_registered_shapes()
self.assertIn("annulus", registered)
self.assertIn("circles", registered)
def test_annulus_profile_rebuilds_as_ring_extrusion(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
cdsl = _document({
"type": "annulus", "center": [0, 0], "inner_radius_mm": 2, "outer_radius_mm": 5,
})
with tempfile.TemporaryDirectory() as directory:
result = rebuild_cdsl(cdsl, Path(directory) / "ring.step")
# 环面面积 π(5²-2²)=21π,拉伸 10 → 210π ≈ 659.734
self.assertAlmostEqual(result["volume_mm3"], 210 * math.pi, places=4)
self.assertEqual(result["solid_count"], 1)
def test_circles_profile_rebuilds_as_independent_solids(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
cdsl = _document({
"type": "circles",
"items": [
{"center": [-4, 0], "radius_mm": 2},
{"center": [4, 0], "radius_mm": 2},
],
})
with tempfile.TemporaryDirectory() as directory:
result = rebuild_cdsl(cdsl, Path(directory) / "two.step")
# 两个独立圆柱:2 × π×2²×10 = 80π ≈ 251.327
self.assertAlmostEqual(result["volume_mm3"], 2 * math.pi * 4 * 10, places=4)
self.assertEqual(result["solid_count"], 2)
def test_annulus_validation_rejects_inverted_radii(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
cdsl = _document({
"type": "annulus", "center": [0, 0], "inner_radius_mm": 5, "outer_radius_mm": 2,
})
with tempfile.TemporaryDirectory() as directory:
# 能力检查阶段以 profile_resolution_failed blocker 拒绝该文档
# (reason 为 "annulus: inner_radius must be < outer_radius")。
with self.assertRaises(ValueError):
rebuild_cdsl(cdsl, Path(directory) / "bad.step")
if __name__ == "__main__":
unittest.main()