UtilityTests.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. TEST(10, formatBuffer(buffer, sizeof(buffer), "a#a##a", 1.0, 2, 3));
  122. TEST_STRING("a1.00a#a23", buffer);
  123. TEST(5, formatBuffer(buffer, sizeof(buffer), "aa##ab"));
  124. TEST_STRING("aa#ab", buffer);
  125. TEST(6, formatBuffer(buffer, 3, "aaaaaa"));
  126. TEST_STRING("aa", buffer);
  127. TEST(4, formatBuffer(buffer, 4, "a#", 456));
  128. TEST_STRING("a45", buffer);
  129. TEST(10, formatBuffer(buffer, 4, "# # #", 456, 567, 78));
  130. TEST_STRING("456", buffer);
  131. TEST(10, formatBuffer(buffer, 1, "# # #", 456, 567, 78));
  132. TEST_STRING("", buffer);
  133. TEST(10, formatBuffer(nullptr, 0, "# # #", 456ll, 567l, 78ull));
  134. }
  135. void testUtility(bool light) {
  136. testPopCount();
  137. testIf();
  138. testZeroRellocate();
  139. testMemoryInfoList();
  140. testZeroAllocate();
  141. testInterpolate();
  142. testRadianToDegree();
  143. testDegreeToRadian();
  144. testSleep(light ? 5'000'000 : 50'000'000);
  145. testSleep(light ? 50'000'000 : 1'300'000'000);
  146. testSleepMillis(light ? 5 : 50);
  147. testSleepMillis(light ? 50 : 1300);
  148. testSwap();
  149. testFail();
  150. testSort();
  151. testMinMax();
  152. testToString();
  153. }
  154. static void outOfMemory(void*) {
  155. Core::setOutOfMemoryHandler(nullptr, nullptr);
  156. }
  157. void testInvalidAllocate(void) {
  158. Core::setOutOfMemoryHandler(outOfMemory, nullptr);
  159. Core::allocateRaw(0xFFF'FFFF'FFFF);
  160. TEST_TRUE(false);
  161. Core::finalizeTests();
  162. EXIT(0);
  163. }
  164. void testInvalidReallocate(void) {
  165. Core::setOutOfMemoryHandler(outOfMemory, nullptr);
  166. void* p = Core::allocateRaw(0xFF);
  167. Core::printMemoryReport();
  168. Core::reallocateRaw(p, 0xFFF'FFFF'FFFF);
  169. TEST_TRUE(false);
  170. Core::finalizeTests();
  171. EXIT(0);
  172. }
  173. [[noreturn]] void testPreCanary(void) {
  174. #ifdef CHECK_MEMORY
  175. char* p = static_cast<char*>(Core::allocateRaw(16));
  176. p[-1] = 0;
  177. Core::deallocateRaw(p);
  178. TEST_TRUE(false);
  179. #endif
  180. Core::finalizeTests();
  181. EXIT(0);
  182. }
  183. [[noreturn]] void testPreCanaryNew(void) {
  184. #ifdef CHECK_MEMORY
  185. volatile char* p2 = new char[3];
  186. volatile char* p = coreNewN(char, 16);
  187. delete[] p2;
  188. coreDeleteN(p);
  189. p = coreNewN(char, 16);
  190. p[-1] = 0;
  191. coreDeleteN(p);
  192. TEST_TRUE(false);
  193. #endif
  194. Core::finalizeTests();
  195. EXIT(0);
  196. }
  197. [[noreturn]] void testPreCanaryNewArray(void) {
  198. #ifdef CHECK_MEMORY
  199. volatile char* p = coreNew(char);
  200. p[-1] = 0;
  201. coreDelete(p);
  202. TEST_TRUE(false);
  203. #endif
  204. Core::finalizeTests();
  205. EXIT(0);
  206. }
  207. [[noreturn]] void testPostCanary(void) {
  208. #ifdef CHECK_MEMORY
  209. char* p = static_cast<char*>(Core::allocateRaw(16));
  210. p[17] = 0;
  211. Core::deallocateRaw(p);
  212. TEST_TRUE(false);
  213. #endif
  214. Core::finalizeTests();
  215. EXIT(0);
  216. }