/src/tests/util/list_test.c

http://embox.googlecode.com/ · C · 527 lines · 364 code · 135 blank · 28 comment · 0 complexity · 3c4a013813010a6dcd9ec8190e797b8a MD5 · raw file

  1. /**
  2. * @file
  3. * @brief Tests methods of util/list.
  4. *
  5. * @date 12.03.11
  6. * @author Eldar Abusalimov
  7. */
  8. #include <embox/test.h>
  9. #include <string.h>
  10. #include <util/array.h>
  11. #include <util/list.h>
  12. EMBOX_TEST_SUITE("util/list test");
  13. TEST_SETUP(setup);
  14. struct element {
  15. int some_stuff;
  16. struct list_link lnk;
  17. };
  18. typedef member_t(struct element, lnk) element_in_list;
  19. static struct element x, y, z;
  20. static struct list m, n;
  21. static struct element * const xyz[] = { &x, &y, &z, NULL };
  22. static struct element * const xy[] = { &x, &y, NULL };
  23. static struct element * const yz[] = { &y, &z, NULL };
  24. static struct element * const xz[] = { &x, &z, NULL };
  25. /**
  26. * Fills a @a list with the contents of an @a array.
  27. *
  28. * @param array
  29. * @a NULL terminated array.
  30. * @param list
  31. * The list to fill in.
  32. * @return
  33. * The given @a list.
  34. */
  35. static struct list *fill_in_from(struct element * const array[],
  36. struct list *list);
  37. /**
  38. * Compares a @a list with the pattern @a array. The list becomes empty after
  39. * the comparison.
  40. *
  41. * @param array
  42. * @a NULL terminated array with the expected pattern.
  43. * @param list
  44. * The list to check.
  45. * @return
  46. * The given @a list.
  47. */
  48. static struct list *compare_with(struct element * const array[],
  49. struct list *list);
  50. TEST_CASE("list_element should cast link member out to its container") {
  51. struct list_link *link = &x.lnk;
  52. test_assert_equal(list_element(link, struct element, lnk), &x);
  53. }
  54. TEST_CASE("list_init should return its argument") {
  55. struct list l;
  56. test_assert_equal(list_init(&l), &l);
  57. }
  58. TEST_CASE("list_link_init should return its argument") {
  59. struct element e;
  60. test_assert_equal(list_link_init(&e.lnk), &e.lnk);
  61. }
  62. TEST_CASE("list_init should have the same effect as static initializer") {
  63. struct list l = LIST_INIT(&l);
  64. char buff[sizeof(l)];
  65. memcpy(buff, &l, sizeof(l));
  66. memset(&l, 0xA5, sizeof(l)); /* poison. */
  67. test_assert_mem_equal(buff, list_init(&l), sizeof(l));
  68. }
  69. TEST_CASE("list_link_init should have the same effect as static initializer") {
  70. struct element e = { .lnk = LIST_LINK_INIT(&e.lnk), .some_stuff = 42, };
  71. char buff[sizeof(e.lnk)];
  72. memcpy(buff, &e.lnk, sizeof(e.lnk));
  73. memset(&e.lnk, 0xA5, sizeof(e.lnk)); /* poison. */
  74. test_assert_mem_equal(buff, list_link_init(&e.lnk), sizeof(e.lnk));
  75. }
  76. TEST_CASE("list_is_empty should return true for just created list") {
  77. test_assert_true(list_is_empty(&m));
  78. }
  79. TEST_CASE("list_alone_link should return true for just initialized link") {
  80. test_assert_true(list_alone_link(&x.lnk));
  81. }
  82. TEST_CASE("list_alone should return true for just initialized element") {
  83. test_assert_true(list_alone(element_in_list, &x));
  84. }
  85. TEST_CASE("list_first should return null for empty list") {
  86. test_assert_null(list_first(element_in_list, &m));
  87. }
  88. TEST_CASE("list_last should return null for empty list") {
  89. test_assert_null(list_last(element_in_list, &m));
  90. }
  91. TEST_CASE("list_first_link should return null for empty list") {
  92. test_assert_null(list_first_link(&m));
  93. }
  94. TEST_CASE("list_last_link should return null for empty list") {
  95. test_assert_null(list_last_link(&m));
  96. }
  97. TEST_CASE("list_add_first should make the list non empty "
  98. "and the element not alone") {
  99. list_add_first(element_in_list, &x, &m);
  100. test_assert_false(list_is_empty(&m));
  101. test_assert_false(list_alone(element_in_list, &x));
  102. }
  103. TEST_CASE("list_add_last should make the list non empty "
  104. "and the element not alone") {
  105. list_add_last(element_in_list, &x, &m);
  106. test_assert_false(list_is_empty(&m));
  107. test_assert_false(list_alone(element_in_list, &x));
  108. }
  109. TEST_CASE("list_add_first_link should make the list non empty "
  110. "and the element's link not alone") {
  111. list_add_first_link(&x.lnk, &m);
  112. test_assert_false(list_is_empty(&m));
  113. test_assert_false(list_alone_link(&x.lnk));
  114. }
  115. TEST_CASE("list_add_last_link should make the list non empty "
  116. "and the element's link not alone") {
  117. list_add_last_link(&x.lnk, &m);
  118. test_assert_false(list_is_empty(&m));
  119. test_assert_false(list_alone_link(&x.lnk));
  120. }
  121. TEST_CASE("list_first_link and list_last_link on a single element list "
  122. "constructed using list_add_first should return the element's link") {
  123. list_add_first(element_in_list, &x, &m);
  124. test_assert_equal(list_first_link(&m), &x.lnk);
  125. test_assert_equal(list_last_link(&m), &x.lnk);
  126. }
  127. TEST_CASE("list_first_link and list_last_link on a single element list "
  128. "constructed using list_add_last should return the element's link") {
  129. list_add_last(element_in_list, &x, &m);
  130. test_assert_equal(list_first_link(&m), &x.lnk);
  131. test_assert_equal(list_last_link(&m), &x.lnk);
  132. }
  133. TEST_CASE("list_first_link and list_last_link should return a new and an old "
  134. "element accordingly after adding a new one with list_add_first") {
  135. test_assert_not_equal(&x, &y);
  136. list_add_first(element_in_list, &x, &m);
  137. list_add_first(element_in_list, &y, &m);
  138. test_assert_equal(list_first_link(&m), &y.lnk);
  139. test_assert_equal(list_last_link(&m), &x.lnk);
  140. }
  141. TEST_CASE("list_first_link and list_last_link should return a new and an old "
  142. "element accordingly after adding a new one with list_add_last") {
  143. test_assert_not_equal(&x, &y);
  144. list_add_last(element_in_list, &x, &m);
  145. list_add_last(element_in_list, &y, &m);
  146. test_assert_equal(list_first_link(&m), &x.lnk);
  147. test_assert_equal(list_last_link(&m), &y.lnk);
  148. }
  149. TEST_CASE("list_unlink on a single element list should make the list empty "
  150. "and element alone again") {
  151. list_add_first(element_in_list, &x, &m);
  152. list_unlink(element_in_list, &x);
  153. test_assert_true(list_is_empty(&m));
  154. test_assert_true(list_alone(element_in_list, &x));
  155. }
  156. TEST_CASE("single list_unlink and subsequent list_add_first to another list "
  157. "should make the first list empty but an element not alone") {
  158. test_assert_not_equal(&m, &n);
  159. list_add_first(element_in_list, &x, &m);
  160. list_unlink(element_in_list, &x);
  161. list_add_first(element_in_list, &x, &n);
  162. test_assert_true(list_is_empty(&m));
  163. test_assert_false(list_is_empty(&n));
  164. test_assert_false(list_alone(element_in_list, &x));
  165. }
  166. TEST_CASE("multiple list_unlink and subsequent list_add_first to another list "
  167. "should make the first list empty but elements not alone") {
  168. fill_in_from(xyz, &m);
  169. list_unlink(element_in_list, &x);
  170. list_unlink(element_in_list, &z);
  171. list_unlink(element_in_list, &y);
  172. fill_in_from(xyz, &n);
  173. test_assert_true(list_is_empty(&m));
  174. test_assert_false(list_is_empty(&n));
  175. test_assert_false(list_alone(element_in_list, &x));
  176. test_assert_false(list_alone(element_in_list, &y));
  177. test_assert_false(list_alone(element_in_list, &z));
  178. test_assert_equal(list_first_link(&n), &x.lnk);
  179. test_assert_equal(list_last_link(&n), &z.lnk);
  180. }
  181. TEST_CASE("list_remove_first should return null for empty list") {
  182. test_assert_null(list_remove_first(element_in_list, &m));
  183. }
  184. TEST_CASE("list_remove_last should return null for empty list") {
  185. test_assert_null(list_remove_last(element_in_list, &m));
  186. }
  187. TEST_CASE("list_remove_first on a single element list should return the "
  188. "element and make the list empty and element alone again") {
  189. list_add_first(element_in_list, &x, &m);
  190. test_assert_equal(list_remove_first(element_in_list, &m), &x);
  191. test_assert_true(list_is_empty(&m));
  192. test_assert_true(list_alone(element_in_list, &x));
  193. }
  194. TEST_CASE("list_remove_last on a single element list should return the "
  195. "element and make the list empty and element alone again") {
  196. list_add_first(element_in_list, &x, &m);
  197. test_assert_equal(list_remove_last(element_in_list, &m), &x);
  198. test_assert_true(list_is_empty(&m));
  199. test_assert_true(list_alone(element_in_list, &x));
  200. }
  201. TEST_CASE("list_insert_before on a single element list should make "
  202. "a new element the first one in the list") {
  203. list_add_first(element_in_list, &x, &m);
  204. list_insert_before(element_in_list, &y, &x);
  205. test_assert_equal(list_last_link(&m), &x.lnk);
  206. test_assert_equal(list_first_link(&m), &y.lnk);
  207. }
  208. TEST_CASE("list_insert_after on a single element list should make "
  209. "a new element the last one in the list") {
  210. list_add_first(element_in_list, &x, &m);
  211. list_insert_after(element_in_list, &y, &x);
  212. test_assert_equal(list_first_link(&m), &x.lnk);
  213. test_assert_equal(list_last_link(&m), &y.lnk);
  214. }
  215. TEST_CASE("list_insert_before: inserting a new element before the last one "
  216. "in a list of two elements should insert a new one between them") {
  217. list_add_first(element_in_list, &x, &m);
  218. list_add_last(element_in_list, &z, &m);
  219. list_insert_before(element_in_list, &y, &z);
  220. test_assert_equal(list_remove_first_link(&m), &x.lnk);
  221. test_assert_equal(list_remove_last_link(&m), &z.lnk);
  222. test_assert_equal(list_first_link(&m), &y.lnk);
  223. test_assert_equal(list_last_link(&m), &y.lnk);
  224. }
  225. TEST_CASE("list_insert_after: inserting a new element after the first one "
  226. "in a list of two elements should insert a new one between them") {
  227. list_add_first(element_in_list, &x, &m);
  228. list_add_last(element_in_list, &z, &m);
  229. list_insert_after(element_in_list, &y, &x);
  230. test_assert_equal(list_remove_first_link(&m), &x.lnk);
  231. test_assert_equal(list_remove_last_link(&m), &z.lnk);
  232. test_assert_equal(list_first_link(&m), &y.lnk);
  233. test_assert_equal(list_last_link(&m), &y.lnk);
  234. }
  235. TEST_CASE("list_insert_before and list_insert_after on a single element list"
  236. "should make new elements the first and the last accordingly") {
  237. list_add_first(element_in_list, &y, &m);
  238. list_insert_before(element_in_list, &x, &y);
  239. list_insert_after(element_in_list, &z, &y);
  240. test_assert_equal(list_first_link(&m), &x.lnk);
  241. test_assert_equal(list_last_link(&m), &z.lnk);
  242. }
  243. TEST_CASE("list_bulk_add_first shouldn't modify a destination list "
  244. "if a source list is empty") {
  245. fill_in_from(xyz, &n);
  246. list_bulk_add_first(&m, &n);
  247. test_assert_true(list_is_empty(&m));
  248. compare_with(xyz, &n);
  249. }
  250. TEST_CASE("list_bulk_add_last shouldn't modify a destination list "
  251. "if a source list is empty") {
  252. fill_in_from(xyz, &n);
  253. list_bulk_add_last(&m, &n);
  254. test_assert_true(list_is_empty(&m));
  255. compare_with(xyz, &n);
  256. }
  257. TEST_CASE("list_bulk_add_first should move all the elements from a source "
  258. "list to the beginning of a destination and make the source empty") {
  259. fill_in_from(xy, &m);
  260. list_add_last(element_in_list, &z, &n);
  261. list_bulk_add_first(&m, &n);
  262. test_assert_true(list_is_empty(&m));
  263. compare_with(xyz, &n);
  264. }
  265. TEST_CASE("list_bulk_add_last should move all the elements from a source "
  266. "list to the end of a destination and make the source empty") {
  267. list_add_first(element_in_list, &x, &n);
  268. fill_in_from(yz, &m);
  269. list_bulk_add_last(&m, &n);
  270. test_assert_true(list_is_empty(&m));
  271. compare_with(xyz, &n);
  272. }
  273. TEST_CASE("list_bulk_insert_before shouldn't modify a destination list "
  274. "if a source list is empty") {
  275. fill_in_from(xyz, &n);
  276. list_bulk_insert_before(&m, &y, lnk);
  277. test_assert_true(list_is_empty(&m));
  278. compare_with(xyz, &n);
  279. }
  280. TEST_CASE("list_bulk_insert_after shouldn't modify a destination list "
  281. "if a source list is empty") {
  282. fill_in_from(xyz, &n);
  283. list_bulk_insert_after(&m, &y, lnk);
  284. test_assert_true(list_is_empty(&m));
  285. compare_with(xyz, &n);
  286. }
  287. TEST_CASE("list_bulk_insert_before: inserting new elements before the last "
  288. "one in a list of two elements should insert them in the middle of the"
  289. "target list") {
  290. list_add_last(element_in_list, &y, &m);
  291. fill_in_from(xz, &n);
  292. list_bulk_insert_before(&m, &z, lnk);
  293. test_assert_true(list_is_empty(&m));
  294. compare_with(xyz, &n);
  295. }
  296. TEST_CASE("list_bulk_insert_after: inserting new elements after the first "
  297. "one in a list of two elements should insert them in the middle of the"
  298. "target list") {
  299. list_add_last(element_in_list, &y, &m);
  300. fill_in_from(xz, &n);
  301. list_bulk_insert_after(&m, &x, lnk);
  302. test_assert_true(list_is_empty(&m));
  303. compare_with(xyz, &n);
  304. }
  305. TEST_CASE("list_foreach_link on empty list must not execute the body and "
  306. "should not touch the iteration variable") {
  307. struct list_link *lnk = (struct list_link *) 0xc0ffee00;
  308. list_foreach_link(lnk, &m) {
  309. test_fail("the list must be empty");
  310. }
  311. test_assert_equal(lnk, (struct list_link *) 0xc0ffee00);
  312. }
  313. TEST_CASE("list_foreach_link on a single element list should execute the body "
  314. "only once") {
  315. struct list_link *lnk = NULL;
  316. int executed = 0;
  317. list_add_first(element_in_list, &x, &m);
  318. list_foreach_link(lnk, &m) {
  319. test_assert_zero(executed++);
  320. test_assert_equal(lnk, &x.lnk);
  321. }
  322. test_assert_not_zero(executed);
  323. test_assert_equal(lnk, &x.lnk);
  324. }
  325. TEST_CASE("list_foreach_link should continue iterating even if the value of "
  326. "the iteration variable is modified in the body") {
  327. struct list_link *lnk = NULL;
  328. struct element * const *p_element = xyz;
  329. fill_in_from(p_element, &m);
  330. list_foreach_link(lnk, &m) {
  331. test_assert_equal(lnk, &(*p_element++)->lnk);
  332. lnk = NULL;
  333. }
  334. test_assert_null(lnk);
  335. }
  336. TEST_CASE("list_foreach_link should evaluate the list argument only once") {
  337. struct list_link *lnk = NULL;
  338. int i = 0, eval_cnt = 0;
  339. fill_in_from(xyz, &m);
  340. list_foreach_link(lnk, eval_cnt++ ? &n : &m) {
  341. ++i;
  342. }
  343. test_assert_equal(eval_cnt, 1);
  344. test_assert_equal(i, 3);
  345. test_assert_equal(lnk, &z.lnk);
  346. }
  347. TEST_CASE("list_foreach_link should support safe removal of the element "
  348. "pointed by the iteration variable") {
  349. struct list_link *lnk;
  350. fill_in_from(xyz, &m);
  351. list_foreach_link(lnk, &m) {
  352. list_unlink_link(lnk);
  353. }
  354. test_assert_true(list_is_empty(&m));
  355. }
  356. TEST_CASE("list_foreach simple test case") {
  357. struct element *e = NULL;
  358. struct element * const *p_element = xyz;
  359. fill_in_from(p_element, &m);
  360. list_foreach(e, &m, lnk) {
  361. test_assert_equal(e, *p_element++);
  362. }
  363. test_assert_equal(e, &z);
  364. }
  365. static struct list *fill_in_from(struct element * const array[],
  366. struct list *list) {
  367. struct element *e;
  368. test_assert_true(list_is_empty(list));
  369. array_nullterm_foreach(e, array) {
  370. test_assert_true(list_alone(element_in_list, e));
  371. list_add_last(element_in_list, e, list);
  372. }
  373. test_assert_false(list_is_empty(list));
  374. return list;
  375. }
  376. static struct list *compare_with(struct element * const array[],
  377. struct list *list) {
  378. struct element *e;
  379. array_nullterm_foreach(e, array) {
  380. test_assert_equal(list_remove_first(element_in_list, list), e);
  381. }
  382. test_assert_true(list_is_empty(list));
  383. return list;
  384. }
  385. static int setup(void) {
  386. list_init(&m);
  387. list_init(&n);
  388. list_link_init(&x.lnk);
  389. list_link_init(&y.lnk);
  390. list_link_init(&z.lnk);
  391. return 0;
  392. }