Files
qt5-legatus-legacy/Lts/Services/AreaEffectSimulation/UnitTests/UnitTest_Basics/basics_unit_test.cpp
T
2026-08-13 18:33:10 +02:00

428 lines
14 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* Unittest
* $Id$
* $HeadURL$
* $Author$
*/
#include "basics_unit_test.h"
#include <nglapplication/nglcoreapplication.h>
#include <AreaEffectSimulation/aes.hpp>
#include <QtTest/QTest>
#include <QTimer>
#include <QDebug>
#include <QtTest/QSignalSpy>
#include <iostream>
using namespace AreaEffectSimulation;
UnitTestBasics::UnitTestBasics()
: m_logger(getLogger("UnitTest"))
{}
void UnitTestBasics::test_isNull_isNaN()
{
QPointF point1(1.1, 1.2);
QVERIFY2(point1.isNull() == false, "QPointF isNull failed");
QPointF point2;
QVERIFY2(point2.isNull() == true, "QPointF isNull failed");
QPointF point3(0, 0);
QVERIFY2(point3.isNull() == true, "QPointF isNull failed");
QPointF point4(1, 2);
point4.ry() = 0;
QVERIFY2(point4.isNull() == false, "QPointF isNull failed");
QPointF point5(1, 2);
point5.rx() = std::nan("");
point5.ry() = std::nan("");
// !!! nan is not detected be isNull !!!
QVERIFY2(point5.isNull() == false, "QPointF isNull failed");
// Qt::5.14.1: mit isNull() wird NaN nicht erkannt.
// Eine separate Prüfung ergibt Sinn!
}
void UnitTestBasics::test_operator_equal_1()
{
// Some cases the operator == recognizes a difference, but i don´t know why.
// crate this testCase:
AesItemView aesItem1, aesItem2;
QVERIFY2(aesItem1 == aesItem2, "AesItemView::operator== failed");
aesItem1.id(1);
aesItem2.id(1);
QVERIFY2(aesItem1 == aesItem2, "AesItemView::operator== failed");
std::vector<Core::GeoPosition> formVec;
formVec.reserve(100);
for (int i=1; i< 100; ++i)
formVec.emplace_back(Core::GeoPosition(i*0.001, 100/i, 100/i));
aesItem1.aesItemId(12);
aesItem1.sampleTime(12345567);
aesItem1.chargeStruct().chargeTypeId(123);
aesItem1.effectStart(123456789);
aesItem1.form(formVec);
aesItem1.boundingBoxBottomLeft(Core::GeoPosition2D(0.1, 0.2));
aesItem1.boundingBoxTopRight(Core::GeoPosition2D(1.1, 1.2));
aesItem1.aesTypeId(AreaEffectSimulation::AesType_def::AtBoobyTrap);
aesItem1.effectStateId(AreaEffectSimulation::AesEffectState_def::EsActivated);
aesItem1.partyId(2);
aesItem1.setId(2334);
aesItem2 = aesItem1;
QVERIFY2(aesItem1 == aesItem2, "AesItemView::operator== failed");
}
void foo(const std::vector<QPoint> &vec)
{
qCritical() << " foo: number of elements = " << vec.size();
// copy data to tele
for (unsigned int i = 0; i < 4; ++i)
{
int offsetX = -1;
int offsetY = -1;
// qCritical() << " foo: vec.size()-1 = " << vec.size()-1;
if (i <= vec.size()-1)
{
offsetX = vec[i].x();
offsetY = vec[i].y();
}
// instead of writing data to telegram, use qCritical() to print:
qCritical() << " i=" << i
<< " # offset [x-y]=" << offsetX << " # " << offsetY;
}
}
void UnitTestBasics::test_container()
{
// Define source data
std::vector<QPoint> sourcePointVec;
sourcePointVec.push_back(QPoint(1, 1));
sourcePointVec.push_back(QPoint(2, 2));
// call foo
foo(sourcePointVec);
}
// https://medium.com/@sidbhasin82/c-templates-what-is-std-enable-if-and-how-to-use-it-fd76d3abbabe
class ObjectBASE
{
public:
int32_t memberBaseINT{0};
int32_t getMemberInt() { return 11; }
};
class ObjectINT : public ObjectBASE
{
public:
int32_t memberINT{0};
int32_t getMemberInt() { return memberINT; }
};
class ObjectDOUBLE : public ObjectBASE
{
public:
double memberDOUBLE{0.0};
};
template <class C>
class HasRequestId
{
template <class T>
static std::true_type testSignature(const int32_t &(T::*)() const);
template <class T>
static std::true_type testSignature(int32_t (T::*)() const);
template <class T>
static decltype(testSignature(&T::getMemberInt)) test(std::nullptr_t);
template <class T>
static std::false_type test(...);
public:
using type = decltype(test<C>(nullptr));
static const bool value = type::value;
};
template<typename T>
struct has_memberDouble {
static const bool value = false; //Compile time Constant
};
template<>
struct has_memberDouble<ObjectINT> {
static const bool value = true;
};
template < typename T, typename std::enable_if < has_memberDouble<T>::value, int >::type = 0 >
void getFilterType(const T &obj)
{
qCritical() << " HasRequestId";
// sendErrorInternal(request.errorSlot, reason, request.uniqueId, request.sample.data().requestId());
}
// -------------------------------------------------------------------------------------------------------------
template < typename T, typename std::enable_if < !has_memberDouble<T>::value, int >::type = 0 >
void getFilterType(const T &obj)
{
qCritical() << " ! HasRequestId";
// sendErrorInternal(request.errorSlot, reason, request.uniqueId, -1);
}
template <typename T>
class worker
{
public:
virtual void do_stuff()
{
qCritical() << "**** do_stuff: this" << typeid(*this).name();
}
};
void UnitTestBasics::test_SFINAE()
{
worker<ObjectINT> inst1;
inst1.do_stuff();
worker<ObjectDOUBLE> inst2;
inst2.do_stuff();
ObjectINT oInt;
getFilterType(oInt);
ObjectDOUBLE oDouble;
getFilterType(oDouble);
}
void UnitTestBasics::test_fireTimer10()
{
FiringTimer ft(QStringLiteral("TestEnv10"));
QStringList logSl = ft.getLogHistorie();
QVERIFY2(logSl.size() == 0, "getCommandHistorie failed");
{
bool success = ft.startFiring();
QVERIFY2(!success, "startFiring not failed");
}
{
ft.init(10*1000, 5, 2.567*1000); // effectDuration, ammoCount, ammoFlightDuration
bool success = ft.startFiring();
QVERIFY2(success, "startFiring failed");
success = ft.startFiring();
QVERIFY2(!success, "startFiring failed");
QStringList logSl1 = ft.getLogHistorie();
QVERIFY2(logSl1.size() == 1, "getCommandHistorie failed");
for (const auto &log : qAsConst(logSl1))
NOTICE_LOG(m_logger) << "log ='" << log << "'";
}
{
ft.reset();
QStringList logSl2 = ft.getLogHistorie();
QVERIFY2(logSl2.size() == 0, "getCommandHistorie failed");
}
}
void UnitTestBasics::test_fireTimer15()
{
FiringTimer ft(QStringLiteral("TestEnv15"));
ft.init(10*1000, 5, 0.0); // effectDurationMsec, ammoFlightDurationMsec
// count firing
QSignalSpy spyFiring(&ft, &FiringTimer::firing);
ft.startFiring(); // with this, the very first signal 'firing' will be emitted
// count firingFinished
QSignalSpy spyFinished(&ft, &FiringTimer::firingFinished);
QSignalSpy spyFinishedPlus(&ft, &FiringTimer::firingFinishedPlus);
QSignalSpy spyStateChanged(&ft, &FiringTimer::stateChangeDelayedAsInt);
spyFinishedPlus.wait(20000);
// call wait twice (wait for CMD_EXPIRED, CMD_EXPIRED_PLUS)
spyStateChanged.wait(5000);
spyStateChanged.wait(5000);
// Verify at end:
QVERIFY2(spyFiring.count() == 5, "FiringTimer: signalCount failed, spyFiring");
QVERIFY2(spyFinished.count() == 1, "FiringTimer: signalCount failed, spyFinished");
QVERIFY2(spyFinishedPlus.count() == 1, "FiringTimer: signalCount failed, spyFinishedPlus");
QVERIFY2(spyStateChanged.count() == 3, "FiringTimer: signalCount failed, spyStateChanged");
NOTICE_LOG(m_logger) << " spyStateChanged.count() " << spyStateChanged.count();
// check order of signal paramter:
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[2][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED_PLUS, "FiringTimer: StateChanged.argument failed, spyStateChanged");
}
void UnitTestBasics::test_fireTimer20()
{
FiringTimer ft(QStringLiteral("TestEnv20"));
ft.init(10*1000, 5, 2.567*1000); // effectDurationMsec, ammoFlightDurationMsec
// count firing
QSignalSpy spyFiring(&ft, &FiringTimer::firing);
ft.startFiring(); // with this, the very first signal 'firing' will be emitted
// count firingFinished
QSignalSpy spyFinished(&ft, &FiringTimer::firingFinished);
QSignalSpy spyFinishedPlus(&ft, &FiringTimer::firingFinishedPlus);
QSignalSpy spyStateChanged(&ft, &FiringTimer::stateChangeDelayedAsInt);
spyFinishedPlus.wait(20000);
// call wait twice (wait for CMD_EXPIRED, CMD_EXPIRED_PLUS)
spyStateChanged.wait(5000);
spyStateChanged.wait(5000);
// Verify at end:
QVERIFY2(spyFiring.count() == 5, "FiringTimer: signalCount failed, spyFiring");
QVERIFY2(spyFinished.count() == 1, "FiringTimer: signalCount failed, spyFinished");
QVERIFY2(spyFinishedPlus.count() == 1, "FiringTimer: signalCount failed, spyFinishedPlus");
QVERIFY2(spyStateChanged.count() == 3, "FiringTimer: signalCount failed, spyStateChanged");
// QList<QVariant> arguments = spyStateChanged.takeFirst(); // take the first signal
// NOTICE_LOG(m_logger) << " spyStateChanged.count() " << spyStateChanged.count();
// for (const QList<QVariant> &argument : qAsConst(spyStateChanged))
// NOTICE_LOG(m_logger) << " spyStateChanged . argument " << argument.first().toInt();
// check order of signal paramter:
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[2][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED_PLUS, "FiringTimer: StateChanged.argument failed, spyStateChanged");
}
void UnitTestBasics::test_fireTimer21()
{
FiringTimer ft(QStringLiteral("TestEnv21"));
ft.init(10*1000, 5, 2.567*1000); // effectDuration, ammoCount, ammoFlightDuration
ft.startFiring();
QTimer::singleShot(3000, this, [this, &ft]() {
NOTICE_LOG(m_logger) << " trigger pauseFiring...";
ft.pauseFiring();
});
QSignalSpy spyFinished(&ft, &FiringTimer::firingFinished);
QSignalSpy spyFinishedPlus(&ft, &FiringTimer::firingFinishedPlus);
QSignalSpy spyStateChanged(&ft, &FiringTimer::stateChangeDelayedAsInt);
spyFinishedPlus.wait(10000);
// call wait twice (wait for CMD_EXPIRED, CMD_EXPIRED_PLUS)
spyStateChanged.wait(5000);
spyStateChanged.wait(5000);
// Verify at end:
QVERIFY2(spyFinished.count() == 0, "FiringTimer: signalCount failed, spyFinished");
QVERIFY2(spyFinishedPlus.count() == 0, "FiringTimer: signalCount failed, spyFinishedPlus");
QVERIFY2(spyStateChanged.count() == 2, "FiringTimer: signalCount failed, spyStateChanged");
// check order of signal paramter:
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_PAUSE, "FiringTimer: StateChanged.argument failed, spyStateChanged");
// !! no finished !!
}
void UnitTestBasics::test_fireTimer22()
{
FiringTimer ft(QStringLiteral("TestEnv22"));
ft.init(10*1000, 5, 3.000*1000); // effectDuration, ammoCount, ammoFlightDuration
// count firing
QSignalSpy spyFiring(&ft, &FiringTimer::firing);
ft.startFiring();
// !! Attention: do pauseFiring() WITHIN the intervall will reduce amount of time the firing is active !!
QTimer::singleShot(3000, this, [this, &ft]() {
NOTICE_LOG(m_logger) << " trigger pauseFiring...";
ft.pauseFiring();
});
QTimer::singleShot(5123, this, [this, &ft]() {
NOTICE_LOG(m_logger) << " trigger (re)StartFiring / Resume ...";
ft.startFiring();
});
QSignalSpy spyFinished(&ft, &FiringTimer::firingFinished);
QSignalSpy spyFinishedPlus(&ft, &FiringTimer::firingFinishedPlus);
QSignalSpy spyStateChanged(&ft, &FiringTimer::stateChangeDelayedAsInt);
spyFinishedPlus.wait(20000);
// call wait twice (wait for CMD_EXPIRED, CMD_EXPIRED_PLUS)
spyStateChanged.wait(5000);
spyStateChanged.wait(5000);
// Verify at end:
QVERIFY2(spyFiring.count() == 5, "FiringTimer: signalCount failed, spyFiring");
QVERIFY2(spyFinished.count() == 1, "FiringTimer: signalCount failed, spyFinished");
QVERIFY2(spyFinishedPlus.count() == 1, "FiringTimer: signalCount failed, spyFinishedPlus");
QVERIFY2(spyStateChanged.count() == 5, "FiringTimer: signalCount failed, spyStateChanged");
// check order of signal paramter:
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_PAUSE, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[2][0].toInt()) == FiringTimer::CMD::CMD_RESUME, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[3][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged");
QVERIFY2(static_cast<FiringTimer::CMD>(spyStateChanged[4][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED_PLUS, "FiringTimer: StateChanged.argument failed, spyStateChanged");
// !! Attention: do pauseFiring() WITHIN the intervall will reduce amount of time the firing is active !!
// stop firing2 after [ms]: 5999, m_activeMsec in total = 8902, m_pausedMsec in total = 2000
// ^^^^ maybe you expect 10000
// !! Attention: do pauseFiring() WITHIN the intervall will reduce amount of time the firing is active !!
}
int main(int argc, char *argv[])
{
NGLCoreApplication app(argc, argv);
app.createLogger("UnitTest_TNE-ALOG", "log4cxxUnitTest.props");
UnitTestBasics tc;
return QTest::qExec(&tc, argc, argv);
}