#ifdef HAVE_CONFIG_H # include "config.h" #endif // because libc has its own remove #define remove remove_renamed #include #include #include #include "QF/darray.h" #include "QF/sys.h" #undef remove typedef int (*test_func) (int a, int b); typedef struct intarray_s DARRAY_TYPE(int) intarray_t; intarray_t intarray = {0, 0, 16, 0}; static int append (int val, int b) { return DARRAY_APPEND (&intarray, val); } static int check_size (int a, int b) { return intarray.size; } static int check_maxSize (int a, int b) { return intarray.maxSize; } static int check_grow (int a, int b) { return intarray.grow; } static int check_maxSizeGrowth (int a, int b) { return intarray.maxSize % intarray.grow; } static int check_array (int a, int b) { return !!intarray.a; } static int __attribute__((pure)) check_value (int index, int b) { if ((size_t) index >= intarray.size) { Sys_Error ("indexing beyond array"); } return intarray.a[index]; } static int insert_at (int val, int pos) { return DARRAY_INSERT_AT (&intarray, val, pos); } static int open_at (int pos, int size) { return DARRAY_OPEN_AT (&intarray, pos, size) - intarray.a; } static const char text[] = "Aloy is an awesome huntress."; static int open_at2 (int pos, int size) { memcpy(DARRAY_OPEN_AT (&intarray, pos, size), text, size * sizeof (int)); return strcmp((char*) (intarray.a + pos), text); } static int remove_at (int pos, int b) { return DARRAY_REMOVE_AT (&intarray, pos); } static int remove (int pos, int b) { return DARRAY_REMOVE (&intarray); } static int close_at (int pos, int size) { return DARRAY_CLOSE_AT (&intarray, pos, size); } static int clear (int a, int b) { DARRAY_CLEAR (&intarray); return 0; } static int resize (int size, int b) { DARRAY_RESIZE (&intarray, size); return 0; } struct { test_func test; int param1, param2; int test_expect; } tests[] = { {check_size, 0, 0, 0}, // confirm array empty but can grow {check_maxSize, 0, 0, 0}, {check_grow, 0, 0, 16}, {check_array, 0, 0, 0}, {append, 5, 0, 5}, // test first append to emtpty array {check_size, 0, 0, 1}, {check_maxSizeGrowth, 0, 0, 0}, {check_maxSize, 0, 0, 16}, {check_array, 0, 0, 1}, {check_value, 0, 0, 5}, {append, 42, 0, 42}, // test a second append {check_size, 0, 0, 2}, {check_maxSize, 0, 0, 16}, {check_value, 0, 0, 5}, {check_value, 1, 0, 42}, {insert_at, 69, 1, 69}, // test insertions {insert_at, 96, 0, 96}, {check_size, 0, 0, 4}, {check_maxSize, 0, 0, 16}, {check_value, 0, 0, 96}, {check_value, 1, 0, 5}, {check_value, 2, 0, 69}, {check_value, 3, 0, 42}, {open_at, 2, 14, 2}, // test opening a large hole {check_maxSizeGrowth, 0, 0, 0}, {check_maxSize, 0, 0, 32}, {check_size, 0, 0, 18}, {check_value, 0, 0, 96}, {check_value, 1, 0, 5}, {check_value, 16, 0, 69}, {check_value, 17, 0, 42}, {close_at, 1, 15, 5}, // test block removal {check_maxSize, 0, 0, 32}, {check_size, 0, 0, 3}, {check_value, 0, 0, 96}, {check_value, 1, 0, 69}, {check_value, 2, 0, 42}, {remove, 0, 0, 42}, // test "pop" {check_maxSize, 0, 0, 32}, {check_size, 0, 0, 2}, {check_value, 0, 0, 96}, {check_value, 1, 0, 69}, {remove_at, 0, 0, 96}, // test remove at {check_maxSize, 0, 0, 32}, {check_size, 0, 0, 1}, {check_value, 0, 0, 69}, {insert_at, 71, 1, 71}, // test insertion at end {resize, 48, 0, 0}, // test resize bigger {check_maxSizeGrowth, 0, 0, 0}, {check_maxSize, 0, 0, 48}, {check_size, 0, 0, 48}, {check_value, 0, 0, 69}, {check_value, 1, 0, 71}, {resize, 24, 0, 0}, // test resize smaller {check_maxSizeGrowth, 0, 0, 0}, {check_maxSize, 0, 0, 48}, {check_size, 0, 0, 24}, {check_value, 0, 0, 69}, {check_value, 1, 0, 71}, {open_at2, 1, (sizeof (text) + sizeof (int) - 1) / sizeof (int), 0}, {check_value, 0, 0, 69}, {check_value, 1, 0, 0x796f6c41}, {check_value, 9, 0, 71}, {clear, 0, 0, 0}, // test clearing {check_size, 0, 0, 0}, {check_maxSize, 0, 0, 0}, {check_array, 0, 0, 0}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) int test_start_line = __LINE__ - num_tests - 2; int main (int argc, const char **argv) { int res = 0; size_t i; for (i = 0; i < num_tests; i++) { if (tests[i].test) { int test_res; test_res = tests[i].test (tests[i].param1, tests[i].param2); if (test_res != tests[i].test_expect) { res |= 1; printf ("test %d (line %d) failed\n", (int) i, (int) i + test_start_line); printf ("expect: %d\n", tests[i].test_expect); printf ("got : %d\n", test_res); continue; } } } return res; }