#pragma once #include #include #include #include #include #include namespace Qa { struct TestCase { std::string name; std::function function; }; inline std::vector ®istry() { static std::vector tests; return tests; } class Registrar { public: Registrar(const char *name, std::function function) { registry().push_back({name, std::move(function)}); } }; [[noreturn]] inline void fail(const char *expression, const char *file, int line) { std::ostringstream stream; stream << file << ':' << line << ": expectation failed: " << expression; throw std::runtime_error(stream.str()); } } #define QA_JOIN_IMPL(left, right) left##right #define QA_JOIN(left, right) QA_JOIN_IMPL(left, right) #define QA_TEST(suiteName, testName) \ static void QA_JOIN(qa_test_function_, __LINE__)(); \ static Qa::Registrar QA_JOIN(qa_test_registrar_, __LINE__)( \ #suiteName "." #testName, QA_JOIN(qa_test_function_, __LINE__)); \ static void QA_JOIN(qa_test_function_, __LINE__)() #define QA_EXPECT(expression) \ do \ { \ if (!(expression)) \ { \ Qa::fail(#expression, __FILE__, __LINE__); \ } \ } while (false) #define QA_EXPECT_EQ(actual, expected) \ do \ { \ const auto qaActualValue = (actual); \ const auto qaExpectedValue = (expected); \ if (!(qaActualValue == qaExpectedValue)) \ { \ Qa::fail(#actual " == " #expected, __FILE__, __LINE__); \ } \ } while (false)