1
0
forked from 131/lab6_list
Files
lab6_list/list_test.c
2022-04-23 01:35:06 +03:00

341 lines
7.9 KiB
C

#include <stdio.h>
#include "list.h"
#include "util.h"
#include "macro.h"
#include "munit/munit.h"
#define NAMELEN 128
typedef struct num_node {
list_node l;
int n;
} num_node;
static num_node *
new_num_node(int n)
{
num_node *res;
res = xmalloc(sizeof(*res));
res->n = n;
return res;
}
//#define NEW_ITEM(tp) xmalloc(sizeof(tp))
/*
list l;
list_init(&l);
list_clear(&l, NULL);
*/
int n_hardfrees = 0;
static void
hardmode_free(list_node *n)
{
n_hardfrees++;
memset(n, 0, sizeof(*n));
free(n);
}
void
list_num_print(list *l)
{
struct list_node *iter;
const char *hdrfmt = "%16.10s|%16.10s|%16.10s|%5.5s\n";
const char *itemfmt = "%16.10p|%16.10p|%16.10p|%5d\n";
printf("head = %p tail = %p\n", l->head, l->tail);
printf(hdrfmt, "ptr", "next", "prev", "n");
printf(" -------------------------------------------\n");
list_for_each(iter, l) {
num_node *ni;
ni = (num_node *)iter;
printf(itemfmt, ni, ni->l.next, ni->l.prev, ni->n);
}
}
static MunitResult
test_list_stage1(const MunitParameter params[], void * data)
{
//Tests for: list_init, list_clear, list_push_front, list_first, list_last
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
munit_logf(MUNIT_LOG_INFO, "Tests for %s", "list_init, list_clear, list_push_front, list_first, list_last");
munit_log(MUNIT_LOG_INFO, "Intializing num_node list...");
list_init(&l);
list_clear(&l, NULL);
munit_assert_null(l.head);
munit_assert_null(l.tail);
munit_log(MUNIT_LOG_INFO, "Checking list_push_front...");
// Insert first element, check list sanity
ni = new_num_node(num_arr[0]);
list_push_front(&l, (list_node *)ni);
munit_assert_null(ni->l.next);
munit_assert_null(ni->l.prev);
munit_assert_ptr(l.head, ==, ni);
munit_assert_ptr(l.tail, ==, ni);
// Insert second element, check list sanity
ni = new_num_node(num_arr[1]);
list_push_front(&l, (list_node *)ni);
munit_assert_not_null(ni->l.next);
munit_assert_null(ni->l.prev);
munit_assert_ptr(l.head, ==, ni);
munit_assert_ptr(l.tail, !=, ni);
for (i = 2; i < ARRSZ(num_arr); i++) {
munit_logf(MUNIT_LOG_DEBUG, "list_push_front i = %d", i);
ni = new_num_node(num_arr[i]);
list_push_front(&l, (list_node *)ni);
}
//list_num_print(&l);
munit_log(MUNIT_LOG_INFO, "Checking list contents after list_push_front calls");
// Manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, reverse_arr[i]);
}
ni = (num_node *) list_first(&l);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, reverse_arr[0]);
ni = (num_node *) list_last(&l);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[0]);
munit_assert_size(list_len(&l), ==, ARRSZ(num_arr));
list_clear(&l, (list_free_cb) free);
munit_assert_size(list_len(&l), ==, 0);
munit_log(MUNIT_LOG_INFO, "try to free every node and zero it memory");
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = xmalloc(sizeof(*ni));
ni->n = num_arr[i];
list_push_front(&l, (list_node *)ni);
}
size_t lsz = list_len(&l);
list_clear(&l, hardmode_free);
if (lsz != n_hardfrees) {
munit_log(MUNIT_LOG_WARNING, "not all objects are freed. Bug in list_clear??");
}
munit_assert_int(lsz, ==, n_hardfrees);
munit_assert_size(list_len(&l), ==, 0);
return MUNIT_OK;
}
static MunitResult
test_list_stage2(const MunitParameter params[], void * data)
{
//tests for list_push_back list_get list_insert list_pop_front list_pop_back
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int res_arr[] = {42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, 10};
num_node *n1, *n2;
num_node *ni;
int i;
int idx;
list l;
list_init(&l);
munit_log(MUNIT_LOG_INFO, "Checking list_push_back");
for (i = 2; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
munit_log(MUNIT_LOG_INFO, "Checking list_get");
for (i = 0; i < ARRSZ(num_arr) - 2; i++) {
ni = (num_node *) list_get(&l, i);
munit_assert_int(ni->n, ==, num_arr[i + 2]);
}
list_insert(&l, (list_node *) new_num_node(num_arr[0]), 0);
list_insert(&l, (list_node *) new_num_node(num_arr[1]), 1);
// manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, num_arr[i]);
}
list_insert(&l, (list_node *) new_num_node(42), 0);
list_insert(&l, (list_node *) new_num_node(43), 1);
list_insert(&l, (list_node *) new_num_node(44), list_len(&l) - 1);
// manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, res_arr[i]);
}
n2 = (num_node *) list_pop_front(&l);
munit_assert_not_null(n2);
munit_assert_int(n2->n, ==, 42);
n1 = (num_node *) list_pop_back(&l);
munit_assert_not_null(n1);
munit_assert_int(n1->n, ==, 10);
idx = list_index(&l, (list_node *) n2);
munit_assert_int(idx, ==, -1);
for (i = 0; i < 5; i++) {
munit_assert_int(
i, ==,
list_index(&l, list_get(&l, i))
);
}
list_clear(&l, (list_free_cb) free);
list_push_front(&l, (list_node *) n1);
list_push_front(&l, (list_node *) n2);
ni = (num_node *) list_pop_front(&l);
munit_assert_ptr(ni, ==, n2);
ni = (num_node *) list_pop_front(&l);
munit_assert_ptr(ni, ==, n1);
munit_assert_size(list_len(&l), ==, 0);
list_clear(&l, (list_free_cb) free);
munit_assert_null(list_pop_front(&l));
munit_assert_null(list_pop_back(&l));
return MUNIT_OK;
}
/*
static MunitResult
test_list_tmp(const MunitParameter params[], void * data)
{
//Tests for: list_remove list_reverse
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
list_init(&l);
list_clear(&l, (list_free_cb) free);
return MUNIT_OK;
}
*/
static MunitResult
test_list_remove(const MunitParameter params[], void * data)
{
//Tests for: list_remove list_reverse
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
num_node *ni;
int i;
list l;
list_init(&l);
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
ni = (num_node *) list_remove(&l, 122);
munit_assert_null(ni);
ni = (num_node *) list_remove(&l, 0);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[0]);
ni = (num_node *) list_remove(&l, list_len(&l) - 1);
munit_assert_not_null(ni);
munit_assert_int(ni->n, ==, num_arr[ARRSZ(num_arr) - 1]);
size_t sz = list_len(&l);
for (i = 0; i < sz; i++) {
ni = (num_node *) list_remove(&l, 0);
munit_assert_not_null(ni);
}
list_clear(&l, (list_free_cb) free);
return MUNIT_OK;
}
static MunitResult
test_list_reverse(const MunitParameter params[], void * data)
{
int num_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int reverse_arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
num_node *ni;
int i;
list l;
list_init(&l);
list_reverse(&l);
munit_assert_size(0, ==, list_len(&l));
for (i = 0; i < ARRSZ(num_arr); i++) {
ni = new_num_node(num_arr[i]);
list_push_back(&l, (list_node *)ni);
}
list_reverse(&l);
munit_assert_size(list_len(&l), ==, ARRSZ(reverse_arr));
//manually traverse list and check it
for (i = 0, ni = (num_node *) l.head;
ni != NULL;
i++, ni = (num_node *) (ni->l.next)) {
munit_assert_int(ni->n, ==, reverse_arr[i]);
}
return MUNIT_OK;
}
#define TEST_ITEM(func) {#func, func, NULL, NULL, MUNIT_TEST_OPTION_NONE }
static MunitTest test_suite_tests[] = {
TEST_ITEM(test_list_stage1),
TEST_ITEM(test_list_stage2),
TEST_ITEM(test_list_remove),
TEST_ITEM(test_list_reverse),
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
static const MunitSuite test_suite = {
(char *) "",
test_suite_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE
};
int
main(int argc, const char *argv[])
{
munit_suite_main(&test_suite, (void *) "vector_test", argc, (char * const*) argv);
return 0;
}