优化流程

This commit is contained in:
2026-09-02 13:51:35 +08:00
parent 97a03c290b
commit f3eb5dff54
71 changed files with 5290 additions and 515 deletions
View File
+25
View File
@@ -0,0 +1,25 @@
from __future__ import annotations
import tempfile, unittest
from pathlib import Path
from cadfs_to_cdsl.compare import compare_steps
from cadfs_to_cdsl.featurescript_parser import parse_featurescript
from cadfs_to_cdsl.lowering import lower_model
class IntegrationTests(unittest.TestCase):
def test_known_rp_roundtrip_00000173(self):
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
feature = root / "featurescript_rp/0000/00000173.txt"; gold = root / "step_abc/0000/00000173.step"
if not feature.exists() or not gold.exists(): self.skipTest("CADFS sample is not installed")
cdsl = lower_model(parse_featurescript(feature.read_text(), "00000173"), {}).cdsl
from engine.cdsl_engine.runtime import rebuild_cdsl
with tempfile.TemporaryDirectory() as tmp:
rebuilt = Path(tmp) / "rebuild.step"; rebuild_cdsl(cdsl, rebuilt, strict=True)
comparison = compare_steps(gold, rebuilt)
self.assertFalse(comparison["strict"]["passed"])
self.assertTrue(comparison["rp"]["passed"])
self.assertEqual(comparison["decision"], "approximate_pass")
if __name__ == "__main__": unittest.main()
+45
View File
@@ -0,0 +1,45 @@
from __future__ import annotations
import json, tempfile, unittest
from pathlib import Path
from cadfs_to_cdsl.featurescript_parser import parse_featurescript
from cadfs_to_cdsl.lowering import lower_model
from cadfs_to_cdsl.pipeline import convert_one
from cadfs_to_cdsl.dataset import Sample
from cadfs_to_cdsl.dataset import scan_dataset
from cadfs_to_cdsl.tests.test_parser import SOURCE
class LoweringTests(unittest.TestCase):
def test_missing_dataset_fails_explicitly(self):
with tempfile.TemporaryDirectory() as tmp:
with self.assertRaises(FileNotFoundError): scan_dataset(Path(tmp) / "missing")
def test_circle_extrude_is_valid_cdsl_11(self):
result = lower_model(parse_featurescript(SOURCE, "00000173"), {})
self.assertEqual(result.status, "converted_complete")
self.assertEqual(result.cdsl["schema_version"], "1.1.0")
self.assertEqual(result.cdsl["geometry"]["sketches"][0]["profile"]["radius_mm"], 9.53)
from engine.cdsl_engine.semantic_validation import validate_semantic_cdsl
self.assertTrue(validate_semantic_cdsl(result.cdsl)["future_rebuild_ready"])
def test_unsupported_operation_is_audited_not_invented(self):
source = SOURCE.replace('extrude(context, id + "F1",', 'shell(context, id + "F1",')
result = lower_model(parse_featurescript(source, "00000173"), {})
self.assertEqual(result.status, "deferred_no_executable_feature")
self.assertIsNone(result.cdsl)
self.assertEqual(result.diagnostics[0]["code"], "unsupported_operation")
def test_conversion_writes_status_and_sidecars(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp); source = root / "00000173.txt"; source.write_text(SOURCE)
sample = Sample("00000173", {"featurescript": str(source)}, {"featurescript": "x"})
status = convert_one(sample, root / "out", force=True)
directory = root / "out/samples/00000173"
self.assertEqual(status["conversion_status"], "converted_complete")
for name in ("candidate.cdsl.json", "history.json", "diagnostics.json", "status.json"):
self.assertTrue((directory / name).exists(), name)
self.assertEqual(json.loads((directory / "candidate.cdsl.json").read_text())["part_id"], "00000173")
if __name__ == "__main__": unittest.main()
+47
View File
@@ -0,0 +1,47 @@
from __future__ import annotations
import unittest
from cadfs_to_cdsl.featurescript_lexer import lex
from cadfs_to_cdsl.featurescript_parser import parse_featurescript
from cadfs_to_cdsl.ir import Call
from cadfs_to_cdsl.query_parser import parse_query
from cadfs_to_cdsl.units import length_mm
SOURCE = r'''
FeatureScript 1511;
export const f = defineFeature(function(context, id, definition) {
{ var Q0; Q0=qCreatedBy(makeId("Top.planeOp"), FACE);
var sketch = newSketch(context, id + "F0", {"sketchPlane":qUnion([Q0])});
skCircle(sketch, "E0", {"center":v(0, 0) * mm, "radius":9.53 * mm}); skSolve(sketch); }
{ var Q0; Q0=qSketchRegion(id + "F0", true);
extrude(context, id + "F1", {"entities":qUnion([Q0]), "depth":120 * mm}); }
});
'''
class ParserTests(unittest.TestCase):
def test_lexer_ignores_comments_and_preserves_lines(self):
tokens = lex('// a\nfoo(/*b*/"x")')
self.assertEqual([token.value for token in tokens[:-1]], ["foo", "(", '"x"', ")"])
self.assertEqual(tokens[0].line, 2)
def test_nested_feature_script(self):
model = parse_featurescript(SOURCE, "00000173")
self.assertEqual([step.feature_id for step in model.steps], ["F0", "F1"])
self.assertEqual(model.sketches[0].entities[0].operation, "skCircle")
self.assertIsInstance(model.features[0].params["entities"], Call)
def test_query_parser(self):
query = Call("makeQuery", [Call("__binary__", ["id", "+", "F1.opExtrude"]), "CAP_EDGE", "EDGE", {"isStart": False, "x": Call("sQuery", [Call("__binary__", ["id", "+", "F0.wireOp"]), "EDGE", "E0"])}])
value = parse_query(query)
self.assertEqual((value.owner_feature, value.source_sketch, value.source_entity), ("F1", "F0", "E0"))
self.assertFalse(value.is_start)
def test_safe_units(self):
self.assertEqual(length_mm("2 * inch"), 50.8)
self.assertEqual(length_mm("25.4 / 2 * mm"), 12.7)
with self.assertRaises(ValueError): length_mm("external.value * mm")
if __name__ == "__main__": unittest.main()