Files

105 lines
4.1 KiB
Python
Executable File

from __future__ import annotations
import unittest
from pathlib import Path
import yaml
from cognitive_agent.runtime.contracts import ContractValidator
from seat_domain.generator import build_function_config
from seat_domain.intent import parse_local_intent
from seat_domain.matrix import SeatCanMatrix
from seat_domain.source_matrix import read_source_signals
ROOT = Path(__file__).resolve().parents[4]
DOMAIN_ROOT = ROOT / "domains" / "seat"
class SeatContractTests(unittest.TestCase):
def setUp(self) -> None:
self.validator = ContractValidator(ROOT)
def test_generated_function_config_matches_both_schemas(self) -> None:
parsed = parse_local_intent("打开副驾座椅加热")
config = build_function_config(parsed, "req-contract-001", "local_rules")
self.assertEqual(self.validator.validate(config), [])
def test_inferred_level_function_config_matches_both_schemas(self) -> None:
parsed = parse_local_intent("副驾有点热,有点闷")
config = build_function_config(parsed, "req-contract-002", "local_rules")
self.assertEqual(config["spec"]["operations"][0]["parameters"]["level"], 1)
self.assertEqual(self.validator.validate(config), [])
def test_motion_function_config_matches_both_schemas(self) -> None:
parsed = {
"detected_domains": ["seat"],
"actions": [
{
"action_type": "position",
"target": "passenger",
"axis": "legrest_extension",
"position_pct": 70,
}
],
"deferred_requests": [],
"ambiguities": [],
"decision_summary": ["Extend passenger leg rest."],
"confidence": 1.0,
}
config = build_function_config(parsed, "req-contract-motion", "test")
self.assertEqual(config["spec"]["operations"][0]["parameters"], {"position_pct": 70})
self.assertEqual(self.validator.validate(config), [])
def test_all_active_presets_match_both_schemas(self) -> None:
for path in (DOMAIN_ROOT / "config" / "presets").glob("*.yaml"):
with self.subTest(path=path.name):
document = yaml.safe_load(path.read_text(encoding="utf-8"))
self.assertEqual(self.validator.validate(document), [])
def test_normalized_matrix_matches_source_scope(self) -> None:
matrix = SeatCanMatrix(DOMAIN_ROOT / "can" / "seat-thermal-matrix.yaml")
self.assertEqual(len(matrix.data["messages"]), 6)
self.assertEqual(sum(len(item["signals"]) for item in matrix.data["messages"]), 23)
self.assertFalse(matrix.hardware_execution_allowed)
def test_synthetic_motion_matrix_is_explicitly_non_hardware(self) -> None:
matrix = SeatCanMatrix(DOMAIN_ROOT / "can" / "seat-motion-virtual-matrix.yaml")
self.assertTrue(matrix.data["synthetic"])
self.assertFalse(matrix.hardware_execution_allowed)
self.assertEqual(len(matrix.data["messages"]), 4)
self.assertEqual(sum(len(item["signals"]) for item in matrix.data["messages"]), 34)
def test_normalized_signal_layout_matches_supplied_xlsx(self) -> None:
source = {
item["name"]: item
for item in read_source_signals(ROOT / "座椅部分功能CAN矩阵表.xlsx")
}
matrix = SeatCanMatrix(DOMAIN_ROOT / "can" / "seat-thermal-matrix.yaml")
normalized = {
signal["name"]: {
"frame_id": int(message["frame_id"]),
"start_bit": int(signal["start_bit"]),
"bit_length": int(signal["bit_length"]),
}
for message in matrix.data["messages"]
for signal in message["signals"]
}
self.assertEqual(set(source), set(normalized))
for name, layout in normalized.items():
with self.subTest(signal=name):
self.assertEqual(layout["frame_id"], source[name]["frame_id"])
self.assertEqual(layout["start_bit"], source[name]["start_bit"])
self.assertEqual(layout["bit_length"], source[name]["bit_length"])
if __name__ == "__main__":
unittest.main()