nac3/nac3core/irrt/test/core.hpp

143 lines
4.1 KiB
C++

#pragma once
// Include this header for every test_*.cpp
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <test/print.hpp>
// Some utils can be used here
#include <irrt/utils.hpp>
void __begin_test(const char* function_name, const char* file, int line) {
printf("######### Running %s @ %s:%d\n", function_name, file, line);
}
#define BEGIN_TEST() __begin_test(__FUNCTION__, __FILE__, __LINE__)
void test_fail() {
printf("[!] Test failed. Exiting with status code 1.\n");
exit(1);
}
void print_assertion_passed(const char* file, int line) {
printf("[*] Assertion passed on %s:%d\n", file, line);
}
void print_assertion_failed(const char* file, int line) {
printf("[!] Assertion failed on %s:%d\n", file, line);
}
void __assert_true(const char* file, int line, bool cond) {
if (cond) {
print_assertion_passed(file, line);
} else {
print_assertion_failed(file, line);
test_fail();
}
}
#define assert_true(cond) __assert_true(__FILE__, __LINE__, cond)
template <typename T>
void __assert_arrays_match(const char* file, int line, int len, const T* expected, const T* got) {
if (arrays_match(len, expected, got)) {
print_assertion_passed(file, line);
} else {
print_assertion_failed(file, line);
printf("Expect = ");
print_array(len, expected);
printf("\n");
printf(" Got = ");
print_array(len, got);
printf("\n");
test_fail();
}
}
#define assert_arrays_match(len, expected, got) __assert_arrays_match(__FILE__, __LINE__, len, expected, got)
template <typename T>
void __assert_values_match(const char* file, int line, T expected, T got) {
if (expected == got) {
print_assertion_passed(file, line);
} else {
print_assertion_failed(file, line);
printf("Expect = ");
print_value(expected);
printf("\n");
printf(" Got = ");
print_value(got);
printf("\n");
test_fail();
}
}
#define assert_values_match(expected, got) __assert_values_match(__FILE__, __LINE__, expected, got)
// A fake set of ErrorIds for testing only
const ErrorIds TEST_ERROR_IDS = {
.index_error = 0,
.value_error = 1,
.assertion_error = 2,
.runtime_error = 3,
};
ErrorContext create_testing_errctx() {
// Everything is global so it is fine to directly return a struct ErrorContext
ErrorContext errctx;
errctx.initialize(&TEST_ERROR_IDS);
return errctx;
}
void print_errctx_content(ErrorContext* errctx) {
if (errctx->has_error()) {
printf(
"(Error ID %d): %s ... where param1 = %ld, param2 = %ld, param3 = %ld\n",
errctx->error_id,
errctx->message_template,
errctx->param1,
errctx->param2,
errctx->param3
);
} else {
printf("<no error>\n");
}
}
void __assert_errctx_no_error(const char* file, int line, ErrorContext* errctx) {
if (errctx->has_error()) {
print_assertion_failed(file, line);
printf("Expecting no error but caught the following:\n\n");
print_errctx_content(errctx);
test_fail();
}
}
#define assert_errctx_no_error(errctx) __assert_errctx_no_error(__FILE__, __LINE__, errctx)
void __assert_errctx_has_error(const char* file, int line, ErrorContext *errctx, ErrorId expected_error_id) {
if (errctx->has_error()) {
if (errctx->error_id == expected_error_id) {
// OK
} else {
// Otherwise it got the wrong kind of error
print_assertion_failed(file, line);
printf(
"Expecting error id %d but got error id %d. Error caught:\n\n",
expected_error_id,
errctx->error_id
);
print_errctx_content(errctx);
test_fail();
}
} else {
print_assertion_failed(file, line);
printf("Expecting an error, but there is none.");
test_fail();
}
}
#define assert_errctx_has_error(errctx, expected_error_id) __assert_errctx_has_error(__FILE__, __LINE__, errctx, expected_error_id)