From 5063d4f7a3ddc59b7e3621090726db6ebad841b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Tvrd=C3=ADk?= Date: Fri, 13 Mar 2015 18:36:10 +0100 Subject: [PATCH] Add unit tests for lib/heap.h datastructures --- lib/heap_test.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 lib/heap_test.c diff --git a/lib/heap_test.c b/lib/heap_test.c new file mode 100644 index 00000000..aaf616bc --- /dev/null +++ b/lib/heap_test.c @@ -0,0 +1,153 @@ +#include "lib/heap.h" +#include "birdtest.h" +#include +#include + +#define MAX_NUM 1000 +#define SPECIAL_KEY -3213 + +#define MY_CMP(x, y) ((x) < (y)) + +static int num; +static int heap[MAX_NUM+1]; + +#define SHOW_HEAP(heap) \ + do { \ + uint _i; \ + bt_debug("\nnum = %d; ", num); \ + for(_i = 1; _i <= num; _i++) \ + bt_debug("%d ", heap[_i]); \ + if(is_heap_valid(heap, num)) \ + bt_debug("OK \n"); \ + else \ + bt_debug("NON-VALID HEAP! \n"); \ + } while(0) + + +#undef HEAP_SWAP +#define HEAP_SWAP(heap,a,b,t) \ + do { \ + t=heap[a]; \ + heap[a]=heap[b]; \ + heap[b]=t; \ + bt_debug("swap(%d %d) ", a, b); \ + } while(0) + +static int +is_heap_valid(int heap[], uint num) +{ + /* + * A valid heap must follow these rules: + * - `num >= 0` + * - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]` + */ + + if(num < 0) + return 0; + + int i; + for(i = 2; i <= num; i++) + if(heap[i] < heap[i / 2]) + return 0; + + return 1; +} + +static void +init_heap(void) +{ + int i; + num = 0; + heap[0] = SPECIAL_KEY; /* heap[0] should be unused */ + for(i = 1; i <= MAX_NUM; i++) + heap[i] = 0; +} + +static int +t_heap_insert(void) +{ + init_heap(); + + int i; + for(i = 1; i <= MAX_NUM; i++) + { + bt_debug("ins %d at pos %d ", MAX_NUM - i, i); + heap[i] = MAX_NUM - i; + HEAP_INSERT(heap, ++num, int, MY_CMP, HEAP_SWAP); + SHOW_HEAP(heap); + bt_assert(is_heap_valid(heap, num)); + } + + return BT_SUCCESS; +} + +static int +t_heap_increase_decrease(void) +{ + init_heap(); + t_heap_insert(); + + int i; + for(i = 1; i <= MAX_NUM; i++) + { + if(i > heap[i]) + { + bt_debug("inc %d ", i); + heap[i] = i; + HEAP_INCREASE(heap, num, int, MY_CMP, HEAP_SWAP, i); + } + else if (i < heap[i]) + { + bt_debug("dec %d ", i); + heap[i] = i; + HEAP_INCREASE(heap, num, int, MY_CMP, HEAP_SWAP, i); + } + SHOW_HEAP(heap); + bt_assert(is_heap_valid(heap, num)); + } + + return BT_SUCCESS; +} + +static int +t_heap_delete(void) +{ + init_heap(); + t_heap_insert(); + t_heap_increase_decrease(); + + int i; + for(i = 1; i <= num; i++) + { + bt_debug("del at pos %d ", i); + HEAP_DELETE(heap, num, int, MY_CMP, HEAP_SWAP, i); + SHOW_HEAP(heap); + bt_assert(is_heap_valid(heap, num)); + } + + return BT_SUCCESS; +} + +static int +t_heap_0(void) +{ + init_heap(); + t_heap_insert(); + t_heap_increase_decrease(); + t_heap_delete(); + + return (heap[0] == SPECIAL_KEY) ? BT_SUCCESS : BT_FAILURE; +} + +int +main(int argc, char *argv[]) +{ + bt_init(argc, argv); + + bt_test_case(t_heap_insert, "Test Inserting", 1, 5); + bt_test_case(t_heap_increase_decrease, "Test Increasing/Decreasing", 1, 5); + bt_test_case(t_heap_delete, "Test Deleting", 1, 5); + bt_test_case(t_heap_0, "Is heap[0] unused?", 1, 5); + + return 0; +}