home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / toollib_2 / !ToolLib / tests / c / testlist next >
Text File  |  1996-05-28  |  7KB  |  278 lines

  1. /* testlist.c */
  2. /* A test harness for the list ADT
  3.  * (c) Paul Field
  4.  * v1.00 - 16/5/1995
  5.  * v1.10 - 15/7/1995 - list pointers now used
  6.  * v1.20 -  2/4/1996 - slight alterations to list interface because of exceptions
  7.  * v1.30 - 26/5/1996 - added tests for list_ptr functions
  8.  */
  9.  
  10. #include "list.h"
  11.  
  12. #include <stdarg.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <errno.h>
  16. #include "allocate.h"
  17.  
  18.  
  19.  
  20. static void _test_truth(const char* expression, bool value, unsigned line)
  21.  { if (!value)
  22.     { printf("line %u: %s is not true\n", line, expression);
  23.       exit(EXIT_FAILURE);
  24.     }
  25.  }
  26.  
  27. #define test_truth(a) _test_truth(#a, a, __LINE__)
  28.  
  29.  
  30.  
  31.  
  32. static void check_list(const list* l, unsigned length, ...)
  33.  { va_list  args;
  34.    list_ptr lptr;
  35.  
  36.    test_truth(list_length(l) == length);
  37.  
  38.    va_start(args, length);
  39.  
  40.    for (lptr = list_ptr_head(l); !list_ptr_past_the_end(lptr); list_ptr_inc(&lptr))
  41.     { int* element;
  42.  
  43.       element = va_arg(args, int*);
  44.       test_truth(list_ptr_element(lptr) == element);
  45.     }
  46.  
  47.    va_end(args);
  48.  }
  49.  
  50.  
  51.  
  52. static void check_functionality(void)
  53.  { int*     one;
  54.    int*     two;
  55.    int*     three;
  56.    list*    l;
  57.    list_ptr lptr;
  58.  
  59.    one   = list_alloc_element(sizeof(int));
  60.    *one  = 1;
  61.  
  62.    two   = list_alloc_element(sizeof(int));
  63.    *two  = 2;
  64.  
  65.    three  = list_alloc_element(sizeof(int));
  66.    *three = 3;
  67.  
  68.    /**** Check list_is_empty ****/
  69.    l = list_create();
  70.    test_truth(list_is_empty(l));
  71.    list_cons(l, one);
  72.    test_truth(!list_is_empty(l));
  73.  
  74.  
  75.    /**** Check list_cons (already called)/list_remove_head (l = [1]) ****/
  76.    test_truth(list_remove_head(l) == one);
  77.    test_truth(list_is_empty(l));
  78.  
  79.  
  80.    /**** Check list_length (l = []) ****/
  81.    test_truth(list_length(l) == 0);
  82.    list_cons(l, one);
  83.    test_truth(list_length(l) == 1);
  84.    list_cons(l, two);
  85.    test_truth(list_length(l) == 2);
  86.  
  87.    test_truth(list_remove_head(l) == two);
  88.    test_truth(list_length(l) == 1);
  89.    test_truth(list_remove_head(l) == one);
  90.    test_truth(list_length(l) == 0);
  91.  
  92.  
  93.    /**** Check list_ptr_head (l = []) ****/
  94.    test_truth(list_ptr_past_the_end(list_ptr_head(l)));
  95.  
  96.    list_cons(l, three);
  97.    test_truth(list_ptr_element(list_ptr_head(l)) == three);
  98.  
  99.    /**** Check list_ptr_past_the_end (l = [3]) ****/
  100.    /* Already tested on l = [] */
  101.    lptr = list_ptr_head(l);
  102.    test_truth(!list_ptr_past_the_end(lptr));
  103.  
  104.    list_ptr_inc(&lptr);
  105.    test_truth(list_ptr_past_the_end(lptr));
  106.  
  107.    /**** Check list_ptr_inc (l = [3]) ****/
  108.    list_cons(l, two);
  109.    list_cons(l, one);
  110.  
  111.    /* l = [1,2,3] */
  112.    check_list(l, 3, one, two, three);  /* Uses list_ptr_inc() */
  113.  
  114.    /**** Check list_ptr_add_element_after (l = [1,2,3]) ****/
  115.    test_truth(list_remove_head(l) == one);
  116.  
  117.    /** Check add after head element **/
  118.    /* l = [2,3] */
  119.    lptr = list_ptr_head(l);
  120.    list_ptr_add_element_after(lptr, one);
  121.    test_truth(list_ptr_element(lptr) == two);
  122.    check_list(l, 3, two, one, three);
  123.  
  124.    test_truth(list_remove_head(l) == two);
  125.  
  126.    /** Check add after non-head element **/
  127.    /* l = [1,3] */
  128.    lptr = list_ptr_head(l);
  129.    list_ptr_inc(&lptr);
  130.    list_ptr_add_element_after(lptr, two);
  131.    test_truth(list_ptr_element(lptr) == three);
  132.    check_list(l, 3, one, three, two);
  133.  
  134.  
  135.    /**** Check list_ptr_add_element_before (l = [1,3,2]) ****/
  136.    test_truth(list_remove_head(l) == one);
  137.  
  138.    /** Check add before head element **/
  139.    /* l = [3,2] */
  140.    lptr = list_ptr_head(l);
  141.    list_ptr_add_element_before(lptr, one);
  142.    check_list(l, 3, one, three, two);
  143.  
  144.    test_truth(list_remove_head(l) == one);
  145.  
  146.    /** Check add before non-head element **/
  147.    /* l = [3,2] */
  148.    lptr = list_ptr_head(l);
  149.    list_ptr_inc(&lptr);
  150.    list_ptr_add_element_before(lptr, one);
  151.    check_list(l, 3, three, one, two);
  152.  
  153.    test_truth(list_remove_head(l) == three);
  154.  
  155.    /** Check add before past_the_end **/
  156.    /* l = [1,2] */
  157.    lptr = list_ptr_head(l);
  158.    list_ptr_inc(&lptr);
  159.    list_ptr_inc(&lptr);
  160.    test_truth(list_ptr_past_the_end(lptr));
  161.    list_ptr_add_element_before(lptr, three);
  162.    check_list(l, 3, one, two, three);
  163.  
  164.  
  165.    /**** Check list_ptr_remove_element (l = [1,2,3]) ****/
  166.    /** Check remove head element **/
  167.    lptr = list_ptr_head(l);
  168.    list_ptr_remove_element(lptr);
  169.    check_list(l, 2, two, three);
  170.    list_cons(l, one);
  171.  
  172.    /** Check remove non-head element **/
  173.    lptr = list_ptr_head(l);
  174.    list_ptr_inc(&lptr);
  175.    list_ptr_remove_element(lptr);
  176.    check_list(l, 2, one, three);
  177.    list_cons(l, two);
  178.  
  179.  
  180.    /**** 'check' list_free_element & list_destroy l = [2,1,3] ****/
  181.    test_truth(list_remove_head(l) == two);
  182.    test_truth(list_remove_head(l) == one);
  183.    list_free_element(two);
  184.    list_free_element(one);
  185.    list_destroy(l);  /* Should also free 'three' */
  186.  }
  187.  
  188.  
  189.  
  190.  
  191. static void violate_precondition(unsigned conditionno)
  192.  { list* l;
  193.    list* emptyl;
  194.    list* notcreatedl;
  195.    int*  one;
  196.    int*  two;
  197.    int*  bogus;
  198.    int*  notinlist;
  199.  
  200.    one  = list_alloc_element(sizeof(int));
  201.    *one = 1;
  202.  
  203.    two  = list_alloc_element(sizeof(int));
  204.    *two = 2;
  205.  
  206.    bogus = memory_allocate(sizeof(int));
  207.    notinlist = list_alloc_element(sizeof(int));
  208.  
  209.    l = list_create();
  210.    list_cons(l, two);
  211.    list_cons(l, one);
  212.  
  213.    emptyl = list_create();
  214.  
  215.    /* This list is not complete, it serves to test some of the main debugging routines */
  216.    /* but doesn't check that all the routines call the appropriate routines or perform */
  217.    /* the appropriate test_truths (it does check some)                                     */
  218.    switch(conditionno)
  219.     { case 1:
  220.         puts("list_free_element: freeing an element that's in a list");
  221.         list_free_element(one);
  222.       case 2:
  223.         puts("list_cons: element not allocated by list_alloc_element");
  224.         list_cons(l, bogus);
  225.       case 3:
  226.         puts("list_cons: element already in list");
  227.         list_cons(l, one);
  228.       case 4:
  229.         puts("list_remove_head: list is empty");
  230.         list_remove_head(emptyl);
  231.       case 5:
  232.         puts("Using a list that hasn't been created. Problem may not get caught - depends on machine/compiler");
  233.         list_is_empty(notcreatedl);
  234.       case 6:
  235.         puts("Using a list that has been destroyed. Problem may not get caught - depends on machine/compiler");
  236.         list_destroy(l);
  237.         list_is_empty(l);
  238.       case 7:
  239.         puts("Various elements and lists have not been deallocated/destroyed");
  240.         /* Nothing - but we have not deallocated the elements & lists
  241.          * so we should get a debugging message
  242.          */
  243.     }
  244.  }
  245.  
  246.  
  247.  
  248.  
  249. static const char errmess[] =
  250.   "Please give a single integer (0-7) as the program argument\n"
  251.   "0 tests list module, 1-7 test various debugging routines";
  252.  
  253.  
  254.  
  255.  
  256. int main(int argc, char* argv[])
  257.  { unsigned code;
  258.  
  259.    if (argc != 2)
  260.     { puts(errmess);
  261.       return EXIT_FAILURE;
  262.     }
  263.    errno = 0;
  264.    code = (unsigned) strtoul(argv[1], NULL, 10);
  265.    if (code > 7 || errno == ERANGE)
  266.     { puts(errmess);
  267.       return EXIT_FAILURE;
  268.     }
  269.    if (code == 0)
  270.     { check_functionality();
  271.       puts("All is well - remember to check with NDEBUG defined and not defined");
  272.     }
  273.    else
  274.     { violate_precondition(code);
  275.     }
  276.    return EXIT_SUCCESS;
  277.  }
  278.