]> begriffs open source - libderp/blob - test/t_treemap.c
Handy wrappers for std lib functions
[libderp] / test / t_treemap.c
1 #include "derp/common.h"
2 #include "derp/treemap.h"
3
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 int ivals[] = {0,1,2,3,4,5,6,7,8,9};
9
10 int icmp(const void *a, const void *b, void *aux)
11 {
12         (void)aux;
13         return *(int*)a - *(int*)b;
14 }
15
16 int main(void)
17 {
18         treemap *t = tm_new(derp_strcmp, NULL);
19         assert(tm_length(t) == 0);
20         assert(tm_is_empty(t));
21
22         assert(!tm_at(t, "zero"));
23         tm_insert(t, "zero", ivals);
24         assert(tm_length(t) == 1);
25         assert(*(int*)tm_at(t, "zero") == 0);
26
27         /* change it */
28         tm_insert(t, "zero", ivals+1);
29         assert(tm_length(t) == 1);
30         assert(*(int*)tm_at(t, "zero") == 1);
31         /* set it back */
32         tm_insert(t, "zero", ivals);
33         assert(*(int*)tm_at(t, "zero") == 0);
34
35         tm_insert(t, "one", ivals+1);
36         assert(tm_length(t) == 2);
37         assert(*(int*)tm_at(t, "zero") == 0);
38         assert(*(int*)tm_at(t, "one") == 1);
39         assert(!tm_at(t, "flurgle"));
40
41         tm_remove(t, "one");
42         assert(!tm_at(t, "one"));
43
44         tm_clear(t);
45         assert(tm_length(t) == 0);
46         assert(!tm_at(t, "zero"));
47
48         /* iterator should sort */
49         tm_insert(t, "d", NULL);
50         tm_insert(t, "a", NULL);
51         tm_insert(t, "e", NULL);
52         tm_insert(t, "c", NULL);
53         tm_insert(t, "b", NULL);
54
55         tm_iter *i = tm_iter_begin(t);
56         assert(*(char*)tm_iter_next(i)->k == 'a');
57         assert(*(char*)tm_iter_next(i)->k == 'b');
58         assert(*(char*)tm_iter_next(i)->k == 'c');
59         assert(*(char*)tm_iter_next(i)->k == 'd');
60         assert(*(char*)tm_iter_next(i)->k == 'e');
61         assert(!tm_iter_next(i));
62         tm_iter_free(i);
63         tm_clear(t);
64
65         /* test for memory leak */
66         tm_dtor(t, derp_free, derp_free, NULL);
67         char *key = malloc(5),
68                  *dupkey = malloc(5),
69                  *otherkey = malloc(3);
70         int  *val1 = malloc(sizeof *val1),
71              *val2 = malloc(sizeof *val2),
72              *val3 = malloc(sizeof *val3);
73         strcpy(key, "life");
74         strcpy(dupkey, "life");
75         *val1 = 42;
76         *val2 = 13;
77         tm_insert(t, key, val1);
78         /* will free key, since dupkey is the same */
79         tm_insert(t, dupkey, val2);
80         /* safe to double-insert same key */
81         tm_insert(t, dupkey, val2);
82
83         /* tm_remove should free as needed */
84         *val3 = 200;
85         strcpy(otherkey, "hi");
86         tm_insert(t, otherkey, val3);
87         tm_remove(t, otherkey);
88
89         tm_free(t);
90
91         treemap *t2 = tm_new(icmp, NULL);
92         /* insert in ascending order, inherently unbalanced,
93          * to exercise split/skew */
94         for (size_t i = 0; i < 10; i++)
95                 tm_insert(t2, ivals+i, ivals+i);
96         assert(tm_length(t2) == 10);
97
98         /* all there? */
99         for (size_t i = 0; i < 10; i++)
100                 assert(*(int*)tm_at(t2, ivals+i) == (int)i);
101
102         /* remove odd ones */
103         for (size_t i = 1; i < 10; i+=2)
104                 tm_remove(t2, ivals+i);
105         assert(tm_length(t2) == 5);
106
107         /* evens should still be there */
108         for (size_t i = 0; i < 10; i+=2)
109                 assert((int)i == *(int*)tm_at(t2, ivals+i));
110
111         /* remove evens */
112         for (size_t i = 0; i < 10; i+=2)
113                 tm_remove(t2, ivals+i);
114         assert(tm_is_empty(t2));
115
116         tm_free(t2);
117
118         return 0;
119 }