furi_string_test.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. #include <furi.h>
  2. #include "../minunit.h"
  3. static void test_setup(void) {
  4. }
  5. static void test_teardown(void) {
  6. }
  7. static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) {
  8. va_list args;
  9. va_start(args, format);
  10. FuriString* string = furi_string_alloc_vprintf(format, args);
  11. va_end(args);
  12. return string;
  13. }
  14. MU_TEST(mu_test_furi_string_alloc_free) {
  15. FuriString* tmp;
  16. FuriString* string;
  17. // test alloc and free
  18. string = furi_string_alloc();
  19. mu_check(string != NULL);
  20. mu_check(furi_string_empty(string));
  21. furi_string_free(string);
  22. // test furi_string_alloc_set_str and free
  23. string = furi_string_alloc_set_str("test");
  24. mu_check(string != NULL);
  25. mu_check(!furi_string_empty(string));
  26. mu_check(furi_string_cmp(string, "test") == 0);
  27. furi_string_free(string);
  28. // test furi_string_alloc_set and free
  29. tmp = furi_string_alloc_set("more");
  30. string = furi_string_alloc_set(tmp);
  31. furi_string_free(tmp);
  32. mu_check(string != NULL);
  33. mu_check(!furi_string_empty(string));
  34. mu_check(furi_string_cmp(string, "more") == 0);
  35. furi_string_free(string);
  36. // test alloc_printf and free
  37. string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04);
  38. mu_check(string != NULL);
  39. mu_check(!furi_string_empty(string));
  40. mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0);
  41. furi_string_free(string);
  42. // test alloc_vprintf and free
  43. string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07);
  44. mu_check(string != NULL);
  45. mu_check(!furi_string_empty(string));
  46. mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0);
  47. furi_string_free(string);
  48. // test alloc_move and free
  49. tmp = furi_string_alloc_set("move");
  50. string = furi_string_alloc_move(tmp);
  51. mu_check(string != NULL);
  52. mu_check(!furi_string_empty(string));
  53. mu_check(furi_string_cmp(string, "move") == 0);
  54. furi_string_free(string);
  55. }
  56. MU_TEST(mu_test_furi_string_mem) {
  57. FuriString* string = furi_string_alloc_set("test");
  58. mu_check(string != NULL);
  59. mu_check(!furi_string_empty(string));
  60. // TODO: how to test furi_string_reserve?
  61. // test furi_string_reset
  62. furi_string_reset(string);
  63. mu_check(furi_string_empty(string));
  64. // test furi_string_swap
  65. furi_string_set(string, "test");
  66. FuriString* swap_string = furi_string_alloc_set("swap");
  67. furi_string_swap(string, swap_string);
  68. mu_check(furi_string_cmp(string, "swap") == 0);
  69. mu_check(furi_string_cmp(swap_string, "test") == 0);
  70. furi_string_free(swap_string);
  71. // test furi_string_move
  72. FuriString* move_string = furi_string_alloc_set("move");
  73. furi_string_move(string, move_string);
  74. mu_check(furi_string_cmp(string, "move") == 0);
  75. // move_string is now empty
  76. // and tested by leaked memory check at the end of the tests
  77. furi_string_set(string, "abracadabra");
  78. // test furi_string_hash
  79. mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string));
  80. // test furi_string_size
  81. mu_assert_int_eq(11, furi_string_size(string));
  82. // test furi_string_empty
  83. mu_check(!furi_string_empty(string));
  84. furi_string_reset(string);
  85. mu_check(furi_string_empty(string));
  86. furi_string_free(string);
  87. }
  88. MU_TEST(mu_test_furi_string_getters) {
  89. FuriString* string = furi_string_alloc_set("test");
  90. // test furi_string_get_char
  91. mu_check(furi_string_get_char(string, 0) == 't');
  92. mu_check(furi_string_get_char(string, 1) == 'e');
  93. mu_check(furi_string_get_char(string, 2) == 's');
  94. mu_check(furi_string_get_char(string, 3) == 't');
  95. // test furi_string_get_cstr
  96. mu_assert_string_eq("test", furi_string_get_cstr(string));
  97. furi_string_free(string);
  98. }
  99. static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) {
  100. va_list args;
  101. va_start(args, format);
  102. furi_string_vprintf(string, format, args);
  103. va_end(args);
  104. return string;
  105. }
  106. MU_TEST(mu_test_furi_string_setters) {
  107. FuriString* tmp;
  108. FuriString* string = furi_string_alloc();
  109. // test furi_string_set_str
  110. furi_string_set_str(string, "test");
  111. mu_assert_string_eq("test", furi_string_get_cstr(string));
  112. // test furi_string_set
  113. tmp = furi_string_alloc_set("more");
  114. furi_string_set(string, tmp);
  115. furi_string_free(tmp);
  116. mu_assert_string_eq("more", furi_string_get_cstr(string));
  117. // test furi_string_set_strn
  118. furi_string_set_strn(string, "test", 2);
  119. mu_assert_string_eq("te", furi_string_get_cstr(string));
  120. // test furi_string_set_char
  121. furi_string_set_char(string, 0, 'a');
  122. furi_string_set_char(string, 1, 'b');
  123. mu_assert_string_eq("ab", furi_string_get_cstr(string));
  124. // test furi_string_set_n
  125. tmp = furi_string_alloc_set("dodecahedron");
  126. furi_string_set_n(string, tmp, 4, 5);
  127. furi_string_free(tmp);
  128. mu_assert_string_eq("cahed", furi_string_get_cstr(string));
  129. // test furi_string_printf
  130. furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
  131. mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string));
  132. // test furi_string_vprintf
  133. furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
  134. mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string));
  135. furi_string_free(string);
  136. }
  137. static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) {
  138. va_list args;
  139. va_start(args, format);
  140. furi_string_cat_vprintf(string, format, args);
  141. va_end(args);
  142. return string;
  143. }
  144. MU_TEST(mu_test_furi_string_appends) {
  145. FuriString* tmp;
  146. FuriString* string = furi_string_alloc();
  147. // test furi_string_push_back
  148. furi_string_push_back(string, 't');
  149. furi_string_push_back(string, 'e');
  150. furi_string_push_back(string, 's');
  151. furi_string_push_back(string, 't');
  152. mu_assert_string_eq("test", furi_string_get_cstr(string));
  153. furi_string_push_back(string, '!');
  154. mu_assert_string_eq("test!", furi_string_get_cstr(string));
  155. // test furi_string_cat_str
  156. furi_string_cat_str(string, "test");
  157. mu_assert_string_eq("test!test", furi_string_get_cstr(string));
  158. // test furi_string_cat
  159. tmp = furi_string_alloc_set("more");
  160. furi_string_cat(string, tmp);
  161. furi_string_free(tmp);
  162. mu_assert_string_eq("test!testmore", furi_string_get_cstr(string));
  163. // test furi_string_cat_printf
  164. furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04);
  165. mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string));
  166. // test furi_string_cat_vprintf
  167. furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07);
  168. mu_assert_string_eq(
  169. "test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string));
  170. furi_string_free(string);
  171. }
  172. MU_TEST(mu_test_furi_string_compare) {
  173. FuriString* string_1 = furi_string_alloc_set("string_1");
  174. FuriString* string_2 = furi_string_alloc_set("string_2");
  175. // test furi_string_cmp
  176. mu_assert_int_eq(0, furi_string_cmp(string_1, string_1));
  177. mu_assert_int_eq(0, furi_string_cmp(string_2, string_2));
  178. mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2));
  179. mu_assert_int_eq(1, furi_string_cmp(string_2, string_1));
  180. // test furi_string_cmp_str
  181. mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1"));
  182. mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2"));
  183. mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2"));
  184. mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1"));
  185. // test furi_string_cmpi
  186. furi_string_set(string_1, "string");
  187. furi_string_set(string_2, "StrIng");
  188. mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1));
  189. mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2));
  190. mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2));
  191. mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1));
  192. furi_string_set(string_1, "string_1");
  193. furi_string_set(string_2, "StrIng_2");
  194. mu_assert_int_eq(32, furi_string_cmp(string_1, string_2));
  195. mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1));
  196. mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2));
  197. mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1));
  198. // test furi_string_cmpi_str
  199. furi_string_set(string_1, "string");
  200. mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string"));
  201. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String"));
  202. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring"));
  203. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing"));
  204. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng"));
  205. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg"));
  206. mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING"));
  207. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string"));
  208. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String"));
  209. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring"));
  210. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing"));
  211. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng"));
  212. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg"));
  213. mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING"));
  214. furi_string_free(string_1);
  215. furi_string_free(string_2);
  216. }
  217. MU_TEST(mu_test_furi_string_search) {
  218. // 012345678901234567
  219. FuriString* haystack = furi_string_alloc_set("test321test123test");
  220. FuriString* needle = furi_string_alloc_set("test");
  221. // test furi_string_search
  222. mu_assert_int_eq(0, furi_string_search(haystack, needle));
  223. mu_assert_int_eq(7, furi_string_search(haystack, needle, 1));
  224. mu_assert_int_eq(14, furi_string_search(haystack, needle, 8));
  225. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15));
  226. FuriString* tmp = furi_string_alloc_set("testnone");
  227. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp));
  228. furi_string_free(tmp);
  229. // test furi_string_search_str
  230. mu_assert_int_eq(0, furi_string_search_str(haystack, "test"));
  231. mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1));
  232. mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8));
  233. mu_assert_int_eq(4, furi_string_search_str(haystack, "321"));
  234. mu_assert_int_eq(11, furi_string_search_str(haystack, "123"));
  235. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone"));
  236. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15));
  237. // test furi_string_search_char
  238. mu_assert_int_eq(0, furi_string_search_char(haystack, 't'));
  239. mu_assert_int_eq(1, furi_string_search_char(haystack, 'e'));
  240. mu_assert_int_eq(2, furi_string_search_char(haystack, 's'));
  241. mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1));
  242. mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4));
  243. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x'));
  244. // test furi_string_search_rchar
  245. mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't'));
  246. mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e'));
  247. mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's'));
  248. mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3'));
  249. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14));
  250. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x'));
  251. furi_string_free(haystack);
  252. furi_string_free(needle);
  253. }
  254. MU_TEST(mu_test_furi_string_equality) {
  255. FuriString* string = furi_string_alloc_set("test");
  256. FuriString* string_eq = furi_string_alloc_set("test");
  257. FuriString* string_neq = furi_string_alloc_set("test2");
  258. // test furi_string_equal
  259. mu_check(furi_string_equal(string, string_eq));
  260. mu_check(!furi_string_equal(string, string_neq));
  261. // test furi_string_equal_str
  262. mu_check(furi_string_equal_str(string, "test"));
  263. mu_check(!furi_string_equal_str(string, "test2"));
  264. mu_check(furi_string_equal_str(string_neq, "test2"));
  265. mu_check(!furi_string_equal_str(string_neq, "test"));
  266. furi_string_free(string);
  267. furi_string_free(string_eq);
  268. furi_string_free(string_neq);
  269. }
  270. MU_TEST(mu_test_furi_string_replace) {
  271. FuriString* needle = furi_string_alloc_set("test");
  272. FuriString* replace = furi_string_alloc_set("replace");
  273. FuriString* string = furi_string_alloc_set("test123test");
  274. // test furi_string_replace_at
  275. furi_string_replace_at(string, 4, 3, "!biglongword!");
  276. mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
  277. // test furi_string_replace
  278. mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1));
  279. mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string));
  280. mu_assert_int_eq(0, furi_string_replace(string, needle, replace));
  281. mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
  282. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace));
  283. mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
  284. // test furi_string_replace_str
  285. mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1));
  286. mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string));
  287. mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test"));
  288. mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
  289. mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test"));
  290. mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
  291. // test furi_string_replace_all
  292. furi_string_replace_all(string, needle, replace);
  293. mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string));
  294. // test furi_string_replace_all_str
  295. furi_string_replace_all_str(string, "replace", "test");
  296. mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string));
  297. furi_string_free(string);
  298. furi_string_free(needle);
  299. furi_string_free(replace);
  300. }
  301. MU_TEST(mu_test_furi_string_start_end) {
  302. FuriString* string = furi_string_alloc_set("start_end");
  303. FuriString* start = furi_string_alloc_set("start");
  304. FuriString* end = furi_string_alloc_set("end");
  305. // test furi_string_start_with
  306. mu_check(furi_string_start_with(string, start));
  307. mu_check(!furi_string_start_with(string, end));
  308. // test furi_string_start_with_str
  309. mu_check(furi_string_start_with_str(string, "start"));
  310. mu_check(!furi_string_start_with_str(string, "end"));
  311. // test furi_string_end_with
  312. mu_check(furi_string_end_with(string, end));
  313. mu_check(!furi_string_end_with(string, start));
  314. // test furi_string_end_with_str
  315. mu_check(furi_string_end_with_str(string, "end"));
  316. mu_check(!furi_string_end_with_str(string, "start"));
  317. furi_string_free(string);
  318. furi_string_free(start);
  319. furi_string_free(end);
  320. }
  321. MU_TEST(mu_test_furi_string_trim) {
  322. FuriString* string = furi_string_alloc_set("biglongstring");
  323. // test furi_string_left
  324. furi_string_left(string, 7);
  325. mu_assert_string_eq("biglong", furi_string_get_cstr(string));
  326. // test furi_string_right
  327. furi_string_right(string, 3);
  328. mu_assert_string_eq("long", furi_string_get_cstr(string));
  329. // test furi_string_mid
  330. furi_string_mid(string, 1, 2);
  331. mu_assert_string_eq("on", furi_string_get_cstr(string));
  332. // test furi_string_trim
  333. furi_string_set(string, " \n\r\tbiglongstring \n\r\t ");
  334. furi_string_trim(string);
  335. mu_assert_string_eq("biglongstring", furi_string_get_cstr(string));
  336. furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa");
  337. furi_string_trim(string, "ab");
  338. mu_assert_string_eq("test", furi_string_get_cstr(string));
  339. furi_string_free(string);
  340. }
  341. MU_TEST(mu_test_furi_string_utf8) {
  342. FuriString* utf8_string = furi_string_alloc_set("イルカ");
  343. // test furi_string_utf8_length
  344. mu_assert_int_eq(9, furi_string_size(utf8_string));
  345. mu_assert_int_eq(3, furi_string_utf8_length(utf8_string));
  346. // test furi_string_utf8_decode
  347. const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC};
  348. FuriStringUTF8State state = FuriStringUTF8StateStarting;
  349. FuriStringUnicodeValue value = 0;
  350. furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value);
  351. mu_assert_int_eq(FuriStringUTF8StateDecoding3, state);
  352. furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value);
  353. mu_assert_int_eq(FuriStringUTF8StateDecoding2, state);
  354. furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value);
  355. mu_assert_int_eq(FuriStringUTF8StateDecoding1, state);
  356. furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value);
  357. mu_assert_int_eq(FuriStringUTF8StateStarting, state);
  358. mu_assert_int_eq(0x1F42C, value);
  359. // test furi_string_utf8_push
  360. furi_string_set(utf8_string, "");
  361. furi_string_utf8_push(utf8_string, value);
  362. mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string));
  363. furi_string_free(utf8_string);
  364. }
  365. MU_TEST_SUITE(test_suite) {
  366. MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
  367. MU_RUN_TEST(mu_test_furi_string_alloc_free);
  368. MU_RUN_TEST(mu_test_furi_string_mem);
  369. MU_RUN_TEST(mu_test_furi_string_getters);
  370. MU_RUN_TEST(mu_test_furi_string_setters);
  371. MU_RUN_TEST(mu_test_furi_string_appends);
  372. MU_RUN_TEST(mu_test_furi_string_compare);
  373. MU_RUN_TEST(mu_test_furi_string_search);
  374. MU_RUN_TEST(mu_test_furi_string_equality);
  375. MU_RUN_TEST(mu_test_furi_string_replace);
  376. MU_RUN_TEST(mu_test_furi_string_start_end);
  377. MU_RUN_TEST(mu_test_furi_string_trim);
  378. MU_RUN_TEST(mu_test_furi_string_utf8);
  379. }
  380. int run_minunit_test_furi_string() {
  381. MU_RUN_SUITE(test_suite);
  382. return MU_EXIT_CODE;
  383. }