"""End-to-end roundtrip test — Sprint 0 acceptance criterion. This is the test the brief calls out by name (section 12, "Criterio de aceptación"): build a project programmatically, persist it, reload it, and verify the reloaded object matches the original exactly. """ from __future__ import annotations from pathlib import Path from arautopilot.core import ( ActuatorConfig, ActuatorType, ProjectConfig, VesselConfig, VesselType, ) from arautopilot.library.loader import ( load_actuator_profile, load_default_tuning, ) def test_full_roundtrip_using_seed_library(tmp_path: Path) -> None: # 1. Assemble a project using the seed library actuator: ActuatorConfig = load_actuator_profile("hydraulic_reversible") pid = load_default_tuning("yacht_motor_planeo_30m") vessel = VesselConfig( name="M/Y Sprint-0", type=VesselType.YACHT_MOTOR_PLANEO, length_m=30.0, displacement_t=125.0, max_speed_kn=28.0, actuator=actuator, pid=pid, ) project = ProjectConfig( client_name="Acceptance Test Client", project_name="Sprint 0 Roundtrip", notes="Demonstrates the brief's acceptance criterion.", vessel=vessel, ) # 2. Save to YAML and JSON yaml_path = tmp_path / "project.yaml" json_path = tmp_path / "project.json" project.save_yaml(yaml_path) project.save_json(json_path) assert yaml_path.exists() and yaml_path.stat().st_size > 0 assert json_path.exists() and json_path.stat().st_size > 0 # 3. Reload both and verify exact equality from_yaml = ProjectConfig.load(yaml_path) from_json = ProjectConfig.load(json_path) assert from_yaml == project assert from_json == project # Critical structural invariants survive serialisation assert from_yaml.vessel.actuator.type is ActuatorType.HYDRAULIC_REVERSIBLE assert from_yaml.vessel.pid.inner_loop_freq_hz > from_yaml.vessel.pid.outer_loop_freq_hz assert len(from_yaml.vessel.pid.gain_schedule) == 3 def test_roundtrip_preserves_ids(tmp_path: Path, basic_project: ProjectConfig) -> None: p = tmp_path / "p.yaml" basic_project.save_yaml(p) rebuilt = ProjectConfig.load(p) assert rebuilt.project_id == basic_project.project_id assert rebuilt.vessel.vessel_id == basic_project.vessel.vessel_id def test_roundtrip_preserves_timestamps(tmp_path: Path, basic_project: ProjectConfig) -> None: p = tmp_path / "p.json" basic_project.save_json(p) rebuilt = ProjectConfig.load(p) assert rebuilt.created_at == basic_project.created_at assert rebuilt.modified_at == basic_project.modified_at