/* $Header: /cvsroot/dhcp-agent/dhcp-agent/tests/tests-list.c,v 1.1 2003/01/02 04:23:02 actmodern Exp $
 * 
 * Copyright 2002 Thamer Alharbash <tmh@whitefang.com>
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 * 3. The names of the authors may not be used to endorse or promote
 * products derived from this software without specific prior
 * written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * list test code
 *
 */

/* this code is very redundant but since it's test code it
 * doesn't really matter. */

#include "dhcp-local.h"
#include "dhcp-libutil.h"

#include "tests.h"

int foo[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int bar[] = { 11, 12, 13, 14, 15 };
int foo_rand[]   =  {  9, 2, 1, 7, 13, 5 };
int foo_sorted[] =  { 13, 9, 7, 5, 2,  1 };

/* array of test routines. */
static int test_create_destroy(const char *name)
{
    list_t *list;

    list = list_create();
    list_destroy(list, NULL);

    return 0;
}

static int test_add_get_len(const char *name)
{
    list_t *list;
    int i, len;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++) {
        list_add(list, &foo[i]);
    }

    if(len != list_get_len(list)) {
            TEST_ERROR(name, "length do not match after list_add");
            list_destroy(list, NULL);
            return 1;
    }

    list_destroy(list, NULL);
    return 0;
}

static int test_add_get_by_index(const char *name)
{
    list_t *list;
    int i, j, len;
    int *ptr;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++) {
        list_add(list, &foo[i]);
    }

    j = 0;
    /* list should come back backward. */
    for(i = (len - 1);i >= 0; i--) {

        ptr = list_get_by_index(list, j);
        j++;

        if(*ptr != foo[i]) {
            TEST_ERROR(name, "values do not match after list_add");
            list_destroy(list, NULL);
            return 1;
        }
    }

    list_destroy(list, NULL);
    return 0;
}

static int test_add_to_end_get_len(const char *name)
{    
    list_t *list;
    int i, len;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++) {
        list_add_to_end(list, &foo[i]);
    }

    if(len != list_get_len(list)) {
            TEST_ERROR(name, "length do not match after list_add");
            list_destroy(list, NULL);
            return 1;
    }

    list_destroy(list, NULL);
    return 0;
}

static int test_add_to_end_get_by_index(const char *name)
{
    list_t *list;
    int i, len;
    int *ptr;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++) {
        list_add_to_end(list, &foo[i]);
    }

     /* list should come back backward. */
    for(i = 0;i < len; i++) {

        ptr = list_get_by_index(list, i);
 
        if(*ptr != foo[i])  {
            TEST_ERROR(name, "values do not match after list_add_to_end");
            list_destroy(list, NULL);
            return 1;
        }
    }

    list_destroy(list, NULL);
    return 0;
}

static int test_add_remove_get_len(const char *name)
{
    list_t *list;
    int i, len;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++)  {
        list_add(list, &foo[i]);
    }

    if(list_get_len(list) != len)  {
        TEST_ERROR(name, "len do not match after list_add");
        list_destroy(list, NULL);
        return 1;
    }

    for(i = 0;i < len; i++) {

        list_remove_by_datum(list, &foo[i]);
        if(list_get_len(list) != (len - (i + 1)))  {
            TEST_ERROR(name, "len do not match after list_remove");
            list_destroy(list, NULL);
            return 1;
        }
    }

    list_destroy(list, NULL);
    return 0;
}

static int test_add_to_end_remove_get_len(const char *name)
{
    list_t *list;
    int i, len;

    list = list_create();
    len = TEST_NELMS(foo);

    for(i = 0; i < len; i++)  {
        list_add_to_end(list, &foo[i]);
    }

    if(list_get_len(list) != len)  {
        TEST_ERROR(name, "len do not match after list_add");
        list_destroy(list, NULL);
        return 1;
    }

    for(i = 0;i < len; i++) {

        list_remove_by_datum(list, &foo[i]);
        if(list_get_len(list) != (len - (i + 1)))  {
            TEST_ERROR(name, "len do not match after list_remove");
            list_destroy(list, NULL);
            return 1;
        }
    }

    list_destroy(list, NULL);
    return 0;


}

