"""Tests del validador cross-entity.""" from __future__ import annotations from vmssailor.core import ( Bus, BusRole, CardInstance, ChannelType, Equipment, Project, Protocol, Scaling, ShipCoord, SignalType, SystemId, Tag, TagBinding, Topology, UnitSI, Vessel, VesselSubtype, VesselType, ) from vmssailor.core.validation import Severity, validate_project def _make_vessel() -> Vessel: return Vessel( id="v", name="V", type=VesselType.YACHT_MOTOR, subtype=VesselSubtype.PLANING, length_overall_m=20.0, beam_max_m=5.0, draft_m=1.5, ) def _basic_topology() -> Topology: b = Bus(id="bm", name="bm", protocol=Protocol.MODBUS_RTU, physical_port="COM3") c = CardInstance( id="c1", slot_number=1, bus_id="bm", bus_role=BusRole.MODBUS_SLAVE, modbus_address=1, ) return Topology(buses=[b], cards=[c]) def test_orphan_system_warning() -> None: p = Project( id="p", name="p", vessel=_make_vessel(), systems_enabled=[SystemId.MAIN_ENGINE, SystemId.WATERMAKER], equipment=[], topology=_basic_topology(), ) r = validate_project(p) assert r.ok() assert any(i.code == "SYSTEM_WITHOUT_EQUIPMENT" for i in r.warnings) def test_card_capacity_high_info() -> None: topo = _basic_topology() eq = Equipment( id="eq", model_ref="m", tag_prefix="X", display_name="x", location=ShipCoord(x_pp=5, y_cl=0, z_bl=1), system_id=SystemId.MAIN_ENGINE, ) # 4 AI = 100% (at-limit -> warning) tags = [] for i in range(4): tags.append( Tag( id=f"X.AI{i + 1}", equipment_id="eq", unit_si=UnitSI.BAR, protocol=Protocol.MODBUS_RTU, physical_binding=TagBinding( card_id="c1", channel_type=ChannelType.AI, channel_number=i + 1, signal_type=SignalType.SIG_4_20_MA, scaling=Scaling(raw_min=4, raw_max=20, eng_min=0, eng_max=10), ), ) ) p = Project( id="p", name="p", vessel=_make_vessel(), systems_enabled=[SystemId.MAIN_ENGINE], equipment=[eq], tags=tags, topology=topo, ) r = validate_project(p) codes = {i.code for i in r.issues} assert "CARD_CAPACITY_AT_LIMIT" in codes def test_equipment_out_of_hull_warning() -> None: eq = Equipment( id="eq", model_ref="m", tag_prefix="X", display_name="x", location=ShipCoord(x_pp=100.0, y_cl=0.0, z_bl=1.0), # fuera del buque system_id=SystemId.MAIN_ENGINE, ) p = Project( id="p", name="p", vessel=_make_vessel(), systems_enabled=[SystemId.MAIN_ENGINE], equipment=[eq], topology=_basic_topology(), ) r = validate_project(p) codes = {i.code for i in r.issues} assert "EQUIPMENT_OUT_OF_HULL" in codes def test_validation_report_format() -> None: p = Project( id="p", name="p", vessel=_make_vessel(), systems_enabled=[], equipment=[], topology=_basic_topology(), ) r = validate_project(p) assert "OK" in r.format() or "Total" in r.format() def test_severity_values() -> None: assert Severity.ERROR.value == "error" assert Severity.WARNING.value == "warning" assert Severity.INFO.value == "info"