From 89424a914e79d276923e624b5cf3a9f85383b0f6 Mon Sep 17 00:00:00 2001 From: Madeline Busig Date: Sun, 18 Aug 2024 23:53:16 -0700 Subject: [PATCH] Rewrite test framework This new framework does not automatically register test suites, but it is much simpler to use. I might revisit the old approach later, but for now this works, KISS. --- include/mtl/test.hpp | 91 ++++++++++++++++++++++++++++++++++ include/test/mtl/test.hpp | 101 -------------------------------------- src/test/test.cpp | 35 ------------- 3 files changed, 91 insertions(+), 136 deletions(-) create mode 100644 include/mtl/test.hpp delete mode 100644 include/test/mtl/test.hpp delete mode 100644 src/test/test.cpp diff --git a/include/mtl/test.hpp b/include/mtl/test.hpp new file mode 100644 index 0000000..f7a50ca --- /dev/null +++ b/include/mtl/test.hpp @@ -0,0 +1,91 @@ +#pragma once + +#ifdef __GBA__ + +#ifndef REG_TM2D +#define REG_TM2D *(volatile uint32_t*)(0x04000108) +#endif + +#ifndef REG_TM2CNT +#define REG_TM2CNT *(volatile uint32_t*)(0x0400010A) +#endif + +#ifndef TM_ENABLE +#define TM_ENABLE 0x80 +#endif + +#endif + +#include "mtl/log.hpp" +#include "mtl/string_view.hpp" +#include "mtl/vector.hpp" + +namespace mtl { + +namespace test { + +template +class suite { +public: + using TEST_TYPE = bool (*)(); + + vector m_tests; + vector m_test_names; + + virtual string_view name() = 0; + + void add_test(TEST_TYPE test, const string_view& name) { + m_tests.push_back(test); + m_test_names.push_back(name); + } + + static bool run_tests() { + log::info << "=========================" << endl; + log::info << "Running suite \"" << instance().name() << '\"' << endl; + log::info << endl; + + size_t num_ok = 0; + size_t num_fail = 0; + + for (size_t i = 0; i < instance().m_tests.size(); ++i) { + TEST_TYPE test = instance().m_tests[i]; + string_view name = instance().m_test_names[i]; + + log::info << "Running \"" << name << "\"..." << endl; + + uint16_t time = 0; + +#ifdef __GBA__ + REG_TM2D = 0; + REG_TM2CNT = TM_ENABLE; +#endif + bool result = (test)(); +#ifdef __GBA__ + time = REG_TM2D; + REG_TM2CNT = ~TM_ENABLE; +#endif + + log::info << (result ? "OK" : "FAILED") << ", TIME: " << time << endl; + + if (result) { ++num_ok; } + else { ++num_fail; } + } + + + log::info << endl; + log::info << "Finished. Tests OK: " << num_ok << '/' << num_ok + num_fail << endl; + log::info << (num_fail == 0 ? "ALL OK" : "FAILED") << endl; + log::info << "=========================" << endl; + + return num_fail == 0; + } + + static SUITE_TYPE& instance() { + static SUITE_TYPE instance; + return instance; + } +}; + +} // namespace test + +} // namespace mtl diff --git a/include/test/mtl/test.hpp b/include/test/mtl/test.hpp deleted file mode 100644 index a4107bc..0000000 --- a/include/test/mtl/test.hpp +++ /dev/null @@ -1,101 +0,0 @@ -#ifdef __GBA__ -#define REG_TM2D *(volatile uint32_t*)(0x04000108) -#define REG_TM2CNT *(volatile uint32_t*)(0x0400010A) -#define TM_ENABLE 0x80 -#endif - -#include "mtl/log.hpp" -#include "mtl/string_view.hpp" -#include "mtl/vector.hpp" - -namespace mtl { - -namespace test { - -class isuite { -public: - virtual string_view name() const = 0; - virtual bool run_tests() = 0; -}; - -extern mtl::vector suites; - -template -struct suite : public isuite { -private: - template - friend void run_test_suite(); - - using TEST_TYPE = int32_t (SUITE_TYPE::*)(); - - static SUITE_TYPE s_instance; - - SUITE_TYPE* m_suite; - vector m_tests; - vector m_test_names; - -protected: - suite() { - suites.push_back(&s_instance); - } - -public: - void add_test(TEST_TYPE test, string_view name) { - m_tests.push_back(test); - m_test_names.push_back(name); - } - - bool run_tests() override { - log::info << "=========================" << endl; - log::info << "Running suite \"" << name() << '\"' << endl; - log::info << endl; - - int32_t num_ok = 0; - int32_t num_fail = 0; - - for (size_t i = 0; i < m_tests.size(); ++i) { - log::info << "Running \"" << m_test_names[i] - << "\"..." << endl; - - TEST_TYPE test = m_tests[i]; - uint16_t time = 0; - -#ifdef __GBA__ - REG_TM2D = 0; - REG_TM2CNT = TM_ENABLE; -#endif - int32_t result = (s_instance.*test)(); -#ifdef __GBA__ - time = REG_TM2D; - REG_TM2CNT = ~TM_ENABLE; -#endif - - log::info << (result == 0 ? "OK (" : "FAILED (") << result << "), TIME: " << time << endl; - - if (result == 0) { ++num_ok; } - else { ++num_fail; } - } - - - log::info << endl; - log::info << "Finished. Tests OK: " << num_ok << '/' << m_tests.size() << endl; - log::info << "=========================" << endl; - - return num_fail == 0; - } -}; - -template -SUITE_TYPE suite::s_instance; - -template -void run_test_suite() { - suite::s_instance->run_tests(); -} - -void run_all_suites(); -isuite* get_suite(const string_view& name); - -} // namespace test - -} // namespace mtl diff --git a/src/test/test.cpp b/src/test/test.cpp deleted file mode 100644 index 515ff13..0000000 --- a/src/test/test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "mtl/test.hpp" - -#include "mtl/log.hpp" - -namespace mtl { - -namespace test { - -vector suites; - -void run_all_suites() { - log::info << "=========================" << endl; - log::info << "RUNNING " << suites.size() << " TEST SUITES" << endl; - log::info << "=========================" << endl; - log::info << endl; - - for (isuite* suite : suites) { - suite->run_tests(); - } -} - -isuite* get_suite(const string_view& name) { - for (isuite* suite : suites) { - if (suite->name() == name) { - return suite; - } - } - - return nullptr; -} - -} // namespace test - -} // namespace mtl -