/** * lda-utest.c * Unit tests for list_delete_all. */ // +---------+-------------------------------------------------------- // | Headers | // +---------+ #include #include #include "list.h" #include "list-delete-all.h" #include "mem.h" // +---------+-------------------------------------------------------- // | Globals | // +---------+ /** * The number of tests. */ static int tests = 0; /** * The number of errors */ static int errors = 0; // +---------+-------------------------------------------------------- // | Helpers | // +---------+ static int string_equal (char *str1, char *str2) { if (str1 == str2) return 1; else if ((str1 == NULL) || (str2 == NULL)) return 0; else return (strcmp (str1, str2) == 0); } // string_equal static void print_array (char *strings[], int size, FILE *fp) { int i; if (size == 0) { fprintf (fp, "()"); return; } fprintf (fp, "(\"%s\"", strings[0]); for (i = 1; i < size; i++) fprintf (fp, " \"%s\"", strings[i]); fprintf (fp, ")"); } // print_array /** * Report info on list and array. A helper for list_check */ static void report_info (struct list *lst, char *strings[], int size) { fprintf (stderr, " Expected: "); print_array (strings, size, stderr); fprintf (stderr, "\n"); fprintf (stderr, " Got: "); list_print (lst, stderr); fprintf (stderr, "\n"); } // report_info /** * Check if a list has a particular set of strings. That is, for * all i, 0 <= i < size; list_get (lst, i) is strings[i]. */ static void list_check (char *name, struct list *lst, char *strings[], int size) { int i; char *str; ++tests; if (list_length (lst) != size) { ++errors; fprintf (stderr, "Test failed: %s\n", name); fprintf (stderr, " Expected size %d list, got %d.\n", size, list_length (lst)); report_info (lst, strings, size); return; } for (i = 0; i < size; i++) { str = list_get (lst, i); if (! string_equal (str, strings[i])) { ++errors; fprintf (stderr, "Test failed: %s\n", name); fprintf (stderr, " Got incorrect string at position %d.\n", i); report_info (lst, strings, size); return; } // if } // for } // list_check // +------+----------------------------------------------------------- // | Main | // +------+ int main () { int empty_list_allocated; struct list *lst; lst = list_new (); empty_list_allocated = mem_allocated (); // Deleting from an empty list. list_delete_all (lst, "a"); list_check ("deleting from empty list", lst, ((char *[]) { }), 0); // Deleting an element not in the list. list_append (lst, "a"); list_append (lst, "a"); list_append (lst, "b"); list_append (lst, "b"); list_append (lst, "c"); list_append (lst, "a"); list_append (lst, "d"); list_append (lst, "c"); list_append (lst, "c"); list_delete_all (lst, "e"); list_check ("deleting element not in list", lst, ((char *[]) {"a","a","b","b","c","a","d","c","c"}), 9); // Simple deletion, just one element in a list list_delete_all (lst, "d"); list_check ("deleting element from middle of list", lst, ((char *[]) {"a","a","b","b","c","a","c","c"}), 8); // Delete multiple elements in a row list_delete_all (lst, "b"); list_check ("deleting multiple elements in a row", lst, ((char *[]) {"a","a","c","a","c","c"}), 6); // Delete elements from the beginning of the list (and elsewher) list_delete_all (lst, "a"); list_check ("deleting elements from front", lst, ((char *[]) {"c","c","c"}), 3); // Delete elements from the end of the list list_prepend (lst, "b"); list_delete_all (lst, "c"); list_check ("deleting elements from end", lst, ((char *[]) {"b"}), 1); // Delete all elements list_delete_all (lst, "b"); list_check ("deleting all remaining elements", lst, ((char *[]) { }), 0); // Check memory allocation ++tests; if (mem_allocated () != empty_list_allocated) { ++errors; fprintf (stderr, "Error: Memory leak.\n"); } // Make sure that we can still append values. list_append (lst, "z"); list_prepend (lst, "a"); list_append (lst, "y"); list_check ("appending elements", lst, ((char *[]) {"a","z","y"}), 3); // And we're done fprintf (stderr, "%d tests conducted.\n", tests); fprintf (stderr, "%d errors encountered.\n", errors); return errors; } // main