2017-10-25 18:35:04 +02:00
|
|
|
/*
|
|
|
|
* test_hashtable.c
|
|
|
|
*
|
|
|
|
* Created on: 21.10.2017
|
|
|
|
* Author: julian
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "tests.h"
|
|
|
|
#include "hashtable.h"
|
|
|
|
|
|
|
|
struct hashtable table = {};
|
|
|
|
struct entry nEntry;
|
|
|
|
|
|
|
|
void testresize() {
|
|
|
|
init("resize");
|
|
|
|
int err = hashtable_resize(&table, 20);
|
|
|
|
if (err != 0) {
|
|
|
|
fail("resize return code was error %d", err);
|
|
|
|
}
|
|
|
|
if (table.len != 20) {
|
|
|
|
fail("table has wrong size %d", table.len);
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
|
|
|
void testadd() {
|
|
|
|
init("add");
|
|
|
|
nEntry = hashtable_make_entry("hi", "20");
|
|
|
|
size_t count = table.count;
|
|
|
|
|
|
|
|
int err = hashtable_add(&table, nEntry);
|
|
|
|
|
|
|
|
if (err != 0) {
|
|
|
|
fail("add gave error %d", err);
|
|
|
|
}
|
|
|
|
if (table.count != count +1) {
|
|
|
|
fail("table has wrong count (has %d, needs %d)", table.count, count+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
2017-10-25 20:28:01 +02:00
|
|
|
volatile int number_copied = 0;
|
|
|
|
|
|
|
|
void* test_copy(void * data) {
|
|
|
|
number_copied++;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-10-25 18:35:04 +02:00
|
|
|
void testget() {
|
|
|
|
init("get");
|
|
|
|
|
2020-12-02 15:35:20 +01:00
|
|
|
hashtable_clear(&table);
|
|
|
|
|
|
|
|
if (hashtable_get(&table, "hi") != hashtable_end(&table)) {
|
|
|
|
fail("found entry in empty table");
|
|
|
|
}
|
|
|
|
|
|
|
|
hashtable_add(&table, nEntry);
|
2017-10-25 18:35:04 +02:00
|
|
|
hashtable_iterator_t elem = hashtable_get(&table, "hi");
|
|
|
|
|
|
|
|
if (elem == hashtable_end(&table)) {
|
|
|
|
fail("element was not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (elem->data != nEntry.data) {
|
|
|
|
fail("returned wrong element");
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
|
|
|
void testiterate() {
|
|
|
|
init("iterate");
|
|
|
|
|
|
|
|
hashtable_iterator_t it = hashtable_next(&table, NULL);
|
|
|
|
|
|
|
|
if (it == hashtable_end(&table)) {
|
|
|
|
fail("table seems empty?");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(it->key, "hi")) {
|
|
|
|
fail("wrong entry (smh)");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
volatile int dealloc_called = 0;
|
|
|
|
|
|
|
|
void test_dealloc(void* data) {
|
|
|
|
dealloc_called++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void testremove() {
|
|
|
|
init("remove");
|
|
|
|
dealloc_called = 0;
|
|
|
|
table.dealloc_data = test_dealloc;
|
|
|
|
|
|
|
|
if (hashtable_add(&table, hashtable_make_entry("woop", NULL)) < 0) {
|
|
|
|
fail("could not add");
|
|
|
|
}
|
|
|
|
|
|
|
|
hashtable_iterator_t it = hashtable_get(&table, "woop");
|
|
|
|
int ret = hashtable_remove(&table, it);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
fail("negative return code");
|
|
|
|
}
|
|
|
|
if (!ret) {
|
|
|
|
fail("could not remove");
|
|
|
|
}
|
|
|
|
if (!dealloc_called) {
|
|
|
|
fail("deallocator not called");
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
void testclear() {
|
|
|
|
init("clear");
|
|
|
|
|
|
|
|
size_t count = table.count;
|
|
|
|
table.dealloc_data = test_dealloc;
|
|
|
|
|
|
|
|
hashtable_clear(&table);
|
|
|
|
if (table.count != 0 || table.len != 0 || table.data != NULL) {
|
|
|
|
fail("memory was not freed");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dealloc_called != count) {
|
|
|
|
fail("dealloc was not called for all the data");
|
|
|
|
}
|
|
|
|
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
init("hashtable");
|
|
|
|
testresize();
|
|
|
|
testadd();
|
|
|
|
testget();
|
|
|
|
testiterate();
|
|
|
|
testclear();
|
|
|
|
pass();
|
|
|
|
}
|
|
|
|
|
|
|
|
|