C++ Utilities  4.17.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 "../conversion/stringbuilder.h" // FIXME: remove in v5
6 #include "../conversion/types.h"
7 #include "../misc/traits.h"
8 
9 #include <iomanip>
10 #include <ostream>
11 #include <string>
12 
13 namespace TestUtilities {
14 
18 enum class WorkingCopyMode {
19  CreateCopy,
20  NoCopy
21 };
22 
24 public:
25  TestApplication(int argc, char **argv);
26  ~TestApplication();
27 
28  operator bool() const;
29  std::string testFilePath(const std::string &relativeTestFilePath) const;
30  std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode) const;
31  std::string workingCopyPath(const std::string &relativeTestFilePath) const;
32  std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath,
34 #ifdef PLATFORM_UNIX
35  int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
36 #endif
37  bool unitsSpecified() const;
38  const std::vector<const char *> &units() const;
39  static const TestApplication *instance();
40  static const char *appPath();
41 
42 private:
43  static std::string readTestfilePathFromEnv();
44  static std::string readTestfilePathFromSrcRef();
45 
48  ApplicationUtilities::Argument m_testFilesPathArg;
49  ApplicationUtilities::Argument m_applicationPathArg;
50  ApplicationUtilities::Argument m_workingDirArg;
52  std::string m_testFilesPath;
53  std::string m_fallbackTestFilesPath;
54  std::string m_workingDir;
55  bool m_valid;
56  static TestApplication *m_instance;
57 };
58 
65 inline TestApplication::operator bool() const
66 {
67  return m_valid;
68 }
69 
74 {
75  return TestApplication::m_instance;
76 }
77 
81 inline const char *TestApplication::appPath()
82 {
83  return m_instance && m_instance->m_applicationPathArg.firstValue() ? m_instance->m_applicationPathArg.firstValue() : "";
84 }
85 
90 {
91  return m_unitsArg.isPresent();
92 }
93 
98 inline const std::vector<const char *> &TestApplication::units() const
99 {
100  return m_unitsArg.values();
101 }
102 
107 inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
108 {
109  return TestApplication::instance()->testFilePath(relativeTestFilePath);
110 }
111 
116 inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath)
117 {
118  return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, WorkingCopyMode::CreateCopy);
119 }
120 
125 inline CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode)
126 {
127  return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeTestFilePath, mode);
128 }
129 
135  const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode = WorkingCopyMode::CreateCopy)
136 {
137  return TestApplication::instance()->workingCopyPathAs(relativeTestFilePath, relativeWorkingCopyPath, mode);
138 }
139 
140 #ifdef PLATFORM_UNIX
141 
146 inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
147 {
148  return TestApplication::instance()->execApp(args, output, errors);
149 }
150 
151 CPP_UTILITIES_EXPORT int execHelperApp(
152  const char *appPath, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
153 #endif // PLATFORM_UNIX
154 
159 template <typename T> class AsHexNumber {
160 public:
162  AsHexNumber(const T &value)
163  : value(value)
164  {
165  }
166  const T &value;
167 };
168 
172 template <typename T> bool operator==(const AsHexNumber<T> &lhs, const AsHexNumber<T> &rhs)
173 {
174  return lhs.value == rhs.value;
175 }
176 
180 template <typename T> std::ostream &operator<<(std::ostream &out, const AsHexNumber<T> &value)
181 {
182  return out << '0' << 'x' << std::hex << std::setfill('0') << std::setw(2) << unsigned(value.value) << std::dec;
183 }
184 
189 template <typename T> AsHexNumber<T> asHexNumber(const T &value)
190 {
191  return AsHexNumber<T>(value);
192 }
193 
199 template <typename T, Traits::EnableIf<std::is_integral<T>> * = nullptr> AsHexNumber<T> integralsAsHexNumber(const T &value)
200 {
201  return AsHexNumber<T>(value);
202 }
203 
209 template <typename T, Traits::DisableIf<std::is_integral<T>> * = nullptr> const T &integralsAsHexNumber(const T &value)
210 {
211  return value;
212 }
213 
222 #define TESTUTILS_ASSERT_EXEC(args) \
223  { \
224  const auto returnCode = execApp(args, stdout, stderr); \
225  if (returnCode != 0) { \
226  CPPUNIT_FAIL( \
227  ::ConversionUtilities::argsToString("app failed with return code ", returnCode, "\nstdout: ", stdout, "\nstderr: ", stderr)); \
228  } \
229  }
230 
235 #define TESTUTILS_ASSERT_LIKE(message, expectedRegex, actualString) \
236  (CPPUNIT_NS::Asserter::failIf(!(std::regex_match(actualString, std::regex(expectedRegex))), \
237  CPPUNIT_NS::Message(ConversionUtilities::argsToString('\"', actualString, "\"\n not like\n\"", expectedRegex, '\"'), \
238  "Expression: " #actualString, message), \
239  CPPUNIT_SOURCELINE()))
240 
244 template <typename Pair, Traits::EnableIf<Traits::IsSpecializationOf<Pair, std::pair>> * = nullptr>
245 inline std::ostream &operator<<(std::ostream &out, const Pair &pair)
246 {
247  return out << "key: " << pair.first << "; value: " << pair.second << '\n';
248 }
249 
253 template <typename Iteratable, Traits::EnableIf<Traits::IsIteratable<Iteratable>, Traits::Not<Traits::IsString<Iteratable>>> * = nullptr>
254 inline std::ostream &operator<<(std::ostream &out, const Iteratable &iteratable)
255 {
256  out << '\n';
257  std::size_t index = 0;
258  for (const auto &item : iteratable) {
259  out << std::setw(2) << index << ':' << ' ' << integralsAsHexNumber(item) << '\n';
260  ++index;
261  }
262  return out;
263 }
264 
268 namespace Literals {
273 constexpr std::size_t operator"" _st(unsigned long long size)
274 {
275  return static_cast<std::size_t>(size);
276 }
277 
282 constexpr uint64 operator"" _uint64(unsigned long long size)
283 {
284  return static_cast<uint64>(size);
285 }
286 
291 constexpr int64 operator"" _int64(unsigned long long size)
292 {
293  return static_cast<int64>(size);
294 }
295 } // namespace Literals
296 } // namespace TestUtilities
297 
298 #endif // TESTUTILS_H
std::int64_t int64
signed 64-bit integer
Definition: types.h:29
bool unitsSpecified() const
Returns whether particular units have been specified.
Definition: testutils.h:89
#define CPP_UTILITIES_EXPORT
The TestApplication class simplifies writing test applications that require opening test files.
Definition: testutils.h:23
std::ostream & operator<<(std::ostream &out, const AsHexNumber< T > &value)
Provides the actual formatting of the output for AsHexNumber class.
Definition: testutils.h:180
CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &relativeTestFilePath, WorkingCopyMode mode)
Convenience function to invoke TestApplication::workingCopyPathMode().
Definition: testutils.h:125
AsHexNumber(const T &value)
Constructs a new instance; use asHexNumber() for convenience instead.
Definition: testutils.h:162
const char * firstValue() const
Returns the first parameter value of the first occurrence of the argument.
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:199
std::uint64_t uint64
unsigned 64-bit integer
Definition: types.h:49
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath)
Convenience function to invoke TestApplication::workingCopyPath().
Definition: testutils.h:116
static const char * appPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:81
std::string testFilePath(const std::string &relativeTestFilePath) const
Returns the full path of the test file with the specified relativeTestFilePath.
Definition: testutils.cpp:236
Contains classes and functions utilizing creating of test applications.
Definition: testutils.h:13
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:134
const std::vector< const char * > & values(std::size_t occurrence=0) const
Returns the parameter values for the specified occurrence of argument.
bool operator==(const AsHexNumber< T > &lhs, const AsHexNumber< T > &rhs)
Provides operator == required by CPPUNIT_ASSERT_EQUAL.
Definition: testutils.h:172
The Argument class is a wrapper for command line argument information.
const std::vector< const char * > & units() const
Returns the specified test units.
Definition: testutils.h:98
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:189
WorkingCopyMode
The WorkingCopyMode enum specifies additional options to influence behavior of TestApplication::worki...
Definition: testutils.h:18
bool isPresent() const
Returns an indication whether the argument could be detected when parsing.
The HelpArgument class prints help information for an argument parser when present (–help,...
static const TestApplication * instance()
Returns the current TestApplication instance.
Definition: testutils.h:73
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:296
The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using ...
Definition: testutils.h:159
The ArgumentParser class provides a means for handling command line arguments.
CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &relativeTestFilePath)
Convenience function to invoke TestApplication::testFilePath().
Definition: testutils.h:107