C++ Utilities  4.16.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 &name) const;
30  std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode) const;
31  std::string workingCopyPath(const std::string &name) const;
32 #ifdef PLATFORM_UNIX
33  int execApp(const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1) const;
34 #endif
35  bool unitsSpecified() const;
36  const std::vector<const char *> &units() const;
37  static const TestApplication *instance();
38  static const char *appPath();
39 
40 private:
41  static std::string readTestfilePathFromEnv();
42  static std::string readTestfilePathFromSrcRef();
43 
46  ApplicationUtilities::Argument m_testFilesPathArg;
47  ApplicationUtilities::Argument m_applicationPathArg;
48  ApplicationUtilities::Argument m_workingDirArg;
50  std::string m_testFilesPath;
51  std::string m_fallbackTestFilesPath;
52  std::string m_workingDir;
53  bool m_valid;
54  static TestApplication *m_instance;
55 };
56 
63 inline TestApplication::operator bool() const
64 {
65  return m_valid;
66 }
67 
72 {
73  return TestApplication::m_instance;
74 }
75 
79 inline const char *TestApplication::appPath()
80 {
81  return m_instance && m_instance->m_applicationPathArg.firstValue() ? m_instance->m_applicationPathArg.firstValue() : "";
82 }
83 
88 {
89  return m_unitsArg.isPresent();
90 }
91 
96 inline const std::vector<const char *> &TestApplication::units() const
97 {
98  return m_unitsArg.values();
99 }
100 
106 inline CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &name)
107 {
108  return TestApplication::instance()->testFilePath(name);
109 }
110 
116 inline CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &name)
117 {
119 }
120 
126 inline CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode)
127 {
128  return TestApplication::instance()->workingCopyPathMode(name, mode);
129 }
130 
131 #ifdef PLATFORM_UNIX
132 
137 inline CPP_UTILITIES_EXPORT int execApp(const char *const *args, std::string &output, std::string &errors)
138 {
139  return TestApplication::instance()->execApp(args, output, errors);
140 }
141 
142 CPP_UTILITIES_EXPORT int execHelperApp(
143  const char *appPath, const char *const *args, std::string &output, std::string &errors, bool suppressLogging = false, int timeout = -1);
144 #endif // PLATFORM_UNIX
145 
150 template <typename T> class AsHexNumber {
151 public:
153  AsHexNumber(const T &value)
154  : value(value)
155  {
156  }
157  const T &value;
158 };
159 
163 template <typename T> bool operator==(const AsHexNumber<T> &lhs, const AsHexNumber<T> &rhs)
164 {
165  return lhs.value == rhs.value;
166 }
167 
171 template <typename T> std::ostream &operator<<(std::ostream &out, const AsHexNumber<T> &value)
172 {
173  return out << '0' << 'x' << std::hex << std::setfill('0') << std::setw(2) << unsigned(value.value) << std::dec;
174 }
175 
180 template <typename T> AsHexNumber<T> asHexNumber(const T &value)
181 {
182  return AsHexNumber<T>(value);
183 }
184 
190 template <typename T, Traits::EnableIf<std::is_integral<T>> * = nullptr> AsHexNumber<T> integralsAsHexNumber(const T &value)
191 {
192  return AsHexNumber<T>(value);
193 }
194 
200 template <typename T, Traits::DisableIf<std::is_integral<T>> * = nullptr> const T &integralsAsHexNumber(const T &value)
201 {
202  return value;
203 }
204 
213 #define TESTUTILS_ASSERT_EXEC(args) \
214  { \
215  const auto returnCode = execApp(args, stdout, stderr); \
216  if (returnCode != 0) { \
217  CPPUNIT_FAIL( \
218  ::ConversionUtilities::argsToString("app failed with return code ", returnCode, "\nstdout: ", stdout, "\nstderr: ", stderr)); \
219  } \
220  }
221 
226 #define TESTUTILS_ASSERT_LIKE(message, expectedRegex, actualString) \
227  (CPPUNIT_NS::Asserter::failIf(!(std::regex_match(actualString, std::regex(expectedRegex))), \
228  CPPUNIT_NS::Message(ConversionUtilities::argsToString('\"', actualString, "\"\n not like\n\"", expectedRegex, '\"'), \
229  "Expression: " #actualString, message), \
230  CPPUNIT_SOURCELINE()))
231 
235 template <typename Pair, Traits::EnableIf<Traits::IsSpecializationOf<Pair, std::pair>> * = nullptr>
236 inline std::ostream &operator<<(std::ostream &out, const Pair &pair)
237 {
238  return out << "key: " << pair.first << "; value: " << pair.second << '\n';
239 }
240 
244 template <typename Iteratable, Traits::EnableIf<Traits::IsIteratable<Iteratable>, Traits::Not<Traits::IsString<Iteratable>>> * = nullptr>
245 inline std::ostream &operator<<(std::ostream &out, const Iteratable &iteratable)
246 {
247  out << '\n';
248  std::size_t index = 0;
249  for (const auto &item : iteratable) {
250  out << std::setw(2) << index << ':' << ' ' << integralsAsHexNumber(item) << '\n';
251  ++index;
252  }
253  return out;
254 }
255 
259 namespace Literals {
264 constexpr std::size_t operator"" _st(unsigned long long size)
265 {
266  return static_cast<std::size_t>(size);
267 }
268 
273 constexpr uint64 operator"" _uint64(unsigned long long size)
274 {
275  return static_cast<uint64>(size);
276 }
277 
282 constexpr int64 operator"" _int64(unsigned long long size)
283 {
284  return static_cast<int64>(size);
285 }
286 } // namespace Literals
287 } // namespace TestUtilities
288 
289 #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:87
std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode) const
Returns the full path to a working copy of the test file with the specified name. ...
Definition: testutils.cpp:269
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:171
AsHexNumber(const T &value)
Constructs a new instance; use asHexNumber() for convenience instead.
Definition: testutils.h:153
std::string testFilePath(const std::string &name) const
Returns the full path of the test file with the specified name.
Definition: testutils.cpp:235
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:190
std::uint64_t uint64
unsigned 64-bit integer
Definition: types.h:49
std::string workingCopyPath(const std::string &name) const
Creates a working copy of the test file with the specified name and returns the full path of the crea...
Definition: testutils.cpp:359
static const char * appPath()
Returns the application path or an empty string if no application path has been set.
Definition: testutils.h:79
Contains classes and functions utilizing creating of test applications.
Definition: testutils.h:13
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:163
The Argument class is a wrapper for command line argument information.
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &name)
Convenience function which returns the full path to a working copy of the test file with the specifie...
Definition: testutils.h:116
const std::vector< const char * > & units() const
Returns the specified test units.
Definition: testutils.h:96
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:180
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:71
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
The AsHexNumber class allows printing values asserted with cppunit (or similar test framework) using ...
Definition: testutils.h:150
CPP_UTILITIES_EXPORT std::string testFilePath(const std::string &name)
Convenience function which returns the full path of the test file with the specified name...
Definition: testutils.h:106
The ArgumentParser class provides a means for handling command line arguments.
CPP_UTILITIES_EXPORT std::string workingCopyPathMode(const std::string &name, WorkingCopyMode mode)
Convenience function which returns the full path to a working copy of the test file with the specifie...
Definition: testutils.h:126