2024-08-01 17:56:38 +00:00
|
|
|
#pragma once
|
|
|
|
|
2024-08-02 22:27:36 +00:00
|
|
|
#include <algorithm>
|
2024-08-01 17:56:38 +00:00
|
|
|
#include <cstdint>
|
2024-08-02 22:27:36 +00:00
|
|
|
#include <cstdio>
|
|
|
|
|
|
|
|
#include "common.hpp"
|
|
|
|
#include "result.hpp"
|
2024-08-01 17:56:38 +00:00
|
|
|
|
|
|
|
const uint64_t MAX_TESTS = 1024 * 1024;
|
|
|
|
static void (*tests[MAX_TESTS])() = {0};
|
|
|
|
|
|
|
|
const char* add_test(void (*fun)(void)) {
|
|
|
|
for (uint64_t i = 0; i < MAX_TESTS; ++i) {
|
|
|
|
if (tests[i] == 0) {
|
|
|
|
tests[i] = fun;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool run_tests() {
|
|
|
|
for (uint64_t i = 0; i < MAX_TESTS; ++i) {
|
|
|
|
if (tests[i] == 0) break;
|
|
|
|
|
|
|
|
tests[i]();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CONCAT_IMPL(x, y) x##y
|
|
|
|
#define MACRO_CONCAT(x, y) CONCAT_IMPL(x, y)
|
|
|
|
|
|
|
|
#define TEST_CASE_IMPL(ID, ...) \
|
|
|
|
static void ID(); \
|
|
|
|
static const char* MACRO_CONCAT(test_id_, __COUNTER__) [[maybe_unused]] = \
|
|
|
|
add_test(&ID); \
|
|
|
|
void ID()
|
|
|
|
|
|
|
|
#define TEST_CASE(fun_) TEST_CASE_IMPL(MACRO_CONCAT(fun_, _COUNTER_))
|
|
|
|
|
2024-08-02 22:27:36 +00:00
|
|
|
template <class T>
|
|
|
|
struct Capture {
|
|
|
|
Capture(T& value) : value(value) {}
|
|
|
|
T& value;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
struct Capture<T&> {
|
|
|
|
Capture(T& value) : value(value) {}
|
|
|
|
T& value;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
struct Capture<T&&> {
|
|
|
|
Capture(T&& value) : value(value) {}
|
|
|
|
T value;
|
|
|
|
};
|
|
|
|
|
|
|
|
Value& to_value(Arena& arena, Value& val) { return val; }
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
requires std::derived_from<T, Object>
|
|
|
|
Value to_value(Arena& arena, T& val) {
|
|
|
|
return DIEX(val.copy(arena));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
requires(!std::derived_from<T, Object>)
|
|
|
|
Value to_value(Arena& arena, T& val) {
|
|
|
|
return DIEX(Value::create(arena, val));
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ASSERT_EQUALS(lhs, rhs) \
|
|
|
|
do { \
|
|
|
|
auto l = Capture(lhs); \
|
|
|
|
auto r = Capture(rhs); \
|
|
|
|
auto lv = to_value(arena, l.value); \
|
|
|
|
auto rv = to_value(arena, r.value); \
|
2024-08-03 12:43:59 +00:00
|
|
|
short c = DIEX(lv.cmp(arena, rv)); \
|
2024-08-02 22:27:36 +00:00
|
|
|
if (c != 0) { \
|
|
|
|
fprintf(stderr, "Values not equal at %s:%d\n", __FILE__, __LINE__); \
|
|
|
|
debug_print(arena, lv); \
|
|
|
|
debug_print(arena, rv); \
|
|
|
|
exit(EXIT_FAILURE); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2024-08-01 17:56:38 +00:00
|
|
|
int main() { return run_tests() ? 0 : 1; }
|