Newer
Older
libkc / modules / test / src / test_list_linked.c
  1. #include <errno.h>
  2.  
  3. #include <kc.h>
  4. #include <kc_ut.h>
  5. #include <kc_assert.h>
  6. #include <kc_list.h>
  7. #include <kc_memory.h>
  8.  
  9. #include "ut.h"
  10.  
  11. // プロトタイプ宣言
  12. static void test_list_linked_new(void);
  13. static void test_list_linked_add(void);
  14. static void test_list_linked_remove(void);
  15. static void test_list_linked_set(void);
  16. static void test_list_linked_search(void);
  17. static void test_list_linked_sort(void);
  18. static void test_list_linked_malloc_error(void);
  19.  
  20. /**
  21. * LinkedList 単体テストスイート
  22. */
  23. void suite_list_linked(void)
  24. {
  25. KcUt *ut = KcUt_get_instance();
  26. ut->add(ut, UT_TESTCASE, "list_linked new LinkedList", test_list_linked_new);
  27. ut->add(ut, UT_TESTCASE, "list_linked add/get", test_list_linked_add);
  28. ut->add(ut, UT_TESTCASE, "list_linked remove", test_list_linked_remove);
  29. ut->add(ut, UT_TESTCASE, "list_linked set", test_list_linked_set);
  30. ut->add(ut, UT_TESTCASE, "list_linked search", test_list_linked_search);
  31. ut->add(ut, UT_TESTCASE, "list_linked sort", test_list_linked_sort);
  32. ut->add(ut, UT_TESTCASE, "list_linked malloc error", test_list_linked_malloc_error);
  33. }
  34.  
  35. /**
  36. * LinkedList 生成/破棄。
  37. *
  38. * @process KcList_new_LinkedList を実行する。。
  39. * @result LinkedList が生成されること。
  40. *
  41. * @process KcList_delete にて LinkedList を破棄する。
  42. * @result LinkedList が破棄されること。
  43. */
  44. static void test_list_linked_new(void)
  45. {
  46. KcList *list = KcList_new_LinkedList();
  47. assert_not_null(list);
  48. KcList_delete(list);
  49. }
  50.  
  51. /**
  52. * LinkedList データ追加/取得。
  53. *
  54. * @process 初回追加 (index = 0)
  55. * @process 2つめ追加 (index = 1)
  56. * @process 先頭に追加 (index = 0)
  57. * @process 末尾に追加 (index = 負値(-1))
  58. * @process 追加(index 不正)
  59. * @process 値取得(サイズ取得あり)
  60. * @process 値取得(サイズ取得なし)
  61. * @process 値取得 (index 不正[負の値を指定])
  62. * @process 値取得 (index 不正[サイズ以上を指定])
  63. */
  64. static void test_list_linked_add(void)
  65. {
  66. KcList *list = KcList_new_LinkedList();
  67. assert_not_null(list);
  68.  
  69. // 空
  70. bool is_empty = list->is_empty(list);
  71. assert_true(is_empty);
  72.  
  73. // 1つめ追加
  74. int val = 10;
  75. bool res = list->add(list, 0, &val, sizeof(int));
  76. assert_true(res);
  77. is_empty = list->is_empty(list);
  78. assert_false(is_empty);
  79.  
  80. // 2つめ追加
  81. val = 20;
  82. res = list->add(list, 1, &val, sizeof(int));
  83. assert_true(res);
  84.  
  85. // 先頭に追加
  86. val = 30;
  87. res = list->add(list, 0, &val, sizeof(int));
  88. assert_true(res);
  89.  
  90. // 末尾に追加
  91. val = 40;
  92. res = list->add(list, -1, &val, sizeof(int));
  93. assert_true(res);
  94.  
  95. // 追加不可位置への追加
  96. val = 50;
  97. res = list->add(list, 10, &val, sizeof(int));
  98. assert_false(res);
  99.  
  100. // 1つめ取得
  101. size_t size;
  102. int *res_val = list->get(list, 0, &size);
  103. assert_equals((int)sizeof(int), (int)size);
  104. assert_equals(30, *res_val);
  105.  
  106. // 2つめ取得
  107. res_val = list->get(list, 1, &size);
  108. assert_equals((int)sizeof(int), (int)size);
  109. assert_equals(10, *res_val);
  110.  
  111. // 3つめ取得(サイズ取得なし)
  112. res_val = list->get(list, 2, NULL);
  113. assert_equals(20, *res_val);
  114.  
  115. // 4つめ取得(サイズ取得なし)
  116. res_val = list->get(list, 3, NULL);
  117. assert_equals(40, *res_val);
  118.  
  119. // 値取得 (index 不正[負の値を指定])
  120. res_val = list->get(list, -1, NULL);
  121. assert_null(res_val);
  122.  
  123. // 値取得 (index 不正[サイズを指定])
  124. res_val = list->get(list, 4, NULL);
  125. assert_null(res_val);
  126.  
  127. // 値取得 (index 不正[サイズ以上を指定])
  128. res_val = list->get(list, 5, NULL);
  129. assert_null(res_val);
  130.  
  131. KcList_delete(list);
  132. }
  133.  
  134. /**
  135. * LinkedList データ削除。
  136. *
  137. * @process 末尾削除
  138. * @process 中間削除
  139. * @process 先頭削除
  140. * @process 削除(index 不正[負の値を指定])
  141. * @process 削除(index 不正[サイズ以上を指定])
  142. * @process 残っているデータを確認
  143. * @process 容量調整(初期容量→1/4以下)
  144. */
  145. static void test_list_linked_remove(void)
  146. {
  147. KcList *list = KcList_new_LinkedList();
  148. assert_not_null(list);
  149.  
  150. // 値設定
  151. int vals[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160};
  152. int default_size = 16;
  153. for (int i = 0; i < (int)(sizeof(vals) / sizeof(int)); i++)
  154. {
  155. int val = vals[i];
  156. bool res = list->add(list, -1, &val, sizeof(int));
  157. assert_true(res);
  158. }
  159.  
  160. // 末尾削除 (値、サイズ取得あり)
  161. int rval;
  162. size_t rsize = sizeof(int);
  163. bool ret = list->remove(list, (default_size - 1), &rval, &rsize);
  164. assert_true(ret);
  165. assert_equals(vals[(default_size - 1)], rval);
  166. assert_equals((int)sizeof(int), (int)rsize);
  167. int now_size = list->size(list);
  168. assert_equals((default_size - 1), now_size);
  169.  
  170. // 値を追加して戻しておく
  171. list->add(list, (default_size - 1), &vals[(default_size - 1)], sizeof(int));
  172. now_size = list->size(list);
  173. assert_equals(default_size, now_size);
  174.  
  175. // 中間削除 (値取得設定あり、サイズ指定なし [=値取得できない])
  176. // 10, 20, <30>, 40, 50, ...
  177. rval = 9999;
  178. ret = list->remove(list, 2, &rval, NULL);
  179. assert_true(ret);
  180. assert_equals(9999, rval); // size 指定なしのため、値は取得できない。
  181. now_size = list->size(list);
  182. assert_equals((default_size - 1), now_size);
  183.  
  184. // 先頭削除 (値取得なし)
  185. // <10>, 20, 40, 50, ...
  186. ret = list->remove(list, 0, NULL, NULL);
  187. assert_true(ret);
  188. now_size = list->size(list);
  189. assert_equals((default_size - 2), now_size);
  190.  
  191. // 削除(index 不正[負の値指定])
  192. ret = list->remove(list, -1, NULL, NULL);
  193. assert_false(ret);
  194.  
  195. // 削除(index 不正[サイズ以上を指定])
  196. ret = list->remove(list, default_size, NULL, NULL);
  197. assert_false(ret);
  198.  
  199. // 残り3つになるまで削除 (3つめを削除)
  200. int rest_size = list->size(list);
  201. while (rest_size > 3)
  202. {
  203. ret = list->remove(list, 3, NULL, NULL);
  204. assert_true(ret);
  205. rest_size = list->size(list);
  206. }
  207.  
  208. // 残っているデータの確認
  209. // 20, 40, 50
  210. int *res_val_1 = list->get(list, 0, NULL);
  211. int *res_val_2 = list->get(list, 1, NULL);
  212. int *res_val_3 = list->get(list, 2, NULL);
  213. assert_equals(20, *res_val_1);
  214. assert_equals(40, *res_val_2);
  215. assert_equals(50, *res_val_3);
  216.  
  217. bool is_empty = list->is_empty(list);
  218. assert_false(is_empty);
  219.  
  220. // クリア
  221. list->clear(list);
  222. is_empty = list->is_empty(list);
  223. assert_true(is_empty);
  224.  
  225. KcList_delete(list);
  226. }
  227.  
  228. /**
  229. * LinkedList データ設定。
  230. *
  231. * @process 値設定(複数設定)
  232. * @process 値設定(元の値、サイズ取得)
  233. * @process 値設定(元の値取得)
  234. * @process 値設定(不正index[負の値指定])
  235. * @process 値設定(不正index[サイズ以上指定])
  236. */
  237. static void test_list_linked_set(void)
  238. {
  239. KcList *list = KcList_new_LinkedList();
  240. assert_not_null(list);
  241.  
  242. // 値設定
  243. int vals[] = {10, 20, 30, 40, 50};
  244. for (int i = 0; i < (int)(sizeof(vals) / sizeof(int)); i++)
  245. {
  246. int val = vals[i];
  247. bool res = list->add(list, -1, &val, sizeof(int));
  248. assert_true(res);
  249. }
  250. int now_size = list->size(list);
  251. assert_equals(5, now_size);
  252.  
  253. // 値設定 (元の値, サイズ取得)
  254. int set_value = 99;
  255. int orig_val = 9999;
  256. size_t orig_size = sizeof(int);
  257. bool ret = list->set(list, 1, &set_value, sizeof(int), &orig_val, &orig_size);
  258. assert_true(ret);
  259. assert_equals(20, orig_val);
  260. assert_equals((int)sizeof(int), (int)orig_size);
  261. int *res_val = list->get(list, 1, NULL);
  262. assert_equals(99, *res_val);
  263.  
  264. // 値設定 (元の値, サイズ取得[設定値の方がサイズが大きい])
  265. set_value = 101;
  266. int orig_val_array[2];
  267. orig_size = sizeof(int) * 2;
  268. ret = list->set(list, 1, &set_value, sizeof(int), orig_val_array, &orig_size);
  269. assert_true(ret);
  270. assert_equals(99, orig_val_array[0]);
  271. assert_equals((int)sizeof(int), (int)orig_size);
  272. res_val = list->get(list, 1, NULL);
  273. assert_equals(101, *res_val);
  274.  
  275. // 値設定 (元の値取得, サイズ指定なし[=値取得不可])
  276. set_value = 98;
  277. orig_val = 9999;
  278. ret = list->set(list, 0, &set_value, sizeof(int), &orig_val, NULL);
  279. assert_true(ret);
  280. assert_equals(9999, orig_val); // size 指定なしのため、値取得不可
  281. res_val = list->get(list, 0, NULL);
  282. assert_equals(98, *res_val);
  283.  
  284. // 値設定 (サイズ取得 [=値指定なしのためサイズ取得不可])
  285. set_value = 97;
  286. orig_size = 0;
  287. ret = list->set(list, 0, &set_value, sizeof(int), NULL, &orig_size);
  288. assert_true(ret);
  289. assert_equals(0, (int)orig_size); // size 取得不可
  290. res_val = list->get(list, 0, NULL);
  291. assert_equals(97, *res_val);
  292.  
  293. now_size = list->size(list);
  294. assert_equals(5, now_size);
  295.  
  296. // 値設定(不正index[負の値指定])
  297. set_value = 96;
  298. ret = list->set(list, -1, &set_value, sizeof(int), NULL, NULL);
  299. assert_false(ret);
  300.  
  301. // 値設定(不正index[サイズ指定])
  302. set_value = 95;
  303. ret = list->set(list, 5, &set_value, sizeof(int), NULL, NULL);
  304. assert_false(ret);
  305.  
  306. // 値設定(不正index[サイズ以上指定])
  307. set_value = 95;
  308. ret = list->set(list, 6, &set_value, sizeof(int), NULL, NULL);
  309. assert_false(ret);
  310.  
  311. KcList_delete(list);
  312. }
  313.  
  314. /**
  315. * LinkedList 検索。
  316. *
  317. * @process リスト {10, 30, 50, 40, 20, 10, 30, 60, 20 } を構築する。
  318. * @result リストが構築されること
  319. *
  320. * @process is_contains でリストに含まれる値を確認する。
  321. * @result true が返されること。
  322. *
  323. * @process index_of で各インデックス位置を取得する。
  324. * @result 先頭からのインデックス位置が正しく取得されること。
  325. *
  326. * @process last_index_of で各インデックス位置を取得する。
  327. * @result 末尾からのインデックス位置が正しく取得されること。
  328. *
  329. * @process リストに含まれない値を指定して、is_contains を実行する。
  330. * @result false が返されること。
  331. *
  332. * @process リストに含まれない値を指定して、index_of を実行する。
  333. * @result -1 が返されること。
  334. *
  335. * @process リストに含まれない値を指定して、last_index_of を実行する。
  336. * @result -1 が返されること。
  337. *
  338. * @process 異なるサイズ指定して、is_contains を実行する。
  339. * @result -1 が返されること。
  340. *
  341. */
  342. static void test_list_linked_search(void)
  343. {
  344. KcList *list = KcList_new_LinkedList();
  345. assert_not_null(list);
  346.  
  347. // 値設定
  348. int vals[] = {10, 30, 50, 40, 20, 10, 30, 60, 20};
  349. for (int i = 0; i < (int)(sizeof(vals) / sizeof(int)); i++)
  350. {
  351. int val = vals[i];
  352. bool res = list->add(list, -1, &val, sizeof(int));
  353. assert_true(res);
  354. }
  355. int now_size = list->size(list);
  356. assert_equals(9, now_size);
  357.  
  358. // 値が含まれることの確認
  359. // index_of, last_index_of の確認
  360. int c_vals[] = {10, 20, 30, 40, 50, 60};
  361. int c_vals_index[] = {0, 4, 1, 3, 2, 7};
  362. int c_vals_lindex[] = {5, 8, 6, 3, 2, 7};
  363. bool is_contains;
  364. int res_index;
  365. int res_lindex;
  366. for (int i = 0; i < (int)(sizeof(c_vals) / sizeof(int)); i++)
  367. {
  368. is_contains = list->contains(list, &c_vals[i], sizeof(int));
  369. assert_true(is_contains);
  370.  
  371. res_index = list->index_of(list, &c_vals[i], sizeof(int));
  372. assert_equals(c_vals_index[i], res_index);
  373.  
  374. res_lindex = list->last_index_of(list, &c_vals[i], sizeof(int));
  375. assert_equals(c_vals_lindex[i], res_lindex);
  376. }
  377.  
  378. // 値が含まれないことの確認
  379. int c_val = 99;
  380. is_contains = list->contains(list, &c_val, sizeof(int));
  381. assert_false(is_contains);
  382.  
  383. res_index = list->index_of(list, &c_val, sizeof(int));
  384. assert_equals(-1, res_index);
  385.  
  386. res_lindex = list->last_index_of(list, &c_val, sizeof(int));
  387. assert_equals(-1, res_lindex);
  388.  
  389. // 値が含まれないことの確認(異なるサイズ指定)
  390. c_val = 10;
  391. is_contains = list->contains(list, &c_val, sizeof(int) * 2);
  392. assert_false(is_contains);
  393.  
  394. res_index = list->index_of(list, &c_val, sizeof(int) * 2);
  395. assert_equals(-1, res_index);
  396.  
  397. res_lindex = list->last_index_of(list, &c_val, sizeof(int) * 2);
  398. assert_equals(-1, res_lindex);
  399.  
  400. KcList_delete(list);
  401. }
  402.  
  403. // ソート用コンパレータ
  404. static int test_list_linked_sort_comparator(
  405. const void *element1, size_t size1,
  406. const void *element2, size_t size2,
  407. void *args)
  408. {
  409. int val1 = *((int *)element1);
  410. int val2 = *((int *)element2);
  411. assert_equals((int)sizeof(int), (int)size1);
  412. assert_equals((int)sizeof(int), (int)size2);
  413. assert_equals("ABCDEFG", (const char *)args);
  414. return (val1 - val2);
  415. }
  416.  
  417. /**
  418. * LinkedList ソート。
  419. *
  420. * @process リスト {10, 30, 50, 40, 20, 10, 30, 60, 20} を構築する。
  421. * @result リストが構築されること。
  422. *
  423. * @process 昇順用コンパレータを渡し、ソートする。
  424. * @result リストがソートされること。
  425. *
  426. * @process Iterator を取得する。
  427. * @result Iterator にて順次値が取得できること。
  428. */
  429. static void test_list_linked_sort(void)
  430. {
  431. KcList *list = KcList_new_LinkedList();
  432. assert_not_null(list);
  433.  
  434. // 値設定
  435. int vals[] = {10, 30, 50, 40, 20, 10, 30, 60, 20};
  436. for (int i = 0; i < (int)(sizeof(vals) / sizeof(int)); i++)
  437. {
  438. int val = vals[i];
  439. bool res = list->add(list, -1, &val, sizeof(int));
  440. assert_true(res);
  441. }
  442. int now_size = list->size(list);
  443. assert_equals(9, now_size);
  444.  
  445. // ソート実施
  446. list->sort(list, test_list_linked_sort_comparator, "ABCDEFG");
  447. int sorted_vals[] = {10, 10, 20, 20, 30, 30, 40, 50, 60};
  448.  
  449. // Iterator にて値を取得&確認
  450. KcIterator *ite = list->iterator(list, 0);
  451. int sorted_index = 0;
  452. while (ite->hasNext(ite))
  453. {
  454. size_t res_size;
  455. int *res_val = (int *)ite->next(ite, &res_size);
  456. assert_equals((int)sizeof(int), (int)res_size);
  457. assert_equals(sorted_vals[sorted_index], *res_val);
  458. sorted_index++;
  459. }
  460. KcIterator_delete(ite);
  461.  
  462. // index = 5 より取得
  463. ite = list->iterator(list, 5);
  464. sorted_index = 5;
  465. while (ite->hasNext(ite))
  466. {
  467. int *res_val = (int *)ite->next(ite, NULL);
  468. assert_equals(sorted_vals[sorted_index], *res_val);
  469. sorted_index++;
  470. }
  471. KcIterator_delete(ite);
  472.  
  473. KcList_delete(list);
  474. }
  475.  
  476. /**
  477. * LinkedList メモリ確保失敗。
  478. */
  479. static void test_list_linked_malloc_error(void)
  480. {
  481. // LinkedList のメモリ確保失敗
  482. ut_alloc_control(0)
  483. {
  484. KcList *list = KcList_new_LinkedList();
  485. assert_null(list);
  486. }
  487.  
  488. // LinkedList の add 時のメモリ確保失敗
  489. KcList *list = KcList_new_LinkedList();
  490. ut_alloc_control(0)
  491. {
  492. bool ret = list->add(list, 0, "ABC", 4);
  493. assert_false(ret);
  494. assert_equals(0, list->size(list));
  495. }
  496.  
  497. // Iterator 生成時のメモリ確保失敗
  498. ut_alloc_control(0)
  499. {
  500. KcIterator *ite = list->iterator(list, 0);
  501. assert_null(ite);
  502. }
  503.  
  504. // set 時のメモリ確保失敗
  505. list->add(list, 0, "ABC", 4);
  506. ut_alloc_control(0)
  507. {
  508. list->set(list, 0, "XYZXYZ", 7, NULL, NULL);
  509. assert_equals("ABC", (const char *)list->get(list, 0, NULL));
  510. }
  511.  
  512. KcList_delete(list);
  513. }