diff options
Diffstat (limited to 'tests/gtests')
-rw-r--r-- | tests/gtests/blenlib/BLI_ghash_performance_test.cc | 2 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_listbase_test.cc | 218 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_ressource_strings.h | 2 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_stack_test.cc | 54 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_string_test.cc | 70 | ||||
-rw-r--r-- | tests/gtests/blenlib/CMakeLists.txt | 4 |
6 files changed, 341 insertions, 9 deletions
diff --git a/tests/gtests/blenlib/BLI_ghash_performance_test.cc b/tests/gtests/blenlib/BLI_ghash_performance_test.cc index ef17349268c..fcee72466b7 100644 --- a/tests/gtests/blenlib/BLI_ghash_performance_test.cc +++ b/tests/gtests/blenlib/BLI_ghash_performance_test.cc @@ -26,7 +26,7 @@ extern "C" { double q, lf, var, pempty, poverloaded; \ int bigb; \ q = BLI_ghash_calc_quality_ex((_gh), &lf, &var, &pempty, &poverloaded, &bigb); \ - printf("GHash stats (%d entries):\n\t" \ + printf("GHash stats (%u entries):\n\t" \ "Quality (the lower the better): %f\n\tVariance (the lower the better): %f\n\tLoad: %f\n\t" \ "Empty buckets: %.2f%%\n\tOverloaded buckets: %.2f%% (biggest bucket: %d)\n", \ BLI_ghash_size(_gh), q, var, lf, pempty * 100.0, poverloaded * 100.0, bigb); \ diff --git a/tests/gtests/blenlib/BLI_listbase_test.cc b/tests/gtests/blenlib/BLI_listbase_test.cc index 4b4d5d80a43..994b8f74541 100644 --- a/tests/gtests/blenlib/BLI_listbase_test.cc +++ b/tests/gtests/blenlib/BLI_listbase_test.cc @@ -3,10 +3,69 @@ #include "testing/testing.h" extern "C" { +#include "BLI_array_utils.h" #include "BLI_listbase.h" #include "MEM_guardedalloc.h" + +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_ressource_strings.h" +} + + +/* local validation function */ +static bool listbase_is_valid(const ListBase *listbase) +{ +#define TESTFAIL(test) \ + if (!(test)) goto fail; + + if (listbase->first) { + const Link *prev, *link; + link = (Link *)listbase->first; + TESTFAIL(link->prev == NULL); + + link = (Link *)listbase->last; + TESTFAIL(link->next == NULL); + + prev = NULL; + link = (Link *)listbase->first; + do { + TESTFAIL(link->prev == prev); + } while ((prev = link), (link = link->next)); + TESTFAIL(prev == listbase->last); + + prev = NULL; + link = (Link *)listbase->last; + do { + TESTFAIL(link->next == prev); + } while ((prev = link), (link = link->prev)); + TESTFAIL(prev == listbase->first); + } + else { + TESTFAIL(listbase->last == NULL); + } +#undef TESTFAIL + + return true; + +fail: + return false; +} + +static int char_switch(char *string, char ch_src, char ch_dst) +{ + int tot = 0; + while (*string != 0) { + if (*string == ch_src) { + *string = ch_dst; + tot++; + } + string++; + } + return tot; } + TEST(listbase, FindLinkOrIndex) { ListBase lb; @@ -37,3 +96,162 @@ TEST(listbase, FindLinkOrIndex) BLI_freelistN(&lb); } + + +/* -------------------------------------------------------------------- */ +/* Sort utilities & test */ + +static int testsort_array_str_cmp(const void *a, const void *b) +{ + int i = strcmp(*(const char **)a, *(const char **)b); + return (i > 0) ? 1 : (i < 0) ? -1 : 0; +} + +static int testsort_listbase_str_cmp(const void *a, const void *b) +{ + const LinkData *link_a = (LinkData *)a; + const LinkData *link_b = (LinkData *)b; + int i = strcmp((const char *)link_a->data, (const char *)link_b->data); + return (i > 0) ? 1 : (i < 0) ? -1 : 0; +} + +static int testsort_array_str_cmp_reverse(const void *a, const void *b) +{ + return -testsort_array_str_cmp(a, b); +} + +static int testsort_listbase_str_cmp_reverse(const void *a, const void *b) +{ + return -testsort_listbase_str_cmp(a, b); +} + +/* check array and listbase compare */ +static bool testsort_listbase_array_str_cmp(ListBase *lb, char **arr, int arr_tot) +{ + LinkData *link_step; + int i; + + link_step = (LinkData *)lb->first; + for (i = 0; i < arr_tot; i++) { + if (strcmp(arr[i], (char *)link_step->data) != 0) { + return false; + } + link_step = link_step->next; + } + if (link_step) { + return false; + } + + return true; +} + +/* assumes nodes are allocated in-order */ +static bool testsort_listbase_sort_is_stable(ListBase *lb, bool forward) +{ + LinkData *link_step; + + link_step = (LinkData *)lb->first; + while (link_step && link_step->next) { + if (strcmp((const char *)link_step->data, (const char *)link_step->next->data) == 0) { + if ((link_step < link_step->next) != forward) { + return false; + } + } + link_step = link_step->next; + } + return true; +} + +TEST(listbase, Sort) +{ + const int words_len = sizeof(words10k) - 1; + char *words = BLI_strdupn(words10k, words_len); + int words_tot; + char **words_arr; /* qsort for comparison */ + int i; + char *w_step; + ListBase words_lb; + LinkData *words_linkdata_arr; + + /* delimit words */ + words_tot = 1 + char_switch(words, ' ', '\0'); + + words_arr = (char **)MEM_mallocN(sizeof(*words_arr) * words_tot, __func__); + + words_linkdata_arr = (LinkData *)MEM_mallocN(sizeof(*words_linkdata_arr) * words_tot, __func__); + + /* create array */ + w_step = words; + for (i = 0; i < words_tot; i++) { + words_arr[i] = w_step; + w_step += strlen(w_step) + 1; + } + + /* sort empty list */ + { + BLI_listbase_clear(&words_lb); + BLI_listbase_sort(&words_lb, testsort_listbase_str_cmp); + EXPECT_TRUE(listbase_is_valid(&words_lb)); + } + + /* sort single single */ + { + LinkData link; + link.data = words; + BLI_addtail(&words_lb, &link); + BLI_listbase_sort(&words_lb, testsort_listbase_str_cmp); + EXPECT_TRUE(listbase_is_valid(&words_lb)); + BLI_listbase_clear(&words_lb); + } + + /* create listbase */ + BLI_listbase_clear(&words_lb); + w_step = words; + for (i = 0; i < words_tot; i++) { + LinkData *link = &words_linkdata_arr[i]; + link->data = w_step; + BLI_addtail(&words_lb, link); + w_step += strlen(w_step) + 1; + } + EXPECT_TRUE(listbase_is_valid(&words_lb)); + + /* sort (forward) */ + { + qsort(words_arr, words_tot, sizeof(*words_arr), testsort_array_str_cmp); + + BLI_listbase_sort(&words_lb, testsort_listbase_str_cmp); + EXPECT_TRUE(listbase_is_valid(&words_lb)); + EXPECT_TRUE(testsort_listbase_array_str_cmp(&words_lb, words_arr, words_tot)); + EXPECT_TRUE(testsort_listbase_sort_is_stable(&words_lb, true)); + } + + /* sort (reverse) */ + { + qsort(words_arr, words_tot, sizeof(*words_arr), testsort_array_str_cmp_reverse); + + BLI_listbase_sort(&words_lb, testsort_listbase_str_cmp_reverse); + EXPECT_TRUE(listbase_is_valid(&words_lb)); + EXPECT_TRUE(testsort_listbase_array_str_cmp(&words_lb, words_arr, words_tot)); + EXPECT_TRUE(testsort_listbase_sort_is_stable(&words_lb, true)); + } + + /* sort (forward but after reversing, test stability in alternate direction) */ + { + BLI_array_reverse(words_arr, words_tot); + BLI_listbase_reverse(&words_lb); + + EXPECT_TRUE(listbase_is_valid(&words_lb)); + EXPECT_TRUE(testsort_listbase_array_str_cmp(&words_lb, words_arr, words_tot)); + EXPECT_TRUE(testsort_listbase_sort_is_stable(&words_lb, false)); + + /* and again */ + BLI_array_reverse(words_arr, words_tot); + BLI_listbase_sort(&words_lb, testsort_listbase_str_cmp_reverse); + EXPECT_TRUE(testsort_listbase_array_str_cmp(&words_lb, words_arr, words_tot)); + EXPECT_TRUE(testsort_listbase_sort_is_stable(&words_lb, false)); + } + + MEM_freeN(words); + MEM_freeN(words_arr); + MEM_freeN(words_linkdata_arr); +} diff --git a/tests/gtests/blenlib/BLI_ressource_strings.h b/tests/gtests/blenlib/BLI_ressource_strings.h index b823f14af53..d7002d748c9 100644 --- a/tests/gtests/blenlib/BLI_ressource_strings.h +++ b/tests/gtests/blenlib/BLI_ressource_strings.h @@ -3,7 +3,7 @@ #ifndef __BLENDER_TESTING_BLI_RESSOURCE_STRING_H__ #define __BLENDER_TESTING_BLI_RESSOURCE_STRING_H__ -const char *words10k = +const char words10k[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor ultrices purus tincidunt mollis. Vestibulum " "tincidunt imperdiet molestie. Vivamus posuere, risus ut mollis rutrum, lacus nulla mollis velit, consectetur auctor " "erat est in odio. Proin quis lobortis ex. Ut id quam lacus. Morbi ultrices orci quis sem suscipit tincidunt. Nullam " diff --git a/tests/gtests/blenlib/BLI_stack_test.cc b/tests/gtests/blenlib/BLI_stack_test.cc index 08701356816..44956a589dc 100644 --- a/tests/gtests/blenlib/BLI_stack_test.cc +++ b/tests/gtests/blenlib/BLI_stack_test.cc @@ -11,6 +11,14 @@ extern "C" { #define SIZE 1024 +/* number of items per chunk. use a small value to expose bugs */ +#define STACK_CHUNK_SIZE 8 + +/* Ensure block size is set to #STACK_NEW_EX_ARGS */ +#define BLI_stack_new(esize, descr) \ + BLI_stack_new_ex(esize, descr, esize * STACK_CHUNK_SIZE) + + TEST(stack, Empty) { BLI_Stack *stack; @@ -110,18 +118,60 @@ TEST(stack, Peek) EXPECT_EQ(BLI_stack_is_empty(stack), true); } +/* Check that clearing the stack leaves in it a correct state. */ +TEST(stack, Clear) +{ + const int tot_rerun = 4; + int rerun; + + /* based on range test */ + int tot = SIZE; + BLI_Stack *stack; + int in, out; + + /* use a small chunk size to ensure we test */ + stack = BLI_stack_new(sizeof(in), __func__); + + for (rerun = 0; rerun < tot_rerun; rerun++) { + for (in = 0; in < tot; in++) { + BLI_stack_push(stack, (void *)&in); + } + + BLI_stack_clear(stack); + EXPECT_EQ(BLI_stack_is_empty(stack), true); + + /* and again, this time check its valid */ + for (in = 0; in < tot; in++) { + BLI_stack_push(stack, (void *)&in); + } + + for (in = tot - 1; in >= 0; in--) { + EXPECT_EQ(BLI_stack_is_empty(stack), false); + BLI_stack_pop(stack, (void *)&out); + EXPECT_EQ(in, out); + } + + EXPECT_EQ(BLI_stack_is_empty(stack), true); + + /* without this, we wont test case when mixed free/used */ + tot /= 2; + } + + BLI_stack_free(stack); +} + TEST(stack, Reuse) { const int sizes[] = {3, 11, 81, 400, 999, 12, 1, 9721, 7, 99, 5, 0}; int sizes_test[ARRAY_SIZE(sizes)]; const int *s; - int in, out, i; + int out, i; int sum, sum_test; BLI_Stack *stack; - stack = BLI_stack_new(sizeof(in), __func__); + stack = BLI_stack_new(sizeof(i), __func__); /* add a bunch of numbers, ensure we get same sum out */ sum = 0; diff --git a/tests/gtests/blenlib/BLI_string_test.cc b/tests/gtests/blenlib/BLI_string_test.cc index 4c5c410dcb2..fa10e21730b 100644 --- a/tests/gtests/blenlib/BLI_string_test.cc +++ b/tests/gtests/blenlib/BLI_string_test.cc @@ -36,7 +36,7 @@ int mk_wcswidth(const wchar_t *pwcs, size_t n) TEST(string, StrPartition) { const char delim[] = {'-', '.', '_', '~', '\\', '\0'}; - char *sep, *suf; + const char *sep, *suf; size_t pre_ln; { @@ -95,7 +95,7 @@ TEST(string, StrPartition) TEST(string, StrRPartition) { const char delim[] = {'-', '.', '_', '~', '\\', '\0'}; - char *sep, *suf; + const char *sep, *suf; size_t pre_ln; { @@ -150,11 +150,42 @@ TEST(string, StrRPartition) } } +/* BLI_str_partition_ex */ +TEST(string, StrPartitionEx) +{ + const char delim[] = {'-', '.', '_', '~', '\\', '\0'}; + const char *sep, *suf; + size_t pre_ln; + + /* Only considering 'from_right' cases here. */ + + { + const char *str = "mat.e-r_ia.l"; + + /* "mat.e-r_ia.l" over "mat.e-r" -> "mat.e", '.', "r_ia.l", 3 */ + pre_ln = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true); + EXPECT_EQ(5, pre_ln); + EXPECT_EQ(&str[5], sep); + EXPECT_STREQ("r_ia.l", suf); + } + + /* Corner cases. */ + { + const char *str = "mate.rial"; + + /* "mate.rial" over "mate" -> "mate.rial", NULL, NULL, 4 */ + pre_ln = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true); + EXPECT_EQ(4, pre_ln); + EXPECT_EQ(NULL, sep); + EXPECT_EQ(NULL, suf); + } +} + /* BLI_str_partition_utf8 */ TEST(string, StrPartitionUtf8) { const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'}; - char *sep, *suf; + const char *sep, *suf; size_t pre_ln; { @@ -213,7 +244,7 @@ TEST(string, StrPartitionUtf8) TEST(string, StrRPartitionUtf8) { const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'}; - char *sep, *suf; + const char *sep, *suf; size_t pre_ln; { @@ -268,6 +299,37 @@ TEST(string, StrRPartitionUtf8) } } +/* BLI_str_partition_ex_utf8 */ +TEST(string, StrPartitionExUtf8) +{ + const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'}; + const char *sep, *suf; + size_t pre_ln; + + /* Only considering 'from_right' cases here. */ + + { + const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial"; + + /* "ma\xc3\xb1te-r\xe2\x98\xafial" over "ma\xc3\xb1te" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */ + pre_ln = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true); + EXPECT_EQ(2, pre_ln); + EXPECT_EQ(&str[2], sep); + EXPECT_STREQ("te-r\xe2\x98\xafial", suf); + } + + /* Corner cases. */ + { + const char *str = "mate\xe2\x98\xafrial"; + + /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", NULL, NULL, 4 */ + pre_ln = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true); + EXPECT_EQ(4, pre_ln); + EXPECT_EQ(NULL, sep); + EXPECT_EQ(NULL, suf); + } +} + /* BLI_str_format_int_grouped */ TEST(string, StrFormatIntGrouped) { diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt index 152b65617a4..20b876053d9 100644 --- a/tests/gtests/blenlib/CMakeLists.txt +++ b/tests/gtests/blenlib/CMakeLists.txt @@ -45,4 +45,6 @@ BLENDER_TEST(BLI_listbase "bf_blenlib") BLENDER_TEST(BLI_hash_mm2a "bf_blenlib") BLENDER_TEST(BLI_ghash "bf_blenlib") -BLENDER_TEST(BLI_ghash_performance "bf_blenlib") +if(WITH_TESTS_PERFORMANCE) + BLENDER_TEST(BLI_ghash_performance "bf_blenlib") +endif() |