C++ Utilities  5.10.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 
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,
34  WorkingCopyMode mode = WorkingCopyMode::CreateCopy) const;
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
182 
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
CppUtilities::TestApplication::testDirPath
std::string testDirPath(const std::string &relativeTestDirPath) const
Returns the full path of the test directory with the specified relativeTestDirPath.
Definition: testutils.cpp:254
CppUtilities::TestApplication::applicationPath
const char * applicationPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:114
CppUtilities::TestApplication::unitsSpecified
bool unitsSpecified() const
Returns whether particular units have been specified.
Definition: testutils.h:122
CppUtilities::testFilePath
CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
Convenience function to invoke TestApplication::testFilePath().
Definition: testutils.h:148
CppUtilities::integralsAsHexNumber
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
CppUtilities::OperationArgument
The OperationArgument class is an Argument where denotesOperation() is true by default.
Definition: argumentparser.h:430
CppUtilities::workingCopyPathAs
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
CppUtilities::TestApplication::units
const std::vector< const char * > & units() const
Returns the specified test units.
Definition: testutils.h:131
CppUtilities::TestApplication::workingDirectory
const std::string & workingDirectory() const
Returns the directory which is supposed to used for storing files created by tests.
Definition: testutils.h:106
CppUtilities::Argument::values
const std::vector< const char * > & values(std::size_t occurrence=0) const
Returns the parameter values for the specified occurrence of argument.
Definition: argumentparser.h:627
CppUtilities::TestApplication
The TestApplication class simplifies writing test applications that require opening test files.
Definition: testutils.h:21
CppUtilities::TestApplication::testFilePath
std::string testFilePath(const std::string &relativeTestFilePath) const
Returns the full path of the test file with the specified relativeTestFilePath.
Definition: testutils.cpp:236
CppUtilities::WorkingCopyMode::CreateCopy
@ CreateCopy
CppUtilities::AsHexNumber::AsHexNumber
AsHexNumber(const T &value)
Constructs a new instance; use asHexNumber() for convenience instead.
Definition: testutils.h:205
CppUtilities::ConfigValueArgument
The ConfigValueArgument class is an Argument where setCombinable() is true by default.
Definition: argumentparser.h:435
CppUtilities::TestApplication::testFilePaths
const std::vector< std::string > & testFilePaths() const
Returns the list of directories to look for test files.
Definition: testutils.h:98
CppUtilities::operator<<
CPP_UTILITIES_EXPORT std::ostream & operator<<(std::ostream &out, Indentation indentation)
Definition: commandlineutils.h:83
CppUtilities::Argument::firstValue
const char * firstValue() const
Returns the first parameter value of the first occurrence of the argument.
Definition: argumentparser.cpp:491
CppUtilities::TestApplication::workingCopyPathAs
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
CppUtilities
Contains all utilities provides by the c++utilities library.
Definition: argumentparser.h:17
CppUtilities::AsHexNumber::value
const T & value
Definition: testutils.h:209
CppUtilities::Argument::isPresent
bool isPresent() const
Returns an indication whether the argument could be detected when parsing.
Definition: argumentparser.h:739
CppUtilities::WorkingCopyMode
WorkingCopyMode
The WorkingCopyMode enum specifies additional options to influence behavior of TestApplication::worki...
Definition: testutils.h:16
CppUtilities::TestApplication::onlyListUnits
bool onlyListUnits() const
Returns whether the test application should only list available units and not actually run any tests.
Definition: testutils.h:139
CppUtilities::AsHexNumber
The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using ...
Definition: testutils.h:202
CppUtilities::asHexNumber
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
CppUtilities::testDirPath
CPP_UTILITIES_EXPORT std::string testDirPath(const std::string &relativeTestDirPath)
Convenience function to invoke TestApplication::testDirPath().
Definition: testutils.h:157
CppUtilities::TestApplication::appPath
static const char * appPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:90
CppUtilities::TestApplication::instance
static const TestApplication * instance()
Returns the current TestApplication instance.
Definition: testutils.h:82
CPP_UTILITIES_EXPORT
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
CppUtilities::operator==
bool operator==(const AsHexNumber< T > &lhs, const AsHexNumber< T > &rhs)
Provides operator == required by CPPUNIT_ASSERT_EQUAL.
Definition: testutils.h:215
CppUtilities::workingCopyPath
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPath().
Definition: testutils.h:166
CppUtilities::ArgumentParser
The ArgumentParser class provides a means for handling command line arguments.
Definition: argumentparser.h:451