52 lines
1.5 KiB
C++
52 lines
1.5 KiB
C++
#ifndef _test_common_n_
|
|
#define _test_common_n_
|
|
|
|
#pragma once
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
struct TestFailure : public std::runtime_error {
|
|
using std::runtime_error::runtime_error;
|
|
};
|
|
|
|
|
|
#define CHECK(cond, msg) do { if (!(cond)) throw TestFailure(msg); } while (0)
|
|
#define CHECK_EQ(a,b,msg) do { if (!((a)==(b))) { throw TestFailure(std::string(msg) + " (" #a " != " #b ")"); } } while (0)
|
|
|
|
#define TEST_CASE(name) \
|
|
static void name(); \
|
|
struct name##_registrar { name##_registrar(){ TestRegistry::add(#name, &name);} } name##_registrar_instance; \
|
|
static void name()
|
|
|
|
struct TestRegistry {
|
|
using Fn = void(*)();
|
|
static std::vector<std::pair<std::string, Fn>>& list() {
|
|
static std::vector<std::pair<std::string, Fn>> v; return v;
|
|
}
|
|
static void add(const std::string& name, Fn fn) { list().push_back({name, fn}); }
|
|
};
|
|
|
|
// Default test runner main()
|
|
#ifdef TEST_MAIN
|
|
int main() {
|
|
int fails = 0;
|
|
for (auto& t : TestRegistry::list()) {
|
|
try {
|
|
t.second();
|
|
//std::cout << "[PASS] " << t.first << "\n";
|
|
} catch (const TestFailure& e) {
|
|
std::cerr << "[FAIL] " << t.first << " -> " << e.what() << "\n";
|
|
++fails;
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "[ERROR] " << t.first << " -> " << e.what() << "\n";
|
|
++fails;
|
|
}
|
|
}
|
|
std::cout << (fails ? "Some tests failed ❌\n" : "All tests passed ✅\n");
|
|
return fails ? 1 : 0;
|
|
}
|
|
#endif
|
|
|
|
#endif // _test_common_n_
|