1 #ifndef WREPORT_TESTS_H
2 #define WREPORT_TESTS_H
72 std::string local_info;
75 : file(file_), line(line_), call(call_)
80 : file(file_), line(line_), call(call_), local_info(local_info_.str())
84 std::string format()
const;
86 void format(std::ostream& out)
const;
89 struct TestStack :
public std::vector<TestStackFrame>
111 template<
typename ...Args>
112 TestFailed(
const std::exception& e, Args&&... args)
115 add_stack_info(std::forward<Args>(args)...);
118 explicit TestFailed(
const std::string& message_) : message(message_) {}
120 template<
typename ...Args>
121 TestFailed(
const std::string& message_, Args&&... args)
124 add_stack_info(std::forward<Args>(args)...);
127 const char* what()
const noexcept
override {
return message.c_str(); }
129 template<
typename ...Args>
130 void add_stack_info(Args&&... args) { stack.emplace_back(std::forward<Args>(args)...); }
148 #define WREPORT_TEST_INFO(name) \
149 wreport::tests::LocationInfo wreport_test_location_info; \
150 wreport::tests::LocationInfo& name = wreport_test_location_info
162 void assert_true(
const A& actual)
165 std::stringstream ss;
166 ss <<
"actual value " << actual <<
" is not true";
170 [[noreturn]]
void assert_true(std::nullptr_t actual);
174 void assert_false(
const A& actual)
177 std::stringstream ss;
178 ss <<
"actual value " << actual <<
" is not false";
179 throw TestFailed(ss.str());
182 void assert_false(std::nullptr_t actual);
184 template<
typename LIST>
185 static inline void _format_list(std::ostream& o,
const LIST& list) {
188 for (
const auto& v: list)
200 void assert_equal(
const std::vector<T>& actual,
const std::vector<T>& expected)
202 if (actual == expected)
return;
203 std::stringstream ss;
205 _format_list(ss, actual);
206 ss <<
" is different than the expected ";
207 _format_list(ss, expected);
208 throw TestFailed(ss.str());
212 void assert_equal(
const std::vector<T>& actual,
const std::initializer_list<T>& expected)
214 if (actual == expected)
return;
215 std::stringstream ss;
217 _format_list(ss, actual);
218 ss <<
" is different than the expected ";
219 _format_list(ss, expected);
220 throw TestFailed(ss.str());
227 template<
typename A,
typename E>
228 void assert_equal(
const A& actual,
const E& expected)
230 if (actual == expected)
return;
231 std::stringstream ss;
232 ss <<
"value '" << actual <<
"' is different than the expected '" << expected <<
"'";
233 throw TestFailed(ss.str());
240 template<
typename A,
typename E>
241 void assert_not_equal(
const A& actual,
const E& expected)
243 if (actual != expected)
return;
244 std::stringstream ss;
245 ss <<
"value '" << actual <<
"' is not different than the expected '" << expected <<
"'";
246 throw TestFailed(ss.str());
250 template<
typename A,
typename E>
251 void assert_less(
const A& actual,
const E& expected)
253 if (actual < expected)
return;
254 std::stringstream ss;
255 ss <<
"value '" << actual <<
"' is not less than the expected '" << expected <<
"'";
256 throw TestFailed(ss.str());
260 template<
typename A,
typename E>
261 void assert_less_equal(
const A& actual,
const E& expected)
263 if (actual <= expected)
return;
264 std::stringstream ss;
265 ss <<
"value '" << actual <<
"' is not less than or equals to the expected '" << expected <<
"'";
266 throw TestFailed(ss.str());
270 template<
typename A,
typename E>
271 void assert_greater(
const A& actual,
const E& expected)
273 if (actual > expected)
return;
274 std::stringstream ss;
275 ss <<
"value '" << actual <<
"' is not greater than the expected '" << expected <<
"'";
276 throw TestFailed(ss.str());
280 template<
typename A,
typename E>
281 void assert_greater_equal(
const A& actual,
const E& expected)
283 if (actual >= expected)
return;
284 std::stringstream ss;
285 ss <<
"value '" << actual <<
"' is not greater than or equals to the expected '" << expected <<
"'";
286 throw TestFailed(ss.str());
290 void assert_startswith(
const std::string& actual,
const std::string& expected);
293 void assert_endswith(
const std::string& actual,
const std::string& expected);
296 void assert_contains(
const std::string& actual,
const std::string& expected);
299 void assert_not_contains(
const std::string& actual,
const std::string& expected);
307 void assert_re_matches(
const std::string& actual,
const std::string& expected);
315 void assert_not_re_matches(
const std::string& actual,
const std::string& expected);
322 Actual(
const A& actual) : _actual(actual) {}
329 void istrue()
const { assert_true(_actual); }
330 void isfalse()
const { assert_false(_actual); }
331 template<
typename E>
void operator==(
const E& expected)
const { assert_equal(_actual, expected); }
332 template<
typename E>
void operator!=(
const E& expected)
const { assert_not_equal(_actual, expected); }
333 template<
typename E>
void operator<(
const E& expected)
const {
return assert_less(_actual, expected); }
334 template<
typename E>
void operator<=(
const E& expected)
const {
return assert_less_equal(_actual, expected); }
335 template<
typename E>
void operator>(
const E& expected)
const {
return assert_greater(_actual, expected); }
336 template<
typename E>
void operator>=(
const E& expected)
const {
return assert_greater_equal(_actual, expected); }
344 void istrue()
const {
return assert_true(_actual); }
345 void isfalse()
const {
return assert_false(_actual); }
346 void operator==(
const char* expected)
const;
347 void operator==(
const std::string& expected)
const;
348 void operator!=(
const char* expected)
const;
349 void operator!=(
const std::string& expected)
const;
350 void operator<(
const std::string& expected)
const;
351 void operator<=(
const std::string& expected)
const;
352 void operator>(
const std::string& expected)
const;
353 void operator>=(
const std::string& expected)
const;
354 void startswith(
const std::string& expected)
const;
355 void endswith(
const std::string& expected)
const;
356 void contains(
const std::string& expected)
const;
357 void not_contains(
const std::string& expected)
const;
358 void matches(
const std::string& re)
const;
359 void not_matches(
const std::string& re)
const;
367 void operator==(
const std::vector<uint8_t>& expected)
const;
369 void operator!=(
const std::vector<uint8_t>& expected)
const;
370 void startswith(
const std::string& expected)
const;
371 void endswith(
const std::string& expected)
const;
372 void contains(
const std::string& expected)
const;
373 void not_contains(
const std::string& expected)
const;
374 void matches(
const std::string& re)
const;
375 void not_matches(
const std::string& re)
const;
386 void is(
const std::filesystem::path& expected)
const;
387 [[deprecated(
"Use path_startswith")]]
void startswith(
const std::string& data)
const;
389 void path_startswith(
const std::filesystem::path& expected)
const;
390 void path_endswith(
const std::filesystem::path& expected)
const;
391 void path_contains(
const std::filesystem::path& expected)
const;
392 void path_not_contains(
const std::filesystem::path& expected)
const;
395 void not_exists()
const;
397 void not_empty()
const;
399 void contents_startwith(
const std::string& data)
const;
400 void contents_equal(
const std::string& data)
const;
401 void contents_equal(
const std::vector<uint8_t>& data)
const;
402 void contents_equal(
const std::initializer_list<std::string>& lines)
const;
403 void contents_match(
const std::string& data_re)
const;
404 void contents_match(
const std::initializer_list<std::string>& lines_re)
const;
409 using Actual::Actual;
411 void almost_equal(
double expected,
unsigned places)
const;
412 void not_almost_equal(
double expected,
unsigned places)
const;
417 inline ActualCString actual(
const char* actual) {
return ActualCString(actual); }
418 inline ActualCString actual(
char* actual) {
return ActualCString(actual); }
419 inline ActualStdString actual(
const std::string& actual) {
return ActualStdString(actual); }
420 inline ActualStdString actual(
const std::vector<uint8_t>& actual) {
return ActualStdString(std::string(actual.begin(), actual.end())); }
421 inline ActualPath actual(
const std::filesystem::path& actual) {
return ActualPath(actual); }
422 inline ActualDouble actual(
double actual) {
return ActualDouble(actual); }
426 using Actual::Actual;
428 void throws(
const std::string& what_match)
const;
433 inline ActualPath actual_path(
const char* pathname) {
return ActualPath(pathname); }
434 inline ActualPath actual_path(
const std::string& pathname) {
return ActualPath(pathname); }
435 inline ActualPath actual_file(
const char* pathname) {
return ActualPath(pathname); }
436 inline ActualPath actual_file(
const std::string& pathname) {
return ActualPath(pathname); }
445 #define wassert(...) \
448 } catch (wreport::tests::TestFailed& e1) { \
449 e1.add_stack_info(__FILE__, __LINE__, #__VA_ARGS__, wreport_test_location_info); \
451 } catch (std::exception& e2) { \
452 throw wreport::tests::TestFailed(e2, __FILE__, __LINE__, #__VA_ARGS__, wreport_test_location_info); \
456 #define wassert_true(...) wassert(actual(__VA_ARGS__).istrue())
459 #define wassert_false(...) wassert(actual(__VA_ARGS__).isfalse())
466 #define wassert_throws(exc, ...) \
469 wfail_test(#__VA_ARGS__ " did not throw " #exc); \
470 } catch (TestFailed& e1) { \
472 } catch (exc& e2) { \
474 } catch (std::exception& e3) { \
475 std::string msg(#__VA_ARGS__ " did not throw " #exc " but threw "); \
476 msg += typeid(e3).name(); \
488 #define wcallchecked(func) \
491 } catch (wreport::tests::TestFailed& e) { \
492 e.add_stack_info(__FILE__, __LINE__, #func, wreport_test_location_info); \
494 } catch (std::exception& e) { \
495 throw wreport::tests::TestFailed(e, __FILE__, __LINE__, #func, wreport_test_location_info); \
501 #define wfail_test(msg) wassert(throw wreport::tests::TestFailed((msg)))
504 struct TestController;
506 struct TestCaseResult;
508 struct TestMethodResult;
532 TestMethod(
const std::string& name_, std::function<
void()> test_function_)
626 template<
typename ...Args>
629 methods.emplace_back(name_, test_function);
636 template<
typename ...Args>
639 methods.emplace_back(name_, test_function);
662 void test_teardown() {}
665 template<
typename Fixture,
typename... Args>
666 static inline Fixture* fixture_factory(Args... args)
674 template<
typename FIXTURE>
678 typedef FIXTURE Fixture;
680 Fixture* fixture =
nullptr;
681 std::function<Fixture*()> make_fixture;
683 template<
typename... Args>
687 make_fixture = std::bind(fixture_factory<FIXTURE, Args...>, args...);
697 fixture = make_fixture();
710 if (fixture) fixture->test_setup();
715 if (fixture) fixture->test_teardown();
723 template<
typename ...Args>
733 template<
typename ...Args>
734 TestMethod&
add_method(
const std::string& name_,
const std::string& doc, std::function<
void(FIXTURE&)> test_function)
Test case that includes a fixture.
Definition: utils/tests.h:676
void setup() override
Set up the test case before it is run.
Definition: utils/tests.h:694
void method_teardown(TestMethodResult &mr) override
Clean up after the test method is run.
Definition: utils/tests.h:713
void teardown() override
Clean up after the test case is run.
Definition: utils/tests.h:700
void method_setup(TestMethodResult &mr) override
Set up before the test method is run.
Definition: utils/tests.h:707
TestMethod & add_method(const std::string &name_, std::function< void(FIXTURE &)> test_function)
Register a new test method that takes a reference to the fixture as argument.
Definition: utils/tests.h:724
TestMethod & add_method(const std::string &name_, const std::string &doc, std::function< void(FIXTURE &)> test_function)
Register a new test method that takes a reference to the fixture as argument, including documentation...
Definition: utils/tests.h:734
String functions.
Definition: benchmark.h:13
Definition: utils/tests.h:340
Definition: utils/tests.h:408
Definition: utils/tests.h:425
Definition: utils/tests.h:379
Definition: utils/tests.h:363
Definition: utils/tests.h:320
Base class for test fixtures.
Definition: utils/tests.h:657
Add information to the test backtrace for the tests run in the current scope.
Definition: utils/tests.h:56
std::ostream & operator()()
Clear the current information and return the output stream to which new information can be sent.
Result of running a whole test case.
Definition: testrunner.h:97
Test case collecting several test methods, and self-registering with the singleton instance of TestRe...
Definition: utils/tests.h:542
TestMethod & add_method(const std::string &name_, const std::string &doc, std::function< void()> test_function)
Register a new test method, including documentation.
Definition: utils/tests.h:637
virtual TestCaseResult run_tests(TestController &controller)
Call setup(), run all the tests that have been registered, then call teardown().
virtual void register_tests()=0
This will be called before running the test case, to populate it with its test methods.
std::vector< TestMethod > methods
All registered test methods.
Definition: utils/tests.h:547
virtual void setup()
Set up the test case before it is run.
Definition: utils/tests.h:573
virtual void method_teardown(TestMethodResult &)
Clean up after the test method is run.
Definition: utils/tests.h:588
virtual void method_setup(TestMethodResult &)
Set up before the test method is run.
Definition: utils/tests.h:583
TestMethod & add_method(const std::string &name_, std::function< void()> test_function)
Register a new test method.
Definition: utils/tests.h:627
std::string name
Name of the test case.
Definition: utils/tests.h:544
bool tests_registered
Set to true the first time register_tests_once is run.
Definition: utils/tests.h:550
void register_tests_once()
Idempotent wrapper for register_tests()
virtual void teardown()
Clean up after the test case is run.
Definition: utils/tests.h:578
TestMethod & add_method(const std::string &name_)
Register a new test method, with the actual test function to be added later.
Definition: utils/tests.h:617
virtual TestMethodResult run_test(TestController &controller, TestMethod &method)
Run a test method.
Abstract interface for the objects that supervise test execution.
Definition: testrunner.h:159
Exception thrown when a test assertion fails, normally by Location::fail_test.
Definition: utils/tests.h:105
Result of running a test method.
Definition: testrunner.h:27
Test method information.
Definition: utils/tests.h:515
std::string name
Name of the test method.
Definition: utils/tests.h:517
std::function< void()> test_function
Main body of the test method.
Definition: utils/tests.h:527
std::string doc
Documentation attached to this test method.
Definition: utils/tests.h:520
Exception thrown when a test or a test case needs to be skipped.
Definition: utils/tests.h:137
Information about one stack frame in the test execution stack.
Definition: utils/tests.h:68
Definition: utils/tests.h:90
std::string backtrace() const
Return the formatted backtrace for this location.
void backtrace(std::ostream &out) const
Write the formatted backtrace for this location to out.