From 00560a2e83809188f422c81c71c01b6ad25f2a3f Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Fri, 28 Jun 2024 12:50:42 +0200 Subject: [PATCH] restore old unit tests --- data/tests-cutils/test.desktop | 10 + data/tests-cutils/test_readline.txt | 3 + src/cutils | 2 +- src/tests-cutils/cstring-test.c | 63 -- src/tests-cutils/main.c | 25 + src/tests-cutils/makefile.d | 2 +- src/tests-cutils/test-array.c | 301 +++++++++ src/tests-cutils/test-base64.c | 147 +++++ src/tests-cutils/test-cstring.c | 908 ++++++++++++++++++++++++++++ src/tests-cutils/test-desktop.c | 98 +++ src/tests-cutils/tests.c | 16 - src/tests-cutils/tests.h | 20 - 12 files changed, 1494 insertions(+), 101 deletions(-) create mode 100644 data/tests-cutils/test.desktop create mode 100644 data/tests-cutils/test_readline.txt delete mode 100644 src/tests-cutils/cstring-test.c create mode 100644 src/tests-cutils/main.c create mode 100644 src/tests-cutils/test-array.c create mode 100644 src/tests-cutils/test-base64.c create mode 100644 src/tests-cutils/test-cstring.c create mode 100644 src/tests-cutils/test-desktop.c delete mode 100644 src/tests-cutils/tests.c delete mode 100644 src/tests-cutils/tests.h diff --git a/data/tests-cutils/test.desktop b/data/tests-cutils/test.desktop new file mode 100644 index 0000000..234d390 --- /dev/null +++ b/data/tests-cutils/test.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=IRC +Comment=Launch an IRC client +Exec=irssi +Icon=irssi +Terminal=true +Categories=Internet +Type=Application +StartupNotify=true diff --git a/data/tests-cutils/test_readline.txt b/data/tests-cutils/test_readline.txt new file mode 100644 index 0000000..10f2897 --- /dev/null +++ b/data/tests-cutils/test_readline.txt @@ -0,0 +1,3 @@ +ligne 1 + +ligne 3 diff --git a/src/cutils b/src/cutils index 7f42ed2..9e29e2f 160000 --- a/src/cutils +++ b/src/cutils @@ -1 +1 @@ -Subproject commit 7f42ed22b8dab3f7bd1d9e675e2217797cdc29cc +Subproject commit 9e29e2f55d36a2e05a3420825b8ecc33006a45eb diff --git a/src/tests-cutils/cstring-test.c b/src/tests-cutils/cstring-test.c deleted file mode 100644 index e7cdc1b..0000000 --- a/src/tests-cutils/cstring-test.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "cutils/check/launcher.h" -#include "cutils/cstring.h" -#include "cutils/timing.h" - -cstring_t *s; - -static const char str100[101] = - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" -; - -void t_cstring_setup() { - s = new_cstring(); -} - -void t_cstring_teardown() { - free_cstring(s); -} - -START(add) - cstring_add(s, "Basic"); - assert_str("Add text to new cstring", "Basic", s->string); - cstring_add(s, " check for spaces "); - assert_str("Add text to already used cstring", - "Basic check for spaces ", s->string); - cstring_add(s, ""); - assert_str("Check add of ampty string", - "Basic check for spaces ", s->string); -END - -START(add_mem) - // 10M: a memory leak would hopefully be strucked if any - for (size_t i = 0 ; i < 10000000 ; i++) { - cstring_clear(s); - cstring_add(s, str100); cstring_add(s, str100); - cstring_add(s, str100); cstring_add(s, str100); - cstring_add(s, str100); cstring_add(s, str100); - cstring_add(s, str100); cstring_add(s, str100); - cstring_add(s, str100); cstring_add(s, str100); - } -END - -Suite *test_cstring(int more) { - Suite *suite = suite_create("cstring"); - - TCase *init = tcase_create("core"); - tcase_add_checked_fixture(init, t_cstring_setup, t_cstring_teardown); - tcase_add_test(init, add); - - suite_add_tcase(suite, init); - - if (more) { - TCase *extra = tcase_create("extra"); - tcase_add_checked_fixture(extra, - t_cstring_setup, t_cstring_teardown); - tcase_add_test(init, add_mem); - - suite_add_tcase(suite, extra); - } - - return suite; -} - diff --git a/src/tests-cutils/main.c b/src/tests-cutils/main.c new file mode 100644 index 0000000..7d2ffba --- /dev/null +++ b/src/tests-cutils/main.c @@ -0,0 +1,25 @@ +#include +#include "cutils/check/launcher.h" + +// The tests we intend to run: + +SRunner *test_cstring(SRunner *runner, int more); +SRunner *test_array (SRunner *runner, int more); +SRunner *test_base64 (SRunner *runner, int more); +SRunner *test_desktop(SRunner *runner, int more); + +SRunner *get_tests(int more) { + SRunner *runner = NULL; + + runner = test_cstring(runner, more); + runner = test_array (runner, more); + runner = test_base64 (runner, more); + runner = test_desktop(runner, more); + + return runner; +} + +int main(int argc, char **argv) { + return launch_tests(argc, argv); +} + diff --git a/src/tests-cutils/makefile.d b/src/tests-cutils/makefile.d index 7bdfac3..c42debe 100644 --- a/src/tests-cutils/makefile.d +++ b/src/tests-cutils/makefile.d @@ -53,7 +53,7 @@ run-test: test @$(dstdir)/$(NAME) run-test-more: test @echo - @$(dstdir)/($NAME) --more + @$(dstdir)/$(NAME) --more clean: rm -f $(srcdir)/*.o $(srcdir)/*/*.o diff --git a/src/tests-cutils/test-array.c b/src/tests-cutils/test-array.c new file mode 100644 index 0000000..417bd62 --- /dev/null +++ b/src/tests-cutils/test-array.c @@ -0,0 +1,301 @@ +/* + * CUtils: some small C utilities + * + * Copyright (C) 2022 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file test-array.c + * @author Niki + * @date 2022 - 2024 + * + * @brief Unit tests for array + * + * This file implements a series of test cases for array from CUtils. + */ + +#include "cutils/check/launcher.h" +#include "cutils/array.h" + +#include +#include +#include + +static array_t *a; + +static void setup() { + a = new_array(sizeof(char), 80); +} + +static void teardown() { + free_array(a); + a = NULL; +} + +static void reset() { + teardown(); + setup(); +} + +START(init) + if (!a) + failure("new_array returned NULL"); + + if (array_count(a)) + failure("empty array has a size of %zu", array_count(a)); + + END + +START(clear) + char car = 'T'; + + array_push(a, &car); + array_push(a, &car); + array_clear(a); + if (array_count(a)) + failure("empty array has a size of %zu", array_count(a)); + + END + +START(convert) + char car = 'T'; + char eos = '\0'; + char *str; + + array_push(a, &car); + array_push(a, &car); + array_push(a, &eos); + + str = (char*) array_convert(a); + assert_str("array of chars to string conversion", "TT", str); + + free(str); + a = NULL; + + END + +START(data) + char car = 'T'; + char eos = '\0'; + char *str; + + array_push(a, &car); + array_push(a, &car); + array_push(a, &eos); + + str = (char*) array_data(a); + assert_str("array of chars to string conversion", "TT", str); + + END + +START(count) + char car = 'T'; + char eos = '\0'; + + assert_int("empty array", 0, array_count(a)); + reset(); + + array_push(a, &car); + assert_int("1-char array", 1, array_count(a)); + reset(); + + array_push(a, &car); + array_push(a, &car); + array_push(a, &eos); + assert_int("array with a NUL at the end", 3, array_count(a)); + reset(); + + END + +START(pointers) + char *ptr; + char car; + + ptr = array_new(a); + *ptr = 'T'; + assert_int("add a new element via ptr", 1, array_count(a)); + + ptr = array_first(a); + car = *ptr; + if (car != 'T') + failure("first_ptr: 'T' was expected, but we got: '%c'", car); + + reset(); + + char *testy = "Testy"; + ptr = array_newn(a, strlen(testy) + 1); + for (size_t i = 0; i <= strlen(testy); i++) { + *ptr = testy[i]; + ptr++; + } + + ptr = array_first(a); + for (size_t i = 0; i < strlen(testy); i++) { + assert_str("next_ptr", testy + i, (char* )ptr); + ptr = array_next(a, ptr); + } + + array_loop_i(a, ptr2, char, i) { + if (i < strlen(testy)) + assert_str("array_loop", testy + i, ptr2); + else if (i == strlen(testy)) + assert_str("array_loop (last)", "", ptr2); + else + failure("array_loop went out of bounds"); + } + + END + +START(get) + char *str = "Testy"; + size_t sz = strlen(str); + + array_pushn(a, str, sz + 1); + + for (size_t i = 0; i < sz + 1; i++) { + char expected = str[i]; + char *ret = array_get(a, i); + assert_int("get each element", expected, *ret); + } + + END + +START(pop) + char *rep; + + if (array_pop(a)) + failure("popping an item from an empty array"); + + rep = array_new(a); + *rep = 'T'; + + rep = array_pop(a); + if (!rep) + failure("cannot pop item from 1-sized array"); + + assert_int("bad item popped", (int )'T', (int )*rep); + + if (a->count) + failure("popped 1-sized array still has %zu items", a->count); + + rep = array_new(a); + *rep = 'T'; + rep = array_new(a); + *rep = 'T'; + + rep = array_pop(a); + assert_int("bad item 1 popped", (int )'T', (int )*rep); + assert_int("popping should remove 1 from count", 1, a->count); + + rep = array_pop(a); + assert_int("bad item 2 popped", (int )'T', (int )*rep); + assert_int("popping should remove 1 from count", 0, a->count); + + END + +START(cut_at) + char *rep; + + if (array_cut_at(a, 4)) + failure("cutting an empty array returned something"); + + rep = array_new(a); + *rep = 'T'; + rep = array_new(a); + *rep = 'T'; + + if (array_cut_at(a, 4)) + failure("cutting an array above its count returned something"); + + if (!array_cut_at(a, 1)) + failure("failed to cut an array"); + assert_int("cutting at 1 should get a 1-sized array", 1, + a->count); + + if (!array_cut_at(a, 0)) + failure("failed to cut an array"); + assert_int("cutting at 0 should get a 1-sized array", 0, + a->count); + + END + +START(compact) + char car = 'T'; + char eos = '\0'; + + array_compact(a); + + array_push(a, &car); + array_push(a, &car); + array_push(a, &eos); + + assert_str("compacted array has wrong data", "TT", + (char* )array_data(a)); + + END + + // TODO +START(NO_TEST_YET_qsort) + END +START(NO_TEST_YET_push) + END +START(NO_TEST_YET_set) + END +START(NO_TEST_YET_copy) + END + +SRunner *test_array(SRunner *runner, int more) { + Suite *suite = suite_create("array"); + + TCase *core = tcase_create("core"); + tcase_add_checked_fixture(core, setup, teardown); + tcase_add_test(core, init); + tcase_add_test(core, clear); + tcase_add_test(core, convert); + tcase_add_test(core, data); + tcase_add_test(core, count); + tcase_add_test(core, pointers); // new, newn, first, next + tcase_add_test(core, get); + tcase_add_test(core, pop); + tcase_add_test(core, cut_at); + tcase_add_test(core, compact); + + tcase_add_test(core, NO_TEST_YET_qsort); + tcase_add_test(core, NO_TEST_YET_push); + tcase_add_test(core, NO_TEST_YET_set); + tcase_add_test(core, NO_TEST_YET_copy); + + suite_add_tcase(suite, core); + + if (!runner) + runner = srunner_create(suite); + else + srunner_add_suite(runner, suite); + + if (more) { + Suite *suite = suite_create("array -- more (longer)"); + + TCase *tmore = tcase_create("more"); + tcase_add_checked_fixture(tmore, setup, teardown); + // TODO + + suite_add_tcase(suite, tmore); + srunner_add_suite(runner, suite); + } + + return runner; +} + diff --git a/src/tests-cutils/test-base64.c b/src/tests-cutils/test-base64.c new file mode 100644 index 0000000..0275114 --- /dev/null +++ b/src/tests-cutils/test-base64.c @@ -0,0 +1,147 @@ +/* + * CUtils: some small C utilities + * + * Copyright (C) 2022 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file test-base64.c + * @author Niki + * @date 2022 - 2024 + * + * @brief Unit tests for base64 + * + * This file implements a series of test cases for base64 from CUtils. + */ + +#include "cutils/base64.h" +#include "cutils/check/launcher.h" + +#include + +static void setup() { +} + +static void teardown() { +} + +static char decoded[] = "This is Le Test, we will UTF-8 the String, too!"; +static char encoded[] = + "VGhpcyBpcyBMZSBUZXN0LCB3ZSB3aWxsIFVURi04IHRoZSBTdHJpbmcsIHRvbyE="; + +static char decoded_utf8[] = "Le café d'Abigaëlle"; +static char encoded_utf8[] = "TGUgY2Fmw6kgZCdBYmlnYcOrbGxl"; + +START(decode) + char *tmp = base64_decode(encoded); + assert_str("decoding", decoded, tmp); + free(tmp); + END + +START(encode) + char *tmp = base64_encode(decoded); + assert_str("encoding", encoded, tmp); + free(tmp); + END + +START(utf8) + char *tmp; + + tmp = base64_decode(encoded_utf8); + assert_str("UTF-8 decoding", decoded_utf8, tmp); + free(tmp); + + tmp = base64_encode(decoded_utf8); + assert_str("UTF-8 encoding", encoded_utf8, tmp); + free(tmp); + + END + +START(both_ways) + char *enc = base64_encode(decoded); + char *dec = base64_decode(enc); + assert_str("both ways DEC", decoded, dec); + assert_str("both ways ENC", encoded, enc); + free(dec); + free(enc); + END + +START(big) + size_t sz = 10 * 1024 * 1024; + char *dec = malloc((sz + 1) * sizeof(char)); + for (int i = 0; i < sz; i++) { + dec[i] = '0' + (i % 10); + } + dec[sz] = '\0'; + + char *enc = base64_encode(dec); + char *dec2 = base64_decode(enc); + + assert_str("long encode/decode cycle", dec, dec2); + free(dec2); + free(enc); + free(dec); + + END + +START(lots) + size_t count = 1 * 1000 * 1000; + for (size_t i = 0; i < count; i++) { + char *enc = base64_encode(decoded); + char *dec = base64_decode(enc); + + if (strcmp(decoded, dec)) { + failure("Failed short encode/decode cycle at index %zu", i); + } + + free(enc); + free(dec); + } + + END + +SRunner *test_base64(SRunner *runner, int more) { + Suite *suite = suite_create("Base64"); + + TCase *core = tcase_create("core"); + tcase_add_checked_fixture(core, setup, teardown); + tcase_add_test(core, decode); + tcase_add_test(core, encode); + tcase_add_test(core, utf8); + + suite_add_tcase(suite, core); + + if (!runner) + runner = srunner_create(suite); + else + srunner_add_suite(runner, suite); + + if (more) { + Suite *suite = suite_create("Base64 -- more (longer)"); + + TCase *tmore = tcase_create("more"); + tcase_add_checked_fixture(tmore, setup, teardown); + tcase_add_test(tmore, both_ways); + tcase_add_test(tmore, big); + tcase_add_test(tmore, lots); + + suite_add_tcase(suite, tmore); + srunner_add_suite(runner, suite); + } + + return runner; +} + diff --git a/src/tests-cutils/test-cstring.c b/src/tests-cutils/test-cstring.c new file mode 100644 index 0000000..92592c6 --- /dev/null +++ b/src/tests-cutils/test-cstring.c @@ -0,0 +1,908 @@ +/* + * CUtils: some small C utilities + * + * Copyright (C) 2022 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file test-cstring.c + * @author Niki + * @date 2022 - 2024 + * + * @brief Unit tests for cstring + * + * This file implements a series of test cases for cstring from CUtils. + */ + + +#include + +#include "cutils/check/launcher.h" +#include "cutils/cstring.h" + +#define TEST_FILE_READLINE "../data/tests-cutils/test_readline.txt" + +cstring_t *s; + +static void setup() { + s = new_cstring(); +} + +static void teardown() { + free_cstring(s); + s = NULL; +} + +static void reset() { + teardown(); + setup(); +} + +START(init) + if (!s) + failure("new_cstring returned NULL"); + + if (s->length) + failure("empty cstring has a size of %zu", s->length); + +END + +START(add_car) + cstring_add_car(s, 'T'); + assert_str("Cannot add a single char", "T", s->string); + + cstring_add_car(s, 'e'); + cstring_add_car(s, 's'); + cstring_add_car(s, 't'); + cstring_add_car(s, 'y'); + assert_str("Cannot add multiple chars", "Testy", s->string); + +END + +START(add_all_but_p) + char *str; + + str = "testy"; + cstring_add(s, str); + assert_str("Short string", str, s->string); + reset(); + + str = "Fanfan entre dans un bar"; + cstring_add(s, str); + assert_str("Medium string", str, s->string); + reset(); + + str = "Ligne 1\nLigne 2\nLigne 3, attention 4 = vide\n"; + cstring_add(s, str); + assert_str("Multi-line", str, s->string); + reset(); + + str = "Les accents en français sont bien là et se " + "retrouvent avec une fréquence élevée"; + cstring_add(s, str); + assert_str("accents", str, s->string); + reset(); + + str = "cents: ¢, copyright: ©, arrows: →↓↑←"; + cstring_add(s, str); + assert_str("UTF-8", str, s->string); + reset(); + + str = "Os iusti meditabitur sapientiam,\n" + "Et lingua\n" + "eius loquetur\n" + "indicium.\n" + "\n" + "Beatus\n" + "vir qui\n" + "suffert tentationem, Quoniqm\n" + "cum probates\n" + "fuerit accipient\n" + "coronam vitae\n" + "\n" + "Kyrie, fons bonitatis.\n" + "Kyrie, ignis divine, eleison.\n" + "\n" + "O quam sancta, quam serena,\n" + "Quam benigma, quam amoena esse Virgo creditur.\n" + "O quam sancta, quam serena,\n" + "Quam benigma, quam amoena,\n" + "O castitatis lilium.\n" + "\n" + "Kyrie, fons bonitatis.\n" + "Kyrie, ignis divine, eleison.\n" + "\n" + "O quam sancta, quam serena,\n" + "Quam benigma, quam amoena,\n" + "O castitatis lilium.\n"; + cstring_add(s, str); + assert_str("Long, multi-line string", str, s->string); + reset(); + + str = "String 1, String 2"; + cstring_add(s, "String 1, "); + cstring_add(s, "String 2"); + assert_str("Concat with add", str, s->string); + reset(); + + str = "0123456789"; + cstring_addf(s, str, 4); + assert_str("addf error (start at 4)","456789",s->string); + reset(); + + str = "0123456789"; + cstring_addf(s, str, 4); + cstring_addf(s, str, 8); + str = "45678989"; + assert_str("Concat with addf", str, s->string); + reset(); + + str = "0123456789"; + cstring_addn(s, str, 4); + assert_str("addn error (4)", "0123", s->string); + reset(); + + str = "0123456789"; + cstring_addn(s, str, 4); + cstring_addn(s, str, 2); + str = "012301"; + assert_str("Concat with addn", str, s->string); + reset(); + + str = "0123456789"; + cstring_addfn(s, str, 4, 3); + assert_str("addf error (4, 3)", "456", s->string); + reset(); + + str = "0123456789"; + cstring_addfn(s, str, 4, 3); + cstring_addfn(s, str, 2, 2); + str = "45623"; + assert_str("Concat with addfn", str, s->string); + reset(); + +END + +START(addp) + char *str; + + cstring_addp(s, "%d", 42); + assert_str("Simple int", "42", s->string); + reset(); + + cstring_addp(s, "%02d", 1); + assert_str("Leading zero int", "01", s->string); + reset(); + + cstring_addp(s, "%d", 352646); + assert_str("Large int", "352646", s->string); + reset(); + + str = "Simple test string"; + cstring_addp(s, "%s", str); + assert_str("Simple string", str, s->string); + reset(); + + str = "String 1, String 2"; + cstring_addp(s, "%s", "String 1, "); + cstring_addp(s, "%s", "String 2"); + assert_str("Cumulative strings", str, s->string); + reset(); + +END + +START(cut_at) + cstring_add(s, "0123456789"); + cstring_cut_at(s, 4); + assert_str("cut at failed", "0123", s->string); + +END + +START(substring) + free_cstring(s); + s = cstring_substring("0123456789", 4, 2); + assert_str("substring failed 4,2", "45", s->string); + + free_cstring(s); + s = cstring_substring("0123456789", 0, 4); + assert_str("substring failed 0,4", "0123", s->string); + + free_cstring(s); + s = cstring_substring("0123456789", 3, 0); + assert_str("substring failed 3,0", "3456789", s->string); + + free_cstring(s); + s = cstring_substring("0123456789", 0, 0); + assert_str("substring failed 0,0", "0123456789", s->string); + +END + +START(reverse) + cstring_add(s, "kayak"); + cstring_reverse(s->string); + assert_str("reversing a palyndrome failed", "kayak", s->string); + reset(); + + cstring_add(s, "plantigrade"); + cstring_reverse(s->string); + assert_str("reverse failed", "edargitnalp", s->string); + reset(); + + cstring_add(s, "123"); + cstring_reverse(s->string); + assert_str("reverse failed", "321", s->string); + reset(); + + cstring_add(s, "1234"); + cstring_reverse(s->string); + assert_str("reverse failed", "4321", s->string); + reset(); + +END + +START(replace) + cstring_add(s, "test string AC/DC"); + assert_int("(a) Bad number of replacements returned", 0, + cstring_replace(s, "", "")); + assert_str("Replacement failed","test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(b) Bad number of replacements returned", 1, + cstring_replace(s, "AC/DC", "AC/DC")); + assert_str("Replacement failed","test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(c) Bad number of replacements returned", 1, + cstring_replace(s, "AC/DC", "woof")); + assert_str("Replacement failed", "test string woof", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(d) Bad number of replacements returned", 2, + cstring_replace(s, "C", "*")); + assert_str("Replacement failed", "test string A*/D*", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(e) Bad number of replacements returned", 1, + cstring_replace(s, "test ", "")); + assert_str("Replacement failed", "string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(f) Bad number of replacements returned", 1, + cstring_replace(s, "test ", "longer test ")); + assert_str("Replacement failed", "longer test string AC/DC", + s->string); + +END + +START(replace_car) + cstring_add(s, "test string AC/DC"); + assert_int("(a) Bad number of replacements returned", 0, + cstring_replace_car(s->string, '?', '!')); + assert_str("Replacement failed","test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(b) Bad number of replacements returned", 1, + cstring_replace_car(s->string, '/', '/')); + assert_str("Replacement failed","test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(c) Bad number of replacements returned", 1, + cstring_replace_car(s->string, 'A', 'a')); + assert_str("Replacement failed","test string aC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(d) Bad number of replacements returned", 2, + cstring_replace_car(s->string, 'C', '*')); + assert_str("Replacement failed","test string A*/D*", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + assert_int("(e) Bad number of replacements returned", 1, + cstring_replace_car(s->string, '/', '\0')); + assert_str("Replacement failed", "test string AC", s->string); + +END + +START(starts_with) + char *start; + + cstring_add(s, "fichier.ext"); + + start = "fichier"; + if (!cstring_starts_with(s->string, start, 0)) + failure("fichier.ext does not start with %s", start); + + start = "ichier"; + if (cstring_starts_with(s->string, start, 0)) + failure("fichier.ext starts with %s", start); + + start = "afichier"; + if (cstring_starts_with(s->string, start, 0)) + failure("fichier.ext starts with %s", start); + + start = ""; + if (!cstring_starts_with(s->string, start, 0)) + failure("fichier.ext does not start with nothing"); + + start = "chier"; + if (!cstring_starts_with(s->string, start, 2)) + failure("fichier.ext +2 does not start with %s", start); + +END + +START(ends_with) + char *end; + + cstring_add(s, "fichier.ext"); + + end = ".ext"; + if (!cstring_ends_with(s->string, end)) + failure("fichier.ext does not end in %s", end); + + end = ".ex"; + if (cstring_ends_with(s->string, end)) + failure("fichier.ext ends in %s", end); + + end = "aext"; + if (cstring_ends_with(s->string, end)) + failure("fichier.ext does not end in %s", end); + + end = ""; + if (!cstring_ends_with(s->string, end)) + failure("fichier.ext does not end with nothing"); + +END + +START(find) + char *str = "Une petite string pour y chercher des choses"; + + assert_int("(a) find error", 0, cstring_find(str, "Une", 0)); + assert_int("(b) find error", -1, cstring_find(str, "Une", 1)); + assert_int("(c) find error", 4, cstring_find(str, "petite", 0)); + assert_int("(d) find error", 4, cstring_find(str, "petite", 1)); + assert_int("(e) find error", 4, cstring_find(str, "petite", 2)); + assert_int("(f) find error", 4, cstring_find(str, "petite", 3)); + assert_int("(g) find error", 4, cstring_find(str, "petite", 4)); + assert_int("(h) find error",-1, cstring_find(str, "petite", 5)); + assert_int("(i) find error",38, cstring_find(str, "choses", 0)); + assert_int("(j) find error",-1, cstring_find(str, "Oops", 0)); + assert_int("(k) find error", 2, cstring_find(str, "e", 0)); + assert_int("(l) find error", 2, cstring_find(str, "e", 1)); + assert_int("(m) find error", 2, cstring_find(str, "e", 2)); + assert_int("(n) find error", 5, cstring_find(str, "e", 3)); + assert_int("(o) find error", 9, cstring_find(str, "e", 6)); + +END + +START(rfind) + char *str = "Une petite string pour y chercher des choses"; + + assert_int("(a) find error", 0, cstring_rfind(str, "Une", 0)); + assert_int("(b) find error", 0, cstring_rfind(str, "Une", 1)); + assert_int("(c) find error",4, cstring_rfind(str, "petite", 0)); + assert_int("(d) find error",4, + cstring_rfind(str, "petite", 11)); + assert_int("(e) find error", -1, + cstring_rfind(str, "petite", 2)); + assert_int("(f) find error", 38, + cstring_rfind(str, "choses", 0)); + assert_int("(g) find error", -1, cstring_rfind(str, "Oops", 0)); + assert_int("(h) find error", 42, cstring_rfind(str, "e", 0)); + assert_int("(i) find error", 42, cstring_rfind(str, "e", -1)); + assert_int("(j) find error", 35, cstring_rfind(str, "e", -2)); + assert_int("(k) find error", 35, cstring_rfind(str, "e", -3)); + assert_int("(l) find error", 35, cstring_rfind(str, "e", 38)); + +END + +START(clear) + if (!s) + failure("new_cstring returned NULL"); + + if (s->length) + failure("empty cstring has a size of %zu", s->length); + + cstring_add(s, "testy"); + cstring_clear(s); + if (s->length) + failure("cleared cstring has a size of %zu", s->length); + +END + +START(convert) + char *str; + + str = cstring_convert(s); + s = NULL; + + assert_str("Convert failed with an empty string", "", str); + + reset(); + + cstring_add(s, "testy"); + str = cstring_convert(s); + s = NULL; + assert_str("Convert did not return the same string", "testy", + str); + +END + +START(clone) + cstring_t *clone; + + clone = cstring_clone(NULL); + if (clone) + failure("Cloning NULL must return NULL"); + + clone = cstring_clone(""); + assert_str("Cannot clone the empty string", "", clone->string); + free_cstring(clone); + + cstring_add(s, "Testy viva la vida"); + clone = cstring_clone(s->string); + assert_str("Failed to clone the string", s->string, + clone->string); + free_cstring(clone); + +END + +START(rtrim) + char *expected; + + expected = "testy"; + cstring_add(s, expected); + cstring_add(s, " "); + + cstring_rtrim(s, ' '); + assert_str("(a) Failed to rtrim", expected, s->string); + + reset(); + + expected = " testy"; + cstring_add(s, expected); + cstring_add(s, " "); + + cstring_rtrim(s, ' '); + assert_str("(b) Failed to rtrim", expected, s->string); + + reset(); + + expected = " testy "; + cstring_add(s, expected); + cstring_add(s, "..."); + + cstring_rtrim(s, '.'); + assert_str("(c) Failed to rtrim", expected, s->string); + + reset(); + + expected = "...testy "; + cstring_add(s, expected); + cstring_add(s, "..."); + + cstring_rtrim(s, '.'); + assert_str("(d) Failed to rtrim", expected, s->string); + +END + +START(trim) + char *expected; + + expected = "testy"; + cstring_add(s, expected); + cstring_add(s, " "); + + cstring_trim(s, ' '); + assert_str("(a) Failed to trim", expected, s->string); + + reset(); + + expected = "testy"; + cstring_add(s, " "); + cstring_add(s, expected); + cstring_add(s, " "); + + cstring_trim(s, ' '); + assert_str("(b) Failed to trim", expected, s->string); + + reset(); + + expected = " testy "; + cstring_add(s, expected); + cstring_add(s, "..."); + + cstring_trim(s, '.'); + assert_str("(c) Failed to trim", expected, s->string); + + reset(); + + expected = " testy "; + cstring_add(s, "..."); + cstring_add(s, expected); + cstring_add(s, "..."); + + cstring_trim(s, '.'); + assert_str("(d) Failed to trim", expected, s->string); + +END + +START(remove_crlf) + char *str = "testy"; + + cstring_add(s, str); + s->length = cstring_remove_crlf(s->string); + assert_str("no-op failed", str, s->string); + + reset(); + cstring_add(s, str); + cstring_add(s, "\n"); + s->length = cstring_remove_crlf(s->string); + assert_str("\\n failed", str, s->string); + + reset(); + cstring_add(s, str); + cstring_add(s, "\r\n"); + s->length = cstring_remove_crlf(s->string); + assert_str("\\r\\n failed", str, s->string); + + reset(); + cstring_add(s, str); + cstring_add(s, "\n\n"); + s->length = cstring_remove_crlf(s->string); + assert_str("\\n\\n failed", "testy\n", s->string); + + reset(); + cstring_add(s, str); + cstring_add(s, "\r\n\r\n"); + s->length = cstring_remove_crlf(s->string); + assert_str("\\r\\n\\r\\n failed", "testy\r\n", s->string); + + reset(); + cstring_add(s, "\n"); + s->length = cstring_remove_crlf(s->string); + assert_str("\\n uniq failed", "", s->string); + +END + +START(toupper) + cstring_add(s, ""); + cstring_toupper(s); + assert_str("Failed to uppercase empty", "", s->string); + + reset(); + + cstring_add(s, "Simple Testy"); + cstring_toupper(s); + assert_str("Failed to uppercase", "SIMPLE TESTY", s->string); + + reset(); + + cstring_add(s, "C'est l'été"); + cstring_toupper(s); + assert_str("Failed to uppercase", "C'EST L'ÉTÉ", s->string); + + reset(); + + cstring_add(s, "Test en français"); + cstring_toupper(s); + assert_str("Failed to uppercase","TEST EN FRANÇAIS", s->string); + +END + +START(tolower) + cstring_add(s, ""); + cstring_tolower(s); + assert_str("Failed to lowercase empty", "", s->string); + + reset(); + + cstring_add(s, "Simple Testy"); + cstring_tolower(s); + assert_str("Failed to lowercase", "simple testy", s->string); + + reset(); + + cstring_add(s, "Été ! C'est l'été !"); + cstring_tolower(s); + assert_str("Failed to lowercase", "été ! c'est l'été !", + s->string); + + reset(); + + cstring_add(s, "Test en français"); + cstring_tolower(s); + assert_str("Failed to lowercase","test en français", s->string); + + reset(); + + cstring_add(s, "À la claire fontaine"); + cstring_tolower(s); + assert_str("Failed to lowercase", "à la claire fontaine", + s->string); + +END + +START(readline) + int read; + FILE *testin = fopen(TEST_FILE_READLINE, "r"); + if (!testin) + failure("Test file not found: test_readln.txt"); + + read = cstring_readline(s, testin); + if (!read) + failure("first line should not be last"); + assert_str("first line incorrect", "ligne 1", s->string); + reset(); + + read = cstring_readline(s, testin); + if (!read) + failure("second line should not be last"); + assert_str("second line incorrect", "", s->string); + reset(); + + read = cstring_readline(s, testin); + if (!read) + failure("third line should not be last"); + assert_str("third line incorrect", "ligne 3", s->string); + reset(); + + if (cstring_readline(s, testin)) { + failure("fourth line should not exist"); + } + +END + +START(add_path) + cstring_add_path(s, "root"); + assert_str("failed to create root path", "/root", s->string); + + cstring_add_path(s, "dir"); + assert_str("failed to add a dir", "/root/dir", s->string); + + cstring_add_path(s, "sub/"); + assert_str("extra / failed", "/root/dir/sub", s->string); + +END + +START(pop_path) + cstring_add(s, ""); + assert_int("empty test failed", 0, cstring_pop_path(s, 1)); + + reset(); + cstring_add(s, "root"); + assert_int("0 nbr test failed", 0, cstring_pop_path(s, 0)); + assert_str("0 test failed", "root", s->string); + + reset(); + cstring_add(s, "root/"); + assert_int("0² nbr test failed", 0, cstring_pop_path(s, 0)); + assert_str("0² test failed", "root", s->string); + + reset(); + cstring_add(s, "/"); + assert_int("root test nbr failed", 0, cstring_pop_path(s, 1)); + assert_str("root test failed", "/", s->string); + + reset(); + cstring_add(s, "/"); + assert_int("root² test nbr failed", 0, cstring_pop_path(s, 2)); + assert_str("root² test failed", "/", s->string); + + reset(); + cstring_add(s, "/root"); + assert_int("/root test nbr failed", 1, cstring_pop_path(s, 1)); + assert_str("/root test failed", "/", s->string); + + reset(); + cstring_add(s, "/root"); + assert_int("/root³ test nbr failed", 1, cstring_pop_path(s, 2)); + assert_str("/root³ test failed", "/", s->string); + + reset(); + cstring_add(s, "/root/dir/file"); + assert_int("2 test nbr failed", 2, cstring_pop_path(s, 2)); + assert_str("2 test failed", "/root", s->string); + + reset(); + cstring_add(s, "/root/dir/file/"); + assert_int("trailing / test nbr failed", 1, + cstring_pop_path(s, 1)); + assert_str("trailing / test failed", "/root/dir", s->string); + +END + +START(basename) + char *str; + + cstring_add(s, ""); + str = cstring_basename(s->string, NULL); + assert_str("empty test", "", str); + free(str); + + reset(); + cstring_add(s, "/root/path/dir/file"); + str = cstring_basename(s->string, NULL); + assert_str("simple test", "file", str); + free(str); + + reset(); + cstring_add(s, "/root/path/dir/file"); + str = cstring_basename(s->string, ".ext"); + assert_str("no ext test", "file", str); + free(str); + + reset(); + cstring_add(s, "/root/path/dir/file.test"); + str = cstring_basename(s->string, ".ext"); + assert_str("wrong ext test", "file.test", str); + free(str); + + reset(); + cstring_add(s, "/root/path/dir/file.ext"); + str = cstring_basename(s->string, ".ext"); + assert_str("good ext test", "file", str); + free(str); + +END + +START(dirname) + char *str; + + cstring_add(s, "/root/path"); + str = cstring_dirname(s->string); + assert_str("simple test", "/root", str); + free(str); + + reset(); + cstring_add(s, "/root/path/"); + str = cstring_dirname(s->string); + assert_str("trailing / test", "/root", str); + free(str); + + reset(); + cstring_add(s, "/"); + str = cstring_dirname(s->string); + assert_str("root is root of root test", "/", str); + free(str); + +END + +START(concat) + char *cc; + + cc = cstring_concat(NULL); + if (cc) + failure("concat of NULL should return NULL, not: <%s>", + cc); + + cc = cstring_concat("only", NULL); + assert_str("Single parameter", "only", cc); + free(cc); + + cc = cstring_concat("Only", "Fans", NULL); + assert_str("Test 2 params", "OnlyFans", cc); + free(cc); + + cc = cstring_concat("Fanfan", " ", "et", " Tulipe", + " entrent dans un bar", NULL); + assert_str("Test multiple params", + "Fanfan et Tulipe entrent dans un bar", cc); + free(cc); + +END + +static const char str100[101] = + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" +; + +START(long_string) + size_t count = 10 * 1000 * 1000; + for (size_t i = 0; i < count; i++) { + cstring_add(s, str100); + } + + assert_sz("Lot of adds", count * 100, s->length); + +END + +START(many_adds) + // 10M: a memory leak would hopefully be strucked if any + size_t count = 10 * 1000 * 1000; + for (size_t i = 0 ; i < count ; i++) { + cstring_clear(s); + cstring_add(s, str100); cstring_add(s, str100); + cstring_add(s, str100); cstring_add(s, str100); + cstring_add(s, str100); cstring_add(s, str100); + cstring_add(s, str100); cstring_add(s, str100); + cstring_add(s, str100); cstring_add(s, str100); + } +END + +START(many_inits) + // 10M: a memory leak would hopefully be strucked if any + size_t count = 10 * 1000 * 1000; + for (size_t i = 0 ; i < count ; i++) { + cstring_add(s, str100); + free_cstring(s); + s = new_cstring(); + } +END + +SRunner *test_cstring(SRunner *runner, int more) { + Suite *suite = suite_create("cstring"); + + TCase *core = tcase_create("core"); + tcase_add_checked_fixture(core, setup, teardown); + tcase_add_test(core, init); + tcase_add_test(core, add_car); + tcase_add_test(core, add_all_but_p); + tcase_add_test(core, addp); + tcase_add_test(core, cut_at); + tcase_add_test(core, substring); + tcase_add_test(core, reverse); + tcase_add_test(core, replace); + tcase_add_test(core, replace_car); + tcase_add_test(core, starts_with); + tcase_add_test(core, ends_with); + tcase_add_test(core, find); + tcase_add_test(core, rfind); + tcase_add_test(core, clear); + tcase_add_test(core, convert); + tcase_add_test(core, clone); + tcase_add_test(core, rtrim); + tcase_add_test(core, trim); + tcase_add_test(core, remove_crlf); + tcase_add_test(core, toupper); + tcase_add_test(core, tolower); + tcase_add_test(core, readline); + tcase_add_test(core, add_path); + tcase_add_test(core, pop_path); + tcase_add_test(core, basename); + tcase_add_test(core, dirname); + tcase_add_test(core, concat); + + suite_add_tcase(suite, core); + + if (!runner) + runner = srunner_create(suite); + else + srunner_add_suite(runner, suite); + + if (more) { + Suite *suite = suite_create("cstring -- more (longer)"); + + TCase *tmore = tcase_create("more"); + tcase_add_checked_fixture(tmore, setup, teardown); + tcase_add_test(tmore, long_string); + tcase_add_test(tmore, many_adds); + tcase_add_test(tmore, many_inits); + + suite_add_tcase(suite, tmore); + srunner_add_suite(runner, suite); + } + + return runner; +} + diff --git a/src/tests-cutils/test-desktop.c b/src/tests-cutils/test-desktop.c new file mode 100644 index 0000000..347ff04 --- /dev/null +++ b/src/tests-cutils/test-desktop.c @@ -0,0 +1,98 @@ +/* + * CUtils: some small C utilities + * + * Copyright (C) 2022 Niki Roo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file test-desktop.c + * @author Niki + * @date 2022 - 2024 + * + * @brief Unit tests for desktop + * + * This file implements a series of test cases for desktop from CUtils. + */ + +#include "cutils/check/launcher.h" +#include "cutils/desktop.h" + +#include + +#define TEST_FILE_DESKTOP "../data/tests-cutils/test.desktop" + +desktop_t *d; + +static void setup() { + d = new_desktop(TEST_FILE_DESKTOP, 24); +} + +static void teardown() { + free_desktop(d); +} + +START(init) + if (!d) + failure("new_desktop returned NULL"); + + assert_str("Name", "IRC", d->name); + assert_str("Icon", "irssi", d->icon); + assert_str("Exec", "irssi", d->icon); + + END + + // TODO +START(NO_TEST_YET_submenu) + END +START(NO_TEST_YET_icons) + END +START(NO_TEST_YET_find_icon) + END +START(NO_TEST_YET_find_id) + END + +SRunner *test_desktop(SRunner *runner, int more) { + Suite *suite = suite_create("desktop"); + + TCase *core = tcase_create("core"); + tcase_add_checked_fixture(core, setup, teardown); + tcase_add_test(core, init); + tcase_add_test(core, NO_TEST_YET_submenu); + tcase_add_test(core, NO_TEST_YET_icons); + tcase_add_test(core, NO_TEST_YET_find_icon); + tcase_add_test(core, NO_TEST_YET_find_id); + + suite_add_tcase(suite, core); + + if (!runner) + runner = srunner_create(suite); + else + srunner_add_suite(runner, suite); + + if (more) { + Suite *suite = suite_create("desktop -- more (longer)"); + + TCase *tmore = tcase_create("more"); + tcase_add_checked_fixture(tmore, setup, teardown); + // TODO + + suite_add_tcase(suite, tmore); + srunner_add_suite(runner, suite); + } + + return runner; +} + diff --git a/src/tests-cutils/tests.c b/src/tests-cutils/tests.c deleted file mode 100644 index 2cf3803..0000000 --- a/src/tests-cutils/tests.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "tests.h" - -SRunner *get_tests(int more) { - SRunner *runner; - - runner = srunner_create(test_cstring(more)); - //srunner_add_suite(runner, test_clist(more)); - //srunner_add_suite(runner, test_string(mem)); - //srunner_add_suite(runner, test_buffer(mem)); - //srunner_add_suite(runner, other_suite()); - // ... - - return runner; -} - diff --git a/src/tests-cutils/tests.h b/src/tests-cutils/tests.h deleted file mode 100644 index b5cfe47..0000000 --- a/src/tests-cutils/tests.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TESTS_H -#define TESTS_H - -#include - -/** - * Return the test runner (the list of tests to run). - * - * @param mem manage the memory checks and can be: - * - 0 for no memory checks - * - 1 for memory checks - * - 2 for memory checks only - */ -SRunner *get_tests(int more); - -Suite *test_cstring(int more); -// ... - -#endif - -- 2.27.0