|
1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 |
|
29 #include "array_tests.h" |
|
30 #include <ucx/utils.h> |
|
31 |
|
32 UCX_TEST(test_ucx_array_free) { |
|
33 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
34 |
|
35 UCX_TEST_BEGIN |
|
36 ucx_array_free(&array); |
|
37 UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after free"); |
|
38 UCX_TEST_ASSERT(array.size == 0, "size not zero after free"); |
|
39 UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after free"); |
|
40 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(), |
|
41 "allocator corrupted during free"); |
|
42 UCX_TEST_END |
|
43 } |
|
44 |
|
45 UCX_TEST(test_ucx_array_new) { |
|
46 UcxArray array = ucx_array_new(16, 47); |
|
47 |
|
48 UCX_TEST_BEGIN |
|
49 UCX_TEST_ASSERT(array.data, "no memory allocated"); |
|
50 UCX_TEST_ASSERT(array.size == 0, "size not initially zero"); |
|
51 UCX_TEST_ASSERT(array.capacity == 16, "capacity not as requested"); |
|
52 UCX_TEST_ASSERT(array.elemsize == 47, "element size not as requested"); |
|
53 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(), |
|
54 "array not using the default allocator"); |
|
55 UCX_TEST_END |
|
56 ucx_array_free(&array); |
|
57 } |
|
58 |
|
59 UCX_TEST(test_ucx_array_append) { |
|
60 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
61 |
|
62 int x = 42; |
|
63 ucx_array_append(&array, &x); |
|
64 UCX_TEST_BEGIN |
|
65 |
|
66 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "failed"); |
|
67 |
|
68 x = 13; |
|
69 ucx_array_append(&array, &x); |
|
70 |
|
71 UCX_TEST_ASSERT(array.size == 2, "incorrect size after append"); |
|
72 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, "failed"); |
|
73 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, |
|
74 "append corrupted previously inserted data"); |
|
75 |
|
76 ucx_array_append(&array, NULL); |
|
77 |
|
78 UCX_TEST_ASSERT(array.size == 3, "incorrect size after NULL append"); |
|
79 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 0, "element is not zeroed"); |
|
80 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, |
|
81 "NULL append corrupted previously inserted data"); |
|
82 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, |
|
83 "NULL append corrupted previously inserted data"); |
|
84 |
|
85 UCX_TEST_END |
|
86 |
|
87 ucx_array_free(&array); |
|
88 } |
|
89 |
|
90 UCX_TEST(test_ucx_array_prepend) { |
|
91 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
92 |
|
93 int x = 42; |
|
94 ucx_array_prepend(&array, &x); |
|
95 UCX_TEST_BEGIN |
|
96 |
|
97 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "failed"); |
|
98 |
|
99 x = 13; |
|
100 ucx_array_prepend(&array, &x); |
|
101 |
|
102 UCX_TEST_ASSERT(array.size == 2, "incorrect size after prepend"); |
|
103 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 13, "failed"); |
|
104 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 42, |
|
105 "prepend corrupted previously inserted data"); |
|
106 |
|
107 ucx_array_prepend(&array, NULL); |
|
108 |
|
109 UCX_TEST_ASSERT(array.size == 3, "incorrect size after NULL prepend"); |
|
110 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 0, "element is not zeroed"); |
|
111 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, |
|
112 "NULL prepend corrupted previously inserted data"); |
|
113 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 42, |
|
114 "NULL prepend corrupted previously inserted data"); |
|
115 |
|
116 UCX_TEST_END |
|
117 |
|
118 ucx_array_free(&array); |
|
119 } |
|
120 |
|
121 UCX_TEST(test_ucx_array_equals) { |
|
122 UcxArray a1 = ucx_array_new(16, sizeof(int)); |
|
123 UcxArray a2 = ucx_array_new(16, sizeof(int)); |
|
124 UcxArray a3 = ucx_array_new(16, sizeof(long int)); |
|
125 UcxArray a4 = ucx_array_new(16, sizeof(int)); |
|
126 |
|
127 a1.size = 5; |
|
128 ucx_array_at_int(a1, 0) = 47; |
|
129 ucx_array_at_int(a1, 1) = 11; |
|
130 ucx_array_at_int(a1, 2) = 0; |
|
131 ucx_array_at_int(a1, 3) = 8; |
|
132 ucx_array_at_int(a1, 4) = 15; |
|
133 a2.size = 5; |
|
134 ucx_array_at_int(a2, 0) = 47; |
|
135 ucx_array_at_int(a2, 1) = 11; |
|
136 ucx_array_at_int(a2, 2) = 0; |
|
137 ucx_array_at_int(a2, 3) = 8; |
|
138 ucx_array_at_int(a2, 4) = 15; |
|
139 a3.size = 5; |
|
140 ucx_array_at_longint(a3, 0) = 47; |
|
141 ucx_array_at_longint(a3, 1) = 11; |
|
142 ucx_array_at_longint(a3, 2) = 0; |
|
143 ucx_array_at_longint(a3, 3) = 8; |
|
144 ucx_array_at_longint(a3, 4) = 15; |
|
145 a4.size = 5; |
|
146 ucx_array_at_int(a4, 0) = 47; |
|
147 ucx_array_at_int(a4, 1) = 11; |
|
148 ucx_array_at_int(a4, 2) = -6; |
|
149 ucx_array_at_int(a4, 3) = 8; |
|
150 ucx_array_at_int(a4, 4) = 15; |
|
151 |
|
152 UCX_TEST_BEGIN |
|
153 |
|
154 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, ucx_cmp_int, NULL) == 0, "failed"); |
|
155 UCX_TEST_ASSERT(ucx_array_equals(a1, a4, ucx_cmp_int, NULL) > 0, "failed"); |
|
156 UCX_TEST_ASSERT(ucx_array_equals(a4, a1, ucx_cmp_int, NULL) < 0, "failed"); |
|
157 UCX_TEST_ASSERT(ucx_array_equals(a1, a3, ucx_cmp_int, NULL) < 0, |
|
158 "comparing arrays of different element size failed"); |
|
159 UCX_TEST_ASSERT(ucx_array_equals(a3, a1, ucx_cmp_int, NULL) > 0, |
|
160 "comparing arrays of different element size failed"); |
|
161 |
|
162 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, NULL, NULL) == 0, |
|
163 "compare using memcmp() failed"); |
|
164 UCX_TEST_ASSERT(ucx_array_equals(a1, a4, NULL, NULL) > 0, |
|
165 "compare using memcmp() failed"); |
|
166 UCX_TEST_ASSERT(ucx_array_equals(a4, a1, NULL, NULL) < 0, |
|
167 "compare using memcmp() failed"); |
|
168 |
|
169 UCX_TEST_END |
|
170 ucx_array_free(&a1); |
|
171 ucx_array_free(&a2); |
|
172 ucx_array_free(&a3); |
|
173 ucx_array_free(&a4); |
|
174 } |
|
175 |
|
176 UCX_TEST(test_ucx_array_concat) { |
|
177 UcxArray a1 = ucx_array_new(16, sizeof(int)); |
|
178 UcxArray a2 = ucx_array_new(16, sizeof(int)); |
|
179 |
|
180 a1.size = 2; |
|
181 ucx_array_at_int(a1, 0) = 47; |
|
182 ucx_array_at_int(a1, 1) = 11; |
|
183 a2.size = 3; |
|
184 ucx_array_at_int(a2, 0) = 0; |
|
185 ucx_array_at_int(a2, 1) = 8; |
|
186 ucx_array_at_int(a2, 2) = 15; |
|
187 |
|
188 UCX_TEST_BEGIN |
|
189 |
|
190 UCX_TEST_ASSERT(!ucx_array_concat(&a1, &a2), "failed"); |
|
191 UCX_TEST_ASSERT(a1.size == 5, "failed"); |
|
192 UCX_TEST_ASSERT(ucx_array_at_int(a1, 0) == 47, "failed"); |
|
193 UCX_TEST_ASSERT(ucx_array_at_int(a1, 1) == 11, "failed"); |
|
194 UCX_TEST_ASSERT(ucx_array_at_int(a1, 2) == 0, "failed"); |
|
195 UCX_TEST_ASSERT(ucx_array_at_int(a1, 3) == 8, "failed"); |
|
196 UCX_TEST_ASSERT(ucx_array_at_int(a1, 4) == 15, "failed"); |
|
197 |
|
198 a1.elemsize *= 2; |
|
199 UCX_TEST_ASSERT(ucx_array_concat(&a1, &a2), |
|
200 "arrays of different element size must not be concatenated"); |
|
201 UCX_TEST_ASSERT(a1.size == 5, |
|
202 "arrays of different element size must not be concatenated"); |
|
203 |
|
204 UCX_TEST_END |
|
205 ucx_array_free(&a1); |
|
206 ucx_array_free(&a2); |
|
207 } |
|
208 |
|
209 UCX_TEST(test_ucx_array_at) { |
|
210 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
211 |
|
212 int x = 42; |
|
213 ucx_array_append(&array, &x); |
|
214 x = 13; |
|
215 ucx_array_append(&array, &x); |
|
216 x = 5; |
|
217 ucx_array_append(&array, &x); |
|
218 |
|
219 UCX_TEST_BEGIN |
|
220 |
|
221 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, "failed"); |
|
222 ucx_array_at_int(array, 1) = 80; |
|
223 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 80, "assignment failed"); |
|
224 |
|
225 |
|
226 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "corrupted data"); |
|
227 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 5, "corrupted data"); |
|
228 |
|
229 UCX_TEST_END |
|
230 |
|
231 ucx_array_free(&array); |
|
232 } |
|
233 |
|
234 UCX_TEST(test_ucx_array_find) { |
|
235 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
236 |
|
237 array.size = 5; |
|
238 ucx_array_at_int(array, 0) = 47; |
|
239 ucx_array_at_int(array, 1) = 11; |
|
240 ucx_array_at_int(array, 2) = 0; |
|
241 ucx_array_at_int(array, 3) = 8; |
|
242 ucx_array_at_int(array, 4) = 15; |
|
243 |
|
244 int x = 8; |
|
245 int y = 90; |
|
246 |
|
247 UCX_TEST_BEGIN |
|
248 |
|
249 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,ucx_cmp_int,NULL) == 3, |
|
250 "doesn't find element"); |
|
251 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,ucx_cmp_int,NULL) == 5, |
|
252 "finds non-existing element"); |
|
253 |
|
254 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,NULL,NULL) == 3, |
|
255 "failed using memcmp()"); |
|
256 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,NULL,NULL) == 5, |
|
257 "failed using memcmp()"); |
|
258 |
|
259 UCX_TEST_END |
|
260 ucx_array_free(&array); |
|
261 } |
|
262 |
|
263 UCX_TEST(test_ucx_array_contains) { |
|
264 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
265 |
|
266 array.size = 5; |
|
267 ucx_array_at_int(array, 0) = 47; |
|
268 ucx_array_at_int(array, 1) = 11; |
|
269 ucx_array_at_int(array, 2) = 0; |
|
270 ucx_array_at_int(array, 3) = 8; |
|
271 ucx_array_at_int(array, 4) = 15; |
|
272 |
|
273 int x = 8; |
|
274 int y = 90; |
|
275 |
|
276 UCX_TEST_BEGIN |
|
277 |
|
278 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,ucx_cmp_int,NULL), |
|
279 "false negative"); |
|
280 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,ucx_cmp_int,NULL), |
|
281 "false positive"); |
|
282 |
|
283 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,NULL,NULL), |
|
284 "false negative using memcmp()"); |
|
285 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,NULL,NULL), |
|
286 "false positive using memcmp()"); |
|
287 |
|
288 UCX_TEST_END |
|
289 ucx_array_free(&array); |
|
290 } |
|
291 |
|
292 UCX_TEST(test_ucx_array_remove) { |
|
293 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
294 |
|
295 array.size = 5; |
|
296 ucx_array_at_int(array, 0) = 47; |
|
297 ucx_array_at_int(array, 1) = 11; |
|
298 ucx_array_at_int(array, 2) = 0; |
|
299 ucx_array_at_int(array, 3) = 8; |
|
300 ucx_array_at_int(array, 4) = 15; |
|
301 |
|
302 UCX_TEST_BEGIN |
|
303 |
|
304 ucx_array_remove(&array, 2); |
|
305 UCX_TEST_ASSERT( |
|
306 ucx_array_at_int(array, 0) == 47 && |
|
307 ucx_array_at_int(array, 1) == 11 && |
|
308 ucx_array_at_int(array, 2) == 8 && |
|
309 ucx_array_at_int(array, 3) == 15, |
|
310 "wrong contents after remove"); |
|
311 UCX_TEST_ASSERT(array.size == 4, "wrong size after remove"); |
|
312 |
|
313 ucx_array_remove_fast(&array, 1); |
|
314 UCX_TEST_ASSERT( |
|
315 ucx_array_at_int(array, 0) == 47 && |
|
316 ucx_array_at_int(array, 1) == 15 && |
|
317 ucx_array_at_int(array, 2) == 8, |
|
318 "wrong contents after fast remove"); |
|
319 UCX_TEST_ASSERT(array.size == 3, "wrong size after fast remove"); |
|
320 |
|
321 UCX_TEST_END |
|
322 ucx_array_free(&array); |
|
323 } |
|
324 |
|
325 UCX_TEST(test_ucx_array_clone) { |
|
326 |
|
327 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
328 |
|
329 array.size = 5; |
|
330 ucx_array_at_int(array, 0) = 47; |
|
331 ucx_array_at_int(array, 1) = 11; |
|
332 ucx_array_at_int(array, 2) = 0; |
|
333 ucx_array_at_int(array, 3) = 8; |
|
334 ucx_array_at_int(array, 4) = 15; |
|
335 |
|
336 UcxArray copy = ucx_array_clone(array); |
|
337 UCX_TEST_BEGIN |
|
338 |
|
339 UCX_TEST_ASSERT(array.data != copy.data, "no true copy"); |
|
340 UCX_TEST_ASSERT(ucx_array_equals(array, copy, ucx_cmp_int, NULL), "failed"); |
|
341 UCX_TEST_ASSERT(array.size == copy.size, "size mismatch"); |
|
342 UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch"); |
|
343 UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch"); |
|
344 UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch"); |
|
345 |
|
346 UCX_TEST_END |
|
347 |
|
348 ucx_array_free(&array); |
|
349 ucx_array_free(©); |
|
350 } |
|
351 |
|
352 UCX_TEST(test_ucx_array_sort) { |
|
353 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
354 array.size = 5; |
|
355 ucx_array_at_int(array, 0) = 47; |
|
356 ucx_array_at_int(array, 1) = 11; |
|
357 ucx_array_at_int(array, 2) = 0; |
|
358 ucx_array_at_int(array, 3) = 8; |
|
359 ucx_array_at_int(array, 4) = 15; |
|
360 |
|
361 UcxArray expected = ucx_array_new(16, sizeof(int)); |
|
362 expected.size = 5; |
|
363 ucx_array_at_int(expected, 0) = 0; |
|
364 ucx_array_at_int(expected, 1) = 8; |
|
365 ucx_array_at_int(expected, 2) = 11; |
|
366 ucx_array_at_int(expected, 3) = 15; |
|
367 ucx_array_at_int(expected, 4) = 47; |
|
368 |
|
369 |
|
370 UCX_TEST_BEGIN |
|
371 void* original_ptr = array.data; |
|
372 UCX_TEST_ASSERT(!ucx_array_sort(array, ucx_cmp_int, NULL), "failed"); |
|
373 UCX_TEST_ASSERT(!ucx_array_equals(array, expected, NULL, NULL), "failed"); |
|
374 UCX_TEST_ASSERT(array.size == 5, "size corrupted"); |
|
375 UCX_TEST_ASSERT(array.data == original_ptr, "shall not reallocate"); |
|
376 UCX_TEST_END |
|
377 |
|
378 ucx_array_free(&expected); |
|
379 ucx_array_free(&array); |
|
380 } |
|
381 |
|
382 UCX_TEST(test_ucx_array_autogrow) { |
|
383 UcxArray array = ucx_array_new(4, sizeof(int)); |
|
384 array.size = 3; |
|
385 ucx_array_at_int(array, 0) = 47; |
|
386 ucx_array_at_int(array, 1) = 11; |
|
387 int x = 5; |
|
388 |
|
389 UCX_TEST_BEGIN |
|
390 |
|
391 void* oldptr = array.data; |
|
392 |
|
393 ucx_array_append(&array, &x); |
|
394 UCX_TEST_ASSERT(array.capacity == 4 && array.data == oldptr, |
|
395 "array should not grow too early"); |
|
396 ucx_array_append(&array, &x); |
|
397 UCX_TEST_ASSERT(array.capacity == 8, "array did not grow"); |
|
398 UCX_TEST_ASSERT(array.size == 5, "incorrect size after grow"); |
|
399 UCX_TEST_ASSERT(ucx_array_at_int(array, 3) == 5 && |
|
400 ucx_array_at_int(array, 3) == 5, "corrupt data"); |
|
401 |
|
402 UCX_TEST_END |
|
403 ucx_array_free(&array); |
|
404 } |
|
405 |
|
406 UCX_TEST(test_ucx_array_shrink) { |
|
407 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
408 array.size = 4; |
|
409 |
|
410 UCX_TEST_BEGIN |
|
411 UCX_TEST_ASSERT(!ucx_array_shrink(&array), "failed"); |
|
412 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after shrink"); |
|
413 UCX_TEST_END |
|
414 ucx_array_free(&array); |
|
415 } |
|
416 |
|
417 UCX_TEST(test_ucx_array_resize) { |
|
418 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
419 array.size = 8; |
|
420 |
|
421 UCX_TEST_BEGIN |
|
422 |
|
423 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed"); |
|
424 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after resize"); |
|
425 UCX_TEST_ASSERT(array.size == 8, "incorrect size after resize"); |
|
426 |
|
427 UCX_TEST_ASSERT(!ucx_array_resize(&array, 4), "failed"); |
|
428 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after resize"); |
|
429 UCX_TEST_ASSERT(array.size == 4, "incorrect size after resize"); |
|
430 |
|
431 UCX_TEST_END |
|
432 ucx_array_free(&array); |
|
433 } |
|
434 |
|
435 UCX_TEST(test_ucx_array_reserve) { |
|
436 UcxArray array = ucx_array_new(16, sizeof(int)); |
|
437 |
|
438 UCX_TEST_BEGIN |
|
439 |
|
440 UCX_TEST_ASSERT(!ucx_array_reserve(&array, 4), "failed"); |
|
441 UCX_TEST_ASSERT(array.capacity == 16, "reserve shall not shrink"); |
|
442 |
|
443 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed"); |
|
444 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after reserve"); |
|
445 |
|
446 UCX_TEST_END |
|
447 ucx_array_free(&array); |
|
448 } |