86 lines
2.5 KiB
C++
86 lines
2.5 KiB
C++
#pragma once
|
|
#include <cstdio>
|
|
#include <cmath>
|
|
#include <chrono>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <plot/core/types.hpp>
|
|
|
|
using plot::f32;
|
|
using plot::f64;
|
|
using plot::u32;
|
|
using plot::u64;
|
|
|
|
namespace plottest {
|
|
|
|
struct Case {
|
|
const char* name;
|
|
std::function<void()> fn;
|
|
};
|
|
|
|
inline std::vector<Case>& cases() {
|
|
static std::vector<Case> c;
|
|
return c;
|
|
}
|
|
|
|
struct Reg {
|
|
Reg(const char* n, std::function<void()> f) { cases().push_back({n, std::move(f)}); }
|
|
};
|
|
|
|
struct Failure {
|
|
std::string msg;
|
|
};
|
|
|
|
/// Compares two doubles within `eps`. `PLOT_CHECK_NEAR(a, b)` leaves it to the
|
|
/// default below; pass an explicit tolerance for computed values.
|
|
inline constexpr double kNearEps = 1e-9;
|
|
|
|
inline void check_near(double a, double b, double eps, const char* file, int line,
|
|
const char* lhs, const char* rhs) {
|
|
if (!(std::fabs(a - b) <= eps)) {
|
|
throw Failure{std::string(file) + ":" + std::to_string(line) + " CHECK_NEAR(" + lhs + ", " +
|
|
rhs + ") got " + std::to_string(a) + " vs " + std::to_string(b)};
|
|
}
|
|
}
|
|
|
|
inline void check_near(double a, double b, const char* file, int line, const char* lhs,
|
|
const char* rhs) {
|
|
check_near(a, b, kNearEps, file, line, lhs, rhs);
|
|
}
|
|
|
|
inline int run_all() {
|
|
int failed = 0;
|
|
for (auto& c : cases()) {
|
|
try {
|
|
c.fn();
|
|
std::printf("[ ok ] %s\n", c.name);
|
|
} catch (const Failure& f) {
|
|
std::printf("[FAIL] %s: %s\n", c.name, f.msg.c_str());
|
|
++failed;
|
|
}
|
|
}
|
|
std::printf("%zu cases, %d failed\n", cases().size(), failed);
|
|
return failed == 0 ? 0 : 1;
|
|
}
|
|
|
|
} // namespace plottest
|
|
|
|
#define PLOT_TEST(name) \
|
|
static void name(); \
|
|
static ::plottest::Reg reg_##name(#name, name); \
|
|
static void name()
|
|
|
|
#define PLOT_CHECK(cond) \
|
|
do { \
|
|
if (!(cond)) \
|
|
throw ::plottest::Failure{std::string(__FILE__) + ":" + std::to_string(__LINE__) + \
|
|
" CHECK(" #cond ")"}; \
|
|
} while (0)
|
|
|
|
#define PLOT_CHECK_NEAR(a, b, ...) \
|
|
::plottest::check_near((a), (b) __VA_OPT__(,) __VA_ARGS__, __FILE__, __LINE__, #a, #b)
|