#include "core/Test.h" #include #include #include #include #include "core/Logger.h" #include "core/Utility.h" typedef struct { char* file; int tests; int successTests; } Result; static Result* results = nullptr; static size_t resultsIndex = 0; static size_t resultsCapacity = 0; static Result* getResult(const char* file) { for(size_t i = 0; i < resultsIndex; i++) { Result* r = results + i; if(strcmp(r->file, file) == 0) { return r; } } while(resultsIndex >= resultsCapacity) { size_t newCapacity = resultsCapacity == 0 ? 8 : resultsCapacity * 2; results = coreReallocate(results, newCapacity * sizeof(Result)); resultsCapacity = newCapacity; } Result* r = results + (resultsIndex++); r->file = strdup(file); r->successTests = 0; r->tests = 0; return r; } void finalizeTests(void) { for(size_t i = 0; i < resultsIndex; i++) { Result* r = results + i; bool c = r->successTests == r->tests; fputs(c ? TERMINAL_GREEN : TERMINAL_RED, stdout); printf( "%s - %d / %d tests succeeded", r->file, r->successTests, r->tests); puts(TERMINAL_RESET); free(r->file); } coreFree(results); results = nullptr; resultsIndex = 0; resultsCapacity = 0; } static bool addToResult(const char* file, bool comparison) { Result* r = getResult(file); r->tests++; if(comparison) { r->successTests++; return true; } return false; } #define TEST_SUCCESS(result) \ file = getShortFileName(file); \ if(addToResult(file, result)) { \ return true; \ } #define TEST_NAMED_COMPARE(name, type, format) \ bool test##name(TEST_ARGS, type wanted, type actual) { \ TEST_SUCCESS(wanted == actual) \ fputs(TERMINAL_RED, stdout); \ printf( \ "%s:%d - expected '" format "' got '" format "'", file, line, \ wanted, actual); \ puts(TERMINAL_RESET); \ return false; \ } TEST_NAMED_COMPARE(Int, int, "%d") TEST_NAMED_COMPARE(I32, i32, "%" PRId32) TEST_NAMED_COMPARE(I64, i64, "%" PRId64) TEST_NAMED_COMPARE(U32, u32, "%" PRIu32) TEST_NAMED_COMPARE(U64, u64, "%" PRIu64) TEST_NAMED_COMPARE(Size, size_t, "%zu") TEST_NAMED_COMPARE(Bool, bool, "%d") bool testString(TEST_ARGS, const char* wanted, const char* actual) { TEST_SUCCESS(strcmp(wanted, actual) == 0) fputs(TERMINAL_RED, stdout); printf("%s:%d - expected '%s' got '%s'", file, line, wanted, actual); puts(TERMINAL_RESET); return false; } bool testFloat(TEST_ARGS, float wanted, float actual, float error) { float diff = wanted - actual; diff = diff < 0.0f ? -diff : diff; TEST_SUCCESS(diff <= error) fputs(TERMINAL_RED, stdout); printf( "%s:%d - expected '%.3f' got '%.3f'", file, line, (double)wanted, (double)actual); puts(TERMINAL_RESET); return false; } bool testNull(TEST_ARGS, const void* actual) { TEST_SUCCESS(actual == nullptr) fputs(TERMINAL_RED, stdout); printf("%s:%d - expected null", file, line); puts(TERMINAL_RESET); return false; } bool testNotNull(TEST_ARGS, const void* actual) { TEST_SUCCESS(actual != nullptr) fputs(TERMINAL_RED, stdout); printf("%s:%d - expected valid pointer", file, line); puts(TERMINAL_RESET); return false; } bool testVectorN( TEST_ARGS, const float* wanted, const float* actual, size_t n) { for(size_t i = 0; i < n; i++) { if(!testFloat(file, line, wanted[i], actual[i], 0.01f)) { return false; } } return true; } bool testIntVectorN(TEST_ARGS, const int* wanted, const int* actual, size_t n) { for(size_t i = 0; i < n; i++) { if(!testInt(file, line, wanted[i], actual[i])) { return false; } } return true; }