Files
libucore/test/test_htable.c
T
Nils O. Selåsdal 6c76759355 Add more htable tests
2013-10-17 21:29:55 +02:00

183 lines
4.4 KiB
C

#include <check.h>
#include <string.h>
#include <ucore/htable.h>
#include <ucore/utils.h>
struct MyString {
char str[32];
struct UHNode node;
};
size_t hash_str(const char *str)
{
size_t hash = 31;
while (*str) {
hash *= *str++;
}
return hash;
}
size_t bad_hash(const char *str)
{
return str[0];
}
struct MyString *my_find(struct UHTable *table, const char *str, size_t hash)
{
struct UHNode *it;
UC_HTABLE_FOREACH_HASH(table, it, hash) {
struct MyString *my_str = UC_CONTAINER_OF(it, struct MyString, node);
if (strcmp(my_str->str, str) == 0) {
return my_str;
}
}
return NULL;
}
START_TEST (test_htable1)
struct MyString str[5] = {
{"One", {0,NULL}},
{"Two", {0,NULL}},
{"Three",{0,NULL}},
{"Four", {0,NULL}},
{"Five", {0,NULL}}
};
struct UHTable table;
int i;
uc_htable_init(&table, 3);
for (i = 0; i < 5; i++) {
uc_htable_insert(&table, &str[i].node, hash_str(str[i].str));
}
ck_assert_int_eq(uc_htable_count(&table), 5);
fail_if(my_find(&table, "One", hash_str("One")) != &str[0]);
fail_if(my_find(&table, "Two", hash_str("Two")) != &str[1]);
fail_if(my_find(&table, "Three",hash_str("Three")) != &str[2]);
fail_if(my_find(&table, "Four", hash_str("Four")) != &str[3]);
fail_if(my_find(&table, "Five", hash_str("Five")) != &str[4]);
END_TEST
START_TEST (test_htable_hash_collision)
//same as test1 but with a bad hash to force equal hash
struct MyString str[5] = {
{"...", {0,NULL}},
{"", {0,NULL}},
{".", {0,NULL}},
{"..", {0,NULL}},
{"....", {0,NULL}}
};
struct UHTable table;
int i;
uc_htable_init(&table, 1);
for (i = 0; i < 5; i++) {
uc_htable_insert(&table, &str[i].node, bad_hash(str[i].str));
}
ck_assert_int_eq(uc_htable_count(&table), 5);
fail_if(my_find(&table, "....", bad_hash("....")) != &str[4]);
fail_if(my_find(&table, ".", bad_hash(".")) != &str[2]);
fail_if(my_find(&table, "", bad_hash("")) != &str[1]);
fail_if(my_find(&table, "..", bad_hash("..")) != &str[3]);
fail_if(my_find(&table, "...", bad_hash("...")) != &str[0]);
END_TEST
START_TEST (test_htable_resize)
struct MyString str[5] = {
{"One", {0,NULL}},
{"Two", {0,NULL}},
{"Three",{0,NULL}},
{"Four", {0,NULL}},
{"Five", {0,NULL}}
};
struct UHTable table;
int i;
int rc;
rc = uc_htable_init(&table, 3);
ck_assert_int_eq(rc, 0);
for (i = 0; i < 5; i++) {
uc_htable_insert(&table, &str[i].node, hash_str(str[i].str));
}
ck_assert_int_eq(uc_htable_count(&table), 5);
rc = uc_htable_resize(&table, 1024);
ck_assert_int_eq(rc, 0);
ck_assert_int_eq(uc_htable_count(&table), 5);
fail_if(my_find(&table, "One", hash_str("One")) != &str[0]);
fail_if(my_find(&table, "Two", hash_str("Two")) != &str[1]);
fail_if(my_find(&table, "Three",hash_str("Three")) != &str[2]);
fail_if(my_find(&table, "Four", hash_str("Four")) != &str[3]);
fail_if(my_find(&table, "Five", hash_str("Five")) != &str[4]);
END_TEST
START_TEST (test_htable_fail_init_resize)
int rc;
struct UHTable table;
rc = uc_htable_init(&table, 0);
ck_assert_int_ne(rc, 0);
rc = uc_htable_init(&table, 1);
ck_assert_int_eq(rc, 0);
rc = uc_htable_resize(&table, 0);
ck_assert_int_ne(rc, 0);
END_TEST
START_TEST (test_htable_has_node)
struct MyString str1 = {"One", {0,NULL}};
struct MyString str2 = {"Two", {0,NULL}};
struct UHTable table;
int rc;
rc = uc_htable_init(&table, 3);
ck_assert_int_eq(rc, 0);
uc_htable_insert(&table, &str1.node, hash_str(str1.str));
ck_assert_int_eq(uc_htable_count(&table), 1);
rc = uc_htable_has_node(&table, &str1.node);
ck_assert_int_ne(rc, 0);
rc = uc_htable_has_node(&table, &str2.node);
ck_assert_int_eq(rc, 0);
END_TEST
Suite *htable_suite(void)
{
Suite *s = suite_create("htable");
TCase *tc = tcase_create("htable tests");
tcase_add_test(tc, test_htable1);
tcase_add_test(tc, test_htable_hash_collision);
tcase_add_test(tc, test_htable_resize);
tcase_add_test(tc, test_htable_fail_init_resize);
tcase_add_test(tc, test_htable_has_node);
suite_add_tcase(s, tc);
return s;
}