Add per-module unit-test dirs for the Release 2 scope

One unit-test/ directory per module/target, mirroring the existing
TetraIF/unit-test/ layout (one QtTest executable per module, guarded by
BUILD_TESTING and the module target, each registered with ctest):

  Lts/Common/CodeGen      codegen_unit_test
  Lts/Common/LtsCoordinate ltscoordinate_unit_test
  Lts/Common/LtsSession   ltssession_unit_test
  Lts/DDS/Core            ddscore_unit_test
  Lts/DDS/QosProfile      ddsqos_unit_test
  Lts/Tools/LogViewer     logviewer_unit_test
  Lts/Tools/SqlBrowser    sqlbrowser_unit_test
  Z/src/NGLLogger         ngllogger_unit_test
  Z/src/WMS_Interface     wms_json_ds_unit_test
  Z/src/nglapplication    nglcoreapplication_unit_test
  Z/src/nglcompression    nglcompression_unit_test
  Z/src/nglsettings       nglsettings_unit_test
  Z/src/ngltranslator     ngltranslator_unit_test

Where a module is built with hidden visibility and has no export macro
(LogViewer, SqlBrowser, ngltranslator, NGLLogger, nglcompression,
nglsettings), its sources are compiled directly into the test
executable, the same pattern as prtcnv_unit_test.

ctest baseline in the container (QT_QPA_PLATFORM=offscreen): 20/23
passed (13 new + 7 pre-existing in-scope tests), 3 Not Run as before
(nglcomp_test, GrantleeParserSmoke, utils_test).

README: ctest baseline table extended to the 23 registered tests and
section 2.4 now documents the per-module test layout. ddsview has no
unit test (GUI tool, XmlHelper needs the DDS dynamic-xtypes runtime).
This commit is contained in:
berrux-dev committed 2026-11-15 01:08:17 +01:00
1 parent a62b729577
commit 09b6df8bc3
40 files changed
+4966 -17

No files matched your search

