#include "../../src/ErrorSimulator.h" #include "../Tests.h" #include "core/Utility.h" static const float eps = 0.0001f; static void testPopCount() { TEST_U64(4, popCount(0xF)); TEST_U64(0, popCount(0x0)); TEST_U64(2, popCount(0x6)); TEST_U64(7, popCount(0x7F)); TEST_U64(3, popCount(0x2A)); TEST_U64(32, popCount(0xFFFF'FFFF)); TEST_U64(64, popCount(0xFFFF'FFFF'FFFF'FFFF)); TEST_U64(44, popCount(0xFFFF'0FFF'FFFF)); } static void testZeroRellocate() { void* buffer = coreReallocate(nullptr, 16); TEST_NOT_NULL(buffer); buffer = coreReallocate(buffer, 0); TEST_NULL(buffer); } static void testMemoryInfoList() { void* a = coreAllocate(8); void* b = coreAllocate(8); void* c = coreAllocate(8); void* d = coreAllocate(8); coreFree(b); // remove middle element coreFree(a); // remove first coreFree(d); // remove last coreFree(c); // remove single coreFree(nullptr); } static void testZeroAllocate() { constexpr size_t n = 1024 * 1024; void* a = coreAllocate(n); memset(a, 0, n); void* b = coreZeroAllocate(n); TEST_TRUE(memcmp(a, b, n) == 0); coreFree(a); coreFree(b); } static void testInterpolate() { TEST_FLOAT(7.5f, interpolate(5.0f, 10.0f, 0.5f), eps); TEST_FLOAT(-2.0, interpolate(-10.0f, 10.0f, 0.4f), eps); TEST_FLOAT(10.0f, interpolate(-3.0f, 10.0f, 1.0f), eps); TEST_FLOAT(7.0f, interpolate(7.0f, 10.0f, 0.0f), eps); TEST_FLOAT(6.0f, interpolate(0.0f, 10.0f, 0.6f), eps); } static void testRadianToDegree() { TEST_FLOAT(45.0f, radianToDegree(PI * 0.25f), eps); TEST_FLOAT(90.0f, radianToDegree(PI * 0.5f), eps); TEST_FLOAT(180.0f, radianToDegree(PI), eps); TEST_FLOAT(360.0f, radianToDegree(PI * 2.0f), eps); } static void testDegreeToRadian() { TEST_FLOAT(PI * 0.25f, degreeToRadian(45.0f), eps); TEST_FLOAT(PI * 0.5f, degreeToRadian(90.0f), eps); TEST_FLOAT(PI, degreeToRadian(180.0f), eps); TEST_FLOAT(PI * 2.0f, degreeToRadian(360.0f), eps); } static void testSleep(i64 nanos) { i64 time = -getNanos(); TEST_FALSE(sleepNanos(nanos)); time += getNanos(); TEST_TRUE(time >= nanos && time <= (nanos * 13) / 10); } static void testSleepMillis(i64 millis) { i64 time = -getNanos(); TEST_FALSE(sleepMillis(millis)); time += getNanos(); i64 nanos = millis * 1'000'000; TEST_TRUE(time >= nanos && time <= (nanos * 13) / 10); } typedef struct { int i; i64 d; } SwapTest; static void testSwap() { SwapTest a = {3, 20}; SwapTest b = {7, 30}; swap(&a, &b); TEST_INT(7, a.i); TEST_INT(3, b.i); TEST_I64(30, a.d); TEST_I64(20, b.d); } static void testFail() { #ifdef ERROR_SIMULATOR failTimeGet = true; TEST_I64(-1, getNanos()); failTimeGet = false; #endif } BUBBLE_SORT(size_t, Size) #define greateThanSize(a, b) ((a) > (b)) BUBBLE_SORT_SOURCE(size_t, Size, greateThanSize) static void testSort() { size_t data[] = {9, 0, 3, 1, 8, 4, 6, 2, 5, 7}; size_t n = ARRAY_LENGTH(data); bubbleSortSize(data, n); bubbleSortSize(data, n); bubbleSortSize(data, 0); for(size_t i = 0; i < n; i++) { TEST_SIZE(data[i], i); } } static void testMinMax() { TEST_SIZE(5, minSize(5, 7)); TEST_SIZE(7, maxSize(5, 7)); TEST_SIZE(5, clampSize(3, 5, 7)); TEST_SIZE(7, clampSize(9, 5, 7)); TEST_SIZE(6, clampSize(6, 5, 7)); TEST_U32(4, minU32(4, 6)); TEST_U32(6, maxU32(4, 6)); TEST_SIZE(4, clampU32(2, 4, 6)); TEST_SIZE(6, clampU32(8, 4, 6)); TEST_SIZE(5, clampU32(5, 4, 6)); } void testUtility(bool light) { testPopCount(); testZeroRellocate(); testMemoryInfoList(); testZeroAllocate(); testInterpolate(); testRadianToDegree(); testDegreeToRadian(); testSleep(light ? 5'000'000 : 50'000'000); testSleep(light ? 50'000'000 : 1'300'000'000); testSleepMillis(light ? 5 : 50); testSleepMillis(light ? 50 : 1300); testSwap(); testFail(); testSort(); testMinMax(); } static void outOfMemory(void*) { setOutOfMemoryHandler(nullptr, nullptr); } void testInvalidAllocate(void) { setOutOfMemoryHandler(outOfMemory, nullptr); coreAllocate(0xFFF'FFFF'FFFF); TEST_TRUE(false); finalizeTests(); EXIT(0); } void testInvalidReallocate(void) { setOutOfMemoryHandler(outOfMemory, nullptr); void* p = coreAllocate(0xFF); printMemoryReport(); coreReallocate(p, 0xFFF'FFFF'FFFF); TEST_TRUE(false); finalizeTests(); EXIT(0); } [[noreturn]] void testPreCanary(void) { #ifdef CHECK_MEMORY char* p = coreAllocate(16); p[-1] = 0; coreFree(p); TEST_TRUE(false); #endif finalizeTests(); EXIT(0); } [[noreturn]] void testPostCanary(void) { #ifdef CHECK_MEMORY char* p = coreAllocate(16); p[17] = 0; coreFree(p); TEST_TRUE(false); #endif finalizeTests(); EXIT(0); }