C++ Utilities 5.12.0
Useful C++ classes and routines such as argument parser, IO and conversion utilities
testutils.h
Go to the documentation of this file.
1#ifndef TESTUTILS_H
2#define TESTUTILS_H
3
4#include "../application/argumentparser.h"
5#include "../misc/traits.h"
6
7#include <iomanip>
8#include <ostream>
9#include <string>
10
11namespace CppUtilities {
12
16enum class WorkingCopyMode {
18 NoCopy,
19 Cleanup,
20};
21
23public:
24 // construction/destruction
25 explicit TestApplication();
26 explicit TestApplication(int argc, const char *const *argv);
28 operator bool() const;
29
30 // helper for tests
31 std::string testFilePath(const std::string &relativeTestFilePath) const;
32 std::string testDirPath(const std::string &relativeTestDirPath) const;
33 std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy) const;
34 std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath,
36#ifdef PLATFORM_UNIX
37 int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
38#endif
39
40 // read-only accessors
41 const std::vector<std::string> &testFilePaths() const;
42 const std::string &workingDirectory() const;
43 const char *applicationPath();
44 bool unitsSpecified() const;
45 const std::vector<const char *> &units() const;
46 bool onlyListUnits() const;
47
48 // static read-only accessors
49 static const TestApplication *instance();
50 static const char *appPath();
51
52private:
53 static std::string readTestfilePathFromEnv();
54 static std::string readTestfilePathFromSrcRef();
55
56 ArgumentParser m_parser;
57 OperationArgument m_listArg;
58 OperationArgument m_runArg;
59 ConfigValueArgument m_testFilesPathArg;
60 ConfigValueArgument m_applicationPathArg;
61 ConfigValueArgument m_workingDirArg;
62 ConfigValueArgument m_unitsArg;
63 std::vector<std::string> m_testFilesPaths;
64 std::string m_workingDir;
65 bool m_valid;
66 static TestApplication *s_instance;
67};
68
75inline TestApplication::operator bool() const
76{
77 return m_valid;
78}
79
84{
85 return TestApplication::s_instance;
86}
87
91inline const char *TestApplication::appPath()
92{
93 return s_instance ? s_instance->applicationPath() : "";
94}
95
99inline const std::vector<std::string> &TestApplication::testFilePaths() const
100{
101 return m_testFilesPaths;
102}
103
107inline const std::string &TestApplication::workingDirectory() const
108{
109 return m_workingDir;
110}
111
116{
117 return m_applicationPathArg.firstValue() ? m_applicationPathArg.firstValue() : "";
118}
119
124{
125 return m_unitsArg.isPresent();
126}
127
132inline const std::vector<const char *> &TestApplication::units() const
133{
134 return m_unitsArg.values();
135}
136
141{
142 return m_listArg.isPresent();
143}
144
149inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
150{
151 return TestApplication::instance()->testFilePath(relativeTestFilePath);
152}
153
158inline CPP_UTILITIES_EXPORT std::string testDirPath(const std::string &relativeTestDirPath)
159{
160 return TestApplication::instance()->testDirPath(relativeTestDirPath);
161}
162
167inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
168{
169 return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, mode);
170}
171
177 const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
178{
179 return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeWorkingCopyPath, mode);
180}
181
182#ifdef PLATFORM_UNIX
188inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
189{
190 return TestApplication::instance()->execApp(args, output, errors);
191}
192
193CPP_UTILITIES_EXPORT int execHelperApp(
194 const char *appPath, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
195CPP_UTILITIES_EXPORT int execHelperAppInSearchPath(
196 const char *appName, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
197#endif // PLATFORM_UNIX
198
203template <typename T> class AsHexNumber {
204public:
207 : value(value)
208 {
209 }
210 const T &value;
211};
212
216template <typename T> bool operator==(const AsHexNumber<T> &lhs, const AsHexNumber<T> &rhs)
217{
218 return lhs.value == rhs.value;
219}
220
224template <typename T> std::ostream &operator<<(std::ostream &out, const AsHexNumber<T> &value)
225{
226 return out << '0' << 'x' << std::hex << std::setfill('0') << std::setw(2) << unsigned(value.value) << std::dec;
227}
228
233template <typename T> AsHexNumber<T> asHexNumber(const T &value)
234{
235 return AsHexNumber<T>(value);
236}
237
243template <typename T, Traits::EnableIf<std::is_integral<T>> * = nullptr> AsHexNumber<T> integralsAsHexNumber(const T &value)
244{
245 return AsHexNumber<T>(value);
246}
247
253template <typename T, Traits::DisableIf<std::is_integral<T>> * = nullptr> const T &integralsAsHexNumber(const T &value)
254{
255 return value;
256}
257
266#define TESTUTILS_ASSERT_EXEC(args) \
267 { \
268 const auto returnCode = execApp(args, stdout, stderr); \
269 if (returnCode != 0) { \
270 CPPUNIT_FAIL(::CppUtilities::argsToString("app failed with return code ", returnCode, "\nstdout: ", stdout, "\nstderr: ", stderr)); \
271 } \
272 }
273
278#define TESTUTILS_ASSERT_LIKE_FLAGS(message, expectedRegex, regexFlags, actualString) \
279 (CPPUNIT_NS::Asserter::failIf(!(std::regex_match(actualString, std::regex(expectedRegex, regexFlags))), \
280 CPPUNIT_NS::Message( \
281 CppUtilities::argsToString('\"', actualString, "\"\n not like\n\"", expectedRegex, '\"'), "Expression: " #actualString, message), \
282 CPPUNIT_SOURCELINE()))
283
288#define TESTUTILS_ASSERT_LIKE(message, expectedRegex, actualString) \
289 TESTUTILS_ASSERT_LIKE_FLAGS(message, expectedRegex, std::regex::ECMAScript, actualString)
290
294template <typename Pair, CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsSpecializationOf<Pair, std::pair>> * = nullptr>
295inline std::ostream &operator<<(std::ostream &out, const Pair &pair)
296{
297 return out << "key: " << pair.first << "; value: " << pair.second << '\n';
298}
299
303template <typename Iteratable, Traits::EnableIf<Traits::IsIteratable<Iteratable>, Traits::Not<Traits::IsString<Iteratable>>> * = nullptr>
304inline std::ostream &operator<<(std::ostream &out, const Iteratable &iteratable)
305{
306 out << '\n';
307 std::size_t index = 0;
308 for (const auto &item : iteratable) {
309 out << std::setw(2) << index << ':' << ' ' << integralsAsHexNumber(item) << '\n';
310 ++index;
311 }
312 return out;
313}
314
318namespace Literals {
323constexpr std::size_t operator"" _st(unsigned long long size)
324{
325 return static_cast<std::size_t>(size);
326}
327
332constexpr std::uint64_t operator"" _uint64(unsigned long long size)
333{
334 return static_cast<std::uint64_t>(size);
335}
336
341constexpr std::int64_t operator"" _int64(unsigned long long size)
342{
343 return static_cast<std::int64_t>(size);
344}
345} // namespace Literals
346} // namespace CppUtilities
347
348#endif // TESTUTILS_H
The ArgumentParser class provides a means for handling command line arguments.
const char * firstValue() const
Returns the first parameter value of the first occurrence of the argument.
const std::vector< const char * > & values(std::size_t occurrence=0) const
Returns the parameter values for the specified occurrence of argument.
bool isPresent() const
Returns an indication whether the argument could be detected when parsing.
The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using ...
Definition: testutils.h:203
AsHexNumber(const T &value)
Constructs a new instance; use asHexNumber() for convenience instead.
Definition: testutils.h:206
The ConfigValueArgument class is an Argument where setCombinable() is true by default.
The OperationArgument class is an Argument where denotesOperation() is true by default.
The TestApplication class simplifies writing test applications that require opening test files.
Definition: testutils.h:22
bool onlyListUnits() const
Returns whether the test application should only list available units and not actually run any tests.
Definition: testutils.h:140
const std::vector< const char * > & units() const
Returns the specified test units.
Definition: testutils.h:132
std::string testFilePath(const std::string &relativeTestFilePath) const
Returns the full path of the test file with the specified relativeTestFilePath.
Definition: testutils.cpp:237
static const char * appPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:91
const std::vector< std::string > & testFilePaths() const
Returns the list of directories to look for test files.
Definition: testutils.h:99
bool unitsSpecified() const
Returns whether particular units have been specified.
Definition: testutils.h:123
const char * applicationPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:115
const std::string & workingDirectory() const
Returns the directory which is supposed to used for storing files created by tests.
Definition: testutils.h:107
static const TestApplication * instance()
Returns the current TestApplication instance.
Definition: testutils.h:83
std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy) const
Returns the full path to a working copy of the test file with the specified relativeTestFilePath.
Definition: testutils.cpp:293
std::string testDirPath(const std::string &relativeTestDirPath) const
Returns the full path of the test directory with the specified relativeTestDirPath.
Definition: testutils.cpp:255
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Contains all utilities provides by the c++utilities library.
CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
Convenience function to invoke TestApplication::testFilePath().
Definition: testutils.h:149
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPath().
Definition: testutils.h:167
WorkingCopyMode
The WorkingCopyMode enum specifies additional options to influence behavior of TestApplication::worki...
Definition: testutils.h:16
CPP_UTILITIES_EXPORT std::string testDirPath(const std::string &relativeTestDirPath)
Convenience function to invoke TestApplication::testDirPath().
Definition: testutils.h:158
CPP_UTILITIES_EXPORT std::ostream & operator<<(std::ostream &out, Indentation indentation)
bool operator==(const AsHexNumber< T > &lhs, const AsHexNumber< T > &rhs)
Provides operator == required by CPPUNIT_ASSERT_EQUAL.
Definition: testutils.h:216
AsHexNumber< T > asHexNumber(const T &value)
Wraps a value to be printed using the hex system in the error case when asserted with cppunit (or sim...
Definition: testutils.h:233
CPP_UTILITIES_EXPORT std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPathAs().
Definition: testutils.h:176
AsHexNumber< T > integralsAsHexNumber(const T &value)
Wraps a value to be printed using the hex system in the error case when asserted with cppunit (or sim...
Definition: testutils.h:243