#ifndef CORE_TEST_H #define CORE_TEST_H #include "data/HashMap.h" #include "math/Vector.h" #include "utils/Logger.h" namespace Core::Test { namespace Internal { struct Result final { int tests = 0; int successTests = 0; }; using FileName = ArrayString<256>; extern HashMap results; template bool checkEqual(const char* file, int line, const T& wanted, const T& actual) { FileName fileName; if(fileName.append(file)) { CORE_LOG_WARNING("cannot append file name: #", file); return false; } Result* result = results.search(fileName); if(result == nullptr) { result = results.tryEmplace(fileName); if(result == nullptr) { CORE_LOG_WARNING("cannot add test result for #", file); return false; } } result->tests++; if(wanted == actual) { result->successTests++; return true; } CORE_LOG_ERROR("#:# - expected '#' got '#'", fileName, line, wanted, actual) return false; } template bool checkString(const char* file, int line, const A& wanted, const B& actual) { ArrayString<2048> a; if(a.append(wanted)) { CORE_LOG_WARNING("too small buffer"); return false; } ArrayString<2048> b; if(b.append(actual)) { CORE_LOG_WARNING("too small buffer"); return false; } return checkEqual(file, line, a, b); } bool checkFloat(const char* file, int line, float wanted, float actual, float error); template bool checkVector(const char* file, int line, const Core::Vector& wanted, const Core::Vector& actual, float error) { bool result = true; for(int i = 0; i < N; i++) { result = checkFloat(file, line, static_cast(wanted[i]), static_cast(actual[i]), error) && result; } return result; } } void finalize(); } #define CORE_TEST_EQUAL(wanted, actual) \ Core::Test::Internal::checkEqual>( \ __FILE__, __LINE__, wanted, actual) #define CORE_TEST_STRING(wanted, actual) \ Core::Test::Internal::checkString(__FILE__, __LINE__, wanted, actual); #define CORE_TEST_FALSE(actual) CORE_TEST_EQUAL(false, actual); #define CORE_TEST_TRUE(actual) CORE_TEST_EQUAL(true, actual); #define CORE_TEST_NULL(actual) CORE_TEST_EQUAL(true, actual == nullptr); #define CORE_TEST_NOT_NULL(actual) CORE_TEST_EQUAL(true, actual != nullptr); #define CORE_TEST_FLOAT(wanted, actual, error) \ Core::Test::Internal::checkFloat(__FILE__, __LINE__, wanted, actual, error); #define CORE_TEST_VECTOR(wanted, actual) \ Core::Test::Internal::checkVector(__FILE__, __LINE__, wanted, actual, \ 0.0001f); #endif