Add full coverage for list.c

This commit is contained in:
Drew DeVault 2016-06-19 12:06:16 -04:00
parent 5b7cb67779
commit cd64ad56b9
3 changed files with 211 additions and 5 deletions

View file

@ -14,5 +14,10 @@ enum wrapper_behavior {
int reset_mem_wrappers(void **state);
void memory_behavior(enum wrapper_behavior behavior);
int malloc_calls();
int free_calls();
int calloc_calls();
int realloc_calls();
int alloc_calls();
#endif

View file

@ -5,16 +5,185 @@
#include "tests.h"
#include "list.h"
static void test_create_list(void **state) {
memory_behavior(WRAPPER_INVOKE_CMOCKA);
static void assert_list_contents(list_t *list, int contents[], size_t len) {
assert_int_equal(list->length, (int)len);
for (size_t i = 0; i < (size_t)list->length; ++i) {
assert_int_equal(contents[i], *(int *)list->items[i]);
}
}
static list_t *create_test_list(int contents[], size_t len) {
list_t *l = create_list();
for (size_t i = 0; i < len; ++i) {
list_add(l, &contents[i]);
}
return l;
}
static void test_create_and_free(void **state) {
list_t *list = create_list();
assert_int_equal(list->length, 0);
assert_int_equal(list->capacity, 10);
assert_non_null(list->items);
list_free(list);
assert_int_equal(malloc_calls(), 2);
assert_int_equal(free_calls(), 2);
}
static void test_add(void **state) {
list_t *list = create_list();
int items[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
for (size_t i = 0; i < sizeof(items) / sizeof(int); ++i) {
list_add(list, &items[i]);
assert_int_equal(items[i], *(int *)list->items[i]);
assert_int_equal(list->length, i + 1);
}
assert_list_contents(list, items, 15);
assert_int_equal(list->length, 15);
assert_int_equal(list->capacity, 20);
assert_int_equal(realloc_calls(), 1);
list_free(list);
}
static void test_insert(void **state) {
list_t *list = create_list();
int i = 1, j = 2;
list_add(list, &i);
list_add(list, &i);
list_add(list, &i);
list_insert(list, 0, &j);
assert_int_equal(j, *(int *)list->items[0]);
assert_int_equal(list->length, 4);
list_free(list);
}
static void test_del(void **state) {
list_t *list = create_list();
int items[] = { 1, 2, 3, 4, 5 };
int new_items[] = { 1, 2, 4, 5 };
for (size_t i = 0; i < sizeof(items) / sizeof(int); ++i) {
list_add(list, &items[i]);
}
list_del(list, 2);
assert_list_contents(list, new_items, 4);
list_free(list);
}
static void test_cat(void **state) {
int items_a[] = { 1, 2, 3, 4 };
int items_b[] = { 5, 6, 7, 8 };
int items_final[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
list_t *list_a = create_test_list(items_a, 4);
list_t *list_b = create_test_list(items_b, 4);
list_cat(list_a, list_b);
assert_list_contents(list_a, items_final, 8);
list_free(list_a);
list_free(list_b);
}
static int qsort_compare(const void *left, const void *right) {
return **(int * const *)left - **(int * const *)right;
}
static void test_qsort(void **state) {
int items_start[] = { 1, 4, 3, 2 };
int items_final[] = { 1, 2, 3, 4 };
list_t *list = create_test_list(items_start, 4);
list_qsort(list, qsort_compare);
assert_list_contents(list, items_final, 4);
list_free(list);
}
static int find_compare(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
static void test_seq_find(void **state) {
int items[] = { 1, 2, 3, 4 };
int expected = 3;
list_t *list = create_test_list(items, 4);
int index = list_seq_find(list, find_compare, &expected);
assert_int_equal(index, 2);
list_free(list);
}
int foreach_count = 0;
static void foreach(void *item) {
foreach_count++;
assert_int_equal(*(int *)item, foreach_count);
}
static void test_foreach(void **state) {
int items[] = { 1, 2, 3, 4 };
list_t *list = create_test_list(items, 4);
list_foreach(list, foreach);
assert_int_equal(foreach_count, 4);
list_free(list);
}
struct stable_data {
int id, value;
};
static int stable_compare(const void *_a, const void *_b) {
struct stable_data * const *a = _a;
struct stable_data * const *b = _b;
return (*a)->value - (*b)->value;
}
static void test_stable_sort(void **state) {
struct stable_data initial[] = {
{ .id = 0, .value = 0 },
{ .id = 3, .value = 2 },
{ .id = 4, .value = 3 },
{ .id = 1, .value = 1 },
{ .id = 2, .value = 1 },
{ .id = 5, .value = 4 },
{ .id = 7, .value = 5 },
{ .id = 6, .value = 5 },
};
struct stable_data expected[] = {
{ .id = 0, .value = 0 },
{ .id = 1, .value = 1 },
{ .id = 2, .value = 1 },
{ .id = 3, .value = 2 },
{ .id = 4, .value = 3 },
{ .id = 5, .value = 4 },
{ .id = 7, .value = 5 },
{ .id = 6, .value = 5 },
};
list_t *list = create_list();
for (size_t i = 0; i < sizeof(initial) / sizeof(initial[0]); ++i) {
list_add(list, &initial[i]);
}
list_stable_sort(list, stable_compare);
for (size_t i = 0; i < sizeof(expected) / sizeof(expected[0]); ++i) {
struct stable_data *item = list->items[i];
assert_int_equal(item->value, expected[i].value);
assert_int_equal(item->id, expected[i].id);
}
list_free(list);
}
int main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_create_list),
cmocka_unit_test(test_create_and_free),
cmocka_unit_test(test_add),
cmocka_unit_test(test_insert),
cmocka_unit_test(test_del),
cmocka_unit_test(test_cat),
cmocka_unit_test(test_qsort),
cmocka_unit_test(test_seq_find),
cmocka_unit_test(test_foreach),
cmocka_unit_test(test_stable_sort),
};
return cmocka_run_group_tests(tests, reset_mem_wrappers, NULL);
}

View file

@ -6,10 +6,18 @@ void __real_free(void *ptr);
void *__real_calloc(size_t nmemb, size_t size);
void *__real_realloc(void *ptr, size_t size);
enum wrapper_behavior _memory_behavior = WRAPPER_INVOKE_REAL;
enum wrapper_behavior _memory_behavior = WRAPPER_INVOKE_CMOCKA;
int malloc_callcount = 0,
free_callcount = 0,
calloc_callcount = 0,
realloc_callcount = 0;
int reset_mem_wrappers(void **state) {
_memory_behavior = WRAPPER_INVOKE_REAL;
_memory_behavior = WRAPPER_INVOKE_CMOCKA;
malloc_callcount =
free_callcount =
calloc_callcount =
realloc_callcount = 0;
return 0;
}
@ -17,7 +25,28 @@ void memory_behavior(enum wrapper_behavior behavior) {
_memory_behavior = behavior;
}
int malloc_calls() {
return malloc_callcount;
}
int free_calls() {
return free_callcount;
}
int calloc_calls() {
return calloc_callcount;
}
int realloc_calls() {
return realloc_callcount;
}
int alloc_calls() {
return malloc_callcount + calloc_callcount;
}
void *__wrap_malloc(size_t size) {
++malloc_callcount;
switch (_memory_behavior) {
case WRAPPER_INVOKE_CMOCKA:
return test_malloc(size);
@ -31,6 +60,7 @@ void *__wrap_malloc(size_t size) {
}
void __wrap_free(void *ptr) {
++free_callcount;
switch (_memory_behavior) {
case WRAPPER_INVOKE_CMOCKA:
test_free(ptr);
@ -46,6 +76,7 @@ void __wrap_free(void *ptr) {
}
void *__wrap_calloc(size_t nmemb, size_t size) {
++calloc_callcount;
switch (_memory_behavior) {
case WRAPPER_INVOKE_CMOCKA:
return test_calloc(nmemb, size);
@ -60,6 +91,7 @@ void *__wrap_calloc(size_t nmemb, size_t size) {
}
void *__wrap_realloc(void *ptr, size_t size) {
++realloc_callcount;
switch (_memory_behavior) {
case WRAPPER_INVOKE_CMOCKA:
return test_realloc(ptr, size);