DArray_tests.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include <cmocka.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <stdio.h>
  5. #include "scufcont/DArray.h"
  6. #include "scufcont/scufcont.h"
  7. #define SCDARRAY_CHARP_ALLOC(arrptr) SCDArray_charp_alloc((arrptr), darray_charp_destroyer, darray_charp_copyer)
  8. SCDARRAY_HEADER(char *, charp);
  9. SCDARRAY_IMPL(char *, charp)
  10. void darray_charp_destroyer(char **elem) {
  11. if (elem != NULL && *elem != NULL) {
  12. free(*elem);
  13. *elem = NULL;
  14. }
  15. }
  16. void darray_charp_copyer(char **dst, char **src) {
  17. if (dst != NULL && src != NULL && *src != NULL) {
  18. *dst = (char *) malloc(sizeof(char) * (strlen(*src) + 1));
  19. strncpy(*dst, *src, strlen(*src) + 1);
  20. }
  21. }
  22. void test_DArray_alloc(void **state) {
  23. (void) state;
  24. SCDArray_charp arr;
  25. assert_true(SCDARRAY_CHARP_ALLOC(&arr) == SCUFCONT_SUCCESS);
  26. assert_non_null(arr.data);
  27. assert_uint_equal(arr.len, 0u);
  28. assert_uint_equal(arr.capacity, 1u);
  29. SCDArray_charp_free(&arr);
  30. }
  31. void test_DArray_alloc_copy(void **state) {
  32. (void) state;
  33. srand(time(NULL));
  34. SCDArray_charp arr;
  35. assert_true(SCDARRAY_CHARP_ALLOC(&arr) == SCUFCONT_SUCCESS);
  36. const size_t elems_n = rand() % 100;
  37. for (size_t i = 0; i < elems_n; i++) {
  38. const int n = rand();
  39. char buf[100];
  40. snprintf(buf, 100, "%d", n);
  41. char *bufptr = buf;
  42. assert_true(SCDArray_charp_push_back(&arr, &bufptr) == SCUFCONT_SUCCESS);
  43. }
  44. SCDArray_charp copied;
  45. assert_true(SCDArray_charp_alloc_copy(&copied, &arr) == SCUFCONT_SUCCESS);
  46. assert_non_null(copied.data);
  47. assert_uint_equal(copied.capacity, arr.capacity);
  48. assert_uint_equal(copied.len, arr.len);
  49. for (size_t i = 0; i < arr.len; i++) {
  50. char **orig_elem = SCDArray_charp_at(&arr, i);
  51. assert_non_null(orig_elem);
  52. assert_non_null(*orig_elem);
  53. char **copied_elem = SCDArray_charp_at(&copied, i);
  54. assert_non_null(copied_elem);
  55. assert_non_null(*copied_elem);
  56. assert_string_equal(*orig_elem, *copied_elem);
  57. }
  58. const size_t arr_data_len = arr.len;
  59. char **arr_data = (char **) malloc(sizeof(char *) * arr.len);
  60. assert_non_null(arr_data);
  61. for (size_t i = 0; i < arr.len; i++) {
  62. char **src = SCDArray_charp_at(&arr, i);
  63. assert_non_null(src);
  64. assert_non_null(*src);
  65. arr.elem_copy(arr_data + i, src);
  66. }
  67. SCDArray_charp_free(&arr);
  68. // Freeing the first array shouldn't affect the data in the copied array.
  69. assert_uint_equal(arr_data_len, copied.len);
  70. for (size_t i = 0; i < arr_data_len; i++) {
  71. assert_string_equal(arr_data[i], *SCDArray_charp_at(&copied, i));
  72. }
  73. SCDArray_charp_free(&copied);
  74. for (size_t i = 0; i < arr_data_len; i++) {
  75. free(arr_data[i]);
  76. }
  77. free(arr_data);
  78. }
  79. void test_DArray_push_back(void **state) {
  80. (void) state;
  81. SCDArray_charp arr;
  82. SCDARRAY_CHARP_ALLOC(&arr);
  83. const char *str1_lit = "Hello";
  84. const size_t str1_len = strlen(str1_lit);
  85. char *str1 = malloc(sizeof(char) * (str1_len + 1));
  86. strncpy(str1, str1_lit, str1_len + 1);
  87. char *str2 = "World";
  88. assert_true(SCDArray_charp_push_back(&arr, &(char *) { str1 }) == SCUFCONT_SUCCESS);
  89. assert_string_equal(*SCDArray_charp_at(&arr, 0), str1);
  90. assert_true(SCDArray_charp_push_back(&arr, &(char *) { str2 }) == SCUFCONT_SUCCESS);
  91. assert_string_equal(*SCDArray_charp_at(&arr, 0), str1);
  92. assert_string_equal(*SCDArray_charp_at(&arr, 1), str2);
  93. // Freeing the original memory should not affect the array element.
  94. free(str1);
  95. assert_string_equal(*SCDArray_charp_at(&arr, 0), str1_lit);
  96. SCDArray_charp_free(&arr);
  97. }
  98. void test_DArray_at(void **state) {
  99. (void) state;
  100. SCDArray_charp arr;
  101. SCDARRAY_CHARP_ALLOC(&arr);
  102. assert_true(SCDArray_charp_push_back(&arr, &(char *) { "Hello" }) == SCUFCONT_SUCCESS);
  103. assert_string_equal(*SCDArray_charp_at(&arr, 0), "Hello");
  104. assert_true(SCDArray_charp_push_back(&arr, &(char *) { "World" }) == SCUFCONT_SUCCESS);
  105. assert_string_equal(*SCDArray_charp_at(&arr, 0), "Hello");
  106. assert_string_equal(*SCDArray_charp_at(&arr, 1), "World");
  107. SCDArray_charp_free(&arr);
  108. }
  109. void test_DArray_push_back_multiple(void **state) {
  110. (void) state;
  111. SCDArray_charp arr;
  112. SCDARRAY_CHARP_ALLOC(&arr);
  113. char *nums[] = { "1", "2", "3", "4", "5" };
  114. const size_t nums_len = sizeof(nums) / sizeof(nums[0]);
  115. assert_true(SCDArray_charp_push_back_multiple(&arr, nums, nums_len) == SCUFCONT_SUCCESS);
  116. for (size_t i = 0; i < arr.len; i++) {
  117. assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
  118. }
  119. const size_t nums2_len = 3;
  120. char **nums2 = (char **) malloc(sizeof(char *) * nums2_len);
  121. nums2[0] = "6";
  122. nums2[1] = "7";
  123. nums2[2] = "8";
  124. assert_true(SCDArray_charp_push_back_multiple(&arr, nums2, nums2_len) == SCUFCONT_SUCCESS);
  125. for (size_t i = 0; i < nums_len; i++) {
  126. assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
  127. }
  128. for (size_t i = 0; i < nums2_len; i++) {
  129. assert_string_equal(*SCDArray_charp_at(&arr, i + nums_len), nums2[i]);
  130. }
  131. SCDArray_charp_free(&arr);
  132. // Freeing the array should not affect the original memory.
  133. assert_string_equal(nums2[0], "6");
  134. assert_string_equal(nums2[1], "7");
  135. assert_string_equal(nums2[2], "8");
  136. free(nums2);
  137. }
  138. void test_DArray_remove(void **state) {
  139. (void) state;
  140. SCDArray_charp arr;
  141. SCDARRAY_CHARP_ALLOC(&arr);
  142. char *nums[5];
  143. nums[0] = (char *) malloc(2);
  144. strncpy(nums[0], "1", 2);
  145. nums[1] = (char *) malloc(2);
  146. strncpy(nums[1], "2", 2);
  147. nums[2] = (char *) malloc(2);
  148. strncpy(nums[2], "3", 2);
  149. nums[3] = (char *) malloc(2);
  150. strncpy(nums[3], "4", 2);
  151. nums[4] = (char *) malloc(2);
  152. strncpy(nums[4], "5", 2);
  153. const size_t nums_len = 5;
  154. SCDArray_charp_push_back_multiple(&arr, nums, nums_len);
  155. for (size_t i = 0; i < arr.len; i++) {
  156. assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
  157. }
  158. // Remove last
  159. {
  160. const size_t old_len = arr.len;
  161. SCDArray_charp_remove(&arr, arr.len - 1);
  162. assert_uint_equal(arr.len, old_len - 1);
  163. char *new_nums[] = { "1", "2", "3", "4" };
  164. assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
  165. for (size_t i = 0; i < arr.len; i++) {
  166. char **elem = SCDArray_charp_at(&arr, i);
  167. assert_string_equal(*elem, new_nums[i]);
  168. }
  169. assert_non_null(nums[nums_len - 1]);
  170. assert_string_equal(nums[nums_len - 1], "5");
  171. }
  172. // Remove from middle
  173. {
  174. const size_t old_len = arr.len;
  175. SCDArray_charp_remove(&arr, 1);
  176. assert_uint_equal(arr.len, old_len - 1);
  177. char *new_nums[] = { "1", "3", "4" };
  178. assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
  179. for (size_t i = 0; i < arr.len; i++) {
  180. assert_string_equal(*SCDArray_charp_at(&arr, i), new_nums[i]);
  181. }
  182. assert_non_null(nums[1]);
  183. assert_string_equal(nums[1], "2");
  184. }
  185. // Remove first
  186. {
  187. const size_t old_len = arr.len;
  188. SCDArray_charp_remove(&arr, 0);
  189. assert_uint_equal(arr.len, old_len - 1);
  190. char *new_nums[] = { "3", "4" };
  191. assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
  192. for (size_t i = 0; i < arr.len; i++) {
  193. assert_string_equal(*SCDArray_charp_at(&arr, i), new_nums[i]);
  194. }
  195. assert_non_null(nums[0]);
  196. assert_string_equal(nums[0], "1");
  197. }
  198. SCDArray_charp_free(&arr);
  199. for (size_t i = 0; i < nums_len; i++) {
  200. free(nums[i]);
  201. }
  202. }
  203. void test_DArray_clear(void **state) {
  204. (void) state;
  205. SCDArray_charp arr;
  206. SCDARRAY_CHARP_ALLOC(&arr);
  207. char *words[] = { "Hello", "World", "!", "Foo", "bar" };
  208. const size_t words_len = sizeof(words) / sizeof(words[0]);
  209. for (size_t i = 0; i < words_len; i++) {
  210. SCDArray_charp_push_back(&arr, words + i);
  211. }
  212. assert_uint_equal(arr.len, words_len);
  213. for (size_t i = 0; i < words_len; i++) {
  214. char **w = SCDArray_charp_at(&arr, i);
  215. assert_string_equal(*w, words[i]);
  216. }
  217. SCDArray_charp_clear(&arr);
  218. assert_uint_equal(arr.len, 0);
  219. }
  220. int DArray_tests_run(void) {
  221. const struct CMUnitTest tests[] = {
  222. cmocka_unit_test(test_DArray_alloc),
  223. cmocka_unit_test(test_DArray_alloc_copy),
  224. cmocka_unit_test(test_DArray_push_back),
  225. cmocka_unit_test(test_DArray_at),
  226. cmocka_unit_test(test_DArray_push_back_multiple),
  227. cmocka_unit_test(test_DArray_remove),
  228. cmocka_unit_test(test_DArray_clear)
  229. };
  230. return cmocka_run_group_tests_name("DArray", tests, NULL, NULL);
  231. }