55struct LocationInfo :
public std::stringstream
72 std::string local_info;
74 TestStackFrame(
const char* file_,
int line_,
const char* call_)
75 : file(file_), line(line_), call(call_)
79 TestStackFrame(
const char* file_,
int line_,
const char* call_,
const LocationInfo& local_info_)
80 : file(file_), line(line_), call(call_), local_info(local_info_.str())
84 std::string format()
const;
86 void format(std::ostream& out)
const;
89struct TestStack :
public std::vector<TestStackFrame>
104struct TestFailed :
public std::exception
109 explicit TestFailed(
const std::exception& e);
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)
122 : TestFailed(message_)
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)...); }
136struct TestSkipped :
public std::exception
141 explicit TestSkipped(
const std::string& reason);
148#define WREPORT_TEST_INFO(name) \
149 wreport::tests::LocationInfo wreport_test_location_info; \
150 wreport::tests::LocationInfo& name = wreport_test_location_info
162void 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);
174void assert_false(
const A& actual)
177 std::stringstream ss;
178 ss <<
"actual value " << actual <<
" is not false";
179 throw TestFailed(ss.str());
182void assert_false(std::nullptr_t actual);
184template<
typename LIST>
185static inline void _format_list(std::ostream& o,
const LIST& list) {
188 for (
const auto& v: list)
200void 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);
212void 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);
227template<
typename A,
typename E>
228void 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 <<
"'";
240template<
typename A,
typename E>
241void 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 <<
"'";
250template<
typename A,
typename E>
251void 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 <<
"'";
260template<
typename A,
typename E>
261void 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 <<
"'";
270template<
typename A,
typename E>
271void 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 <<
"'";
280template<
typename A,
typename E>
281void 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 <<
"'";
290void assert_startswith(
const std::string& actual,
const std::string& expected);
293void assert_endswith(
const std::string& actual,
const std::string& expected);
296void assert_contains(
const std::string& actual,
const std::string& expected);
299void assert_not_contains(
const std::string& actual,
const std::string& expected);
307void assert_re_matches(
const std::string& actual,
const std::string& expected);
315void assert_not_re_matches(
const std::string& actual,
const std::string& expected);
322 Actual(
const A& actual) : _actual(actual) {}
323 Actual(
const Actual&) =
default;
324 Actual(Actual&&) =
default;
326 Actual& operator=(
const Actual&) =
delete;
327 Actual& operator=(Actual&&) =
delete;
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); }
342 ActualCString(
const char* s) : _actual(s) {}
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;
362struct ActualStdString :
public Actual<std::string>
364 explicit ActualStdString(
const std::string& s) : Actual<std::string>(s) {}
366 using Actual<std::string>::operator==;
367 void operator==(
const std::vector<uint8_t>& expected)
const;
368 using Actual<std::string>::operator!=;
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;
378struct ActualPath :
public Actual<std::filesystem::path>
380 explicit ActualPath(
const std::filesystem::path& p) : Actual<std::filesystem::path>(p) {}
382 using Actual<std::filesystem::path>::operator==;
383 using Actual<std::filesystem::path>::operator!=;
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;
417inline ActualCString actual(
const char* actual) {
return ActualCString(actual); }
418inline ActualCString actual(
char* actual) {
return ActualCString(actual); }
426 using Actual::Actual;
428 void throws(
const std::string& what_match)
const;
433inline ActualPath actual_path(
const char* pathname) {
return ActualPath(pathname); }
434inline ActualPath actual_path(
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)))
529 TestMethod(
const std::string& name_)
532 TestMethod(
const std::string& name_, std::function<
void()> test_function_)
553 TestCase(
const std::string&
name);
554 virtual ~TestCase() {}
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() {}
665template<
typename Fixture,
typename... Args>
666static inline Fixture* fixture_factory(Args... args)
674template<
typename FIXTURE>
675class FixtureTestCase :
public TestCase
678 typedef FIXTURE Fixture;
680 Fixture* fixture =
nullptr;
681 std::function<Fixture*()> make_fixture;
683 template<
typename... Args>
684 FixtureTestCase(
const std::string& name_, Args... args)
687 make_fixture = std::bind(fixture_factory<FIXTURE, Args...>, args...);
689 FixtureTestCase(
const FixtureTestCase&) =
delete;
690 FixtureTestCase(FixtureTestCase&&) =
delete;
691 FixtureTestCase& operator=(
const FixtureTestCase&) =
delete;
692 FixtureTestCase& operator=(FixtureTestCase&) =
delete;
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)
void setup() override
Set up the test case before it is run.
Definition utils/tests.h:694
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
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_, 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: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
virtual TestCaseResult run_tests(TestController &controller)
Call setup(), run all the tests that have been registered, then call teardown().
TestMethod & add_method(const std::string &name_, std::function< void()> test_function)
Register a new test method.
Definition utils/tests.h:627
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
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 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
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
virtual TestMethodResult run_test(TestController &controller, TestMethod &method)
Run a test method.
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
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
Test registry.
Definition testrunner.h:248
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.