UtilityTests.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include <cstring>
  2. #include "../../src/ErrorSimulator.hpp"
  3. #include "../Tests.hpp"
  4. #include "core/Test.hpp"
  5. #include "core/ToString.hpp"
  6. #include "core/Utility.hpp"
  7. static const float eps = 0.0001f;
  8. static void testPopCount() {
  9. TEST(4, Core::popCount(0xF));
  10. TEST(0, Core::popCount(0x0));
  11. TEST(2, Core::popCount(0x6));
  12. TEST(7, Core::popCount(0x7F));
  13. TEST(3, Core::popCount(0x2A));
  14. TEST(32, Core::popCount(0xFFFF'FFFF));
  15. TEST(64, Core::popCount(0xFFFF'FFFF'FFFF'FFFF));
  16. TEST(44, Core::popCount(0xFFFF'0FFF'FFFF));
  17. }
  18. static void testIf() {
  19. TEST_TRUE((Core::IsSame<Core::If<true, int, double>, int>));
  20. TEST_TRUE((Core::IsSame<Core::If<false, int, double>, double>));
  21. }
  22. static void testZeroRellocate() {
  23. void* buffer = Core::reallocateRaw(nullptr, 16);
  24. TEST_NOT_NULL(buffer);
  25. buffer = Core::reallocateRaw(buffer, 0);
  26. TEST_NULL(buffer);
  27. }
  28. static void testMemoryInfoList() {
  29. void* a = Core::allocateRaw(8);
  30. void* b = Core::allocateRaw(8);
  31. void* c = Core::allocateRaw(8);
  32. void* d = Core::allocateRaw(8);
  33. Core::deallocateRaw(b); // remove middle element
  34. Core::deallocateRaw(a); // remove first
  35. Core::deallocateRaw(d); // remove last
  36. Core::deallocateRaw(c); // remove single
  37. Core::deallocateRaw(nullptr);
  38. }
  39. static void testZeroAllocate() {
  40. constexpr size_t n = 1024 * 1024;
  41. void* a = Core::allocateRaw(n);
  42. memset(a, 0, n);
  43. void* b = Core::zeroAllocateRaw(n);
  44. TEST_TRUE(memcmp(a, b, n) == 0);
  45. Core::deallocateRaw(a);
  46. Core::deallocateRaw(b);
  47. }
  48. static void testInterpolate() {
  49. TEST_FLOAT(7.5f, Core::interpolate(5.0f, 10.0f, 0.5f), eps);
  50. TEST_FLOAT(-2.0, Core::interpolate(-10.0f, 10.0f, 0.4f), eps);
  51. TEST_FLOAT(10.0f, Core::interpolate(-3.0f, 10.0f, 1.0f), eps);
  52. TEST_FLOAT(7.0f, Core::interpolate(7.0f, 10.0f, 0.0f), eps);
  53. TEST_FLOAT(6.0f, Core::interpolate(0.0f, 10.0f, 0.6f), eps);
  54. }
  55. static void testRadianToDegree() {
  56. TEST_FLOAT(45.0f, Core::radianToDegree(Core::PI * 0.25f), eps);
  57. TEST_FLOAT(90.0f, Core::radianToDegree(Core::PI * 0.5f), eps);
  58. TEST_FLOAT(180.0f, Core::radianToDegree(Core::PI), eps);
  59. TEST_FLOAT(360.0f, Core::radianToDegree(Core::PI * 2.0f), eps);
  60. }
  61. static void testDegreeToRadian() {
  62. TEST_FLOAT(Core::PI * 0.25f, Core::degreeToRadian(45.0f), eps);
  63. TEST_FLOAT(Core::PI * 0.5f, Core::degreeToRadian(90.0f), eps);
  64. TEST_FLOAT(Core::PI, Core::degreeToRadian(180.0f), eps);
  65. TEST_FLOAT(Core::PI * 2.0f, Core::degreeToRadian(360.0f), eps);
  66. }
  67. static void testSleep(i64 nanos) {
  68. i64 time = -Core::getNanos();
  69. TEST_FALSE(Core::sleepNanos(nanos));
  70. time += Core::getNanos();
  71. TEST_TRUE(time >= nanos && time <= (nanos * 13) / 10);
  72. }
  73. static void testSleepMillis(i64 millis) {
  74. i64 time = -Core::getNanos();
  75. TEST_FALSE(Core::sleepMillis(millis));
  76. time += Core::getNanos();
  77. i64 nanos = millis * 1'000'000;
  78. TEST_TRUE(time >= nanos && time <= (nanos * 13) / 10);
  79. }
  80. typedef struct {
  81. int i;
  82. i64 d;
  83. } SwapTest;
  84. static void testSwap() {
  85. SwapTest a = {3, 20};
  86. SwapTest b = {7, 30};
  87. Core::swap(a, b);
  88. TEST(7, a.i);
  89. TEST(3, b.i);
  90. TEST(30l, a.d);
  91. TEST(20l, b.d);
  92. }
  93. static void testFail() {
  94. #ifdef ERROR_SIMULATOR
  95. failStepThrow = 1;
  96. TEST(-1l, Core::getNanos());
  97. failStepThrow = 1;
  98. TEST_TRUE(Core::sleepMillis(5));
  99. failStepThrow = 0;
  100. #endif
  101. }
  102. static void testSort() {
  103. size_t data[] = {9, 0, 3, 1, 8, 4, 6, 2, 5, 7};
  104. size_t n = 10;
  105. Core::bubbleSort(data, n);
  106. Core::bubbleSort(data, n);
  107. Core::bubbleSort(data, 0);
  108. for(size_t i = 0; i < n; i++) {
  109. TEST(data[i], i);
  110. }
  111. }
  112. static void testMinMax() {
  113. TEST(5, Core::min<int>(5, 7));
  114. TEST(7, Core::max<int>(5, 7));
  115. TEST(5, Core::clamp<int>(3, 5, 7));
  116. TEST(7, Core::clamp<int>(9, 5, 7));
  117. TEST(6, Core::clamp<int>(6, 5, 7));
  118. }
  119. static void testToString() {
  120. char buffer[512];
  121. formatBuffer(buffer, sizeof(buffer), "aa##a", 1, 2, 3);
  122. TEST_STRING("aa#a123", buffer);
  123. }
  124. void testUtility(bool light) {
  125. testPopCount();
  126. testIf();
  127. testZeroRellocate();
  128. testMemoryInfoList();
  129. testZeroAllocate();
  130. testInterpolate();
  131. testRadianToDegree();
  132. testDegreeToRadian();
  133. testSleep(light ? 5'000'000 : 50'000'000);
  134. testSleep(light ? 50'000'000 : 1'300'000'000);
  135. testSleepMillis(light ? 5 : 50);
  136. testSleepMillis(light ? 50 : 1300);
  137. testSwap();
  138. testFail();
  139. testSort();
  140. testMinMax();
  141. testToString();
  142. }
  143. static void outOfMemory(void*) {
  144. Core::setOutOfMemoryHandler(nullptr, nullptr);
  145. }
  146. void testInvalidAllocate(void) {
  147. Core::setOutOfMemoryHandler(outOfMemory, nullptr);
  148. Core::allocateRaw(0xFFF'FFFF'FFFF);
  149. TEST_TRUE(false);
  150. Core::finalizeTests();
  151. EXIT(0);
  152. }
  153. void testInvalidReallocate(void) {
  154. Core::setOutOfMemoryHandler(outOfMemory, nullptr);
  155. void* p = Core::allocateRaw(0xFF);
  156. Core::printMemoryReport();
  157. Core::reallocateRaw(p, 0xFFF'FFFF'FFFF);
  158. TEST_TRUE(false);
  159. Core::finalizeTests();
  160. EXIT(0);
  161. }
  162. [[noreturn]] void testPreCanary(void) {
  163. #ifdef CHECK_MEMORY
  164. char* p = static_cast<char*>(Core::allocateRaw(16));
  165. p[-1] = 0;
  166. Core::deallocateRaw(p);
  167. TEST_TRUE(false);
  168. #endif
  169. Core::finalizeTests();
  170. EXIT(0);
  171. }
  172. [[noreturn]] void testPreCanaryNew(void) {
  173. #ifdef CHECK_MEMORY
  174. volatile char* p2 = new char[3];
  175. volatile char* p = coreNewN(char, 16);
  176. delete[] p2;
  177. coreDeleteN(p);
  178. p = coreNewN(char, 16);
  179. p[-1] = 0;
  180. coreDeleteN(p);
  181. TEST_TRUE(false);
  182. #endif
  183. Core::finalizeTests();
  184. EXIT(0);
  185. }
  186. [[noreturn]] void testPreCanaryNewArray(void) {
  187. #ifdef CHECK_MEMORY
  188. volatile char* p = coreNew(char);
  189. p[-1] = 0;
  190. coreDelete(p);
  191. TEST_TRUE(false);
  192. #endif
  193. Core::finalizeTests();
  194. EXIT(0);
  195. }
  196. [[noreturn]] void testPostCanary(void) {
  197. #ifdef CHECK_MEMORY
  198. char* p = static_cast<char*>(Core::allocateRaw(16));
  199. p[17] = 0;
  200. Core::deallocateRaw(p);
  201. TEST_TRUE(false);
  202. #endif
  203. Core::finalizeTests();
  204. EXIT(0);
  205. }