unit_tests.cpp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444
  1. /*
  2. * Copyright (c) 2012-2020 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. #include "config.h"
  6. #if CROWN_BUILD_UNIT_TESTS
  7. #include "core/command_line.h"
  8. #include "core/containers/array.inl"
  9. #include "core/containers/hash_map.inl"
  10. #include "core/containers/hash_set.inl"
  11. #include "core/containers/vector.inl"
  12. #include "core/filesystem/path.h"
  13. #include "core/guid.h"
  14. #include "core/json/json.h"
  15. #include "core/json/sjson.h"
  16. #include "core/math/aabb.inl"
  17. #include "core/math/color4.inl"
  18. #include "core/math/constants.h"
  19. #include "core/math/math.h"
  20. #include "core/math/matrix3x3.inl"
  21. #include "core/math/matrix4x4.inl"
  22. #include "core/math/quaternion.inl"
  23. #include "core/math/sphere.inl"
  24. #include "core/math/vector2.inl"
  25. #include "core/math/vector3.inl"
  26. #include "core/math/vector4.inl"
  27. #include "core/memory/memory.inl"
  28. #include "core/memory/temp_allocator.inl"
  29. #include "core/murmur.h"
  30. #include "core/os.h"
  31. #include "core/process.h"
  32. #include "core/strings/dynamic_string.inl"
  33. #include "core/strings/string.inl"
  34. #include "core/strings/string_id.inl"
  35. #include "core/thread/thread.h"
  36. #include "core/time.h"
  37. #include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
  38. #define ENSURE(condition) \
  39. do \
  40. { \
  41. if (!(condition)) \
  42. { \
  43. printf("Assertion failed: '%s' in %s:%d\n\n" \
  44. , #condition \
  45. , __FILE__ \
  46. , __LINE__ \
  47. ); \
  48. exit(EXIT_FAILURE); \
  49. } \
  50. } \
  51. while (0)
  52. namespace crown
  53. {
  54. static void test_memory()
  55. {
  56. memory_globals::init();
  57. Allocator& a = default_allocator();
  58. void* p = a.allocate(32);
  59. ENSURE(a.allocated_size(p) >= 32);
  60. a.deallocate(p);
  61. memory_globals::shutdown();
  62. }
  63. static void test_array()
  64. {
  65. memory_globals::init();
  66. Allocator& a = default_allocator();
  67. {
  68. Array<int> v(a);
  69. ENSURE(array::size(v) == 0);
  70. array::push_back(v, 1);
  71. ENSURE(array::size(v) == 1);
  72. ENSURE(v[0] == 1);
  73. }
  74. memory_globals::shutdown();
  75. }
  76. static void test_vector()
  77. {
  78. memory_globals::init();
  79. Allocator& a = default_allocator();
  80. {
  81. Vector<int> v(a);
  82. ENSURE(vector::size(v) == 0);
  83. vector::push_back(v, 1);
  84. ENSURE(vector::size(v) == 1);
  85. ENSURE(v[0] == 1);
  86. }
  87. memory_globals::shutdown();
  88. }
  89. static void test_hash_map()
  90. {
  91. memory_globals::init();
  92. Allocator& a = default_allocator();
  93. {
  94. HashMap<s32, s32> m(a);
  95. ENSURE(hash_map::size(m) == 0);
  96. ENSURE(hash_map::get(m, 0, 42) == 42);
  97. ENSURE(!hash_map::has(m, 10));
  98. for (s32 i = 0; i < 100; ++i)
  99. hash_map::set(m, i, i*i);
  100. for (s32 i = 0; i < 100; ++i)
  101. ENSURE(hash_map::get(m, i, 0) == i*i);
  102. hash_map::remove(m, 20);
  103. ENSURE(!hash_map::has(m, 20));
  104. hash_map::remove(m, 2000);
  105. ENSURE(!hash_map::has(m, 2000));
  106. hash_map::remove(m, 50);
  107. ENSURE(!hash_map::has(m, 50));
  108. hash_map::clear(m);
  109. for (s32 i = 0; i < 100; ++i)
  110. ENSURE(!hash_map::has(m, i));
  111. }
  112. {
  113. HashMap<s32, s32> m(a);
  114. hash_map_internal::grow(m);
  115. ENSURE(hash_map::capacity(m) == 16);
  116. hash_map::set(m, 0, 7);
  117. hash_map::set(m, 1, 1);
  118. for (s32 i = 2; i < 150; ++i)
  119. {
  120. hash_map::set(m, i, 2);
  121. ENSURE(hash_map::has(m, 0));
  122. ENSURE(hash_map::has(m, 1));
  123. ENSURE(hash_map::has(m, i));
  124. hash_map::remove(m, i);
  125. }
  126. }
  127. memory_globals::shutdown();
  128. }
  129. static void test_hash_set()
  130. {
  131. memory_globals::init();
  132. Allocator& a = default_allocator();
  133. {
  134. HashSet<s32> m(a);
  135. ENSURE(hash_set::size(m) == 0);
  136. ENSURE(!hash_set::has(m, 10));
  137. for (s32 i = 0; i < 100; ++i)
  138. hash_set::insert(m, i*i);
  139. for (s32 i = 0; i < 100; ++i)
  140. ENSURE(hash_set::has(m, i*i));
  141. hash_set::remove(m, 5*5);
  142. ENSURE(!hash_set::has(m, 5*5));
  143. hash_set::remove(m, 80*80);
  144. ENSURE(!hash_set::has(m, 80*80));
  145. hash_set::remove(m, 40*40);
  146. ENSURE(!hash_set::has(m, 40*40));
  147. hash_set::clear(m);
  148. for (s32 i = 0; i < 100; ++i)
  149. ENSURE(!hash_set::has(m, i*i));
  150. }
  151. memory_globals::shutdown();
  152. }
  153. static void test_vector2()
  154. {
  155. {
  156. const Vector2 a = vector2(1.2f, 4.2f);
  157. const Vector2 b = vector2(2.7f, -1.9f);
  158. const Vector2 c = a - b;
  159. ENSURE(fequal(c.x, -1.5f, 0.0001f));
  160. ENSURE(fequal(c.y, 6.1f, 0.0001f));
  161. }
  162. {
  163. const Vector2 a = vector2(1.2f, 4.2f);
  164. const Vector2 b = vector2(2.7f, -1.9f);
  165. const Vector2 c = a + b;
  166. ENSURE(fequal(c.x, 3.9f, 0.0001f));
  167. ENSURE(fequal(c.y, 2.3f, 0.0001f));
  168. }
  169. {
  170. const Vector2 a = vector2(1.2f, 4.2f);
  171. const Vector2 b = a * 2.0f;
  172. ENSURE(fequal(b.x, 2.4f, 0.0001f));
  173. ENSURE(fequal(b.y, 8.4f, 0.0001f));
  174. }
  175. {
  176. const Vector2 a = vector2(1.2f, 4.2f);
  177. const Vector2 b = vector2(2.7f, -1.9f);
  178. const f32 c = dot(a, b);
  179. ENSURE(fequal(c, -4.74f, 0.0001f));
  180. }
  181. {
  182. const Vector2 a = vector2(1.2f, 4.2f);
  183. const f32 c = length_squared(a);
  184. ENSURE(fequal(c, 19.08f, 0.0001f));
  185. }
  186. {
  187. const Vector2 a = vector2(1.2f, 4.2f);
  188. const f32 c = length(a);
  189. ENSURE(fequal(c, 4.36806f, 0.0001f));
  190. }
  191. {
  192. Vector2 a = vector2(1.2f, 4.2f);
  193. normalize(a);
  194. ENSURE(fequal(length(a), 1.0f, 0.00001f));
  195. }
  196. {
  197. const Vector2 a = vector2(1.2f, 4.2f);
  198. const Vector2 b = vector2(2.7f, -1.9f);
  199. const float c = distance_squared(a, b);
  200. ENSURE(fequal(c, 39.46f, 0.00001f));
  201. }
  202. {
  203. const Vector2 a = vector2(1.2f, 4.2f);
  204. const Vector2 b = vector2(2.7f, -1.9f);
  205. const float c = distance(a, b);
  206. ENSURE(fequal(c, 6.28171f, 0.00001f));
  207. }
  208. {
  209. const Vector2 a = vector2(1.2f, 4.2f);
  210. const Vector2 b = vector2(2.7f, -1.9f);
  211. const Vector2 c = max(a, b);
  212. ENSURE(fequal(c.x, 2.7f, 0.00001f));
  213. ENSURE(fequal(c.y, 4.2f, 0.00001f));
  214. }
  215. {
  216. const Vector2 a = vector2(1.2f, 4.2f);
  217. const Vector2 b = vector2(2.7f, -1.9f);
  218. const Vector2 c = min(a, b);
  219. ENSURE(fequal(c.x, 1.2f, 0.00001f));
  220. ENSURE(fequal(c.y, -1.9f, 0.00001f));
  221. }
  222. }
  223. static void test_vector3()
  224. {
  225. {
  226. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  227. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  228. const Vector3 c = a - b;
  229. ENSURE(fequal(c.x, -1.5f, 0.0001f));
  230. ENSURE(fequal(c.y, 6.1f, 0.0001f));
  231. ENSURE(fequal(c.z, 1.8f, 0.0001f));
  232. }
  233. {
  234. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  235. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  236. const Vector3 c = a + b;
  237. ENSURE(fequal(c.x, 3.9f, 0.0001f));
  238. ENSURE(fequal(c.y, 2.3f, 0.0001f));
  239. ENSURE(fequal(c.z, -6.4f, 0.0001f));
  240. }
  241. {
  242. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  243. const Vector3 b = a * 2.0f;
  244. ENSURE(fequal(b.x, 2.4f, 0.0001f));
  245. ENSURE(fequal(b.y, 8.4f, 0.0001f));
  246. ENSURE(fequal(b.z, -4.6f, 0.0001f));
  247. }
  248. {
  249. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  250. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  251. const f32 c = dot(a, b);
  252. ENSURE(fequal(c, 4.69f, 0.0001f));
  253. }
  254. {
  255. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  256. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  257. const Vector3 c = cross(a, b);
  258. ENSURE(fequal(c.x, -21.59f, 0.0001f));
  259. ENSURE(fequal(c.y, -1.29f, 0.0001f));
  260. ENSURE(fequal(c.z, -13.62f, 0.0001f));
  261. }
  262. {
  263. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  264. const f32 c = length_squared(a);
  265. ENSURE(fequal(c, 24.37f, 0.0001f));
  266. }
  267. {
  268. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  269. const f32 c = length(a);
  270. ENSURE(fequal(c, 4.93659f, 0.0001f));
  271. }
  272. {
  273. Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  274. normalize(a);
  275. ENSURE(fequal(length(a), 1.0f, 0.00001f));
  276. }
  277. {
  278. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  279. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  280. const float c = distance_squared(a, b);
  281. ENSURE(fequal(c, 42.70f, 0.00001f));
  282. }
  283. {
  284. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  285. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  286. const float c = distance(a, b);
  287. ENSURE(fequal(c, 6.53452f, 0.00001f));
  288. }
  289. {
  290. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  291. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  292. const Vector3 c = max(a, b);
  293. ENSURE(fequal(c.x, 2.7f, 0.00001f));
  294. ENSURE(fequal(c.y, 4.2f, 0.00001f));
  295. ENSURE(fequal(c.z, -2.3f, 0.00001f));
  296. }
  297. {
  298. const Vector3 a = vector3(1.2f, 4.2f, -2.3f);
  299. const Vector3 b = vector3(2.7f, -1.9f, -4.1f);
  300. const Vector3 c = min(a, b);
  301. ENSURE(fequal(c.x, 1.2f, 0.00001f));
  302. ENSURE(fequal(c.y, -1.9f, 0.00001f));
  303. ENSURE(fequal(c.z, -4.1f, 0.00001f));
  304. }
  305. }
  306. static void test_vector4()
  307. {
  308. {
  309. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  310. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  311. const Vector4 c = a - b;
  312. ENSURE(fequal(c.x, -1.5f, 0.0001f));
  313. ENSURE(fequal(c.y, 6.1f, 0.0001f));
  314. ENSURE(fequal(c.z, 1.8f, 0.0001f));
  315. ENSURE(fequal(c.w, 4.5f, 0.0001f));
  316. }
  317. {
  318. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  319. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  320. const Vector4 c = a + b;
  321. ENSURE(fequal(c.x, 3.9f, 0.0001f));
  322. ENSURE(fequal(c.y, 2.3f, 0.0001f));
  323. ENSURE(fequal(c.z, -6.4f, 0.0001f));
  324. ENSURE(fequal(c.w, 6.5f, 0.0001f));
  325. }
  326. {
  327. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 1.5f);
  328. const Vector4 b = a * 2.0f;
  329. ENSURE(fequal(b.x, 2.4f, 0.0001f));
  330. ENSURE(fequal(b.y, 8.4f, 0.0001f));
  331. ENSURE(fequal(b.z, -4.6f, 0.0001f));
  332. ENSURE(fequal(b.w, 3.0f, 0.0001f));
  333. }
  334. {
  335. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  336. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  337. const f32 c = dot(a, b);
  338. ENSURE(fequal(c, 10.19f, 0.0001f));
  339. }
  340. {
  341. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  342. const f32 c = length_squared(a);
  343. ENSURE(fequal(c, 54.62f, 0.0001f));
  344. }
  345. {
  346. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  347. const f32 c = length(a);
  348. ENSURE(fequal(c, 7.39053f, 0.0001f));
  349. }
  350. {
  351. Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  352. normalize(a);
  353. ENSURE(fequal(length(a), 1.0f, 0.00001f));
  354. }
  355. {
  356. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  357. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  358. const float c = distance_squared(a, b);
  359. ENSURE(fequal(c, 62.95f, 0.00001f));
  360. }
  361. {
  362. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  363. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  364. const float c = distance(a, b);
  365. ENSURE(fequal(c, 7.93410f, 0.00001f));
  366. }
  367. {
  368. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  369. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  370. const Vector4 c = max(a, b);
  371. ENSURE(fequal(c.x, 2.7f, 0.00001f));
  372. ENSURE(fequal(c.y, 4.2f, 0.00001f));
  373. ENSURE(fequal(c.z, -2.3f, 0.00001f));
  374. ENSURE(fequal(c.w, 5.5f, 0.00001f));
  375. }
  376. {
  377. const Vector4 a = vector4(1.2f, 4.2f, -2.3f, 5.5f);
  378. const Vector4 b = vector4(2.7f, -1.9f, -4.1f, 1.0f);
  379. const Vector4 c = min(a, b);
  380. ENSURE(fequal(c.x, 1.2f, 0.00001f));
  381. ENSURE(fequal(c.y, -1.9f, 0.00001f));
  382. ENSURE(fequal(c.z, -4.1f, 0.00001f));
  383. ENSURE(fequal(c.w, 1.0f, 0.00001f));
  384. }
  385. }
  386. static void test_quaternion()
  387. {
  388. {
  389. const Quaternion a = from_elements(0.0f, 0.0f, 0.0f, 1.0f);
  390. ENSURE(fequal(a.x, 0.0f, 0.00001f));
  391. ENSURE(fequal(a.y, 0.0f, 0.00001f));
  392. ENSURE(fequal(a.z, 0.0f, 0.00001f));
  393. ENSURE(fequal(a.w, 1.0f, 0.00001f));
  394. }
  395. }
  396. static void test_color4()
  397. {
  398. {
  399. const Color4 a = color4(1.3f, 2.6f, 0.2f, 0.6f);
  400. ENSURE(fequal(a.x, 1.3f, 0.00001f));
  401. ENSURE(fequal(a.y, 2.6f, 0.00001f));
  402. ENSURE(fequal(a.z, 0.2f, 0.00001f));
  403. ENSURE(fequal(a.w, 0.6f, 0.00001f));
  404. }
  405. {
  406. const Color4 a = from_rgba(63, 231, 12, 98);
  407. ENSURE(fequal(a.x, 0.24705f, 0.00001f));
  408. ENSURE(fequal(a.y, 0.90588f, 0.00001f));
  409. ENSURE(fequal(a.z, 0.04705f, 0.00001f));
  410. ENSURE(fequal(a.w, 0.38431f, 0.00001f));
  411. }
  412. {
  413. const Color4 a = from_rgb(63, 231, 12);
  414. ENSURE(fequal(a.x, 0.24705f, 0.00001f));
  415. ENSURE(fequal(a.y, 0.90588f, 0.00001f));
  416. ENSURE(fequal(a.z, 0.04705f, 0.00001f));
  417. ENSURE(fequal(a.w, 1.0f , 0.00001f));
  418. }
  419. {
  420. const Color4 a = from_rgba(0x3fe70c62);
  421. ENSURE(fequal(a.x, 0.24705f, 0.00001f));
  422. ENSURE(fequal(a.y, 0.90588f, 0.00001f));
  423. ENSURE(fequal(a.z, 0.04705f, 0.00001f));
  424. ENSURE(fequal(a.w, 0.38431f, 0.00001f));
  425. }
  426. {
  427. const Color4 a = from_rgba(63, 231, 12, 98);
  428. const u32 rgba = to_rgba(a);
  429. ENSURE(rgba == 0x3fe70c62);
  430. const u32 rgb = to_rgb(a);
  431. ENSURE(rgb == 0x3fe70cff);
  432. const u32 bgr = to_bgr(a);
  433. ENSURE(bgr == 0xff0ce73f);
  434. const u32 abgr = to_abgr(a);
  435. ENSURE(abgr == 0x620ce73f);
  436. }
  437. }
  438. static void test_matrix3x3()
  439. {
  440. {
  441. const Matrix3x3 a = from_elements(1.2f, -2.3f, 5.1f
  442. , 2.2f, -5.1f, 1.1f
  443. , 3.2f, 3.3f, -3.8f
  444. );
  445. const Matrix3x3 b = from_elements(3.2f, 4.8f, 6.0f
  446. , -1.6f, -7.1f, -2.4f
  447. , -3.1f, -2.2f, 8.9f
  448. );
  449. const Matrix3x3 c = a + b;
  450. ENSURE(fequal(c.x.x, 4.4f, 0.00001f));
  451. ENSURE(fequal(c.x.y, 2.5f, 0.00001f));
  452. ENSURE(fequal(c.x.z, 11.1f, 0.00001f));
  453. ENSURE(fequal(c.y.x, 0.6f, 0.00001f));
  454. ENSURE(fequal(c.y.y, -12.2f, 0.00001f));
  455. ENSURE(fequal(c.y.z, -1.3f, 0.00001f));
  456. ENSURE(fequal(c.z.x, 0.1f, 0.00001f));
  457. ENSURE(fequal(c.z.y, 1.1f, 0.00001f));
  458. ENSURE(fequal(c.z.z, 5.1f, 0.00001f));
  459. }
  460. {
  461. const Matrix3x3 a = from_elements(1.2f, -2.3f, 5.1f
  462. , 2.2f, -5.1f, 1.1f
  463. , 3.2f, 3.3f, -3.8f
  464. );
  465. const Matrix3x3 b = from_elements(3.2f, 4.8f, 6.0f
  466. , -1.6f, -7.1f, -2.4f
  467. , -3.1f, -2.2f, 8.9f
  468. );
  469. const Matrix3x3 c = a - b;
  470. ENSURE(fequal(c.x.x, -2.0f, 0.00001f));
  471. ENSURE(fequal(c.x.y, -7.1f, 0.00001f));
  472. ENSURE(fequal(c.x.z, -0.9f, 0.00001f));
  473. ENSURE(fequal(c.y.x, 3.8f, 0.00001f));
  474. ENSURE(fequal(c.y.y, 2.0f, 0.00001f));
  475. ENSURE(fequal(c.y.z, 3.5f, 0.00001f));
  476. ENSURE(fequal(c.z.x, 6.3f, 0.00001f));
  477. ENSURE(fequal(c.z.y, 5.5f, 0.00001f));
  478. ENSURE(fequal(c.z.z, -12.7f, 0.00001f));
  479. }
  480. {
  481. const Matrix3x3 a = from_elements(1.2f, -2.3f, 5.1f
  482. , 2.2f, -5.1f, 1.1f
  483. , 3.2f, 3.3f, -3.8f
  484. );
  485. const Matrix3x3 b = from_elements(3.2f, 4.8f, 6.0f
  486. , -1.6f, -7.1f, -2.4f
  487. , -3.1f, -2.2f, 8.9f
  488. );
  489. const Matrix3x3 c = a * b;
  490. ENSURE(fequal(c.x.x, -8.29f, 0.00001f));
  491. ENSURE(fequal(c.x.y, 10.87f, 0.00001f));
  492. ENSURE(fequal(c.x.z, 58.11f, 0.00001f));
  493. ENSURE(fequal(c.y.x, 11.79f, 0.00001f));
  494. ENSURE(fequal(c.y.y, 44.35f, 0.00001f));
  495. ENSURE(fequal(c.y.z, 35.23f, 0.00001f));
  496. ENSURE(fequal(c.z.x, 16.74f, 0.00001f));
  497. ENSURE(fequal(c.z.y, 0.29f, 0.00001f));
  498. ENSURE(fequal(c.z.z, -22.54f, 0.00001f));
  499. }
  500. {
  501. const Matrix3x3 a = from_elements(1.2f, -2.3f, 5.1f
  502. , 2.2f, -5.1f, 1.1f
  503. , 3.2f, 3.3f, -3.8f
  504. );
  505. const Matrix3x3 b = get_inverted(a);
  506. ENSURE(fequal(b.x.x, 0.140833f, 0.00001f));
  507. ENSURE(fequal(b.x.y, 0.072339f, 0.00001f));
  508. ENSURE(fequal(b.x.z, 0.209954f, 0.00001f));
  509. ENSURE(fequal(b.y.x, 0.106228f, 0.00001f));
  510. ENSURE(fequal(b.y.y, -0.186705f, 0.00001f));
  511. ENSURE(fequal(b.y.z, 0.088524f, 0.00001f));
  512. ENSURE(fequal(b.z.x, 0.210848f, 0.00001f));
  513. ENSURE(fequal(b.z.y, -0.101221f, 0.00001f));
  514. ENSURE(fequal(b.z.z, -0.009478f, 0.00001f));
  515. }
  516. {
  517. const Matrix3x3 a = from_elements(1.2f, -2.3f, 5.1f
  518. , 2.2f, -5.1f, 1.1f
  519. , 3.2f, 3.3f, -3.8f
  520. );
  521. const Matrix3x3 b = get_transposed(a);
  522. ENSURE(fequal(b.x.x, 1.2f, 0.00001f));
  523. ENSURE(fequal(b.x.y, 2.2f, 0.00001f));
  524. ENSURE(fequal(b.x.z, 3.2f, 0.00001f));
  525. ENSURE(fequal(b.y.x, -2.3f, 0.00001f));
  526. ENSURE(fequal(b.y.y, -5.1f, 0.00001f));
  527. ENSURE(fequal(b.y.z, 3.3f, 0.00001f));
  528. ENSURE(fequal(b.z.x, 5.1f, 0.00001f));
  529. ENSURE(fequal(b.z.y, 1.1f, 0.00001f));
  530. ENSURE(fequal(b.z.z, -3.8f, 0.00001f));
  531. }
  532. }
  533. static void test_matrix4x4()
  534. {
  535. {
  536. const Matrix4x4 a = from_elements(1.2f, -2.3f, 5.1f, -1.2f
  537. , 2.2f, -5.1f, 1.1f, -7.4f
  538. , 3.2f, 3.3f, -3.8f, -9.2f
  539. , -6.8f, -2.9f, 1.0f, 4.9f
  540. );
  541. const Matrix4x4 b = from_elements(3.2f, 4.8f, 6.0f, 5.3f
  542. , -1.6f, -7.1f, -2.4f, -6.2f
  543. , -3.1f, -2.2f, 8.9f, 8.3f
  544. , 3.8f, 9.1f, -3.1f, -7.1f
  545. );
  546. const Matrix4x4 c = a + b;
  547. ENSURE(fequal(c.x.x, 4.4f, 0.00001f));
  548. ENSURE(fequal(c.x.y, 2.5f, 0.00001f));
  549. ENSURE(fequal(c.x.z, 11.1f, 0.00001f));
  550. ENSURE(fequal(c.x.w, 4.1f, 0.00001f));
  551. ENSURE(fequal(c.y.x, 0.6f, 0.00001f));
  552. ENSURE(fequal(c.y.y, -12.2f, 0.00001f));
  553. ENSURE(fequal(c.y.z, -1.3f, 0.00001f));
  554. ENSURE(fequal(c.y.w, -13.6f, 0.00001f));
  555. ENSURE(fequal(c.z.x, 0.1f, 0.00001f));
  556. ENSURE(fequal(c.z.y, 1.1f, 0.00001f));
  557. ENSURE(fequal(c.z.z, 5.1f, 0.00001f));
  558. ENSURE(fequal(c.z.w, -0.9f, 0.00001f));
  559. ENSURE(fequal(c.t.x, -3.0f, 0.00001f));
  560. ENSURE(fequal(c.t.y, 6.2f, 0.00001f));
  561. ENSURE(fequal(c.t.z, -2.1f, 0.00001f));
  562. ENSURE(fequal(c.t.w, -2.2f, 0.00001f));
  563. }
  564. {
  565. const Matrix4x4 a = from_elements(1.2f, -2.3f, 5.1f, -1.2f
  566. , 2.2f, -5.1f, 1.1f, -7.4f
  567. , 3.2f, 3.3f, -3.8f, -9.2f
  568. , -6.8f, -2.9f, 1.0f, 4.9f
  569. );
  570. const Matrix4x4 b = from_elements(3.2f, 4.8f, 6.0f, 5.3f
  571. , -1.6f, -7.1f, -2.4f, -6.2f
  572. , -3.1f, -2.2f, 8.9f, 8.3f
  573. , 3.8f, 9.1f, -3.1f, -7.1f
  574. );
  575. const Matrix4x4 c = a - b;
  576. ENSURE(fequal(c.x.x, -2.0f, 0.00001f));
  577. ENSURE(fequal(c.x.y, -7.1f, 0.00001f));
  578. ENSURE(fequal(c.x.z, -0.9f, 0.00001f));
  579. ENSURE(fequal(c.x.w, -6.5f, 0.00001f));
  580. ENSURE(fequal(c.y.x, 3.8f, 0.00001f));
  581. ENSURE(fequal(c.y.y, 2.0f, 0.00001f));
  582. ENSURE(fequal(c.y.z, 3.5f, 0.00001f));
  583. ENSURE(fequal(c.y.w, -1.2f, 0.00001f));
  584. ENSURE(fequal(c.z.x, 6.3f, 0.00001f));
  585. ENSURE(fequal(c.z.y, 5.5f, 0.00001f));
  586. ENSURE(fequal(c.z.z, -12.7f, 0.00001f));
  587. ENSURE(fequal(c.z.w, -17.5f, 0.00001f));
  588. ENSURE(fequal(c.t.x, -10.6f, 0.00001f));
  589. ENSURE(fequal(c.t.y, -12.0f, 0.00001f));
  590. ENSURE(fequal(c.t.z, 4.1f, 0.00001f));
  591. ENSURE(fequal(c.t.w, 12.0f, 0.00001f));
  592. }
  593. {
  594. const Matrix4x4 a = from_elements(1.2f, -2.3f, 5.1f, -1.2f
  595. , 2.2f, -5.1f, 1.1f, -7.4f
  596. , 3.2f, 3.3f, -3.8f, -9.2f
  597. , -6.8f, -2.9f, 1.0f, 4.9f
  598. );
  599. const Matrix4x4 b = from_elements(3.2f, 4.8f, 6.0f, 5.3f
  600. , -1.6f, -7.1f, -2.4f, -6.2f
  601. , -3.1f, -2.2f, 8.9f, 8.3f
  602. , 3.8f, 9.1f, -3.1f, -7.1f
  603. );
  604. const Matrix4x4 c = a * b;
  605. ENSURE(fequal(c.x.x, -12.85f, 0.00001f));
  606. ENSURE(fequal(c.x.y, -0.05f, 0.00001f));
  607. ENSURE(fequal(c.x.z, 61.83f, 0.00001f));
  608. ENSURE(fequal(c.x.w, 71.47f, 0.00001f));
  609. ENSURE(fequal(c.y.x, -16.33f, 0.00001f));
  610. ENSURE(fequal(c.y.y, -22.99f, 0.00001f));
  611. ENSURE(fequal(c.y.z, 58.17f, 0.00001f));
  612. ENSURE(fequal(c.y.w, 104.95f, 0.00001f));
  613. ENSURE(fequal(c.z.x, -18.22f, 0.00001f));
  614. ENSURE(fequal(c.z.y, -83.43f, 0.00001f));
  615. ENSURE(fequal(c.z.z, 5.98f, 0.00001f));
  616. ENSURE(fequal(c.z.w, 30.28f, 0.00001f));
  617. ENSURE(fequal(c.t.x, -1.60f, 0.00001f));
  618. ENSURE(fequal(c.t.y, 30.34f, 0.00001f));
  619. ENSURE(fequal(c.t.z, -40.13f, 0.00001f));
  620. ENSURE(fequal(c.t.w, -44.55f, 0.00001f));
  621. }
  622. {
  623. const Matrix4x4 a = from_elements(1.2f, -2.3f, 5.1f, -1.2f
  624. , 2.2f, -5.1f, 1.1f, -7.4f
  625. , 3.2f, 3.3f, -3.8f, -9.2f
  626. , -6.8f, -2.9f, 1.0f, 4.9f
  627. );
  628. const Matrix4x4 b = get_inverted(a);
  629. ENSURE(fequal(b.x.x, -0.08464f, 0.00001f));
  630. ENSURE(fequal(b.x.y, 0.06129f, 0.00001f));
  631. ENSURE(fequal(b.x.z, -0.15210f, 0.00001f));
  632. ENSURE(fequal(b.x.w, -0.21374f, 0.00001f));
  633. ENSURE(fequal(b.y.x, 0.14384f, 0.00001f));
  634. ENSURE(fequal(b.y.y, -0.18486f, 0.00001f));
  635. ENSURE(fequal(b.y.z, 0.14892f, 0.00001f));
  636. ENSURE(fequal(b.y.w, 0.03565f, 0.00001f));
  637. ENSURE(fequal(b.z.x, 0.26073f, 0.00001f));
  638. ENSURE(fequal(b.z.y, -0.09877f, 0.00001f));
  639. ENSURE(fequal(b.z.z, 0.07063f, 0.00001f));
  640. ENSURE(fequal(b.z.w, 0.04729f, 0.00001f));
  641. ENSURE(fequal(b.t.x, -0.08553f, 0.00001f));
  642. ENSURE(fequal(b.t.y, -0.00419f, 0.00001f));
  643. ENSURE(fequal(b.t.z, -0.13735f, 0.00001f));
  644. ENSURE(fequal(b.t.w, -0.08108f, 0.00001f));
  645. }
  646. {
  647. const Matrix4x4 a = from_elements(1.2f, -2.3f, 5.1f, -1.2f
  648. , 2.2f, -5.1f, 1.1f, -7.4f
  649. , 3.2f, 3.3f, -3.8f, -9.2f
  650. , -6.8f, -2.9f, 1.0f, 4.9f
  651. );
  652. const Matrix4x4 b = get_transposed(a);
  653. ENSURE(fequal(b.x.x, 1.2f, 0.00001f));
  654. ENSURE(fequal(b.x.y, 2.2f, 0.00001f));
  655. ENSURE(fequal(b.x.z, 3.2f, 0.00001f));
  656. ENSURE(fequal(b.x.w, -6.8f, 0.00001f));
  657. ENSURE(fequal(b.y.x, -2.3f, 0.00001f));
  658. ENSURE(fequal(b.y.y, -5.1f, 0.00001f));
  659. ENSURE(fequal(b.y.z, 3.3f, 0.00001f));
  660. ENSURE(fequal(b.y.w, -2.9f, 0.00001f));
  661. ENSURE(fequal(b.z.x, 5.1f, 0.00001f));
  662. ENSURE(fequal(b.z.y, 1.1f, 0.00001f));
  663. ENSURE(fequal(b.z.z, -3.8f, 0.00001f));
  664. ENSURE(fequal(b.z.w, 1.0f, 0.00001f));
  665. ENSURE(fequal(b.t.x, -1.2f, 0.00001f));
  666. ENSURE(fequal(b.t.y, -7.4f, 0.00001f));
  667. ENSURE(fequal(b.t.z, -9.2f, 0.00001f));
  668. ENSURE(fequal(b.t.w, 4.9f, 0.00001f));
  669. }
  670. }
  671. static void test_aabb()
  672. {
  673. {
  674. AABB a;
  675. aabb::reset(a);
  676. ENSURE(a.min == VECTOR3_ZERO);
  677. ENSURE(a.max == VECTOR3_ZERO);
  678. }
  679. {
  680. AABB a;
  681. a.min = vector3(-2.3f, 1.2f, -4.5f);
  682. a.max = vector3( 3.7f, 5.3f, -2.9f);
  683. const Vector3 c = aabb::center(a);
  684. ENSURE(fequal(c.x, 0.70f, 0.00001f));
  685. ENSURE(fequal(c.y, 3.25f, 0.00001f));
  686. ENSURE(fequal(c.z, -3.70f, 0.00001f));
  687. }
  688. {
  689. AABB a;
  690. a.min = vector3(-2.3f, 1.2f, -4.5f);
  691. a.max = vector3( 3.7f, 5.3f, -2.9f);
  692. const float c = aabb::volume(a);
  693. ENSURE(fequal(c, 39.36f, 0.00001f));
  694. }
  695. {
  696. const Vector3 points[] =
  697. {
  698. { -1.2f, 3.4f, 5.5f },
  699. { 8.2f, -2.4f, -1.5f },
  700. { -5.9f, 9.2f, 6.0f }
  701. };
  702. AABB a;
  703. aabb::from_points(a, countof(points), points);
  704. ENSURE(fequal(a.min.x, -5.9f, 0.00001f));
  705. ENSURE(fequal(a.min.y, -2.4f, 0.00001f));
  706. ENSURE(fequal(a.min.z, -1.5f, 0.00001f));
  707. ENSURE(fequal(a.max.x, 8.2f, 0.00001f));
  708. ENSURE(fequal(a.max.y, 9.2f, 0.00001f));
  709. ENSURE(fequal(a.max.z, 6.0f, 0.00001f));
  710. }
  711. {
  712. const Vector3 points[] =
  713. {
  714. { -1.2f, 3.4f, 5.5f },
  715. { 8.2f, -2.4f, -1.5f },
  716. { -5.9f, 9.2f, 6.0f },
  717. { -2.8f, -3.5f, 1.9f },
  718. { -8.3f, -3.1f, 1.9f },
  719. { 4.0f, -3.9f, -1.4f },
  720. { -0.4f, -1.8f, -2.2f },
  721. { -8.6f, -4.8f, 2.8f },
  722. { 4.1f, 4.7f, -0.4f }
  723. };
  724. AABB boxes[3];
  725. aabb::from_points(boxes[0], countof(points)/3, &points[0]);
  726. aabb::from_points(boxes[1], countof(points)/3, &points[3]);
  727. aabb::from_points(boxes[2], countof(points)/3, &points[6]);
  728. AABB d;
  729. aabb::from_boxes(d, countof(boxes), boxes);
  730. ENSURE(fequal(d.min.x, -8.6f, 0.00001f));
  731. ENSURE(fequal(d.min.y, -4.8f, 0.00001f));
  732. ENSURE(fequal(d.min.z, -2.2f, 0.00001f));
  733. ENSURE(fequal(d.max.x, 8.2f, 0.00001f));
  734. ENSURE(fequal(d.max.y, 9.2f, 0.00001f));
  735. ENSURE(fequal(d.max.z, 6.0f, 0.00001f));
  736. }
  737. {
  738. AABB a;
  739. a.min = vector3(-2.3f, 1.2f, -4.5f);
  740. a.max = vector3( 3.7f, 5.3f, -2.9f);
  741. ENSURE( aabb::contains_point(a, vector3(1.2f, 3.0f, -4.4f)));
  742. ENSURE(!aabb::contains_point(a, vector3(3.8f, 3.0f, -4.4f)));
  743. ENSURE(!aabb::contains_point(a, vector3(1.2f, -1.0f, -4.4f)));
  744. ENSURE(!aabb::contains_point(a, vector3(1.2f, 3.0f, -4.6f)));
  745. }
  746. }
  747. static void test_sphere()
  748. {
  749. {
  750. Sphere a;
  751. sphere::reset(a);
  752. ENSURE(a.c == VECTOR3_ZERO);
  753. ENSURE(fequal(a.r, 0.0f, 0.00001f));
  754. }
  755. {
  756. Sphere a;
  757. a.c = VECTOR3_ZERO;
  758. a.r = 1.61f;
  759. const float b = sphere::volume(a);
  760. ENSURE(fequal(b, 17.48099f, 0.00001f));
  761. }
  762. {
  763. Sphere a;
  764. sphere::reset(a);
  765. const Vector3 points[] =
  766. {
  767. { -1.2f, 3.4f, 5.5f },
  768. { 8.2f, -2.4f, -1.5f },
  769. { -5.9f, 9.2f, 6.0f }
  770. };
  771. sphere::add_points(a, countof(points), points);
  772. ENSURE(fequal(a.c.x, 0.0f, 0.00001f));
  773. ENSURE(fequal(a.c.y, 0.0f, 0.00001f));
  774. ENSURE(fequal(a.c.z, 0.0f, 0.00001f));
  775. ENSURE(fequal(a.r, 12.46795f, 0.00001f));
  776. }
  777. {
  778. Sphere spheres[3];
  779. sphere::reset(spheres[0]);
  780. sphere::reset(spheres[1]);
  781. sphere::reset(spheres[2]);
  782. const Vector3 points[] =
  783. {
  784. { 6.6f, 3.5f, -5.7f },
  785. { -5.3f, -9.1f, -7.9f },
  786. { -1.5f, 4.4f, -5.8f },
  787. { 7.2f, -2.4f, -9.5f },
  788. { 4.0f, -8.1f, 6.6f },
  789. { -8.2f, 2.2f, 4.6f },
  790. { 2.9f, -4.8f, -6.8f },
  791. { -7.6f, -7.0f, 0.8f },
  792. { 8.2f, 2.8f, -4.8f }
  793. };
  794. sphere::add_points(spheres[0], countof(points)/3, &points[0]);
  795. sphere::add_points(spheres[1], countof(points)/3, &points[3]);
  796. sphere::add_points(spheres[2], countof(points)/3, &points[6]);
  797. Sphere d;
  798. sphere::reset(d);
  799. sphere::add_spheres(d, countof(spheres), spheres);
  800. ENSURE(fequal(d.r, 13.16472f, 0.00001f));
  801. }
  802. {
  803. Sphere a;
  804. a.c = vector3(-2.3f, 1.2f, -4.5f);
  805. a.r = 1.0f;
  806. ENSURE( sphere::contains_point(a, vector3(-2.9f, 1.6f, -4.0f)));
  807. ENSURE(!sphere::contains_point(a, vector3(-3.9f, 1.6f, -4.0f)));
  808. ENSURE(!sphere::contains_point(a, vector3(-2.9f, 2.6f, -4.0f)));
  809. ENSURE(!sphere::contains_point(a, vector3(-2.9f, 1.6f, -6.0f)));
  810. }
  811. }
  812. static void test_murmur()
  813. {
  814. const u32 m = murmur32("murmur32", 8, 0);
  815. ENSURE(m == 0x7c2365dbu);
  816. const u64 n = murmur64("murmur64", 8, 0);
  817. ENSURE(n == 0x90631502d1a3432bu);
  818. }
  819. static void test_string_id()
  820. {
  821. memory_globals::init();
  822. {
  823. StringId32 a("murmur32");
  824. ENSURE(a._id == 0x7c2365dbu);
  825. StringId32 b("murmur32", 8);
  826. ENSURE(a._id == 0x7c2365dbu);
  827. char str[9];
  828. a.to_string(str, sizeof(str));
  829. ENSURE(strcmp(str, "7c2365db") == 0);
  830. }
  831. {
  832. StringId64 a("murmur64");
  833. ENSURE(a._id == 0x90631502d1a3432bu);
  834. StringId64 b("murmur64", 8);
  835. ENSURE(a._id == 0x90631502d1a3432bu);
  836. char str[17];
  837. a.to_string(str, sizeof(str));
  838. ENSURE(strcmp(str, "90631502d1a3432b") == 0);
  839. }
  840. {
  841. StringId32 id(0x2dd65fa6u);
  842. char str[9];
  843. id.to_string(str, sizeof(str));
  844. StringId32 parsed;
  845. parsed.parse(str);
  846. ENSURE(id == parsed);
  847. }
  848. {
  849. StringId64 id(0xa73491922dd65fa6u);
  850. char str[17];
  851. id.to_string(str, sizeof(str));
  852. StringId64 parsed;
  853. parsed.parse(str);
  854. ENSURE(id == parsed);
  855. }
  856. memory_globals::shutdown();
  857. }
  858. static void test_dynamic_string()
  859. {
  860. memory_globals::init();
  861. {
  862. TempAllocator1024 ta;
  863. DynamicString str(ta);
  864. ENSURE(str.empty());
  865. str.set("murmur32", 8);
  866. ENSURE(str.length() == 8);
  867. const StringId32 id = str.to_string_id();
  868. ENSURE(id._id == 0x7c2365dbu);
  869. }
  870. {
  871. TempAllocator1024 ta;
  872. DynamicString str(ta);
  873. str += "Test ";
  874. str += "string.";
  875. ENSURE(strcmp(str.c_str(), "Test string.") == 0);
  876. }
  877. {
  878. TempAllocator1024 ta;
  879. DynamicString str(ta);
  880. str.set(" \tSushi\t ", 13);
  881. str.ltrim();
  882. ENSURE(strcmp(str.c_str(), "Sushi\t ") == 0);
  883. }
  884. {
  885. TempAllocator1024 ta;
  886. DynamicString str(ta);
  887. str.set(" \tSushi\t ", 13);
  888. str.rtrim();
  889. ENSURE(strcmp(str.c_str(), " \tSushi") == 0);
  890. }
  891. {
  892. TempAllocator1024 ta;
  893. DynamicString str(ta);
  894. str.set(" \tSushi\t ", 13);
  895. str.trim();
  896. ENSURE(strcmp(str.c_str(), "Sushi") == 0);
  897. }
  898. {
  899. TempAllocator1024 ta;
  900. DynamicString str(ta);
  901. str.set("Hello everyone!", 15);
  902. ENSURE( str.has_prefix("Hello"));
  903. ENSURE(!str.has_prefix("Helloo"));
  904. ENSURE( str.has_suffix("one!"));
  905. ENSURE(!str.has_suffix("one"));
  906. ENSURE(!str.has_prefix("Hello everyone!!!"));
  907. ENSURE(!str.has_suffix("Hello everyone!!!"));
  908. }
  909. {
  910. Guid guid = guid::parse("dd733419-bbd0-4248-bc84-e0e8363d7165");
  911. TempAllocator128 ta;
  912. DynamicString str(ta);
  913. str.from_guid(guid);
  914. ENSURE(str.length() == 36);
  915. ENSURE(strcmp(str.c_str(), "dd733419-bbd0-4248-bc84-e0e8363d7165") == 0);
  916. }
  917. {
  918. StringId32 id = StringId32("test");
  919. TempAllocator128 ta;
  920. DynamicString str(ta);
  921. str.from_string_id(id);
  922. ENSURE(str.length() == 8);
  923. ENSURE(strcmp(str.c_str(), "1812752e") == 0);
  924. }
  925. {
  926. StringId64 id = StringId64("test");
  927. TempAllocator128 ta;
  928. DynamicString str(ta);
  929. str.from_string_id(id);
  930. ENSURE(str.length() == 16);
  931. ENSURE(strcmp(str.c_str(), "2f4a8724618f4c63") == 0);
  932. }
  933. memory_globals::shutdown();
  934. }
  935. static void test_guid()
  936. {
  937. memory_globals::init();
  938. guid_globals::init();
  939. {
  940. Guid guid = guid::new_guid();
  941. char str[37];
  942. guid::to_string(str, sizeof(str), guid);
  943. Guid parsed = guid::parse(str);
  944. ENSURE(guid == parsed);
  945. }
  946. {
  947. Guid guid;
  948. ENSURE(guid::try_parse(guid, "961f8005-6a7e-4371-9272-8454dd786884"));
  949. ENSURE(!guid::try_parse(guid, "961f80056a7e-4371-9272-8454dd786884"));
  950. }
  951. guid_globals::shutdown();
  952. memory_globals::shutdown();
  953. }
  954. static void test_json()
  955. {
  956. memory_globals::init();
  957. {
  958. JsonValueType::Enum t = json::type("null");
  959. ENSURE(t == JsonValueType::NIL);
  960. }
  961. {
  962. JsonValueType::Enum t = json::type("true");
  963. ENSURE(t == JsonValueType::BOOL);
  964. }
  965. {
  966. JsonValueType::Enum t = json::type("false");
  967. ENSURE(t == JsonValueType::BOOL);
  968. }
  969. {
  970. JsonValueType::Enum t = json::type("3.14");
  971. ENSURE(t == JsonValueType::NUMBER);
  972. }
  973. {
  974. JsonValueType::Enum t = json::type("\"foo\"");
  975. ENSURE(t == JsonValueType::STRING);
  976. }
  977. {
  978. JsonValueType::Enum t = json::type("[]");
  979. ENSURE(t == JsonValueType::ARRAY);
  980. }
  981. {
  982. JsonValueType::Enum t = json::type("{}");
  983. ENSURE(t == JsonValueType::OBJECT);
  984. }
  985. {
  986. const s32 a = json::parse_int("3.14");
  987. ENSURE(a == 3);
  988. }
  989. {
  990. const f32 a = json::parse_float("3.14");
  991. ENSURE(fequal(a, 3.14f));
  992. }
  993. {
  994. const bool a = json::parse_bool("true");
  995. ENSURE(a == true);
  996. }
  997. {
  998. const bool a = json::parse_bool("false");
  999. ENSURE(a == false);
  1000. }
  1001. {
  1002. TempAllocator1024 ta;
  1003. DynamicString str(ta);
  1004. json::parse_string(str, "\"This is JSON\"");
  1005. ENSURE(strcmp(str.c_str(), "This is JSON") == 0);
  1006. }
  1007. memory_globals::shutdown();
  1008. }
  1009. static void test_sjson()
  1010. {
  1011. memory_globals::init();
  1012. {
  1013. JsonValueType::Enum t = sjson::type("null");
  1014. ENSURE(t == JsonValueType::NIL);
  1015. }
  1016. {
  1017. JsonValueType::Enum t = sjson::type("true");
  1018. ENSURE(t == JsonValueType::BOOL);
  1019. }
  1020. {
  1021. JsonValueType::Enum t = sjson::type("false");
  1022. ENSURE(t == JsonValueType::BOOL);
  1023. }
  1024. {
  1025. JsonValueType::Enum t = sjson::type("3.14");
  1026. ENSURE(t == JsonValueType::NUMBER);
  1027. }
  1028. {
  1029. JsonValueType::Enum t = sjson::type("\"foo\"");
  1030. ENSURE(t == JsonValueType::STRING);
  1031. }
  1032. {
  1033. JsonValueType::Enum t = sjson::type("[]");
  1034. ENSURE(t == JsonValueType::ARRAY);
  1035. }
  1036. {
  1037. JsonValueType::Enum t = sjson::type("{}");
  1038. ENSURE(t == JsonValueType::OBJECT);
  1039. }
  1040. {
  1041. const s32 a = sjson::parse_int("3.14");
  1042. ENSURE(a == 3);
  1043. }
  1044. {
  1045. const f32 a = sjson::parse_float("3.14");
  1046. ENSURE(fequal(a, 3.14f));
  1047. }
  1048. {
  1049. const bool a = sjson::parse_bool("true");
  1050. ENSURE(a == true);
  1051. }
  1052. {
  1053. const bool a = sjson::parse_bool("false");
  1054. ENSURE(a == false);
  1055. }
  1056. {
  1057. TempAllocator1024 ta;
  1058. DynamicString str(ta);
  1059. sjson::parse_string(str, "\"This is JSON\"");
  1060. ENSURE(strcmp(str.c_str(), "This is JSON") == 0);
  1061. }
  1062. {
  1063. const Vector2 a = sjson::parse_vector2("[ 1.2 -2.5 ]");
  1064. ENSURE(fequal(a.x, 1.2f));
  1065. ENSURE(fequal(a.y, -2.5f));
  1066. }
  1067. {
  1068. const Vector3 a = sjson::parse_vector3("[ 3.1 0.5 -5.7]");
  1069. ENSURE(fequal(a.x, 3.1f));
  1070. ENSURE(fequal(a.y, 0.5f));
  1071. ENSURE(fequal(a.z, -5.7f));
  1072. }
  1073. {
  1074. const Vector4 a = sjson::parse_vector4("[ 6.7 -1.3 2.9 -0.4 ]");
  1075. ENSURE(fequal(a.x, 6.7f));
  1076. ENSURE(fequal(a.y, -1.3f));
  1077. ENSURE(fequal(a.z, 2.9f));
  1078. ENSURE(fequal(a.w, -0.4f));
  1079. }
  1080. {
  1081. const Quaternion a = sjson::parse_quaternion("[ -1.5 -3.4 9.1 -3.5 ]");
  1082. ENSURE(fequal(a.x, -1.5f));
  1083. ENSURE(fequal(a.y, -3.4f));
  1084. ENSURE(fequal(a.z, 9.1f));
  1085. ENSURE(fequal(a.w, -3.5f));
  1086. }
  1087. {
  1088. const Matrix4x4 a = sjson::parse_matrix4x4(
  1089. "["
  1090. "-3.2 5.3 -0.7 4.1 "
  1091. " 5.6 7.0 -3.2 -1.2 "
  1092. "-6.3 9.0 3.9 1.1 "
  1093. " 0.4 -7.3 8.9 -0.1 "
  1094. "]"
  1095. );
  1096. ENSURE(fequal(a.x.x, -3.2f));
  1097. ENSURE(fequal(a.x.y, 5.3f));
  1098. ENSURE(fequal(a.x.z, -0.7f));
  1099. ENSURE(fequal(a.x.w, 4.1f));
  1100. ENSURE(fequal(a.y.x, 5.6f));
  1101. ENSURE(fequal(a.y.y, 7.0f));
  1102. ENSURE(fequal(a.y.z, -3.2f));
  1103. ENSURE(fequal(a.y.w, -1.2f));
  1104. ENSURE(fequal(a.z.x, -6.3f));
  1105. ENSURE(fequal(a.z.y, 9.0f));
  1106. ENSURE(fequal(a.z.z, 3.9f));
  1107. ENSURE(fequal(a.z.w, 1.1f));
  1108. ENSURE(fequal(a.t.x, 0.4f));
  1109. ENSURE(fequal(a.t.y, -7.3f));
  1110. ENSURE(fequal(a.t.z, 8.9f));
  1111. ENSURE(fequal(a.t.w, -0.1f));
  1112. }
  1113. {
  1114. const StringId32 a = sjson::parse_string_id("\"murmur32\"");
  1115. ENSURE(a._id == 0x7c2365dbu);
  1116. }
  1117. {
  1118. const StringId64 a = sjson::parse_resource_name("\"murmur64\"");
  1119. ENSURE(a._id == 0x90631502d1a3432bu);
  1120. }
  1121. {
  1122. const Guid guid = guid::parse("0f6c3b1c-9cba-4282-9096-2a77ca047b1b");
  1123. const Guid parsed = sjson::parse_guid("\"0f6c3b1c-9cba-4282-9096-2a77ca047b1b\"");
  1124. ENSURE(guid == parsed);
  1125. }
  1126. {
  1127. TempAllocator128 ta;
  1128. DynamicString str(ta);
  1129. sjson::parse_verbatim(str, "\"\"\"verbatim\"\"\"");
  1130. ENSURE(strcmp(str.c_str(), "verbatim") == 0);
  1131. }
  1132. memory_globals::shutdown();
  1133. }
  1134. static void test_path()
  1135. {
  1136. #if CROWN_PLATFORM_POSIX
  1137. {
  1138. const bool a = path::is_absolute("/home/foo");
  1139. ENSURE(a == true);
  1140. const bool b = path::is_absolute("home/foo");
  1141. ENSURE(b == false);
  1142. }
  1143. {
  1144. const bool a = path::is_relative("/home/foo");
  1145. ENSURE(a == false);
  1146. const bool b = path::is_relative("home/foo");
  1147. ENSURE(b == true);
  1148. }
  1149. {
  1150. const bool a = path::is_root("/");
  1151. ENSURE(a == true);
  1152. const bool b = path::is_root("/home");
  1153. ENSURE(b == false);
  1154. }
  1155. {
  1156. ENSURE(path::has_trailing_separator("/home/foo/"));
  1157. ENSURE(!path::has_trailing_separator("/home/foo"));
  1158. }
  1159. {
  1160. TempAllocator128 ta;
  1161. DynamicString clean(ta);
  1162. path::reduce(clean, "/home//foo/");
  1163. ENSURE(clean == "/home/foo");
  1164. }
  1165. {
  1166. TempAllocator128 ta;
  1167. DynamicString clean(ta);
  1168. path::reduce(clean, "\\home\\\\foo\\");
  1169. ENSURE(clean == "/home/foo");
  1170. }
  1171. #else
  1172. {
  1173. const bool a = path::is_absolute("C:\\Users\\foo");
  1174. ENSURE(a == true);
  1175. const bool b = path::is_absolute("Users\\foo");
  1176. ENSURE(b == false);
  1177. }
  1178. {
  1179. const bool a = path::is_relative("D:\\Users\\foo");
  1180. ENSURE(a == false);
  1181. const bool b = path::is_relative("Users\\foo");
  1182. ENSURE(b == true);
  1183. }
  1184. {
  1185. const bool a = path::is_root("E:\\");
  1186. ENSURE(a == true);
  1187. const bool b = path::is_root("E:\\Users");
  1188. ENSURE(b == false);
  1189. }
  1190. {
  1191. ENSURE(path::has_trailing_separator("C:\\Users\\foo\\"));
  1192. ENSURE(!path::has_trailing_separator("C:\\Users\\foo"));
  1193. }
  1194. {
  1195. TempAllocator128 ta;
  1196. DynamicString clean(ta);
  1197. path::reduce(clean, "C:\\Users\\\\foo\\");
  1198. ENSURE(clean == "C:\\Users\\foo");
  1199. }
  1200. {
  1201. TempAllocator128 ta;
  1202. DynamicString clean(ta);
  1203. path::reduce(clean, "C:/Users//foo/");
  1204. ENSURE(clean == "C:\\Users\\foo");
  1205. }
  1206. #endif // CROWN_PLATFORM_POSIX
  1207. {
  1208. const char* p = path::basename("");
  1209. ENSURE(strcmp(p, "") == 0);
  1210. const char* q = path::basename("/");
  1211. ENSURE(strcmp(q, "") == 0);
  1212. const char* r = path::basename("boot.config");
  1213. ENSURE(strcmp(r, "boot.config") == 0);
  1214. const char* s = path::basename("foo/boot.config");
  1215. ENSURE(strcmp(s, "boot.config") == 0);
  1216. const char* t = path::basename("/foo/boot.config");
  1217. ENSURE(strcmp(t, "boot.config") == 0);
  1218. }
  1219. {
  1220. const char* p = path::extension("");
  1221. ENSURE(p == NULL);
  1222. const char* q = path::extension("boot");
  1223. ENSURE(q == NULL);
  1224. const char* r = path::extension("boot.bar.config");
  1225. ENSURE(strcmp(r, "config") == 0);
  1226. }
  1227. {
  1228. TempAllocator128 ta;
  1229. DynamicString path(ta);
  1230. path::join(path, "", "");
  1231. ENSURE(path == "");
  1232. }
  1233. {
  1234. TempAllocator128 ta;
  1235. DynamicString path(ta);
  1236. path::join(path, "foo", "");
  1237. ENSURE(path == "foo");
  1238. }
  1239. {
  1240. TempAllocator128 ta;
  1241. DynamicString path(ta);
  1242. path::join(path, "", "bar");
  1243. ENSURE(path == "bar");
  1244. }
  1245. #if CROWN_PLATFORM_POSIX
  1246. {
  1247. TempAllocator128 ta;
  1248. DynamicString path(ta);
  1249. path::join(path, "foo", "bar");
  1250. ENSURE(path == "foo/bar");
  1251. }
  1252. #else
  1253. {
  1254. TempAllocator128 ta;
  1255. DynamicString path(ta);
  1256. path::join(path, "C:\\foo", "bar");
  1257. ENSURE(path == "C:\\foo\\bar");
  1258. }
  1259. #endif // CROWN_PLATFORM_POSIX
  1260. }
  1261. static void test_command_line()
  1262. {
  1263. const char* argv[] =
  1264. {
  1265. "args",
  1266. "-s",
  1267. "--switch",
  1268. "--argument",
  1269. "orange"
  1270. };
  1271. CommandLine cl(countof(argv), argv);
  1272. ENSURE(cl.has_option("switch", 's'));
  1273. const char* orange = cl.get_parameter(0, "argument");
  1274. ENSURE(orange != NULL && strcmp(orange, "orange") == 0);
  1275. }
  1276. static void test_thread()
  1277. {
  1278. Thread thread;
  1279. ENSURE(!thread.is_running());
  1280. thread.start([](void*) { return 0xbadc0d3; }, NULL);
  1281. thread.stop();
  1282. ENSURE(thread.exit_code() == 0xbadc0d3);
  1283. }
  1284. static void test_process()
  1285. {
  1286. #if CROWN_PLATFORM_POSIX
  1287. {
  1288. const char* argv[] = {"printf", "Hello,\\nworld.\\n", NULL};
  1289. Process pr;
  1290. if (pr.spawn(argv, ProcessFlags::STDOUT_PIPE) == 0)
  1291. {
  1292. char buf[128] = {0};
  1293. pr.fgets(buf, sizeof(buf));
  1294. ENSURE(strcmp(buf, "Hello,\n") == 0);
  1295. pr.fgets(buf, sizeof(buf));
  1296. ENSURE(strcmp(buf, "world.\n") == 0);
  1297. pr.wait();
  1298. }
  1299. }
  1300. {
  1301. const char* argv[] = {"false", NULL};
  1302. Process pr;
  1303. if (pr.spawn(argv) == 0)
  1304. ENSURE(pr.wait() == 1);
  1305. }
  1306. #endif
  1307. }
  1308. static void test_filesystem()
  1309. {
  1310. #if CROWN_PLATFORM_POSIX
  1311. {
  1312. DeleteResult dr = os::delete_directory("/tmp/none");
  1313. ENSURE(dr.error == DeleteResult::NO_ENTRY);
  1314. }
  1315. {
  1316. os::delete_directory("/tmp/crown");
  1317. CreateResult cr = os::create_directory("/tmp/crown");
  1318. ENSURE(cr.error == CreateResult::SUCCESS);
  1319. cr = os::create_directory("/tmp/crown");
  1320. ENSURE(cr.error == CreateResult::ALREADY_EXISTS);
  1321. DeleteResult dr = os::delete_directory("/tmp/crown");
  1322. ENSURE(dr.error == DeleteResult::SUCCESS);
  1323. }
  1324. #endif // CROWN_PLATFORM_POSIX
  1325. }
  1326. #define RUN_TEST(name) \
  1327. do { \
  1328. printf(#name "\n"); \
  1329. name(); \
  1330. } while (0)
  1331. int main_unit_tests()
  1332. {
  1333. RUN_TEST(test_memory);
  1334. RUN_TEST(test_array);
  1335. RUN_TEST(test_vector);
  1336. RUN_TEST(test_hash_map);
  1337. RUN_TEST(test_hash_set);
  1338. RUN_TEST(test_vector2);
  1339. RUN_TEST(test_vector3);
  1340. RUN_TEST(test_vector4);
  1341. RUN_TEST(test_quaternion);
  1342. RUN_TEST(test_color4);
  1343. RUN_TEST(test_matrix3x3);
  1344. RUN_TEST(test_matrix4x4);
  1345. RUN_TEST(test_aabb);
  1346. RUN_TEST(test_sphere);
  1347. RUN_TEST(test_murmur);
  1348. RUN_TEST(test_string_id);
  1349. RUN_TEST(test_dynamic_string);
  1350. RUN_TEST(test_guid);
  1351. RUN_TEST(test_json);
  1352. RUN_TEST(test_sjson);
  1353. RUN_TEST(test_path);
  1354. RUN_TEST(test_command_line);
  1355. RUN_TEST(test_thread);
  1356. RUN_TEST(test_process);
  1357. RUN_TEST(test_filesystem);
  1358. return EXIT_SUCCESS;
  1359. }
  1360. } // namespace crown
  1361. #endif // CROWN_BUILD_UNIT_TESTS