From b064d435ec4cb2f78bf27a90edde750ae157ebdd Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 25 Aug 2020 10:16:28 +1000 Subject: [PATCH] test: make a separate binary for the utils tests And add the tests for the list and string helpers as a first use-case, copied from the libinput tests. Signed-off-by: Peter Hutterer --- meson.build | 14 ++- src/util-list.c | 69 ++++++++++++++ src/util-strings.c | 223 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 304 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index c9a8f06..b3cac38 100644 --- a/meson.build +++ b/meson.build @@ -17,7 +17,7 @@ config_h.set('_GNU_SOURCE', '1') subdir('proto') -lib_util = static_library('util', +src_libutil = [ 'src/util-io.h', 'src/util-list.h', 'src/util-list.c', @@ -32,7 +32,9 @@ lib_util = static_library('util', 'src/util-sources.c', 'src/util-strings.c', 'src/util-strings.h', -) +] + +lib_util = static_library('util', src_libutil) dep_libutil = declare_dependency(link_with: lib_util) @@ -160,6 +162,14 @@ test('sourcestest', include_directories: 'src', dependencies: [dep_unittest, dep_libutil])) +test('unit-tests-untils', + executable('unit-tests-utils', + 'test/unit-tests.c', + src_libutil, + include_directories: 'src', + c_args: ['-D_enable_tests_'], + dependencies: [dep_unittest])) + test('unit-tests-ei', executable('unit-tests-ei', 'test/unit-tests.c', diff --git a/src/util-list.c b/src/util-list.c index 45fed45..1d01373 100644 --- a/src/util-list.c +++ b/src/util-list.c @@ -86,3 +86,72 @@ list_empty(const struct list *list) return list->next == list; } + +#if _enable_tests_ +#include "util-munit.h" +#include "util-macros.h" + +MUNIT_TEST(test_list_insert) +{ + struct list_test { + int val; + struct list node; + } tests[] = { + { .val = 1 }, + { .val = 2 }, + { .val = 3 }, + { .val = 4 }, + }; + struct list_test *t; + struct list head; + + list_init(&head); + munit_assert(list_empty(&head)); + + ARRAY_FOR_EACH(tests, t) { + list_insert(&head, &t->node); + } + + int val = 4; + list_for_each(t, &head, node) { + munit_assert_int(t->val, ==, val); + val--; + } + + munit_assert_int(val, ==, 0); + return MUNIT_OK; +} + + +MUNIT_TEST(test_list_append) +{ + struct list_test { + int val; + struct list node; + } tests[] = { + { .val = 1 }, + { .val = 2 }, + { .val = 3 }, + { .val = 4 }, + }; + struct list_test *t; + struct list head; + + list_init(&head); + munit_assert(list_empty(&head)); + + ARRAY_FOR_EACH(tests, t) { + list_append(&head, &t->node); + } + + int val = 1; + list_for_each(t, &head, node) { + munit_assert_int(t->val, ==, val); + val++; + } + munit_assert_int(val, ==, 5); + + return MUNIT_OK; +} + +#endif diff --git a/src/util-strings.c b/src/util-strings.c index d2c6de7..f7edc7e 100644 --- a/src/util-strings.c +++ b/src/util-strings.c @@ -155,3 +155,226 @@ strv_join(char **strv, const char *joiner) return str; } + +#if _enable_tests_ +#include "util-munit.h" + +MUNIT_TEST(test_strsplit) +{ + struct strsplit_test { + const char *string; + const char *delim; + const char *results[10]; + } tests[] = { + { "one two three", " ", { "one", "two", "three", NULL } }, + { "one", " ", { "one", NULL } }, + { "one two ", " ", { "one", "two", NULL } }, + { "one two", " ", { "one", "two", NULL } }, + { " one two", " ", { "one", "two", NULL } }, + { "one", "\t \r", { "one", NULL } }, + { "one two three", " t", { "one", "wo", "hree", NULL } }, + { " one two three", "te", { " on", " ", "wo ", "hr", NULL } }, + { "one", "ne", { "o", NULL } }, + { "onene", "ne", { "o", NULL } }, + { NULL, NULL, { NULL }} + }; + struct strsplit_test *t = tests; + + while (t->string) { + char **strv; + int idx = 0; + strv = strv_from_string(t->string, t->delim); + while (t->results[idx]) { + munit_assert_string_equal(t->results[idx], strv[idx]); + idx++; + } + munit_assert_ptr_equal(strv[idx], NULL); + strv_free(strv); + t++; + } + + /* Special cases */ + munit_assert_ptr_equal(strv_from_string("", " "), NULL); + munit_assert_ptr_equal(strv_from_string(" ", " "), NULL); + munit_assert_ptr_equal(strv_from_string(" ", " "), NULL); + munit_assert_ptr_equal(strv_from_string("oneoneone", "one"), NULL); + + return MUNIT_OK; +} + +MUNIT_TEST(test_kvsplit_double) +{ + struct kvsplit_dbl_test { + const char *string; + const char *psep; + const char *kvsep; + ssize_t nresults; + struct { + double a; + double b; + } results[32]; + } tests[] = { + { "1:2;3:4;5:6", ";", ":", 3, { {1, 2}, {3, 4}, {5, 6}}}, + { "1.0x2.3 -3.2x4.5 8.090909x-6.00", " ", "x", 3, { {1.0, 2.3}, {-3.2, 4.5}, {8.090909, -6}}}, + + { "1:2", "x", ":", 1, {{1, 2}}}, + { "1:2", ":", "x", -1, {}}, + { "1:2", NULL, "x", -1, {}}, + { "1:2", "", "x", -1, {}}, + { "1:2", "x", NULL, -1, {}}, + { "1:2", "x", "", -1, {}}, + { "a:b", "x", ":", -1, {}}, + { "", " ", "x", -1, {}}, + { "1.2.3.4.5", ".", "", -1, {}}, + { NULL } + }; + struct kvsplit_dbl_test *t = tests; + + while (t->string) { + struct key_value_double *result = NULL; + ssize_t npairs; + + npairs = kv_double_from_string(t->string, + t->psep, + t->kvsep, + &result); + munit_assert_int(npairs, ==, t->nresults); + + for (ssize_t i = 0; i < npairs; i++) { + munit_assert_double(t->results[i].a, ==, result[i].key); + munit_assert_double(t->results[i].b, ==, result[i].value); + } + + + free(result); + t++; + } + + return MUNIT_OK; +} + +MUNIT_TEST(test_strjoin) +{ + struct strjoin_test { + char *strv[10]; + const char *joiner; + const char *result; + } tests[] = { + { { "one", "two", "three", NULL }, " ", "one two three" }, + { { "one", NULL }, "x", "one" }, + { { "one", "two", NULL }, "x", "onextwo" }, + { { "one", "two", NULL }, ",", "one,two" }, + { { "one", "two", NULL }, ", ", "one, two" }, + { { "one", "two", NULL }, "one", "oneonetwo" }, + { { "one", "two", NULL }, NULL, NULL }, + { { "", "", "", NULL }, " ", " " }, + { { "a", "b", "c", NULL }, "", "abc" }, + { { "", "b", "c", NULL }, "x", "xbxc" }, + { { "", "", "", NULL }, "", "" }, + { { NULL }, NULL, NULL } + }; + struct strjoin_test *t = tests; + struct strjoin_test nulltest = { {NULL}, "x", NULL }; + + while (t->strv[0]) { + char *str; + str = strv_join(t->strv, t->joiner); + if (t->result == NULL) + munit_assert(str == NULL); + else + munit_assert_string_equal(str, t->result); + free(str); + t++; + } + + munit_assert(strv_join(nulltest.strv, "x") == NULL); + + return MUNIT_OK; +} + +MUNIT_TEST(test_strstrip) +{ + struct strstrip_test { + const char *string; + const char *expected; + const char *what; + } tests[] = { + { "foo", "foo", "1234" }, + { "\"bar\"", "bar", "\"" }, + { "'bar'", "bar", "'" }, + { "\"bar\"", "\"bar\"", "'" }, + { "'bar'", "'bar'", "\"" }, + { "\"bar\"", "bar", "\"" }, + { "\"\"", "", "\"" }, + { "\"foo\"bar\"", "foo\"bar", "\"" }, + { "\"'foo\"bar\"", "foo\"bar", "\"'" }, + { "abcfooabcbarbca", "fooabcbar", "abc" }, + { "xxxxfoo", "foo", "x" }, + { "fooyyyy", "foo", "y" }, + { "xxxxfooyyyy", "foo", "xy" }, + { "x xfooy y", " xfooy ", "xy" }, + { " foo\n", "foo", " \n" }, + { "", "", "abc" }, + { "", "", "" }, + { NULL , NULL, NULL } + }; + struct strstrip_test *t = tests; + + while (t->string) { + char *str; + str = strstrip(t->string, t->what); + munit_assert_string_equal(str, t->expected); + free(str); + t++; + } + return MUNIT_OK; +} + +MUNIT_TEST(test_strstartswith) +{ + struct strstartswith_test { + const char *string; + const char *suffix; + bool expected; + } tests[] = { + { "foobar", "foo", true }, + { "foobar", "bar", false }, + { "foobar", "foobar", true }, + { "foo", "foobar", false }, + { "foo", "", false }, + { "", "", false }, + { "foo", "", false }, + { NULL, NULL, false }, + }; + + for (struct strstartswith_test *t = tests; t->string; t++) { + munit_assert_int(strstartswith(t->string, t->suffix), ==, t->expected); + } + + return MUNIT_OK; +} + +MUNIT_TEST(test_strendswith) +{ + struct strendswith_test { + const char *string; + const char *suffix; + bool expected; + } tests[] = { + { "foobar", "bar", true }, + { "foobar", "foo", false }, + { "foobar", "foobar", true }, + { "foo", "foobar", false }, + { "foobar", "", false }, + { "", "", false }, + { "", "foo", false }, + { NULL, NULL, false }, + }; + + for (struct strendswith_test *t = tests; t->string; t++) { + munit_assert_int(strendswith(t->string, t->suffix), ==, t->expected); + } + + return MUNIT_OK; +} +#endif