diff options
author | johannst <johannes.stoelp@gmail.com> | 2021-03-14 21:28:21 +0100 |
---|---|---|
committer | johannst <johannes.stoelp@gmail.com> | 2021-03-14 21:28:21 +0100 |
commit | 59cc5384defab6cb7a949589032963ff3965edfe (patch) | |
tree | d51a1465c53177c9f221904fc37a53d60c54653a /test/test_helper.h | |
parent | 877b4b9889a3ba5e935373580fefaf9d747001ec (diff) | |
download | dynld-59cc5384defab6cb7a949589032963ff3965edfe.tar.gz dynld-59cc5384defab6cb7a949589032963ff3965edfe.zip |
test: Improve type-safety of test fns.
Diffstat (limited to 'test/test_helper.h')
-rw-r--r-- | test/test_helper.h | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/test/test_helper.h b/test/test_helper.h index 43cfce9..b78d9a6 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -3,23 +3,26 @@ #pragma once #include <cstring> #include <exception> +#include <functional> +#include <vector> #include <iostream> -/* Extremely trivial helper, just to get some tests out. */ +// Extremely trivial helper, just to get some tests out. struct TestFailed : std::exception {}; -/* Requirements - * T1: comparable + printable (stream operator) - * T2: comparable + printable (stream operator) - */ +// Value based ASSERT_* helper. +// +// Requirements: +// T1: comparable + printable (stream operator) +// T2: comparable + printable (stream operator) template<typename T1, typename T2> void ASSERT_EQ(T1 expected, T2 have) { if (expected != have) { std::cerr << "ASSERT_EQ failed:\n" - << " expected: " << expected << "\n" - << " have : " << have << "\n" + << " expected: " << expected << '\n' + << " have : " << have << '\n' << std::flush; throw TestFailed{}; } @@ -30,12 +33,14 @@ void ASSERT_EQ(T1* expected, T2* have) { ASSERT_EQ(*expected, *have); } +// Char string based ASSERT_* helper. + template<> void ASSERT_EQ(const char* expected, const char* have) { if (std::strcmp(expected, have) != 0) { std::cerr << "ASSERT_EQ failed:\n" - << " expected: " << expected << "\n" - << " have : " << have << "\n" + << " expected: " << expected << '\n' + << " have : " << have << '\n' << std::flush; throw TestFailed{}; } @@ -51,23 +56,42 @@ void ASSERT_EQ(char* expected, const char* have) { ASSERT_EQ(static_cast<const char*>(expected), have); } +template<> void ASSERT_EQ(char* expected, char* have) { ASSERT_EQ(static_cast<const char*>(expected), static_cast<const char*>(have)); } -#define TEST_INIT unsigned fail_cnt = 0; -#define TEST_FAIL_CNT fail_cnt - -#define TEST(fn) \ - { \ - try { \ - fn(); \ - std::cerr << "SUCCESS " #fn << std::endl; \ - } catch (TestFailed&) { \ - ++fail_cnt; \ - std::cerr << "FAIL " #fn << std::endl; \ - } catch (...) { \ - ++fail_cnt; \ - std::cerr << "FAIL " #fn << "(caught unspecified exception)" << std::endl; \ - } \ +// Simple test runner abstraction. + +struct Runner { + void addTest(const char* name, std::function<void()> fn) { mTests.push_back(Test{name, fn}); } + + int runTests() { + unsigned fail_cnt = 0; + for (auto test : mTests) { + try { + test.fn(); + std::cerr << "SUCCESS " << test.name << std::endl; + } catch (TestFailed&) { + ++fail_cnt; + std::cerr << "FAIL " << test.name << std::endl; + } catch (...) { + ++fail_cnt; + std::cerr << "FAIL " << test.name << "(caught unspecified exception)" << std::endl; + } + } + return fail_cnt; } + + private: + struct Test { + const char* name; + std::function<void()> fn; + }; + + std::vector<Test> mTests{}; +}; + +#define TEST_INIT Runner r; +#define TEST_ADD(fn) r.addTest(#fn, fn); +#define TEST_RUN r.runTests(); |