"""Tests for ``arautopilot.core.vessel_config``.""" from __future__ import annotations import pytest from pydantic import ValidationError from arautopilot.core.actuator_config import ActuatorConfig, ActuatorType from arautopilot.core.pid_config import PidConfig, PidGains from arautopilot.core.vessel_config import VesselConfig, VesselType def _pid() -> PidConfig: return PidConfig( inner_loop_base=PidGains(kp=2.0), outer_loop_base=PidGains(kp=1.0), ) def test_vessel_composes_actuator_and_pid() -> None: v = VesselConfig( name="Test 30", type=VesselType.YACHT_MOTOR_PLANEO, length_m=30.0, max_speed_kn=28.0, actuator=ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE), pid=_pid(), ) assert v.actuator.type is ActuatorType.HYDRAULIC_REVERSIBLE assert v.pid.inner_loop_base.kp == pytest.approx(2.0) assert isinstance(v.vessel_id, str) and len(v.vessel_id) > 0 def test_vessel_id_is_unique_across_instances() -> None: v1 = VesselConfig( name="A", type=VesselType.YACHT_MOTOR_PLANEO, length_m=30.0, max_speed_kn=20.0, actuator=ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE), pid=_pid(), ) v2 = VesselConfig( name="B", type=VesselType.YACHT_MOTOR_PLANEO, length_m=30.0, max_speed_kn=20.0, actuator=ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE), pid=_pid(), ) assert v1.vessel_id != v2.vessel_id def test_rejects_zero_length() -> None: with pytest.raises(ValidationError): VesselConfig( name="X", type=VesselType.YACHT_MOTOR_PLANEO, length_m=0.0, max_speed_kn=20.0, actuator=ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE), pid=_pid(), ) def test_rejects_blank_name() -> None: with pytest.raises(ValidationError): VesselConfig( name="", type=VesselType.YACHT_MOTOR_PLANEO, length_m=30.0, max_speed_kn=20.0, actuator=ActuatorConfig(type=ActuatorType.HYDRAULIC_REVERSIBLE), pid=_pid(), ) def test_vessel_type_covers_brief_categories() -> None: expected = { "yacht_motor_planeo", "yacht_motor_desplazamiento", "sailboat_motor", "fishing_boat", "small_ferry", "patrol_boat", } assert {t.value for t in VesselType} == expected