static int test_join(const char *name)
{
    list_t *list_foo, *list_bar;
    int foo_len, bar_len, i;

    foo_len = TEST_NELMS(foo);
    bar_len = TEST_NELMS(bar);

    /* * * * * * * * * * * * * * * * * *
     * test with two populated lists   *
     * * * * * * * * * * * * * * * * * */

    list_foo = list_create();
    list_bar = list_create();

    for(i = 0; i < foo_len; i++)  {
        list_add_to_end(list_foo, &foo[i]);
    }

    for(i = 0; i < bar_len; i++)  {
        list_add_to_end(list_bar, &bar[i]);
    }

    /* now join the lists and check length
     * as well as individual datums. */

    list_join(list_foo, list_bar);

    if((foo_len + bar_len) != list_get_len(list_foo)) {
        TEST_ERROR(name, "len do not match after list_join");
        list_destroy(list_foo, NULL);
        return 1;
    }

    list_destroy(list_foo, NULL);

    /* * * * * * * * * * * * * * * * * *
     * test with first list populated  *
     * * * * * * * * * * * * * * * * * */
    list_foo = list_create();
    list_bar = list_create();

    for(i = 0; i < foo_len; i++)  {
        list_add_to_end(list_foo, &foo[i]);
    }

    list_join(list_foo, list_bar);

    if(foo_len != list_get_len(list_foo)) {
        TEST_ERROR(name, "len do not match after list_join");
        list_destroy(list_foo, NULL);
        return 1;
    }

    list_destroy(list_foo, NULL);

    /* * * * * * * * * * * * * * * * * * *
     * test with second list populated   *
     * * * * * * * * * * * * * * * * * * */

    list_foo = list_create();
    list_bar = list_create();

    for(i = 0; i < bar_len; i++)  {
        list_add_to_end(list_bar, &foo[i]);
    }

    list_join(list_foo, list_bar);

    if(bar_len != list_get_len(list_foo)) {
        TEST_ERROR(name, "len do not match after list_join");
        list_destroy(list_foo, NULL);
        list_destroy(list_bar, NULL);
        return 1;
    }

    list_destroy(list_foo, NULL);

    return 0;
}

static int compare(void *data1, void *data2)
{
    int *i, *j;

    i = data1;
    j = data2;

    if(*i < *j)
        return 1;

    if(*j < *i)
        return -1;

    return 0;
}

static int test_sort(const char *name)
{
    list_t *list_foo;
    int foo_len, i;
    int *j;

    foo_len = TEST_NELMS(foo_rand);
    list_foo = list_create();

    for(i = 0; i < foo_len; i++) {
        list_add(list_foo, &foo_rand[i]);
    }

    list_foo = list_sort(list_foo, compare);

    i = 0;
    list_rewind(list_foo);
    while((j = list_next(list_foo)) != NULL) {

        if(foo_sorted[i] != *j) {
            TEST_ERROR(name, "data not sorted properly by list_sort");
            list_destroy(list_foo, NULL);
            return 1;
        }

        i++;
    }

    list_destroy(list_foo, NULL);

    return 0;
}
static test_table tests[] = {
    { "create/destroy",  test_create_destroy  },
    { "add/get_len",  test_add_get_len  },
    { "add/get_by_index",  test_add_get_by_index },
    { "add_to_end/get_len",  test_add_to_end_get_len  },
    { "add_to_end/get_by_index",  test_add_to_end_get_by_index },
    { "add/remove/get_len",  test_add_remove_get_len },
    { "add_to_end/remove/get_len",  test_add_to_end_remove_get_len },
    { "join",  test_join },
    { "sort",  test_sort }
};

/* main: loops. */
int main(int argc, char *argv[])
{
    DO_TESTS(tests);

    exit(TESTS_EXIT_SUCCESS);
}


syntax highlighted by Code2HTML, v. 0.9.1