from __future__ import annotations from pathlib import Path from sync_state_machine.engine import StateMachineConfig CFG_PATH = Path(__file__).resolve().parents[2] / "sync_state_machine" / "config" / "node_state_machine.yaml" def test_state_and_event_coverage_contract() -> None: cfg = StateMachineConfig.load(CFG_PATH) transitions = cfg.raw.get("transitions", {}) states = cfg.raw.get("states", {}) pseudo_states = cfg.raw.get("pseudo_states", {}) all_events = set(transitions.keys()) if isinstance(transitions, dict) else set() assert all_events == set(cfg.transitions.keys()) touched_states: set[str] = set() for transition in cfg.transitions.values(): touched_states.update(s for s in transition.from_states if s != "*") for outcome in transition.outcomes: if outcome.to: touched_states.add(outcome.to) declared_states = set(states.keys()) | set(pseudo_states.keys()) # 允许仅作为注释阶段使用的状态极少数暂不触发,但要求覆盖率至少95% coverage = len(touched_states & declared_states) / max(1, len(declared_states)) assert coverage >= 0.95