forked from 131/lab6_list
341 lines
7.9 KiB
C
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;
|
|
} |