C++ Utilities  5.10.5
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 
11 namespace CppUtilities {
12 
16 enum class WorkingCopyMode {
17  CreateCopy,
18  NoCopy
19 };
20 
22 public:
23  // construction/destruction
24  explicit TestApplication();
25  explicit TestApplication(int argc, const char *const *argv);
26  ~TestApplication();
27  operator bool() const;
28 
29  // helper for tests
30  std::string testFilePath(const std::string &relativeTestFilePath) const;
31  std::string testDirPath(const std::string &relativeTestDirPath) const;
32  std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy) const;
33  std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath,
35 #ifdef PLATFORM_UNIX
36  int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
37 #endif
38 
39  // read-only accessors
40  const std::vector<std::string> &testFilePaths() const;
41  const std::string &workingDirectory() const;
42  const char *applicationPath();
43  bool unitsSpecified() const;
44  const std::vector<const char *> &units() const;
45  bool onlyListUnits() const;
46 
47  // static read-only accessors
48  static const TestApplication *instance();
49  static const char *appPath();
50 
51 private:
52  static std::string readTestfilePathFromEnv();
53  static std::string readTestfilePathFromSrcRef();
54 
55  ArgumentParser m_parser;
56  OperationArgument m_listArg;
57  OperationArgument m_runArg;
58  ConfigValueArgument m_testFilesPathArg;
59  ConfigValueArgument m_applicationPathArg;
60  ConfigValueArgument m_workingDirArg;
61  ConfigValueArgument m_unitsArg;
62  std::vector<std::string> m_testFilesPaths;
63  std::string m_workingDir;
64  bool m_valid;
65  static TestApplication *s_instance;
66 };
67 
74 inline TestApplication::operator bool() const
75 {
76  return m_valid;
77 }
78 
83 {
84  return TestApplication::s_instance;
85 }
86 
90 inline const char *TestApplication::appPath()
91 {
92  return s_instance ? s_instance->applicationPath() : "";
93 }
94 
98 inline const std::vector<std::string> &TestApplication::testFilePaths() const
99 {
100  return m_testFilesPaths;
101 }
102 
106 inline const std::string &TestApplication::workingDirectory() const
107 {
108  return m_workingDir;
109 }
110 
115 {
116  return m_applicationPathArg.firstValue() ? m_applicationPathArg.firstValue() : "";
117 }
118 
123 {
124  return m_unitsArg.isPresent();
125 }
126 
131 inline const std::vector<const char *> &TestApplication::units() const
132 {
133  return m_unitsArg.values();
134 }
135 
140 {
141  return m_listArg.isPresent();
142 }
143 
148 inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
149 {
150  return TestApplication::instance()->testFilePath(relativeTestFilePath);
151 }
152 
157 inline CPP_UTILITIES_EXPORT std::string testDirPath(const std::string &relativeTestDirPath)
158 {
159  return TestApplication::instance()->testDirPath(relativeTestDirPath);
160 }
161 
166 inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
167 {
168  return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, mode);
169 }
170 
176  const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
177 {
178  return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeWorkingCopyPath, mode);
179 }
180 
181 #ifdef PLATFORM_UNIX
187 inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
188 {
189  return TestApplication::instance()->execApp(args, output, errors);
190 }
191 
192 CPP_UTILITIES_EXPORT int execHelperApp(
193  const char *appPath, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
194 CPP_UTILITIES_EXPORT int execHelperAppInSearchPath(
195  const char *appName, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
196 #endif // PLATFORM_UNIX
197 
202 template <typename T> class AsHexNumber {
203 public:
205  AsHexNumber(const T &value)
206  : value(value)
207  {
208  }
209  const T &value;
210 };
211 
215 template <typename T> bool operator==(const AsHexNumber<T> &lhs, const AsHexNumber<T> &rhs)
216 {
217  return lhs.value == rhs.value;
218 }
219 
223 template <typename T> std::ostream &operator<<(std::ostream &out, const AsHexNumber<T> &value)
224 {
225  return out << '0' << 'x' << std::hex << std::setfill('0') << std::setw(2) << unsigned(value.value) << std::dec;
226 }
227 
232 template <typename T> AsHexNumber<T> asHexNumber(const T &value)
233 {
234  return AsHexNumber<T>(value);
235 }
236 
242 template <typename T, Traits::EnableIf<std::is_integral<T>> * = nullptr> AsHexNumber<T> integralsAsHexNumber(const T &value)
243 {
244  return AsHexNumber<T>(value);
245 }
246 
252 template <typename T, Traits::DisableIf<std::is_integral<T>> * = nullptr> const T &integralsAsHexNumber(const T &value)
253 {
254  return value;
255 }
256 
265 #define TESTUTILS_ASSERT_EXEC(args) \
266  { \
267  const auto returnCode = execApp(args, stdout, stderr); \
268  if (returnCode != 0) { \
269  CPPUNIT_FAIL(::CppUtilities::argsToString("app failed with return code ", returnCode, "\nstdout: ", stdout, "\nstderr: ", stderr)); \
270  } \
271  }
272 
277 #define TESTUTILS_ASSERT_LIKE_FLAGS(message, expectedRegex, regexFlags, actualString) \
278  (CPPUNIT_NS::Asserter::failIf(!(std::regex_match(actualString, std::regex(expectedRegex, regexFlags))), \
279  CPPUNIT_NS::Message( \
280  CppUtilities::argsToString('\"', actualString, "\"\n not like\n\"", expectedRegex, '\"'), "Expression: " #actualString, message), \
281  CPPUNIT_SOURCELINE()))
282 
287 #define TESTUTILS_ASSERT_LIKE(message, expectedRegex, actualString) \
288  TESTUTILS_ASSERT_LIKE_FLAGS(message, expectedRegex, std::regex::ECMAScript, actualString)
289 
293 template <typename Pair, CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsSpecializationOf<Pair, std::pair>> * = nullptr>
294 inline std::ostream &operator<<(std::ostream &out, const Pair &pair)
295 {
296  return out << "key: " << pair.first << "; value: " << pair.second << '\n';
297 }
298 
302 template <typename Iteratable, Traits::EnableIf<Traits::IsIteratable<Iteratable>, Traits::Not<Traits::IsString<Iteratable>>> * = nullptr>
303 inline std::ostream &operator<<(std::ostream &out, const Iteratable &iteratable)
304 {
305  out << '\n';
306  std::size_t index = 0;
307  for (const auto &item : iteratable) {
308  out << std::setw(2) << index << ':' << ' ' << integralsAsHexNumber(item) << '\n';
309  ++index;
310  }
311  return out;
312 }
313 
317 namespace Literals {
322 constexpr std::size_t operator"" _st(unsigned long long size)
323 {
324  return static_cast<std::size_t>(size);
325 }
326 
331 constexpr std::uint64_t operator"" _uint64(unsigned long long size)
332 {
333  return static_cast<std::uint64_t>(size);
334 }
335 
340 constexpr std::int64_t operator"" _int64(unsigned long long size)
341 {
342  return static_cast<std::int64_t>(size);
343 }
344 } // namespace Literals
345 } // namespace CppUtilities
346 
347 #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:202
AsHexNumber(const T &value)
Constructs a new instance; use asHexNumber() for convenience instead.
Definition: testutils.h:205
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:21
bool onlyListUnits() const
Returns whether the test application should only list available units and not actually run any tests.
Definition: testutils.h:139
const std::vector< const char * > & units() const
Returns the specified test units.
Definition: testutils.h:131
std::string testFilePath(const std::string &relativeTestFilePath) const
Returns the full path of the test file with the specified relativeTestFilePath.
Definition: testutils.cpp:236
static const char * appPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:90
const std::vector< std::string > & testFilePaths() const
Returns the list of directories to look for test files.
Definition: testutils.h:98
bool unitsSpecified() const
Returns whether particular units have been specified.
Definition: testutils.h:122
const char * applicationPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:114
const std::string & workingDirectory() const
Returns the directory which is supposed to used for storing files created by tests.
Definition: testutils.h:106
static const TestApplication * instance()
Returns the current TestApplication instance.
Definition: testutils.h:82
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:292
std::string testDirPath(const std::string &relativeTestDirPath) const
Returns the full path of the test directory with the specified relativeTestDirPath.
Definition: testutils.cpp:254
#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:148
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPath().
Definition: testutils.h:166
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:232
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:157
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:215
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:175
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:242