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.
This commit is contained in:
parent
c1fa39cd8c
commit
89424a914e
91
include/mtl/test.hpp
Normal file
91
include/mtl/test.hpp
Normal file
@ -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 <typename SUITE_TYPE>
|
||||||
|
class suite {
|
||||||
|
public:
|
||||||
|
using TEST_TYPE = bool (*)();
|
||||||
|
|
||||||
|
vector<TEST_TYPE, 256> m_tests;
|
||||||
|
vector<string_view, 256> 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
|
||||||
@ -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<isuite*, 256> suites;
|
|
||||||
|
|
||||||
template <typename SUITE_TYPE>
|
|
||||||
struct suite : public isuite {
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
friend void run_test_suite();
|
|
||||||
|
|
||||||
using TEST_TYPE = int32_t (SUITE_TYPE::*)();
|
|
||||||
|
|
||||||
static SUITE_TYPE s_instance;
|
|
||||||
|
|
||||||
SUITE_TYPE* m_suite;
|
|
||||||
vector<TEST_TYPE, 256> m_tests;
|
|
||||||
vector<string_view, 256> 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 <typename SUITE_TYPE>
|
|
||||||
SUITE_TYPE suite<SUITE_TYPE>::s_instance;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void run_test_suite() {
|
|
||||||
suite<T>::s_instance->run_tests();
|
|
||||||
}
|
|
||||||
|
|
||||||
void run_all_suites();
|
|
||||||
isuite* get_suite(const string_view& name);
|
|
||||||
|
|
||||||
} // namespace test
|
|
||||||
|
|
||||||
} // namespace mtl
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#include "mtl/test.hpp"
|
|
||||||
|
|
||||||
#include "mtl/log.hpp"
|
|
||||||
|
|
||||||
namespace mtl {
|
|
||||||
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
vector<isuite*, 256> 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
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user