#include #include "secsgem/gem/carrier_state.hpp" #include "secsgem/gem/load_port_state.hpp" using namespace secsgem::gem; // ---- CIDS --------------------------------------------------------------- TEST_CASE("CIDS: NotConfirmed -> Confirmed on ProceedWithCarrier") { CarrierStateMachine c; CHECK(c.id_status() == CarrierIDStatus::NotConfirmed); CHECK(c.on_id_event(CarrierIDEvent::ProceedWithCarrier)); CHECK(c.id_status() == CarrierIDStatus::Confirmed); } TEST_CASE("CIDS: NotConfirmed -> Unknown on IDFailed; Bind recovers") { CarrierStateMachine c; CHECK(c.on_id_event(CarrierIDEvent::IDFailed)); CHECK(c.id_status() == CarrierIDStatus::Unknown); CHECK(c.on_id_event(CarrierIDEvent::Bind)); CHECK(c.id_status() == CarrierIDStatus::Confirmed); } TEST_CASE("CIDS: CancelCarrier from any state returns to NotConfirmed") { CarrierStateMachine c; c.on_id_event(CarrierIDEvent::ProceedWithCarrier); REQUIRE(c.id_status() == CarrierIDStatus::Confirmed); CHECK(c.on_id_event(CarrierIDEvent::CancelCarrier)); CHECK(c.id_status() == CarrierIDStatus::NotConfirmed); } // ---- CSMS --------------------------------------------------------------- TEST_CASE("CSMS: NotRead -> Read -> Mismatched -> NotRead via Reset") { CarrierStateMachine c; CHECK(c.slot_map_status() == SlotMapStatus::NotRead); CHECK(c.on_slot_map_event(SlotMapEvent::Read)); CHECK(c.slot_map_status() == SlotMapStatus::Read); CHECK(c.on_slot_map_event(SlotMapEvent::Mismatch)); CHECK(c.slot_map_status() == SlotMapStatus::Mismatched); CHECK(c.on_slot_map_event(SlotMapEvent::Reset)); CHECK(c.slot_map_status() == SlotMapStatus::NotRead); } // ---- CAS ---------------------------------------------------------------- TEST_CASE("CAS: full access lifecycle BeginAccess -> EndAccess -> Complete") { CarrierStateMachine c; CHECK(c.on_access_event(CarrierAccessEvent::BeginAccess)); CHECK(c.access_status() == CarrierAccessStatus::InAccess); CHECK(c.on_access_event(CarrierAccessEvent::EndAccess)); CHECK(c.access_status() == CarrierAccessStatus::Complete); // Terminal: no further transitions. CHECK_FALSE(c.on_access_event(CarrierAccessEvent::BeginAccess)); } TEST_CASE("CAS: Cancel from NotAccessed jumps straight to Complete") { CarrierStateMachine c; CHECK(c.on_access_event(CarrierAccessEvent::Cancel)); CHECK(c.access_status() == CarrierAccessStatus::Complete); } // ---- LoadPort ----------------------------------------------------------- TEST_CASE("LPTS: InService -> Loading -> InService") { LoadPortStateMachine p; CHECK(p.transfer_state() == LoadPortTransferState::InService); CHECK(p.on_transfer_event(LoadPortTransferEvent::StartLoading)); CHECK(p.transfer_state() == LoadPortTransferState::Loading); CHECK(p.on_transfer_event(LoadPortTransferEvent::CompleteLoading)); CHECK(p.transfer_state() == LoadPortTransferState::InService); } TEST_CASE("LPTS: any -> OutOfService via LeaveService") { LoadPortStateMachine p; p.on_transfer_event(LoadPortTransferEvent::StartLoading); CHECK(p.on_transfer_event(LoadPortTransferEvent::LeaveService)); CHECK(p.transfer_state() == LoadPortTransferState::OutOfService); } TEST_CASE("LRS: Reserve / Release") { LoadPortStateMachine p; CHECK(p.on_reservation_event(LoadPortReservationEvent::Reserve)); CHECK(p.reservation_state() == LoadPortReservationStatus::Reserved); CHECK(p.on_reservation_event(LoadPortReservationEvent::Release)); CHECK(p.reservation_state() == LoadPortReservationStatus::NotReserved); } TEST_CASE("LAS: Associate / Disassociate") { LoadPortStateMachine p; CHECK(p.on_association_event(LoadPortAssociationEvent::Associate)); CHECK(p.association_state() == LoadPortAssociationStatus::Associated); CHECK(p.on_association_event(LoadPortAssociationEvent::Disassociate)); CHECK(p.association_state() == LoadPortAssociationStatus::NotAssociated); } TEST_CASE("CarrierStateMachine: change handlers fire on real transitions only") { CarrierStateMachine c; int id_calls = 0; c.set_id_handler([&](CarrierIDStatus, CarrierIDStatus, CarrierIDEvent) { ++id_calls; }); // Read in NotConfirmed has no `to` change, no handler call. c.on_id_event(CarrierIDEvent::Read); CHECK(id_calls == 0); // ProceedWithCarrier does transition. c.on_id_event(CarrierIDEvent::ProceedWithCarrier); CHECK(id_calls == 1); }