@@ -0,0 +1,19 @@
#
# Unit tests for the DDS Core module.
# One test executable per module, each registered with ctest.
#
if (NOT BUILD_TESTING)
return()
endif()
# --- DDS Core: generated function-reply objects and the CORE logger facade
if (TARGET ddscore)
ADD_EXECUTABLE(ddscore_unit_test ddscore_unit_test.cpp)
TARGET_LINK_LIBRARIES(ddscore_unit_test
ddscore
NGLLogger
Qt6::Core
Qt6::Test
)
ADD_TEST(NAME ddscore_unit_test COMMAND $<TARGET_FILE:ddscore_unit_test>)
endif()
@@ -0,0 +1,169 @@
//
// Unit tests for the ddscore module (Lts/DDS/Core): FunctionReplyObject
// (the module's pure data/logic class) and the CORE.* logger helper.
//
#include <QtCore/QCoreApplication>
#include <QtCore/QString>
#include <Core/function_reply_object.h>
#include <Core/logger.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QtTest/QTest>
#include <string>
#include <vector>
class ddscore_unit_test : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void functionReplyObjectDefault();
void functionReplyObjectFromIdAndString();
void functionReplyObjectFromStringOnly();
void functionReplyObjectNullString();
void functionReplyObjectWithArgs();
void functionReplyObjectWithArgsAndAdditionalInfo();
void functionReplyObjectRvalueArgs();
void argOverloads();
void setters();
void formattedWithoutPlaceholders();
void formattedExtraArgsIgnored();
void translatedMatchesFormatted();
void uniqueIdRoundtrip();
void coreGetLoggerName();
};
void ddscore_unit_test::initTestCase()
{
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
}
void ddscore_unit_test::functionReplyObjectDefault()
{
Core::FunctionReplyObject reply;
QCOMPARE(reply.id(), -1);
QVERIFY(!reply.error());
QCOMPARE(reply.str(), std::string());
QCOMPARE(reply.additionalInfo(), std::string());
QCOMPARE(reply.args().size(), 0u);
QCOMPARE(reply.uniqueId(), int64_t(0));
}
void ddscore_unit_test::functionReplyObjectFromIdAndString()
{
Core::FunctionReplyObject reply(42, "error %1");
QCOMPARE(reply.id(), 42);
QVERIFY(reply.error());
QCOMPARE(reply.str(), std::string("error %1"));
}
void ddscore_unit_test::functionReplyObjectFromStringOnly()
{
Core::FunctionReplyObject reply("plain error");
QCOMPARE(reply.id(), -1);
QVERIFY(reply.error());
QCOMPARE(reply.str(), std::string("plain error"));
}
void ddscore_unit_test::functionReplyObjectNullString()
{
Core::FunctionReplyObject reply(7, static_cast<const char *>(nullptr));
QCOMPARE(reply.id(), 7);
QVERIFY(!reply.error());
QCOMPARE(reply.str(), std::string());
}
void ddscore_unit_test::functionReplyObjectWithArgs()
{
Core::FunctionReplyObject reply(5, "%1/%2", std::vector<std::string>{"a", "b"});
QCOMPARE(reply.id(), 5);
QCOMPARE(reply.str(), std::string("%1/%2"));
const std::vector<std::string> expectedArgs = {"a", "b"};
QCOMPARE(reply.args(), expectedArgs);
QCOMPARE(reply(), std::string("a/b"));
}
void ddscore_unit_test::functionReplyObjectWithArgsAndAdditionalInfo()
{
Core::FunctionReplyObject reply(5, "failed: %1", std::vector<std::string>{"x"}, "context");
QCOMPARE(reply.id(), 5);
QCOMPARE(reply.str(), std::string("failed: %1"));
QCOMPARE(reply.additionalInfo(), std::string("context"));
QCOMPARE(reply(), std::string("failed: x"));
}
void ddscore_unit_test::functionReplyObjectRvalueArgs()
{
Core::FunctionReplyObject reply(
9, std::string("moved %1"), std::vector<std::string>{"v"}, std::string("info"));
QCOMPARE(reply.id(), 9);
QCOMPARE(reply.str(), std::string("moved %1"));
QCOMPARE(reply.additionalInfo(), std::string("info"));
QCOMPARE(reply(), std::string("moved v"));
}
void ddscore_unit_test::argOverloads()
{
Core::FunctionReplyObject reply(1, "v=%1 s=%2 q=%3");
reply.arg(7).arg(std::string("hello")).arg(QStringLiteral("qt"));
const std::vector<std::string> expectedArgs = {"7", "hello", "qt"};
QCOMPARE(reply.args(), expectedArgs);
QCOMPARE(reply(), std::string("v=7 s=hello q=qt"));
}
void ddscore_unit_test::setters()
{
Core::FunctionReplyObject reply;
reply.setId(11);
reply.setStr("updated %1");
reply.setAdditionalInfo("note");
QCOMPARE(reply.id(), 11);
QCOMPARE(reply.str(), std::string("updated %1"));
QVERIFY(reply.error());
QCOMPARE(reply.additionalInfo(), std::string("note"));
}
void ddscore_unit_test::formattedWithoutPlaceholders()
{
Core::FunctionReplyObject reply(1, "no placeholder");
reply.arg(QStringLiteral("ignored"));
QCOMPARE(reply(), std::string("no placeholder"));
}
void ddscore_unit_test::formattedExtraArgsIgnored()
{
Core::FunctionReplyObject reply(1, "only %1");
reply.arg(QStringLiteral("a")).arg(QStringLiteral("b"));
QCOMPARE(reply(), std::string("only a"));
}
void ddscore_unit_test::translatedMatchesFormatted()
{
// No translator is installed, so QCoreApplication::translate returns the
// source string and translated() must equal the plain formatted result.
Core::FunctionReplyObject reply(1, "translated %1", std::vector<std::string>{"t"});
QCOMPARE(reply.translated().toStdString(), std::string("translated t"));
QCOMPARE(reply.translated().toStdString(), reply());
}
void ddscore_unit_test::uniqueIdRoundtrip()
{
Core::FunctionReplyObject reply;
reply.setUniqueId(123456);
QCOMPARE(reply.uniqueId(), int64_t(123456));
}
void ddscore_unit_test::coreGetLoggerName()
{
// Core::getLogger prefixes the requested name with the "CORE." namespace.
NGL::INGLLogger &logger = Core::getLogger("UnitTest");
QCOMPARE(logger.getLoggerName(), std::string("CORE.UnitTest"));
}
QTEST_MAIN(ddscore_unit_test)
#include "ddscore_unit_test.moc"