test_list.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /**************************************************************************/
  2. /* test_list.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifndef TEST_LIST_H
  31. #define TEST_LIST_H
  32. #include "core/templates/list.h"
  33. #include "tests/test_macros.h"
  34. namespace TestList {
  35. static void populate_integers(List<int> &p_list, List<int>::Element *r_elements[], int num_elements) {
  36. p_list.clear();
  37. for (int i = 0; i < num_elements; ++i) {
  38. List<int>::Element *n = p_list.push_back(i);
  39. r_elements[i] = n;
  40. }
  41. }
  42. TEST_CASE("[List] List initialization") {
  43. List<int> list{ 0, 1, 2, 3, 4 };
  44. CHECK(list.size() == 5);
  45. CHECK(list.get(0) == 0);
  46. CHECK(list.get(1) == 1);
  47. CHECK(list.get(2) == 2);
  48. CHECK(list.get(3) == 3);
  49. CHECK(list.get(4) == 4);
  50. }
  51. TEST_CASE("[List] Push/pop back") {
  52. List<String> list;
  53. List<String>::Element *n;
  54. n = list.push_back("A");
  55. CHECK(n->get() == "A");
  56. n = list.push_back("B");
  57. CHECK(n->get() == "B");
  58. n = list.push_back("C");
  59. CHECK(n->get() == "C");
  60. CHECK(list.size() == 3);
  61. CHECK(!list.is_empty());
  62. String v;
  63. v = list.back()->get();
  64. list.pop_back();
  65. CHECK(v == "C");
  66. v = list.back()->get();
  67. list.pop_back();
  68. CHECK(v == "B");
  69. v = list.back()->get();
  70. list.pop_back();
  71. CHECK(v == "A");
  72. CHECK(list.size() == 0);
  73. CHECK(list.is_empty());
  74. CHECK(list.back() == nullptr);
  75. CHECK(list.front() == nullptr);
  76. }
  77. TEST_CASE("[List] Push/pop front") {
  78. List<String> list;
  79. List<String>::Element *n;
  80. n = list.push_front("A");
  81. CHECK(n->get() == "A");
  82. n = list.push_front("B");
  83. CHECK(n->get() == "B");
  84. n = list.push_front("C");
  85. CHECK(n->get() == "C");
  86. CHECK(list.size() == 3);
  87. CHECK(!list.is_empty());
  88. String v;
  89. v = list.front()->get();
  90. list.pop_front();
  91. CHECK(v == "C");
  92. v = list.front()->get();
  93. list.pop_front();
  94. CHECK(v == "B");
  95. v = list.front()->get();
  96. list.pop_front();
  97. CHECK(v == "A");
  98. CHECK(list.size() == 0);
  99. CHECK(list.is_empty());
  100. CHECK(list.back() == nullptr);
  101. CHECK(list.front() == nullptr);
  102. }
  103. TEST_CASE("[List] Set and get") {
  104. List<String> list;
  105. list.push_back("A");
  106. List<String>::Element *n = list.front();
  107. CHECK(n->get() == "A");
  108. n->set("X");
  109. CHECK(n->get() == "X");
  110. }
  111. TEST_CASE("[List] Insert before") {
  112. List<String> list;
  113. List<String>::Element *a = list.push_back("A");
  114. List<String>::Element *b = list.push_back("B");
  115. List<String>::Element *c = list.push_back("C");
  116. list.insert_before(b, "I");
  117. CHECK(a->next()->get() == "I");
  118. CHECK(c->prev()->prev()->get() == "I");
  119. CHECK(list.front()->next()->get() == "I");
  120. CHECK(list.back()->prev()->prev()->get() == "I");
  121. }
  122. TEST_CASE("[List] Insert after") {
  123. List<String> list;
  124. List<String>::Element *a = list.push_back("A");
  125. List<String>::Element *b = list.push_back("B");
  126. List<String>::Element *c = list.push_back("C");
  127. list.insert_after(b, "I");
  128. CHECK(a->next()->next()->get() == "I");
  129. CHECK(c->prev()->get() == "I");
  130. CHECK(list.front()->next()->next()->get() == "I");
  131. CHECK(list.back()->prev()->get() == "I");
  132. }
  133. TEST_CASE("[List] Insert before null") {
  134. List<String> list;
  135. List<String>::Element *a = list.push_back("A");
  136. List<String>::Element *b = list.push_back("B");
  137. List<String>::Element *c = list.push_back("C");
  138. list.insert_before(nullptr, "I");
  139. CHECK(a->next()->get() == "B");
  140. CHECK(b->get() == "B");
  141. CHECK(c->prev()->prev()->get() == "A");
  142. CHECK(list.front()->next()->get() == "B");
  143. CHECK(list.back()->prev()->prev()->get() == "B");
  144. CHECK(list.back()->get() == "I");
  145. }
  146. TEST_CASE("[List] Insert after null") {
  147. List<String> list;
  148. List<String>::Element *a = list.push_back("A");
  149. List<String>::Element *b = list.push_back("B");
  150. List<String>::Element *c = list.push_back("C");
  151. list.insert_after(nullptr, "I");
  152. CHECK(a->next()->get() == "B");
  153. CHECK(b->get() == "B");
  154. CHECK(c->prev()->prev()->get() == "A");
  155. CHECK(list.front()->next()->get() == "B");
  156. CHECK(list.back()->prev()->prev()->get() == "B");
  157. CHECK(list.back()->get() == "I");
  158. }
  159. TEST_CASE("[List] Find") {
  160. List<int> list;
  161. List<int>::Element *n[10];
  162. // Indices match values.
  163. populate_integers(list, n, 10);
  164. for (int i = 0; i < 10; ++i) {
  165. CHECK(n[i]->get() == list.find(i)->get());
  166. }
  167. }
  168. TEST_CASE("[List] Erase (by value)") {
  169. List<int> list;
  170. List<int>::Element *n[4];
  171. // Indices match values.
  172. populate_integers(list, n, 4);
  173. CHECK(list.front()->next()->next()->get() == 2);
  174. bool erased = list.erase(2); // 0, 1, 3.
  175. CHECK(erased);
  176. CHECK(list.size() == 3);
  177. // The pointer n[2] points to the freed memory which is not reset to zero,
  178. // so the below assertion may pass, but this relies on undefined behavior.
  179. // CHECK(n[2]->get() == 2);
  180. CHECK(list.front()->get() == 0);
  181. CHECK(list.front()->next()->next()->get() == 3);
  182. CHECK(list.back()->get() == 3);
  183. CHECK(list.back()->prev()->get() == 1);
  184. CHECK(n[1]->next()->get() == 3);
  185. CHECK(n[3]->prev()->get() == 1);
  186. erased = list.erase(9000); // Doesn't exist.
  187. CHECK(!erased);
  188. }
  189. TEST_CASE("[List] Erase (by element)") {
  190. List<int> list;
  191. List<int>::Element *n[4];
  192. // Indices match values.
  193. populate_integers(list, n, 4);
  194. bool erased = list.erase(n[2]);
  195. CHECK(erased);
  196. CHECK(list.size() == 3);
  197. CHECK(n[1]->next()->get() == 3);
  198. CHECK(n[3]->prev()->get() == 1);
  199. }
  200. TEST_CASE("[List] Element erase") {
  201. List<int> list;
  202. List<int>::Element *n[4];
  203. // Indices match values.
  204. populate_integers(list, n, 4);
  205. n[2]->erase();
  206. CHECK(list.size() == 3);
  207. CHECK(n[1]->next()->get() == 3);
  208. CHECK(n[3]->prev()->get() == 1);
  209. }
  210. TEST_CASE("[List] Clear") {
  211. List<int> list;
  212. List<int>::Element *n[100];
  213. populate_integers(list, n, 100);
  214. list.clear();
  215. CHECK(list.size() == 0);
  216. CHECK(list.is_empty());
  217. }
  218. TEST_CASE("[List] Invert") {
  219. List<int> list;
  220. List<int>::Element *n[4];
  221. populate_integers(list, n, 4);
  222. list.reverse();
  223. CHECK(list.front()->get() == 3);
  224. CHECK(list.front()->next()->get() == 2);
  225. CHECK(list.back()->prev()->get() == 1);
  226. CHECK(list.back()->get() == 0);
  227. }
  228. TEST_CASE("[List] Move to front") {
  229. List<int> list;
  230. List<int>::Element *n[4];
  231. populate_integers(list, n, 4);
  232. list.move_to_front(n[3]);
  233. CHECK(list.front()->get() == 3);
  234. CHECK(list.back()->get() == 2);
  235. }
  236. TEST_CASE("[List] Move to back") {
  237. List<int> list;
  238. List<int>::Element *n[4];
  239. populate_integers(list, n, 4);
  240. list.move_to_back(n[0]);
  241. CHECK(list.back()->get() == 0);
  242. CHECK(list.front()->get() == 1);
  243. }
  244. TEST_CASE("[List] Move before") {
  245. List<int> list;
  246. List<int>::Element *n[4];
  247. populate_integers(list, n, 4);
  248. list.move_before(n[3], n[1]);
  249. CHECK(list.front()->next()->get() == n[3]->get());
  250. }
  251. TEST_CASE("[List] Sort") {
  252. List<String> list;
  253. list.push_back("D");
  254. list.push_back("B");
  255. list.push_back("A");
  256. list.push_back("C");
  257. list.sort();
  258. CHECK(list.front()->get() == "A");
  259. CHECK(list.front()->next()->get() == "B");
  260. CHECK(list.back()->prev()->get() == "C");
  261. CHECK(list.back()->get() == "D");
  262. }
  263. TEST_CASE("[List] Swap adjacent front and back") {
  264. List<int> list;
  265. List<int>::Element *n[2];
  266. populate_integers(list, n, 2);
  267. list.swap(list.front(), list.back());
  268. CHECK(list.front()->prev() == nullptr);
  269. CHECK(list.front() != list.front()->next());
  270. CHECK(list.front() == n[1]);
  271. CHECK(list.back() == n[0]);
  272. CHECK(list.back()->next() == nullptr);
  273. CHECK(list.back() != list.back()->prev());
  274. }
  275. TEST_CASE("[List] Swap first adjacent pair") {
  276. List<int> list;
  277. List<int>::Element *n[4];
  278. populate_integers(list, n, 4);
  279. list.swap(n[0], n[1]);
  280. CHECK(list.front()->prev() == nullptr);
  281. CHECK(list.front() != list.front()->next());
  282. CHECK(list.front() == n[1]);
  283. CHECK(list.front()->next() == n[0]);
  284. CHECK(list.back()->prev() == n[2]);
  285. CHECK(list.back() == n[3]);
  286. CHECK(list.back()->next() == nullptr);
  287. CHECK(list.back() != list.back()->prev());
  288. }
  289. TEST_CASE("[List] Swap middle adjacent pair") {
  290. List<int> list;
  291. List<int>::Element *n[4];
  292. populate_integers(list, n, 4);
  293. list.swap(n[1], n[2]);
  294. CHECK(list.front()->prev() == nullptr);
  295. CHECK(list.front() == n[0]);
  296. CHECK(list.front()->next() == n[2]);
  297. CHECK(list.back()->prev() == n[1]);
  298. CHECK(list.back() == n[3]);
  299. CHECK(list.back()->next() == nullptr);
  300. }
  301. TEST_CASE("[List] Swap last adjacent pair") {
  302. List<int> list;
  303. List<int>::Element *n[4];
  304. populate_integers(list, n, 4);
  305. list.swap(n[2], n[3]);
  306. CHECK(list.front()->prev() == nullptr);
  307. CHECK(list.front() == n[0]);
  308. CHECK(list.front()->next() == n[1]);
  309. CHECK(list.back()->prev() == n[3]);
  310. CHECK(list.back() == n[2]);
  311. CHECK(list.back()->next() == nullptr);
  312. }
  313. TEST_CASE("[List] Swap first cross pair") {
  314. List<int> list;
  315. List<int>::Element *n[4];
  316. populate_integers(list, n, 4);
  317. list.swap(n[0], n[2]);
  318. CHECK(list.front()->prev() == nullptr);
  319. CHECK(list.front() == n[2]);
  320. CHECK(list.front()->next() == n[1]);
  321. CHECK(list.back()->prev() == n[0]);
  322. CHECK(list.back() == n[3]);
  323. CHECK(list.back()->next() == nullptr);
  324. }
  325. TEST_CASE("[List] Swap last cross pair") {
  326. List<int> list;
  327. List<int>::Element *n[4];
  328. populate_integers(list, n, 4);
  329. list.swap(n[1], n[3]);
  330. CHECK(list.front()->prev() == nullptr);
  331. CHECK(list.front() == n[0]);
  332. CHECK(list.front()->next() == n[3]);
  333. CHECK(list.back()->prev() == n[2]);
  334. CHECK(list.back() == n[1]);
  335. CHECK(list.back()->next() == nullptr);
  336. }
  337. TEST_CASE("[List] Swap edges") {
  338. List<int> list;
  339. List<int>::Element *n[4];
  340. populate_integers(list, n, 4);
  341. list.swap(n[1], n[3]);
  342. CHECK(list.front()->prev() == nullptr);
  343. CHECK(list.front() == n[0]);
  344. CHECK(list.front()->next() == n[3]);
  345. CHECK(list.back()->prev() == n[2]);
  346. CHECK(list.back() == n[1]);
  347. CHECK(list.back()->next() == nullptr);
  348. }
  349. TEST_CASE("[List] Swap middle (values check)") {
  350. List<String> list;
  351. List<String>::Element *n_str1 = list.push_back("Still");
  352. List<String>::Element *n_str2 = list.push_back("waiting");
  353. List<String>::Element *n_str3 = list.push_back("for");
  354. List<String>::Element *n_str4 = list.push_back("Godot.");
  355. CHECK(n_str1->get() == "Still");
  356. CHECK(n_str4->get() == "Godot.");
  357. CHECK(list.front()->get() == "Still");
  358. CHECK(list.front()->next()->get() == "waiting");
  359. CHECK(list.back()->prev()->get() == "for");
  360. CHECK(list.back()->get() == "Godot.");
  361. list.swap(n_str2, n_str3);
  362. CHECK(list.front()->next()->get() == "for");
  363. CHECK(list.back()->prev()->get() == "waiting");
  364. }
  365. TEST_CASE("[List] Swap front and back (values check)") {
  366. List<Variant> list;
  367. Variant str = "Godot";
  368. List<Variant>::Element *n_str = list.push_back(str);
  369. Variant color = Color(0, 0, 1);
  370. List<Variant>::Element *n_color = list.push_back(color);
  371. CHECK(list.front()->get() == "Godot");
  372. CHECK(list.back()->get() == Color(0, 0, 1));
  373. list.swap(n_str, n_color);
  374. CHECK(list.front()->get() == Color(0, 0, 1));
  375. CHECK(list.back()->get() == "Godot");
  376. }
  377. TEST_CASE("[List] Swap adjacent back and front (reverse order of elements)") {
  378. List<int> list;
  379. List<int>::Element *n[2];
  380. populate_integers(list, n, 2);
  381. list.swap(n[1], n[0]);
  382. List<int>::Element *it = list.front();
  383. while (it) {
  384. List<int>::Element *prev_it = it;
  385. it = it->next();
  386. if (it == prev_it) {
  387. FAIL_CHECK("Infinite loop detected.");
  388. break;
  389. }
  390. }
  391. }
  392. static void swap_random(List<int> &p_list, List<int>::Element *r_elements[], size_t p_size, size_t p_iterations) {
  393. Math::seed(0);
  394. for (size_t test_i = 0; test_i < p_iterations; ++test_i) {
  395. // A and B elements have corresponding indices as values.
  396. const int a_idx = static_cast<int>(Math::rand() % p_size);
  397. const int b_idx = static_cast<int>(Math::rand() % p_size);
  398. List<int>::Element *a = p_list.find(a_idx); // via find.
  399. List<int>::Element *b = r_elements[b_idx]; // via pointer.
  400. int va = a->get();
  401. int vb = b->get();
  402. p_list.swap(a, b);
  403. CHECK(va == a->get());
  404. CHECK(vb == b->get());
  405. size_t element_count = 0;
  406. // Fully traversable after swap?
  407. List<int>::Element *it = p_list.front();
  408. while (it) {
  409. element_count += 1;
  410. List<int>::Element *prev_it = it;
  411. it = it->next();
  412. if (it == prev_it) {
  413. FAIL_CHECK("Infinite loop detected.");
  414. break;
  415. }
  416. }
  417. // We should not lose anything in the process.
  418. if (element_count != p_size) {
  419. FAIL_CHECK("Element count mismatch.");
  420. break;
  421. }
  422. }
  423. }
  424. TEST_CASE("[Stress][List] Swap random 100 elements, 500 iterations.") {
  425. List<int> list;
  426. List<int>::Element *n[100];
  427. populate_integers(list, n, 100);
  428. swap_random(list, n, 100, 500);
  429. }
  430. TEST_CASE("[Stress][List] Swap random 10 elements, 1000 iterations.") {
  431. List<int> list;
  432. List<int>::Element *n[10];
  433. populate_integers(list, n, 10);
  434. swap_random(list, n, 10, 1000);
  435. }
  436. } // namespace TestList
  437. #endif // TEST_LIST_H