更新功能
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(ROOT / "backend"))
|
||||
|
||||
from app.services.feature_plan import FeaturePlanError, compute_node_statuses, validate_feature_plan # noqa: E402
|
||||
|
||||
|
||||
class FeaturePlanTests(unittest.TestCase):
|
||||
def plan(self) -> dict:
|
||||
return {
|
||||
"schema_version": "cad.feature-plan.v1",
|
||||
"plan_id": "plan_test",
|
||||
"task_id": "cad_test",
|
||||
"nodes": [
|
||||
{"id": "base", "atomic_id": "extrude_add_blind", "depends_on": []},
|
||||
{"id": "round", "atomic_id": "fillet", "depends_on": ["base"], "requires_topology": True},
|
||||
],
|
||||
}
|
||||
|
||||
def test_rejects_cycles_and_missing_dependencies(self) -> None:
|
||||
cyclic = self.plan()
|
||||
cyclic["nodes"][0]["depends_on"] = ["round"]
|
||||
with self.assertRaises(FeaturePlanError):
|
||||
validate_feature_plan(cyclic, supported_atomic_ids={"extrude_add_blind", "fillet"})
|
||||
missing = self.plan()
|
||||
missing["nodes"][1]["depends_on"] = ["missing"]
|
||||
with self.assertRaises(FeaturePlanError):
|
||||
validate_feature_plan(missing, supported_atomic_ids={"extrude_add_blind", "fillet"})
|
||||
|
||||
def test_ready_prefix_waits_for_topology(self) -> None:
|
||||
statuses = compute_node_statuses(self.plan(), cdsl={"features": []})
|
||||
self.assertEqual(statuses["ready_nodes"], ["base"])
|
||||
self.assertEqual(statuses["waiting_nodes"], [])
|
||||
|
||||
def test_built_prefix_unlocks_topology_dependent_node(self) -> None:
|
||||
statuses = compute_node_statuses(
|
||||
self.plan(),
|
||||
cdsl={"features": [{"id": "base"}]},
|
||||
topology={"records": [{"record_id": "body:base", "kind": "body", "executable": True}]},
|
||||
)
|
||||
self.assertEqual(statuses["completed_nodes"], ["base"])
|
||||
self.assertEqual(statuses["waiting_nodes"], ["round"])
|
||||
|
||||
def test_inspected_snapshot_unlocks_topology_dependent_node(self) -> None:
|
||||
plan = self.plan()
|
||||
plan["topology_snapshot_id"] = "cad_test/rev_001"
|
||||
statuses = compute_node_statuses(
|
||||
plan,
|
||||
cdsl={"features": [{"id": "base"}]},
|
||||
topology={
|
||||
"snapshot_id": "cad_test/rev_001",
|
||||
"records": [{"record_id": "body:base", "kind": "body", "executable": True}],
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(statuses["ready_nodes"], ["round"])
|
||||
self.assertEqual(statuses["waiting_nodes"], [])
|
||||
|
||||
def test_dependency_must_appear_before_dependent_node(self) -> None:
|
||||
plan = self.plan()
|
||||
plan["nodes"] = [plan["nodes"][1], plan["nodes"][0]]
|
||||
with self.assertRaisesRegex(FeaturePlanError, "appear after dependency"):
|
||||
validate_feature_plan(plan, supported_atomic_ids={"extrude_add_blind", "fillet"})
|
||||
Reference in New Issue
Block a user