Add workingCopyPathAs()

This commit is contained in:
Martchus 2019-01-20 22:56:22 +01:00
parent d21cde6fe3
commit 789af62d97
3 changed files with 58 additions and 20 deletions

View File

@ -2,6 +2,7 @@
#include "../misc/multiarray.h"
#include "../conversion/stringbuilder.h"
#include "../conversion/stringconversion.h"
#include "../io/misc.h"
@ -144,6 +145,14 @@ void MiscTests::testTestUtilities()
const auto workingCopyPathForNestedTestFile = workingCopyPath("subdir/nested-testfile.txt");
CPPUNIT_ASSERT_EQUAL_MESSAGE("creation of subdirectories in working dir", "some file\n"s, readFile(workingCopyPathForNestedTestFile));
const auto workingCopyPathUnderDifferentNameForNestedTestFile = workingCopyPathAs("subdir/nested-testfile.txt", "subdir2/foo.txt");
const auto splittedPath = splitString<vector<string>>(workingCopyPathUnderDifferentNameForNestedTestFile, "/", EmptyPartsTreat::Omit);
CPPUNIT_ASSERT_GREATEREQUAL(2_st, splittedPath.size());
CPPUNIT_ASSERT_EQUAL_MESSAGE("different subdir", "subdir2"s, splittedPath[splittedPath.size() - 2]);
CPPUNIT_ASSERT_EQUAL_MESSAGE("different file name", "foo.txt"s, splittedPath[splittedPath.size() - 1]);
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"creation of subdirectories in working dir", "some file\n"s, readFile(workingCopyPathUnderDifferentNameForNestedTestFile));
stringstream ss;
ss << asHexNumber(16);
CPPUNIT_ASSERT_EQUAL_MESSAGE("printing hex numbers", "0x10"s, ss.str());

View File

@ -266,6 +266,35 @@ string TestApplication::testFilePath(const string &relativeTestFilePath) const
* \remarks The test file is located using testFilePath().
*/
string TestApplication::workingCopyPathMode(const string &relativeTestFilePath, WorkingCopyMode mode) const
{
return workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, mode);
}
/*!
* \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().
*/
string TestApplication::workingCopyPath(const string &relativeTestFilePath) const
{
return workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, WorkingCopyMode::CreateCopy);
}
/*!
* \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. If only the
* path is returned, the \a relativeTestFilePath is ignored.
*
* In contrast to workingCopyPath(), this method allows to adjust the relative path of the working copy within the working copy
* directory via \a relativeWorkingCopyPath.
*
* \remarks
* - The test file specified via \a relativeTestFilePath is located using testFilePath().
* - The name of the working copy file specified via \a relativeWorkingCopyPath will be adjusted if it already exists in the file
* system and can not be truncated.
*/
string TestApplication::workingCopyPathAs(
const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode) const
{
// ensure working directory is present
if (!dirExists(m_workingDir) && !makeDir(m_workingDir)) {
@ -275,11 +304,11 @@ string TestApplication::workingCopyPathMode(const string &relativeTestFilePath,
}
// ensure subdirectory exists
const auto parts = splitString<vector<string>>(relativeTestFilePath, "/", EmptyPartsTreat::Omit);
const auto parts = splitString<vector<string>>(relativeWorkingCopyPath, "/", EmptyPartsTreat::Omit);
if (!parts.empty()) {
// create subdirectory level by level
string currentLevel;
currentLevel.reserve(m_workingDir.size() + relativeTestFilePath.size() + 1);
currentLevel.reserve(m_workingDir.size() + relativeWorkingCopyPath.size() + 1);
currentLevel.assign(m_workingDir);
for (auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) {
if (currentLevel.back() != '/') {
@ -292,7 +321,7 @@ string TestApplication::workingCopyPathMode(const string &relativeTestFilePath,
continue;
}
// fail otherwise
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeTestFilePath << "\": can't create directory \""
cerr << Phrases::Error << "Unable to create working copy for \"" << relativeWorkingCopyPath << "\": can't create directory \""
<< currentLevel << "\" (inside working directory)." << Phrases::EndFlush;
return string();
}
@ -300,12 +329,12 @@ string TestApplication::workingCopyPathMode(const string &relativeTestFilePath,
// just return the path if we don't want to actually create a copy
if (mode == WorkingCopyMode::NoCopy) {
return m_workingDir + relativeTestFilePath;
return m_workingDir + relativeWorkingCopyPath;
}
// copy the file
const auto origFilePath(testFilePath(relativeTestFilePath));
auto workingCopyPath(m_workingDir + relativeTestFilePath);
auto workingCopyPath(m_workingDir + relativeWorkingCopyPath);
size_t workingCopyPathAttempt = 0;
NativeFileStream origFile, workingCopy;
origFile.open(origFilePath, ios_base::in | ios_base::binary);
@ -318,7 +347,7 @@ string TestApplication::workingCopyPathMode(const string &relativeTestFilePath,
workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc);
while (workingCopy.fail() && fileSystemItemExists(workingCopyPath)) {
// adjust the working copy path if the target file already exists and can not be truncated
workingCopyPath = argsToString(m_workingDir, relativeTestFilePath, '.', ++workingCopyPathAttempt);
workingCopyPath = argsToString(m_workingDir, relativeWorkingCopyPath, '.', ++workingCopyPathAttempt);
workingCopy.clear();
workingCopy.open(workingCopyPath, ios_base::out | ios_base::binary | ios_base::trunc);
}
@ -348,18 +377,6 @@ string TestApplication::workingCopyPathMode(const string &relativeTestFilePath,
return string();
}
/*!
* \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().
*/
string TestApplication::workingCopyPath(const string &relativeTestFilePath) const
{
return workingCopyPathMode(relativeTestFilePath, WorkingCopyMode::CreateCopy);
}
{
return workingCopyPathMode(name, WorkingCopyMode::CreateCopy);
}
#ifdef PLATFORM_UNIX
/*!
* \brief Executes an application with the specified \a args.

View File

@ -29,6 +29,8 @@ public:
std::string testFilePath(const std::string &relativeTestFilePath) const;
std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode) const;
std::string workingCopyPath(const std::string &relativeTestFilePath) const;
std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath,
WorkingCopyMode mode = WorkingCopyMode::CreateCopy) const;
#ifdef PLATFORM_UNIX
int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
#endif
@ -113,7 +115,7 @@ inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relative
*/
inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath)
{
return TestApplication::instance()->workingCopyPath(relativeTestFilePath);
return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, WorkingCopyMode::CreateCopy);
}
/*!
@ -122,7 +124,17 @@ inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relat
*/
inline CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode)
{
return TestApplication::instance()->workingCopyPathMode(relativeTestFilePath, mode);
return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, mode);
}
/*!
* \brief Convenience function to invoke TestApplication::workingCopyPathAs().
* \remarks A TestApplication must be present.
*/
inline CPP_UTILITIES_EXPORT std::string workingCopyPathAs(
const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
{
return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeWorkingCopyPath, mode);
}
#ifdef PLATFORM_UNIX