From 59cc5384defab6cb7a949589032963ff3965edfe Mon Sep 17 00:00:00 2001 From: johannst Date: Sun, 14 Mar 2021 21:28:21 +0100 Subject: test: Improve type-safety of test fns. --- test/checker.cc | 14 +++++------ test/test_helper.h | 72 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/test/checker.cc b/test/checker.cc index 2a06666..d5afa87 100644 --- a/test/checker.cc +++ b/test/checker.cc @@ -58,11 +58,11 @@ void check_exceed_len() { int main() { TEST_INIT; - TEST(check_dec); - TEST(check_hex); - TEST(check_ptr); - TEST(check_null); - TEST(check_exact_len); - TEST(check_exceed_len); - return TEST_FAIL_CNT; + TEST_ADD(check_dec); + TEST_ADD(check_hex); + TEST_ADD(check_ptr); + TEST_ADD(check_null); + TEST_ADD(check_exact_len); + TEST_ADD(check_exceed_len); + return TEST_RUN; } 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 #include +#include +#include #include -/* 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 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(expected), have); } +template<> void ASSERT_EQ(char* expected, char* have) { ASSERT_EQ(static_cast(expected), static_cast(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 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 fn; + }; + + std::vector mTests{}; +}; + +#define TEST_INIT Runner r; +#define TEST_ADD(fn) r.addTest(#fn, fn); +#define TEST_RUN r.runTests(); -- cgit v1.2.3