Improve documentation for testFilePath()/workingCopyPath()

This commit is contained in:
Martchus 2019-01-20 22:15:35 +01:00
parent 70f4b20d8a
commit 8b35d06aa7
2 changed files with 45 additions and 48 deletions

View File

@ -221,66 +221,66 @@ TestApplication::~TestApplication()
} }
/*! /*!
* \brief Returns the full path of the test file with the specified \a name. * \brief Returns the full path of the test file with the specified \a relativeTestFilePath.
* *
* The specified \a name might be a relative path in the testfiles directory. * The specified \a relativeTestFilePath is considered to be a path to a test file which is relative
* to at least one of the considered test file search directories.
* *
* The following directories are searched for the specified testfile: * The following directories are searched for test files in the given order:
* 1. The directory specified as CLI argument. * 1. The directory specified as CLI argument.
* 2. The fallback directory, which can be set by setting the environment * 2. The fallback directory, which can be set by setting the environment
* variable `TEST_FILE_PATH`. * variable `TEST_FILE_PATH`.
* 3. The source directory, if it could be determined via "srcref"-file * 3. The source directory, if it could be determined via "srcref"-file
* unless both, the CLI argument and environment variable are present. * unless both, the CLI argument and environment variable are present.
*/ */
string TestApplication::testFilePath(const string &name) const string TestApplication::testFilePath(const string &relativeTestFilePath) const
{ {
string path; string path;
fstream file; // used to check whether the file is present fstream file; // used to check whether the file is present
// check the path specified by command line argument or via environment variable // check the path specified by command line argument or via environment variable
if (!m_testFilesPath.empty()) { if (!m_testFilesPath.empty()) {
if (fileExists(path = m_testFilesPath + name)) { if (fileExists(path = m_testFilesPath + relativeTestFilePath)) {
return path; return path;
} }
} }
// check the fallback path (value from environment variable or source directory) // check the fallback path (value from environment variable or source directory)
if (!m_fallbackTestFilesPath.empty()) { if (!m_fallbackTestFilesPath.empty()) {
if (fileExists(path = m_fallbackTestFilesPath + name)) { if (fileExists(path = m_fallbackTestFilesPath + relativeTestFilePath)) {
return path; return path;
} }
} }
// file still not found -> return default path // file still not found -> return default path
if (!fileExists(path = "./testfiles/" + name)) { if (!fileExists(path = "./testfiles/" + relativeTestFilePath)) {
cerr << Phrases::Warning << "The testfile \"" << name << "\" can not be located." << Phrases::EndFlush; cerr << Phrases::Warning << "The testfile \"" << relativeTestFilePath << "\" can not be located." << Phrases::EndFlush;
} }
return path; return path;
} }
/*! /*!
* \brief Returns the full path to a working copy of the test file with the specified \a name. * \brief Returns the full path to a working copy of the test file with the specified \a relativeTestFilePath.
* *
* The specified \a mode controls whether a working copy is actually created or whether just the path is returned. * The specified \a mode controls whether a working copy is actually created or whether just the path is returned.
* The test file is located using testFilePath().
* *
* \remarks Currently only available under UNIX. * \remarks The test file is located using testFilePath().
*/ */
string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode mode) const string TestApplication::workingCopyPathMode(const string &relativeTestFilePath, WorkingCopyMode mode) const
{ {
// ensure working directory is present // ensure working directory is present
if (!dirExists(m_workingDir) && !makeDir(m_workingDir)) { if (!dirExists(m_workingDir) && !makeDir(m_workingDir)) {
cerr << Phrases::Error << "Unable to create working copy for \"" << name << "\": can't create working directory \"" << m_workingDir << "\"." cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": can't create working directory \""
<< Phrases::EndFlush; << m_workingDir << "\"." << Phrases::EndFlush;
return string(); return string();
} }
// ensure subdirectory exists // ensure subdirectory exists
const auto parts = splitString<vector<string>>(name, "/", EmptyPartsTreat::Omit); const auto parts = splitString<vector<string>>(relativeTestFilePath, "/", EmptyPartsTreat::Omit);
if (!parts.empty()) { if (!parts.empty()) {
// create subdirectory level by level // create subdirectory level by level
string currentLevel; string currentLevel;
currentLevel.reserve(m_workingDir.size() + name.size() + 1); currentLevel.reserve(m_workingDir.size() + relativeTestFilePath.size() + 1);
currentLevel.assign(m_workingDir); currentLevel.assign(m_workingDir);
for (auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) { for (auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) {
if (currentLevel.back() != '/') { if (currentLevel.back() != '/') {
@ -293,39 +293,39 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
continue; continue;
} }
// fail otherwise // fail otherwise
cerr << Phrases::Error << "Unable to create working copy for \"" << name << "\": can't create directory \"" << currentLevel cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": can't create directory \""
<< "\" (inside working directory)." << Phrases::EndFlush; << currentLevel << "\" (inside working directory)." << Phrases::EndFlush;
return string(); return string();
} }
} }
// just return the path if we don't want to actually create a copy // just return the path if we don't want to actually create a copy
if (mode == WorkingCopyMode::NoCopy) { if (mode == WorkingCopyMode::NoCopy) {
return m_workingDir + name; return m_workingDir + relativeTestFilePath;
} }
// copy the file // copy the file
const auto origFilePath(testFilePath(name)); const auto origFilePath(testFilePath(relativeTestFilePath));
auto workingCopyPath(m_workingDir + name); auto workingCopyPath(m_workingDir + relativeTestFilePath);
size_t workingCopyPathAttempt = 0; size_t workingCopyPathAttempt = 0;
NativeFileStream origFile, workingCopy; NativeFileStream origFile, workingCopy;
origFile.open(origFilePath, ios_base::in | ios_base::binary); origFile.open(origFilePath, ios_base::in | ios_base::binary);
if (origFile.fail()) { if (origFile.fail()) {
cerr << Phrases::Error << "Unable to create working copy for \"" << name << "\": an IO error occurred when opening original file \"" cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath
<< origFilePath << "\"." << Phrases::EndFlush; << "\": an IO error occurred when opening original file \"" << origFilePath << "\"." << Phrases::EndFlush;
cerr << "error: " << strerror(errno) << endl; cerr << "error: " << strerror(errno) << endl;
return string(); return string();
} }
workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc); workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc);
while (workingCopy.fail() && fileSystemItemExists(workingCopyPath)) { while (workingCopy.fail() && fileSystemItemExists(workingCopyPath)) {
// adjust the working copy path if the target file already exists and can not be truncated // adjust the working copy path if the target file already exists and can not be truncated
workingCopyPath = argsToString(m_workingDir, name, '.', ++workingCopyPathAttempt); workingCopyPath = argsToString(m_workingDir, relativeTestFilePath, '.', ++workingCopyPathAttempt);
workingCopy.clear(); workingCopy.clear();
workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc); workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc);
} }
if (workingCopy.fail()) { if (workingCopy.fail()) {
cerr << Phrases::Error << "Unable to create working copy for \"" << name << "\": an IO error occurred when opening target file \"" cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath
<< workingCopyPath << "\"." << Phrases::EndFlush; << "\": an IO error occurred when opening target file \"" << workingCopyPath << "\"." << Phrases::EndFlush;
cerr << "error: " << strerror(errno) << endl; cerr << "error: " << strerror(errno) << endl;
return string(); return string();
} }
@ -334,7 +334,7 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
return workingCopyPath; return workingCopyPath;
} }
cerr << Phrases::Error << "Unable to create working copy for \"" << name << "\": "; cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": ";
if (origFile.fail()) { if (origFile.fail()) {
cerr << "an IO error occurred when reading original file \"" << origFilePath << "\""; cerr << "an IO error occurred when reading original file \"" << origFilePath << "\"";
return string(); return string();
@ -350,13 +350,13 @@ string TestApplication::workingCopyPathMode(const string &name, WorkingCopyMode
} }
/*! /*!
* \brief Creates a working copy of the test file with the specified \a name and returns the full path of the created file. * \brief Returns the full path to a working copy of the test file with the specified \a relativeTestFilePath.
* * \remarks The test file is located using testFilePath().
* The test file is located using testFilePath().
*
* \remarks Currently only available under UNIX.
*/ */
string TestApplication::workingCopyPath(const string &name) const string TestApplication::workingCopyPath(const string &relativeTestFilePath) const
{
return workingCopyPathMode(relativeTestFilePath, WorkingCopyMode::CreateCopy);
}
{ {
return workingCopyPathMode(name, WorkingCopyMode::CreateCopy); return workingCopyPathMode(name, WorkingCopyMode::CreateCopy);
} }

View File

@ -26,9 +26,9 @@ public:
~TestApplication(); ~TestApplication();
operator bool() const; operator bool() const;
std::string testFilePath(const std::string &name) const; std::string testFilePath(const std::string &relativeTestFilePath) const;
std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode) const; std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode) const;
std::string workingCopyPath(const std::string &name) const; std::string workingCopyPath(const std::string &relativeTestFilePath) const;
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const; int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
#endif #endif
@ -99,33 +99,30 @@ inline const std::vector<const char *> &TestApplication::units() const
} }
/*! /*!
* \brief Convenience function which returns the full path of the test file with the specified \a name. * \brief Convenience function to invoke TestApplication::testFilePath().
* \remarks A TestApplication must be present. * \remarks A TestApplication must be present.
* \sa TestApplication::testFilePath()
*/ */
inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &name) inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
{ {
return TestApplication::instance()->testFilePath(name); return TestApplication::instance()->testFilePath(relativeTestFilePath);
} }
/*! /*!
* \brief Convenience function which returns the full path to a working copy of the test file with the specified \a name. * \brief Convenience function to invoke TestApplication::workingCopyPath().
* \remarks A TestApplication must be present. * \remarks A TestApplication must be present.
* \sa TestApplication::workingCopyPath()
*/ */
inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &name) inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath)
{ {
return TestApplication::instance()->workingCopyPath(name); return TestApplication::instance()->workingCopyPath(relativeTestFilePath);
} }
/*! /*!
* \brief Convenience function which returns the full path to a working copy of the test file with the specified \a name. * \brief Convenience function to invoke TestApplication::workingCopyPathMode().
* \remarks A TestApplication must be present. * \remarks A TestApplication must be present.
* \sa TestApplication::workingCopyPathMode()
*/ */
inline CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode) inline CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode)
{ {
return TestApplication::instance()->workingCopyPathMode(name, mode); return TestApplication::instance()->workingCopyPathMode(relativeTestFilePath, mode);
} }
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX