/** * @file test_nme_dtc.cpp * @brief Verhaltenstests für die generierte NmeaManagement Dtc/Ftc/Dts/Fts-Schnittstelle * * Diese Tests prüfen die von CODEGEN_CLIENT_TOPICS_IFC / CODEGEN_SERVER_TOPICS * aus nme_service.xml generierten Header (NmeaManagement/nme_dtc.h, nme_ftc.h, * nme_dts.h, nme_fts.h) aus dem Build-Tree sowie die plainen DDS-Typ-Member * aus nme.hpp (BatteryState, BatteryAlarm, PositionExcon, ServiceControl, * TurnRadioMasterOffRequest), die der migrierte NmeaHandler, DdsHandler und * SocketHandler direkt als Felder und Member-Assignment nutzen. */ #include "NmeaManagement/nme.hpp" #include "NmeaManagement/nme_dtc.h" #include "NmeaManagement/nme_dts.h" #include "NmeaManagement/nme_ftc.h" #include "NmeaManagement/nme_fts.h" #include #include #include /** * @test Der generierte Dtc ist von QObject abgeleitet (Signale für * Topic-Updates); alle vier Interfaces sind abstrakt. */ TEST(nme_dtc_Generated, InterfacesAreAbstract) { static_assert(std::is_base_of::value, "generierter Dtc muss von QObject abgeleitet sein"); static_assert(std::is_abstract::value, "Dtc muss abstrakt sein"); static_assert(std::is_abstract::value, "Ftc muss abstrakt sein"); static_assert(std::is_abstract::value, "Dts muss abstrakt sein"); static_assert(std::is_abstract::value, "Fts muss abstrakt sein"); SUCCEED(); } /** * @test DdsHandler::init nutzt diese Dts-Enable-Methoden — sie müssen * über nme_dts.h vorliegen (Adresse ableitbar = existiert und ist * public). */ TEST(nme_dtc_Generated, DtsEnableMethodsExist) { using Dts = NmeaManagement::Interface::Dts; // Member-Funktionszeiger: auto deduziert ohne '*' (auto* kann // Member-Pointer-Typen nicht deduzieren). auto enableBatteryAlarm = &Dts::enableBatteryAlarm; auto enableServiceControl = &Dts::enableServiceControl; auto enableBatteryState = &Dts::enableBatteryState; auto enablePositionExcon = &Dts::enablePositionExcon; (void)enableBatteryAlarm; (void)enableServiceControl; (void)enableBatteryState; (void)enablePositionExcon; SUCCEED(); } /** * @test SocketHandler erbt von Fts::TurnRadioMasterOffRequestHandler und * antwortet über Fts::turnRadioMasterOffReply — beides muss über * nme_fts.h vollständig vorliegen. */ TEST(nme_dtc_Generated, FtsTurnRadioMasterOffInterface) { using namespace NmeaManagement::Interface; static_assert(std::is_class::value, "Fts::TurnRadioMasterOffRequestHandler fehlt"); // turnRadioMasterOffReply ist überladen (FunctionReply / FunctionReplyObject) — // den vom SocketHandler genutzten FunctionReplyObject-Overload explizit nehmen. auto reply = static_cast( &Fts::turnRadioMasterOffReply); (void)reply; SUCCEED(); } /** * @test Die DDS-Typen aus nme.hpp müssen plain-Member bereitstellen * (rtiddsgen 7.7): BatteryState, den der migrierte NmeaHandler * (IIXDR) per Member-Assignment befüllt. */ TEST(nme_dtc_Generated, BatteryStateHasPlainMembers) { using BatteryState = NmeaManagement::BatteryState; static_assert(std::is_same::value, "id muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "battery muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "temperature muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "frequency muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "generic muss ein plain double-Member sein"); static_assert(std::is_same::value, "current muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "switchOrValue muss ein plain bool-Member sein"); static_assert(std::is_same::value, "voltage muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "serialNumber muss ein plain std::string-Member sein"); // Wie im migrierten IIXDR-Pfad: Member-Assignment statt Setter. BatteryState bs; bs.id = 1; bs.battery = 4; bs.temperature = 25; bs.frequency = 100; bs.generic = 1.5; bs.current = 55; bs.switchOrValue = true; bs.voltage = 3300; bs.serialNumber = "SER123"; EXPECT_EQ(bs.id, 1); EXPECT_EQ(bs.battery, 4); EXPECT_EQ(bs.temperature, 25); EXPECT_EQ(bs.frequency, 100); EXPECT_DOUBLE_EQ(bs.generic, 1.5); EXPECT_EQ(bs.current, 55); EXPECT_TRUE(bs.switchOrValue); EXPECT_EQ(bs.voltage, 3300); EXPECT_EQ(bs.serialNumber, "SER123"); } /** * @test BatteryAlarm (IIALR-Pfad) muss plain-Member bereitstellen. */ TEST(nme_dtc_Generated, BatteryAlarmHasPlainMembers) { using BatteryAlarm = NmeaManagement::BatteryAlarm; static_assert(std::is_same::value, "id muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "description muss ein plain std::string-Member sein"); static_assert(std::is_same::value, "acknowledge muss ein plain bool-Member sein"); static_assert(std::is_same::value, "condition muss ein plain bool-Member sein"); static_assert(std::is_same::value, "uniqueAlarmNumber muss ein plain int32_t-Member sein"); static_assert(std::is_same::value, "time muss ein plain int64_t-Member sein"); BatteryAlarm alarm; alarm.id = 0; alarm.time = 1700000000000LL; alarm.description = "overvoltage"; alarm.acknowledge = true; alarm.condition = false; alarm.uniqueAlarmNumber = 7; EXPECT_EQ(alarm.id, 0); EXPECT_EQ(alarm.time, 1700000000000LL); EXPECT_EQ(alarm.description, "overvoltage"); EXPECT_TRUE(alarm.acknowledge); EXPECT_FALSE(alarm.condition); EXPECT_EQ(alarm.uniqueAlarmNumber, 7); } /** * @test PositionExcon (GPGGA-Pfad): position ist Core::GeoPosition2D mit * plain double-Member lat/lon; valid ist plain bool. */ TEST(nme_dtc_Generated, PositionExconHasPlainMembers) { using PositionExcon = NmeaManagement::PositionExcon; static_assert(std::is_same::value, "position muss ein plain Core::GeoPosition2D-Member sein"); static_assert(std::is_same::value, "position.lat muss ein plain double-Member sein"); static_assert(std::is_same::value, "position.lon muss ein plain double-Member sein"); static_assert(std::is_same::value, "valid muss ein plain bool-Member sein"); // Wie im migrierten GPGGA-Pfad: Member-Assignment statt Setter. PositionExcon pos; pos.position.lat = 1.0; pos.position.lon = 2.0; pos.valid = true; EXPECT_DOUBLE_EQ(pos.position.lat, 1.0); EXPECT_DOUBLE_EQ(pos.position.lon, 2.0); EXPECT_TRUE(pos.valid); } /** * @test ServiceControl (IIXDR-ServiceControl-Pfad) muss das * ServiceControlState-Enum-Member bereitstellen. */ TEST(nme_dtc_Generated, ServiceControlHasEnumMember) { using ServiceControl = NmeaManagement::ServiceControl; static_assert( std::is_same::value, "ServiceControlState muss ein plain ServiceControlEnum-Member sein"); ServiceControl sc; sc.ServiceControlState = NmeaManagement::ServiceControlEnum::SHUTDOWN; EXPECT_EQ(sc.ServiceControlState, NmeaManagement::ServiceControlEnum::SHUTDOWN); } /** * @test TurnRadioMasterOffRequest muss das plain bool-Member shutdown * bereitstellen (Request-Typ der Fts-Funktions-Topic). */ TEST(nme_dtc_Generated, TurnRadioMasterOffRequestHasPlainMember) { using TurnRadioMasterOffRequest = NmeaManagement::TurnRadioMasterOffRequest; static_assert(std::is_same::value, "shutdown muss ein plain bool-Member sein"); TurnRadioMasterOffRequest req; req.shutdown = true; EXPECT_TRUE(req.shutdown); } /** * @test Include-Guard: mehrfaches Einbinden der generierten Header ist erlaubt. */ TEST(nme_dtc_Generated, MultipleIncludeGuard) { // Including the header multiple times should not cause errors #include "NmeaManagement/nme.hpp" #include "NmeaManagement/nme_dtc.h" #include "NmeaManagement/nme_dts.h" #include "NmeaManagement/nme_ftc.h" #include "NmeaManagement/nme_fts.h" SUCCEED(); }