Adds NmeaManagement tests, fixes codegen includes and Qt6 SerialPort CMake target.
232 lines
9.4 KiB
C++
232 lines
9.4 KiB
C++
/**
|
|
* @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 <QObject>
|
|
#include <gtest/gtest.h>
|
|
#include <type_traits>
|
|
|
|
/**
|
|
* @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<QObject, NmeaManagement::Interface::Dtc>::value,
|
|
"generierter Dtc muss von QObject abgeleitet sein");
|
|
static_assert(std::is_abstract<NmeaManagement::Interface::Dtc>::value, "Dtc muss abstrakt sein");
|
|
static_assert(std::is_abstract<NmeaManagement::Interface::Ftc>::value, "Ftc muss abstrakt sein");
|
|
static_assert(std::is_abstract<NmeaManagement::Interface::Dts>::value, "Dts muss abstrakt sein");
|
|
static_assert(std::is_abstract<NmeaManagement::Interface::Fts>::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<Fts::TurnRadioMasterOffRequestHandler>::value,
|
|
"Fts::TurnRadioMasterOffRequestHandler fehlt");
|
|
// turnRadioMasterOffReply ist überladen (FunctionReply / FunctionReplyObject) —
|
|
// den vom SocketHandler genutzten FunctionReplyObject-Overload explizit nehmen.
|
|
auto reply = static_cast<bool (Fts::*)(const rti::core::SampleIdentity&, const Core::FunctionReplyObject&)>(
|
|
&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<decltype(BatteryState{}.id), int32_t>::value, "id muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.battery), int32_t>::value,
|
|
"battery muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.temperature), int32_t>::value,
|
|
"temperature muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.frequency), int32_t>::value,
|
|
"frequency muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.generic), double>::value,
|
|
"generic muss ein plain double-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.current), int32_t>::value,
|
|
"current muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.switchOrValue), bool>::value,
|
|
"switchOrValue muss ein plain bool-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.voltage), int32_t>::value,
|
|
"voltage muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryState{}.serialNumber), std::string>::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<decltype(BatteryAlarm{}.id), int32_t>::value, "id muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryAlarm{}.description), std::string>::value,
|
|
"description muss ein plain std::string-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryAlarm{}.acknowledge), bool>::value,
|
|
"acknowledge muss ein plain bool-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryAlarm{}.condition), bool>::value,
|
|
"condition muss ein plain bool-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryAlarm{}.uniqueAlarmNumber), int32_t>::value,
|
|
"uniqueAlarmNumber muss ein plain int32_t-Member sein");
|
|
static_assert(std::is_same<decltype(BatteryAlarm{}.time), int64_t>::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<decltype(PositionExcon{}.position), Core::GeoPosition2D>::value,
|
|
"position muss ein plain Core::GeoPosition2D-Member sein");
|
|
static_assert(std::is_same<decltype(PositionExcon{}.position.lat), double>::value,
|
|
"position.lat muss ein plain double-Member sein");
|
|
static_assert(std::is_same<decltype(PositionExcon{}.position.lon), double>::value,
|
|
"position.lon muss ein plain double-Member sein");
|
|
static_assert(std::is_same<decltype(PositionExcon{}.valid), bool>::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<decltype(ServiceControl{}.ServiceControlState), NmeaManagement::ServiceControlEnum>::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<decltype(TurnRadioMasterOffRequest{}.shutdown), bool>::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();
|
|
}
|