from __future__ import annotations import copy import importlib.util import json import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "designir_pipeline.py" SPEC = importlib.util.spec_from_file_location("designir_pipeline", SCRIPT) MODULE = importlib.util.module_from_spec(SPEC) assert SPEC.loader SPEC.loader.exec_module(MODULE) class DesignIRPipelineTests(unittest.TestCase): def payload(self) -> dict: return json.loads( (ROOT / "examples" / "raised_hub_flange.designir.json").read_text() ) def test_example_is_valid_and_compiles(self) -> None: payload = MODULE.validate_designir(self.payload()) with tempfile.TemporaryDirectory() as temporary: output = Path(temporary) / "flange.step" result = MODULE.compile_designir(payload, output) self.assertTrue(output.is_file()) self.assertEqual(1, result["facts"]["solid_count"]) self.assertGreater(result["facts"]["volume_mm3"], 30_000) def test_legacy_model_migrates_to_semantic_designir_3(self) -> None: migrated = MODULE.migrate_designir_2_to_3(self.payload()) self.assertEqual("3.0", migrated["schema_version"]) self.assertEqual( "fully_semantic_parametric", migrated["reconstruction_mode"] ) self.assertIn( "outer_radius", migrated["edit_interface"]["semantic_parameters"] ) with tempfile.TemporaryDirectory() as temporary: output = Path(temporary) / "flange.step" result = MODULE.compile_designir(migrated, output) self.assertEqual(1, result["facts"]["solid_count"]) def test_generated_step_materializes_hybrid_surface_snapshot(self) -> None: migrated = MODULE.migrate_designir_2_to_3(self.payload()) with tempfile.TemporaryDirectory() as temporary: output = Path(temporary) / "flange.step" MODULE.compile_designir(migrated, output) hybrid = MODULE.materialize_hybrid_designir(migrated, output) self.assertEqual( "hybrid_semantic_surface_parametric", hybrid["reconstruction_mode"], ) self.assertTrue(hybrid["surface_layer"]["solids"]) self.assertTrue( hybrid["compiled_surface_provenance"][ "semantic_layer_authoritative" ] ) self.assertTrue(MODULE.anti_cheat(hybrid)["valid"]) rebuilt = Path(temporary) / "hybrid-rebuilt.step" MODULE.compile_designir(hybrid, rebuilt) self.assertTrue(rebuilt.is_file()) def test_teacher_dependency_is_rejected(self) -> None: payload = self.payload() payload["source_step"] = "teacher.step" with self.assertRaisesRegex(MODULE.DesignIRError, "Teacher geometry"): MODULE.validate_designir(payload) def test_example_compiles_with_simplecadapi_and_exports_graph(self) -> None: payload = self.payload() with tempfile.TemporaryDirectory() as temporary: output = Path(temporary) / "flange.step" result = MODULE.compile_designir( payload, output, backend="simplecadapi" ) self.assertEqual("simplecadapi", result["backend"]) self.assertGreater(result["facts"]["volume_mm3"], 30_000) model_json_path = Path(result["model_json"]) self.assertTrue(model_json_path.is_file()) model_json = json.loads(model_json_path.read_text(encoding="utf-8")) serialized = json.dumps(model_json) self.assertIn("feature.base.flange", serialized) self.assertIn("feature.central.bore", serialized) self.assertTrue(model_json.get("leaf_ids")) def test_arbitrary_axis_geometric_center_preserves_pose(self) -> None: payload = self.payload() payload["family"] = "axis_aligned_cylinder" payload["parameters"] = { "outer_radius": {"value": 10, "unit": "mm", "editable": True}, "overall_length": {"value": 400, "unit": "mm", "editable": True}, } payload["expressions"] = {} payload["features"] = [ { "id": "main_body", "operation": "extrude_circle", "radius": {"parameter": "outer_radius"}, "height": {"parameter": "overall_length"}, "axis": [0, -1, 0], "center": [7, 11, 13], "anchor": "geometric_center", } ] payload["edit_interface"] = { "editable_parameters": ["outer_radius", "overall_length"], "preserved_interfaces": ["part_center", "primary_axis"], } payload["validation_contract"]["perturbations"] = [ { "parameter": "outer_radius", "scale": 1.1, "expected_change": "radius", "preserve": ["overall_length", "part_center"], }, { "parameter": "overall_length", "scale": 1.1, "expected_change": "length", "preserve": ["outer_radius", "part_center"], }, ] shape = MODULE.build_shape(payload) bounds = shape.bounding_box() self.assertAlmostEqual(-189, bounds.min.Y, places=6) self.assertAlmostEqual(211, bounds.max.Y, places=6) self.assertAlmostEqual(7, shape.center(MODULE.CenterOf.MASS).X, places=6) self.assertAlmostEqual(11, shape.center(MODULE.CenterOf.MASS).Y, places=6) self.assertAlmostEqual(13, shape.center(MODULE.CenterOf.MASS).Z, places=6) def test_embedded_mesh_is_rejected(self) -> None: payload = self.payload() payload["features"][0]["mesh"] = {"vertices": [[0, 0, 0]]} with self.assertRaisesRegex(MODULE.DesignIRError, "Teacher geometry"): MODULE.validate_designir(payload) def test_isolated_rebuild_has_no_teacher(self) -> None: with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) designir = root / "flange.designir.json" designir.write_text(json.dumps(self.payload()), encoding="utf-8") output = root / "rebuilt.step" result = MODULE.isolated_rebuild(designir, output) self.assertTrue(result["valid"]) self.assertFalse(result["teacher_step_available"]) self.assertTrue(output.is_file()) def test_acceptance_passes_identical_designir_rebuild(self) -> None: payload = self.payload() with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) teacher = root / "teacher.step" rebuilt = root / "rebuilt.step" MODULE.compile_designir(payload, teacher) MODULE.compile_designir(payload, rebuilt) report = MODULE.acceptance_report(teacher, rebuilt, payload) self.assertEqual("pass", report["verdict"]) self.assertEqual("replay_validated", report["next_state"]) self.assertEqual( 1.0, report["editability"]["parameter_perturbation_success_rate"] ) def test_unsupported_vocabulary_is_honest_failure(self) -> None: payload = self.payload() payload["reconstruction_status"] = "unsupported_feature_vocabulary" payload["missing_capabilities"] = ["multi_rail_sweep"] with self.assertRaisesRegex(MODULE.DesignIRError, "multi_rail_sweep"): MODULE.build_shape(payload) def test_promotion_requires_independent_replay_validated_cases(self) -> None: with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) reports = [] for index in range(3): report = root / f"case-{index}.json" report.write_text( json.dumps( { "model_id": f"case-{index}", "teacher_sha256": f"teacher-{index}", "applied_experience_ids": [ "reconstruction.flange.primary" ], "next_state": "replay_validated", } ), encoding="utf-8", ) reports.append(report) result = MODULE.promotion_check( reports, ROOT / "config" / "promotion-policy.json" ) self.assertTrue(result["eligible"]) self.assertEqual( ["reconstruction.flange.primary"], result["validated_experience_ids"], ) self.assertEqual("promoted", result["next_state"]) if __name__ == "__main__": unittest.main()