Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/tests/test_export_headers.cpp
T

147 lines
5.6 KiB
C++

/**
* @file test_export_headers.cpp
* @brief Tests für Export Header Guards
*
* Tests verify that export headers exist and can be included without errors.
* Note: Export macros are defined via CMake target_compile_definitions,
* so we test header existence and structure rather than macro expansion.
*
* All export headers are generated into the build tree. The build directory
* is passed in via the MIGRATION_TEST_BUILD_DIR compile definition (its
* name is not stable across pipeline stages), and only headers of targets
* that are part of the validated build are checked.
*/
#include <fstream>
#include <gtest/gtest.h>
#include <string>
#include <vector>
#ifndef MIGRATION_TEST_BUILD_DIR
#error "MIGRATION_TEST_BUILD_DIR must be defined by tests/CMakeLists.txt"
#endif
namespace
{
const std::string kBuildDir = MIGRATION_TEST_BUILD_DIR;
// Helper to check if file exists and is readable
bool fileExists(const std::string& path)
{
std::ifstream file(path);
return file.good();
}
// Helper to read file content
std::string readFile(const std::string& path)
{
std::ifstream file(path);
if (!file.is_open())
{
return "";
}
return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
}
} // namespace
// Test 1: nglwidgets_export.h exists
TEST(ExportHeaders, NglWidgetsExportExists)
{
std::string path = kBuildDir + "/Z/src/nglwidgets/nglwidgets_export.h";
EXPECT_TRUE(fileExists(path)) << "Export header not found: " << path;
}
// Test 2: qtsingleapplication_export.h exists
TEST(ExportHeaders, QtSingleApplicationExportExists)
{
std::string path = kBuildDir + "/Z/src/QtSingleApplication/qtsingleapplication_export.h";
EXPECT_TRUE(fileExists(path)) << "Export header not found: " << path;
}
// Test 3: ltssessiondata_export.h exists
TEST(ExportHeaders, LtsSessionDataExportExists)
{
std::string path = kBuildDir + "/Lts/Common/LtsSession/ltssessiondata_export.h";
EXPECT_TRUE(fileExists(path)) << "Export header not found: " << path;
}
// Test 4: ddsconnector_export.h exists
TEST(ExportHeaders, DdsConnectorExportExists)
{
// This originally asserted svcgmpserver_export.h (GuezMinelayerProcessing).
// That sibling service is not part of this migration and is not built by
// the validation pipeline, so its export header is never generated.
// ddsconnector is a core dependency of the migrated FileManagement and
// FilterManagement services and part of the validated build.
std::string path = kBuildDir + "/Lts/DDS/DDSConnector/ddsconnector_export.h";
EXPECT_TRUE(fileExists(path)) << "Export header not found: " << path;
}
// Test 5: Export headers have proper include guards
TEST(ExportHeaders, HaveIncludeGuards)
{
std::vector<std::string> headers = {
kBuildDir + "/Z/src/nglwidgets/nglwidgets_export.h",
kBuildDir + "/Z/src/QtSingleApplication/qtsingleapplication_export.h",
kBuildDir + "/Lts/Common/LtsSession/ltssessiondata_export.h",
kBuildDir + "/Lts/DDS/DDSConnector/ddsconnector_export.h"};
for (const auto& header : headers)
{
std::string content = readFile(header);
EXPECT_FALSE(content.empty()) << "Export header not found: " << header;
if (!content.empty())
{
// Check for #ifndef guard
bool hasIfndef = content.find("#ifndef") != std::string::npos;
bool hasDefine = content.find("#define") != std::string::npos;
bool hasEndif = content.find("#endif") != std::string::npos;
EXPECT_TRUE(hasIfndef && hasDefine && hasEndif) << "Header " << header << " missing proper include guards";
}
}
}
// Test 6: Export macros follow naming convention
TEST(ExportHeaders, MacroNamingConvention)
{
// Check that export headers follow CMake naming convention:
// <PREFIX>_EXPORT_H guard for target <prefix>
std::string connectorPath = kBuildDir + "/Lts/DDS/DDSConnector/ddsconnector_export.h";
std::string content = readFile(connectorPath);
EXPECT_FALSE(content.empty()) << "Export header not found: " << connectorPath;
if (!content.empty())
{
// Should have DDSCONNECTOR_EXPORT_H guard
bool hasCorrectGuard = content.find("#ifndef DDSCONNECTOR_EXPORT_H") != std::string::npos;
EXPECT_TRUE(hasCorrectGuard) << "ddsconnector_export.h should use DDSCONNECTOR_EXPORT_H guard";
}
}
// Test 7: Export headers define both EXPORT and NO_EXPORT macros
TEST(ExportHeaders, ExportAndNoExportMacros)
{
std::vector<std::pair<std::string, std::string>> expectedMacros = {
{kBuildDir + "/Lts/DDS/DDSConnector/ddsconnector_export.h", "DDSCONNECTOR"},
{kBuildDir + "/Lts/DDS/FTS/ddsfts_export.h", "DDSFTS"},
{kBuildDir + "/Lts/DDS/Core/ddscore_export.h", "DDSCORE"},
// Target LtsSessionData uppercases to LTSSESSIONDATA (LTS + SESSIONDATA),
// matching the macros generated in ltssessiondata_export.h.
{kBuildDir + "/Lts/Common/LtsSession/ltssessiondata_export.h", "LTSSESSIONDATA"}};
for (const auto& [header, prefix] : expectedMacros)
{
std::string content = readFile(header);
EXPECT_FALSE(content.empty()) << "Export header not found: " << header;
if (!content.empty())
{
bool hasExport = content.find(prefix + "_EXPORT") != std::string::npos;
bool hasNoExport = content.find(prefix + "_NO_EXPORT") != std::string::npos;
EXPECT_TRUE(hasExport) << header << " should define " << prefix << "_EXPORT";
EXPECT_TRUE(hasNoExport) << header << " should define " << prefix << "_NO_EXPORT";
}
}
}