From 2b6f26895d6eb71dabf16f1ae099f998ccc3fff4 Mon Sep 17 00:00:00 2001 From: Martchus Date: Mon, 27 Feb 2023 18:01:14 +0100 Subject: [PATCH] Support multiple source directories in `srcdirref` file * Locate test files in all source directories specified in `srcdirref` * Allow overriding contents of `srcdirref` so the directory of another component (within the same repository) can be appended to share testfiles --- cmake/modules/BasicConfig.cmake | 5 ++++- tests/testutils.cpp | 32 +++++++++++++++++++------------- tests/testutils.h | 2 +- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cmake/modules/BasicConfig.cmake b/cmake/modules/BasicConfig.cmake index dddaaea..0f47663 100644 --- a/cmake/modules/BasicConfig.cmake +++ b/cmake/modules/BasicConfig.cmake @@ -344,7 +344,10 @@ endif () # useful if there's a test target; this is for instance also used in mocked configuration of syncthingtray) -> add a file # called "srcdirref" to the build directory; this file contains the path of the sources so tests can easily find test files # contained in the source directory -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/srcdirref" "${CMAKE_CURRENT_SOURCE_DIR}") +if (NOT META_SRCDIR_REFS) + set(META_SRCDIR_REFS "${CMAKE_CURRENT_SOURCE_DIR}") +endif () +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/srcdirref" "${META_SRCDIR_REFS}") # -> ensure the directory "testfiles" exists in the build directory; tests of my projects use it by default to create working # copies of testfiles file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/testfiles") diff --git a/tests/testutils.cpp b/tests/testutils.cpp index bae9c88..b750afa 100644 --- a/tests/testutils.cpp +++ b/tests/testutils.cpp @@ -178,7 +178,7 @@ TestApplication::TestApplication(int argc, const char *const *argv) } // -> find source directory if (auto testFilePathFromSrcDirRef = readTestfilePathFromSrcRef(); !testFilePathFromSrcDirRef.empty()) { - m_testFilesPaths.emplace_back(std::move(testFilePathFromSrcDirRef)); + m_testFilesPaths.insert(m_testFilesPaths.end(), std::make_move_iterator(testFilePathFromSrcDirRef.begin()), std::make_move_iterator(testFilePathFromSrcDirRef.end())); } // -> try testfiles directory in working directory m_testFilesPaths.emplace_back("./testfiles/"); @@ -612,10 +612,11 @@ string TestApplication::readTestfilePathFromEnv() * \remarks That file is supposed to contain the path the the source directory. It is supposed to be stored by the build system in the * same directory as the test executable. The CMake modules contained of these utilities ensure that's the case. */ -string TestApplication::readTestfilePathFromSrcRef() +std::vector TestApplication::readTestfilePathFromSrcRef() { // find the path of the current executable on platforms supporting "/proc/self/exe"; otherwise assume the current working directory // is the executable path + auto res = std::vector(); auto binaryPath = std::string(); #if defined(CPP_UTILITIES_USE_STANDARD_FILESYSTEM) && defined(PLATFORM_UNIX) try { @@ -628,25 +629,30 @@ string TestApplication::readTestfilePathFromSrcRef() const auto srcdirrefPath = binaryPath + "srcdirref"; try { // read "srcdirref" file which should contain the path of the source directory - auto srcDirContent(readFile(srcdirrefPath, 2 * 1024)); + const auto srcDirContent = readFile(srcdirrefPath, 2 * 1024); if (srcDirContent.empty()) { cerr << Phrases::Warning << "The file \"srcdirref\" is empty." << Phrases::EndFlush; - return string(); + return res; } - srcDirContent += "/testfiles/"; - // check whether the referenced source directory contains a "testfiles" directory - if (!dirExists(srcDirContent)) { - cerr << Phrases::Warning - << "The source directory referenced by the file \"srcdirref\" does not contain a \"testfiles\" directory or does not exist." - << Phrases::End << "Referenced source directory: " << srcDirContent << endl; - return string(); + // check whether the referenced source directories contain a "testfiles" directory + const auto srcPaths = splitStringSimple>(srcDirContent, "\n"); + for (const auto &srcPath : srcPaths) { + auto testfilesPath = argsToString(srcPath, "/testfiles/"); + if (dirExists(testfilesPath)) { + res.emplace_back(std::move(testfilesPath)); + } else { + cerr << Phrases::Warning + << "The source directory referenced by the file \"srcdirref\" does not contain a \"testfiles\" directory or does not exist." + << Phrases::End << "Referenced source directory: " << testfilesPath << endl; + } + } - return srcDirContent; + return res; } catch (const std::ios_base::failure &e) { cerr << Phrases::Warning << "The file \"" << srcdirrefPath << "\" can not be opened: " << e.what() << Phrases::EndFlush; } - return string(); + return res; } } // namespace CppUtilities diff --git a/tests/testutils.h b/tests/testutils.h index 441023a..c1bc57b 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -52,7 +52,7 @@ public: private: static std::string readTestfilePathFromEnv(); - static std::string readTestfilePathFromSrcRef(); + static std::vector readTestfilePathFromSrcRef(); ArgumentParser m_parser; OperationArgument m_listArg;