test_strmap.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /* _
  2. * ___ __ _ __ _ _ _(_)
  3. * / __|/ _` |/ _` | | | | |
  4. * \__ \ (_| | (_| | |_| | |
  5. * |___/\__,_|\__, |\__,_|_|
  6. * |___/
  7. *
  8. * Cross-platform library which helps to develop web servers or frameworks.
  9. *
  10. * Copyright (C) 2016-2019 Silvio Clecio <[email protected]>
  11. *
  12. * Sagui library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * Sagui library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public
  23. * License along with Sagui library; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. */
  26. #define SG_EXTERN
  27. #include "sg_assert.h"
  28. #include <string.h>
  29. #include <errno.h>
  30. #include "sg_strmap.c"
  31. #include <sagui.h>
  32. static void test__strmap_new(void) {
  33. struct sg_strmap *pair = sg__strmap_new("ABC", "123");
  34. ASSERT(pair);
  35. ASSERT(strcmp(pair->name, "ABC") == 0);
  36. ASSERT(strcmp(pair->val, "123") == 0);
  37. ASSERT(strcmp(pair->key, "abc") == 0);
  38. sg__strmap_free(pair);
  39. }
  40. static void test__strmap_free(void) {
  41. sg__strmap_free(NULL);
  42. }
  43. static void test_strmap_name(struct sg_strmap *pair) {
  44. errno = 0;
  45. ASSERT(sg_strmap_name(NULL) == NULL);
  46. ASSERT(errno == EINVAL);
  47. ASSERT(strcmp(sg_strmap_name(pair), "abç") == 0);
  48. }
  49. static void test_strmap_val(struct sg_strmap *pair) {
  50. errno = 0;
  51. ASSERT(sg_strmap_val(NULL) == NULL);
  52. ASSERT(errno == EINVAL);
  53. ASSERT(strcmp(sg_strmap_val(pair), "déf") == 0);
  54. }
  55. static void test_strmap_add(struct sg_strmap **map, const char *name,
  56. const char *val) {
  57. ASSERT(sg_strmap_add(NULL, name, val) == EINVAL);
  58. ASSERT(sg_strmap_add(map, NULL, val) == EINVAL);
  59. ASSERT(sg_strmap_add(map, name, NULL) == EINVAL);
  60. sg_strmap_cleanup(map);
  61. ASSERT(sg_strmap_count(*map) == 0);
  62. ASSERT(sg_strmap_add(map, "", val) == 0);
  63. ASSERT(sg_strmap_count(*map) == 1);
  64. sg_strmap_cleanup(map);
  65. ASSERT(sg_strmap_add(map, name, "") == 0);
  66. ASSERT(sg_strmap_count(*map) == 1);
  67. sg_strmap_cleanup(map);
  68. ASSERT(sg_strmap_add(map, name, val) == 0);
  69. ASSERT(sg_strmap_add(map, name, val) == 0);
  70. ASSERT(sg_strmap_count(*map) == 2);
  71. }
  72. static void test_strmap_set(struct sg_strmap **map, const char *name,
  73. const char *val) {
  74. ASSERT(sg_strmap_set(NULL, name, val) == EINVAL);
  75. ASSERT(sg_strmap_set(map, NULL, val) == EINVAL);
  76. ASSERT(sg_strmap_set(map, name, NULL) == EINVAL);
  77. sg_strmap_cleanup(map);
  78. ASSERT(sg_strmap_count(*map) == 0);
  79. ASSERT(sg_strmap_set(map, "", val) == 0);
  80. ASSERT(sg_strmap_count(*map) == 1);
  81. sg_strmap_cleanup(map);
  82. ASSERT(sg_strmap_set(map, name, "") == 0);
  83. ASSERT(sg_strmap_count(*map) == 1);
  84. sg_strmap_cleanup(map);
  85. ASSERT(sg_strmap_set(map, name, val) == 0);
  86. ASSERT(sg_strmap_set(map, name, val) == 0);
  87. ASSERT(sg_strmap_count(*map) == 1);
  88. }
  89. static void test_strmap_find(struct sg_strmap **map, const char *name,
  90. const char *val) {
  91. struct sg_strmap *pair;
  92. ASSERT(sg_strmap_find(NULL, name, &pair) == EINVAL);
  93. ASSERT(sg_strmap_find(*map, NULL, &pair) == EINVAL);
  94. ASSERT(sg_strmap_find(*map, name, NULL) == EINVAL);
  95. sg_strmap_cleanup(map);
  96. ASSERT(sg_strmap_count(*map) == 0);
  97. sg_strmap_add(map, name, val);
  98. ASSERT(sg_strmap_count(*map) == 1);
  99. ASSERT(sg_strmap_find(*map, "", &pair) == ENOENT);
  100. ASSERT(!pair);
  101. ASSERT(sg_strmap_find(*map, "xxx", &pair) == ENOENT);
  102. ASSERT(!pair);
  103. ASSERT(sg_strmap_find(*map, "yyy", &pair) == ENOENT);
  104. ASSERT(!pair);
  105. sg_strmap_add(map, "", "");
  106. sg_strmap_add(map, "xxx", "yyy");
  107. sg_strmap_add(map, "yyy", "xxx");
  108. ASSERT(sg_strmap_count(*map) == 4);
  109. ASSERT(sg_strmap_find(*map, name, &pair) == 0);
  110. ASSERT(pair);
  111. ASSERT(strcmp(sg_strmap_name(pair), name) == 0 &&
  112. strcmp(sg_strmap_val(pair), val) == 0);
  113. ASSERT(sg_strmap_find(*map, "", &pair) == 0);
  114. ASSERT(pair);
  115. ASSERT(strcmp(sg_strmap_name(pair), "") == 0 &&
  116. strcmp(sg_strmap_val(pair), "") == 0);
  117. ASSERT(sg_strmap_find(*map, "xxx", &pair) == 0);
  118. ASSERT(pair);
  119. ASSERT(strcmp(sg_strmap_name(pair), "xxx") == 0 &&
  120. strcmp(sg_strmap_val(pair), "yyy") == 0);
  121. ASSERT(sg_strmap_find(*map, "yyy", &pair) == 0);
  122. ASSERT(pair);
  123. ASSERT(strcmp(sg_strmap_name(pair), "yyy") == 0 &&
  124. strcmp(sg_strmap_val(pair), "xxx") == 0);
  125. }
  126. static void test_strmap_get(struct sg_strmap **map, const char *name,
  127. const char *val) {
  128. ASSERT(!sg_strmap_get(NULL, name));
  129. ASSERT(!sg_strmap_get(*map, NULL));
  130. sg_strmap_cleanup(map);
  131. ASSERT(sg_strmap_count(*map) == 0);
  132. sg_strmap_add(map, name, val);
  133. ASSERT(sg_strmap_count(*map) == 1);
  134. ASSERT(!sg_strmap_get(*map, ""));
  135. ASSERT(!sg_strmap_get(*map, "xxx"));
  136. ASSERT(!sg_strmap_get(*map, "yyy"));
  137. sg_strmap_add(map, "", "");
  138. sg_strmap_add(map, "xxx", "yyy");
  139. sg_strmap_add(map, "yyy", "xxx");
  140. ASSERT(sg_strmap_count(*map) == 4);
  141. ASSERT(strcmp(sg_strmap_get(*map, name), val) == 0);
  142. ASSERT(strcmp(sg_strmap_get(*map, ""), "") == 0);
  143. ASSERT(strcmp(sg_strmap_get(*map, "xxx"), "yyy") == 0);
  144. ASSERT(strcmp(sg_strmap_get(*map, "yyy"), "xxx") == 0);
  145. }
  146. static void test_strmap_rm(struct sg_strmap **map, const char *name,
  147. const char *val) {
  148. struct sg_strmap *pair;
  149. ASSERT(sg_strmap_rm(NULL, name) == EINVAL);
  150. ASSERT(sg_strmap_rm(map, NULL) == EINVAL);
  151. sg_strmap_cleanup(map);
  152. ASSERT(sg_strmap_count(*map) == 0);
  153. sg_strmap_add(map, name, val);
  154. ASSERT(sg_strmap_count(*map) == 1);
  155. ASSERT(sg_strmap_rm(map, "") == ENOENT);
  156. ASSERT(sg_strmap_count(*map) == 1);
  157. ASSERT(sg_strmap_rm(map, "xxx") == ENOENT);
  158. ASSERT(sg_strmap_count(*map) == 1);
  159. ASSERT(sg_strmap_rm(map, "yyy") == ENOENT);
  160. ASSERT(sg_strmap_count(*map) == 1);
  161. sg_strmap_add(map, "", "");
  162. sg_strmap_add(map, "xxx", "yyy");
  163. sg_strmap_add(map, "yyy", "xxx");
  164. ASSERT(sg_strmap_count(*map) == 4);
  165. ASSERT(sg_strmap_find(*map, name, &pair) == 0);
  166. ASSERT(sg_strmap_rm(map, name) == 0);
  167. ASSERT(sg_strmap_count(*map) == 3);
  168. ASSERT(sg_strmap_find(*map, name, &pair) == ENOENT);
  169. ASSERT(sg_strmap_find(*map, "", &pair) == 0);
  170. ASSERT(sg_strmap_rm(map, "") == 0);
  171. ASSERT(sg_strmap_count(*map) == 2);
  172. ASSERT(sg_strmap_find(*map, "", &pair) == ENOENT);
  173. ASSERT(sg_strmap_find(*map, "xxx", &pair) == 0);
  174. ASSERT(sg_strmap_rm(map, "xxx") == 0);
  175. ASSERT(sg_strmap_count(*map) == 1);
  176. ASSERT(sg_strmap_find(*map, "xxx", &pair) == ENOENT);
  177. ASSERT(sg_strmap_find(*map, "yyy", &pair) == 0);
  178. ASSERT(sg_strmap_rm(map, "yyy") == 0);
  179. ASSERT(sg_strmap_count(*map) == 0);
  180. ASSERT(sg_strmap_find(*map, "yyy", &pair) == EINVAL);
  181. }
  182. static int strmap_iter_empty(void *cls, struct sg_strmap *pair) {
  183. (void) cls;
  184. (void) pair;
  185. return 0;
  186. }
  187. static int strmap_iter_123(void *cls, struct sg_strmap *pair) {
  188. (void) cls;
  189. (void) pair;
  190. return 123;
  191. }
  192. static int strmap_iter_concat(void *cls, struct sg_strmap *pair) {
  193. strcat(cls, sg_strmap_name(pair));
  194. strcat(cls, sg_strmap_val(pair));
  195. return 0;
  196. }
  197. static void test_strmap_iter(struct sg_strmap **map) {
  198. char str[100];
  199. ASSERT(sg_strmap_iter(NULL, strmap_iter_empty, "") == EINVAL);
  200. ASSERT(sg_strmap_iter(*map, NULL, "") == EINVAL);
  201. sg_strmap_cleanup(map);
  202. sg_strmap_add(map, "abc", "123");
  203. sg_strmap_add(map, "def", "456");
  204. ASSERT(sg_strmap_iter(*map, strmap_iter_empty, NULL) == 0);
  205. ASSERT(sg_strmap_iter(*map, strmap_iter_123, NULL) == 123);
  206. memset(str, 0, sizeof(str));
  207. ASSERT(strcmp(str, "") == 0);
  208. ASSERT(sg_strmap_iter(*map, strmap_iter_concat, str) == 0);
  209. ASSERT(strcmp(str, "abc123def456") == 0);
  210. }
  211. static int strmap_sort_empty(void *cls, struct sg_strmap *pair_a,
  212. struct sg_strmap *pair_b) {
  213. const char *str1 = cls, *str2 = cls;
  214. sprintf(cls, "%s%s", str1, str2);
  215. (void) pair_a;
  216. (void) pair_b;
  217. return 0;
  218. }
  219. static int strmap_sort_name_desc(void *cls, struct sg_strmap *pair_a,
  220. struct sg_strmap *pair_b) {
  221. (void) cls;
  222. return strcmp(sg_strmap_name(pair_b), sg_strmap_name(pair_a));
  223. }
  224. static int strmap_sort_name_asc(void *cls, struct sg_strmap *pair_a,
  225. struct sg_strmap *pair_b) {
  226. (void) cls;
  227. return strcmp(sg_strmap_name(pair_a), sg_strmap_name(pair_b));
  228. }
  229. static int strmap_sort_val_desc(void *cls, struct sg_strmap *pair_a,
  230. struct sg_strmap *pair_b) {
  231. (void) cls;
  232. return strcmp(sg_strmap_val(pair_b), sg_strmap_val(pair_a));
  233. }
  234. static int strmap_sort_val_asc(void *cls, struct sg_strmap *pair_a,
  235. struct sg_strmap *pair_b) {
  236. (void) cls;
  237. return strcmp(sg_strmap_val(pair_a), sg_strmap_val(pair_b));
  238. }
  239. static void test_strmap_sort(struct sg_strmap **map) {
  240. char str[100];
  241. ASSERT(sg_strmap_sort(NULL, strmap_sort_empty, "") == EINVAL);
  242. ASSERT(sg_strmap_sort(map, NULL, "") == EINVAL);
  243. sg_strmap_cleanup(map);
  244. sg_strmap_add(map, "abc", "123");
  245. sg_strmap_add(map, "def", "456");
  246. memset(str, 0, sizeof(str));
  247. strcpy(str, "abc");
  248. ASSERT(strcmp(str, "abc") == 0);
  249. ASSERT(sg_strmap_sort(map, strmap_sort_empty, str) == 0);
  250. ASSERT(strcmp(str, "abcabc") == 0);
  251. memset(str, 0, sizeof(str));
  252. ASSERT(strcmp(str, "") == 0);
  253. sg_strmap_iter(*map, strmap_iter_concat, str);
  254. ASSERT(strcmp(str, "abc123def456") == 0);
  255. ASSERT(sg_strmap_sort(map, strmap_sort_name_desc, NULL) == 0);
  256. memset(str, 0, sizeof(str));
  257. sg_strmap_iter(*map, strmap_iter_concat, str);
  258. ASSERT(strcmp(str, "def456abc123") == 0);
  259. ASSERT(sg_strmap_sort(map, strmap_sort_name_asc, NULL) == 0);
  260. memset(str, 0, sizeof(str));
  261. sg_strmap_iter(*map, strmap_iter_concat, str);
  262. ASSERT(strcmp(str, "abc123def456") == 0);
  263. ASSERT(sg_strmap_sort(map, strmap_sort_val_desc, NULL) == 0);
  264. memset(str, 0, sizeof(str));
  265. sg_strmap_iter(*map, strmap_iter_concat, str);
  266. ASSERT(strcmp(str, "def456abc123") == 0);
  267. ASSERT(sg_strmap_sort(map, strmap_sort_val_asc, NULL) == 0);
  268. memset(str, 0, sizeof(str));
  269. sg_strmap_iter(*map, strmap_iter_concat, str);
  270. ASSERT(strcmp(str, "abc123def456") == 0);
  271. }
  272. static void test_strmap_count(struct sg_strmap **map, const char *name,
  273. const char *val) {
  274. ASSERT(sg_strmap_count(NULL) == 0);
  275. sg_strmap_cleanup(map);
  276. ASSERT(sg_strmap_count(*map) == 0);
  277. sg_strmap_add(map, name, val);
  278. ASSERT(sg_strmap_count(*map) == 1);
  279. sg_strmap_add(map, "xxx", "yyy");
  280. ASSERT(sg_strmap_count(*map) == 2);
  281. sg_strmap_add(map, "yyy", "xxx");
  282. ASSERT(sg_strmap_count(*map) == 3);
  283. sg_strmap_add(map, name, val);
  284. ASSERT(sg_strmap_count(*map) == 4);
  285. sg_strmap_rm(map, name);
  286. ASSERT(sg_strmap_count(*map) == 3);
  287. sg_strmap_cleanup(map);
  288. ASSERT(sg_strmap_count(*map) == 0);
  289. }
  290. static void test_strmap_next(struct sg_strmap **map) {
  291. struct sg_strmap *pair;
  292. char str[100];
  293. ASSERT(sg_strmap_next(NULL) == EINVAL);
  294. sg_strmap_cleanup(map);
  295. pair = NULL;
  296. ASSERT(sg_strmap_next(&pair) == 0);
  297. ASSERT(!pair);
  298. sg_strmap_add(map, "abc", "123");
  299. sg_strmap_add(map, "def", "456");
  300. sg_strmap_add(map, "xxx", "yyy");
  301. memset(str, 0, sizeof(str));
  302. ASSERT(strcmp(str, "") == 0);
  303. pair = *map;
  304. while (pair) {
  305. strcat(str, sg_strmap_name(pair));
  306. strcat(str, sg_strmap_val(pair));
  307. sg_strmap_next(&pair);
  308. }
  309. ASSERT(strcmp(str, "abc123def456xxxyyy") == 0);
  310. }
  311. static void test_strmap_cleanup(struct sg_strmap **map) {
  312. sg_strmap_cleanup(NULL);
  313. sg_strmap_cleanup(map);
  314. ASSERT(sg_strmap_count(*map) == 0);
  315. sg_strmap_add(map, "abc", "123");
  316. sg_strmap_add(map, "def", "456");
  317. sg_strmap_add(map, "xxx", "yyy");
  318. ASSERT(sg_strmap_count(*map) == 3);
  319. sg_strmap_cleanup(map);
  320. ASSERT(sg_strmap_count(*map) == 0);
  321. sg_strmap_cleanup(map);
  322. ASSERT(sg_strmap_count(*map) == 0);
  323. }
  324. int main(void) {
  325. struct sg_strmap *map = NULL, *pair;
  326. char name[] = "abç";
  327. char val[] = "déf";
  328. sg_strmap_add(&map, name, val);
  329. sg_strmap_find(map, name, &pair);
  330. ASSERT(pair);
  331. test__strmap_new();
  332. test__strmap_free();
  333. test_strmap_name(pair);
  334. test_strmap_val(pair);
  335. test_strmap_add(&map, name, val);
  336. test_strmap_set(&map, name, val);
  337. test_strmap_find(&map, name, val);
  338. test_strmap_get(&map, name, val);
  339. test_strmap_rm(&map, name, val);
  340. test_strmap_iter(&map);
  341. test_strmap_sort(&map);
  342. test_strmap_count(&map, name, val);
  343. test_strmap_next(&map);
  344. test_strmap_cleanup(&map);
  345. sg_strmap_cleanup(&map);
  346. return EXIT_SUCCESS;
  347. }