/** * @RDE_HEADER@ * Unittest * $Id$ * $HeadURL$ * $Author$ */ #include "basics_unit_test.h" #include #include #include #include #include #include #include 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 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 &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 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 HasRequestId { template static std::true_type testSignature(const int32_t &(T::*)() const); template static std::true_type testSignature(int32_t (T::*)() const); template static decltype(testSignature(&T::getMemberInt)) test(std::nullptr_t); template static std::false_type test(...); public: using type = decltype(test(nullptr)); static const bool value = type::value; }; template struct has_memberDouble { static const bool value = false; //Compile time Constant }; template<> struct has_memberDouble { static const bool value = true; }; template < typename T, typename std::enable_if < has_memberDouble::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::value, int >::type = 0 > void getFilterType(const T &obj) { qCritical() << " ! HasRequestId"; // sendErrorInternal(request.errorSlot, reason, request.uniqueId, -1); } template class worker { public: virtual void do_stuff() { qCritical() << "**** do_stuff: this" << typeid(*this).name(); } }; void UnitTestBasics::test_SFINAE() { worker inst1; inst1.do_stuff(); worker 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(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(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 arguments = spyStateChanged.takeFirst(); // take the first signal // NOTICE_LOG(m_logger) << " spyStateChanged.count() " << spyStateChanged.count(); // for (const QList &argument : qAsConst(spyStateChanged)) // NOTICE_LOG(m_logger) << " spyStateChanged . argument " << argument.first().toInt(); // check order of signal paramter: QVERIFY2(static_cast(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(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(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(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(spyStateChanged[0][0].toInt()) == FiringTimer::CMD::CMD_START, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(spyStateChanged[1][0].toInt()) == FiringTimer::CMD::CMD_PAUSE, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(spyStateChanged[2][0].toInt()) == FiringTimer::CMD::CMD_RESUME, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(spyStateChanged[3][0].toInt()) == FiringTimer::CMD::CMD_EXPIRED, "FiringTimer: StateChanged.argument failed, spyStateChanged"); QVERIFY2(static_cast(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); }