summaryrefslogtreecommitdiff
path: root/tests/t_vector.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/t_vector.c')
-rw-r--r--tests/t_vector.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/tests/t_vector.c b/tests/t_vector.c
new file mode 100644
index 0000000..fee336b
--- /dev/null
+++ b/tests/t_vector.c
@@ -0,0 +1,161 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever.
3
4 $id$ */
5
6/* System */
7#include <stdlib.h>
8#include <string.h>
9
10/* Opentracker */
11#include "trackerlogic.h"
12#include "test.h"
13
14/* binary_search returns the matching member when there is one, and otherwise
15 the position at which the key would have to be inserted to keep the vector
16 sorted. exactmatch distinguishes the two. */
17
18static const unsigned char sorted[5][4] = {{0, 0, 0, 1}, {0, 0, 0, 3}, {0, 0, 0, 5}, {0, 0, 0, 7}, {0, 0, 0, 9}};
19
20static void case_search_finds_member(void) {
21 const unsigned char key[4] = {0, 0, 0, 5};
22 int exactmatch;
23 void *found;
24
25 test_case("an existing key is found");
26 found = binary_search(key, sorted, 5, 4, 4, &exactmatch);
27 CHECK(exactmatch != 0);
28 CHECK_PTR(found, sorted[2]);
29}
30
31static void case_search_finds_first_and_last(void) {
32 const unsigned char first[4] = {0, 0, 0, 1};
33 const unsigned char last[4] = {0, 0, 0, 9};
34 int exactmatch;
35
36 test_case("the first and last members are found");
37 CHECK_PTR(binary_search(first, sorted, 5, 4, 4, &exactmatch), sorted[0]);
38 CHECK(exactmatch != 0);
39 CHECK_PTR(binary_search(last, sorted, 5, 4, 4, &exactmatch), sorted[4]);
40 CHECK(exactmatch != 0);
41}
42
43static void case_search_insert_position(void) {
44 const unsigned char middle[4] = {0, 0, 0, 4};
45 const unsigned char before[4] = {0, 0, 0, 0};
46 int exactmatch;
47 void *slot;
48
49 test_case("a missing key yields its insert position");
50 slot = binary_search(middle, sorted, 5, 4, 4, &exactmatch);
51 CHECK_INT(exactmatch, 0);
52 CHECK_PTR(slot, sorted[2]);
53
54 slot = binary_search(before, sorted, 5, 4, 4, &exactmatch);
55 CHECK_INT(exactmatch, 0);
56 CHECK_PTR(slot, sorted[0]);
57}
58
59static void case_search_past_the_end(void) {
60 const unsigned char beyond[4] = {0, 0, 0, 0xff};
61 int exactmatch;
62 void *slot;
63
64 test_case("a key above every member yields the position past the end");
65 slot = binary_search(beyond, sorted, 5, 4, 4, &exactmatch);
66 CHECK_INT(exactmatch, 0);
67 CHECK_PTR(slot, sorted[5]);
68}
69
70static void case_search_empty(void) {
71 int exactmatch;
72 void *base = (void *)sorted;
73
74 test_case("searching an empty vector reports no match at the base");
75 CHECK_PTR(binary_search(sorted[0], base, 0, 4, 4, &exactmatch), base);
76 CHECK_INT(exactmatch, 0);
77}
78
79static void case_insert_keeps_order(void) {
80 ot_vector vector = {NULL, 0, 0};
81 const unsigned char five[4] = {0, 0, 0, 5};
82 const unsigned char one[4] = {0, 0, 0, 1};
83 const unsigned char nine[4] = {0, 0, 0, 9};
84 int exactmatch;
85 void *slot;
86
87 test_case("inserts land in sorted order and grow the vector");
88 slot = vector_find_or_insert(&vector, (void *)five, 4, 4, &exactmatch);
89 CHECK(slot != NULL);
90 CHECK_INT(exactmatch, 0);
91 memcpy(slot, five, 4);
92 CHECK_INT(vector.size, 1);
93 CHECK_INT(vector.space, OT_VECTOR_MIN_MEMBERS);
94
95 slot = vector_find_or_insert(&vector, (void *)one, 4, 4, &exactmatch);
96 CHECK(slot != NULL);
97 CHECK_INT(exactmatch, 0);
98 memcpy(slot, one, 4);
99 CHECK_INT(vector.size, 2);
100
101 slot = vector_find_or_insert(&vector, (void *)nine, 4, 4, &exactmatch);
102 CHECK(slot != NULL);
103 CHECK_INT(exactmatch, 0);
104 memcpy(slot, nine, 4);
105 CHECK_INT(vector.size, 3);
106 CHECK_INT(vector.space, OT_VECTOR_MIN_MEMBERS * OT_VECTOR_GROW_RATIO);
107
108 CHECK_MEM(vector.data, "\0\0\0\1\0\0\0\5\0\0\0\11", 12);
109
110 free(vector.data);
111}
112
113static void case_insert_finds_existing(void) {
114 ot_vector vector = {NULL, 0, 0};
115 const unsigned char five[4] = {0, 0, 0, 5};
116 int exactmatch;
117 void *slot, *again;
118
119 test_case("a second insert of the same key returns the existing member");
120 slot = vector_find_or_insert(&vector, (void *)five, 4, 4, &exactmatch);
121 CHECK(slot != NULL);
122 memcpy(slot, five, 4);
123
124 again = vector_find_or_insert(&vector, (void *)five, 4, 4, &exactmatch);
125 CHECK(exactmatch != 0);
126 CHECK_PTR(again, vector.data);
127 CHECK_INT(vector.size, 1);
128
129 free(vector.data);
130}
131
132static void case_insert_compare_prefix(void) {
133 ot_vector vector = {NULL, 0, 0};
134 unsigned char first[6] = {1, 2, 3, 0xaa, 0xaa, 0xaa};
135 unsigned char second[6] = {1, 2, 3, 0xbb, 0xbb, 0xbb};
136 int exactmatch;
137 void *slot;
138
139 test_case("only the compare prefix decides identity");
140 slot = vector_find_or_insert(&vector, first, 6, 3, &exactmatch);
141 CHECK(slot != NULL);
142 memcpy(slot, first, 6);
143
144 slot = vector_find_or_insert(&vector, second, 6, 3, &exactmatch);
145 CHECK(exactmatch != 0);
146 CHECK_INT(vector.size, 1);
147 CHECK_MEM(slot, first, 6);
148
149 free(vector.data);
150}
151
152void test_vector(void) {
153 case_search_finds_member();
154 case_search_finds_first_and_last();
155 case_search_insert_position();
156 case_search_past_the_end();
157 case_search_empty();
158 case_insert_keeps_order();
159 case_insert_finds_existing();
160 case_insert_compare_prefix();
161}