EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / tests / eina_test_inlist.c
1 /* EINA - EFL data type library
2  * Copyright (C) 2008 Cedric Bail
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include "eina_suite.h"
27 #include "Eina.h"
28 #include "eina_safety_checks.h"
29
30 typedef struct _Eina_Test_Inlist Eina_Test_Inlist;
31 struct _Eina_Test_Inlist
32 {
33    int i;
34    EINA_INLIST;
35 };
36
37 #ifdef EINA_SAFETY_CHECKS
38 struct log_ctx {
39    const char *msg;
40    const char *fnc;
41    Eina_Bool did;
42 };
43
44 /* tests should not output on success, just uncomment this for debugging */
45 //#define SHOW_LOG 1
46
47 static void
48 _eina_test_safety_print_cb(const Eina_Log_Domain *d, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, void *data, va_list args __UNUSED__)
49 {
50    struct log_ctx *ctx = data;
51    va_list cp_args;
52    const char *str;
53
54    va_copy(cp_args, args);
55    str = va_arg(cp_args, const char *);
56    va_end(cp_args);
57
58    ck_assert_int_eq(level, EINA_LOG_LEVEL_ERR);
59    ck_assert_str_eq(fmt, "%s");
60    ck_assert_str_eq(ctx->msg, str);
61    ck_assert_str_eq(ctx->fnc, fnc);
62    ctx->did = EINA_TRUE;
63
64 #ifdef SHOW_LOG
65    eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, NULL, args);
66 #else
67    (void)d;
68    (void)file;
69    (void)line;
70 #endif
71 }
72 #endif
73
74 static Eina_Test_Inlist *
75 _eina_test_inlist_build(int i)
76 {
77    Eina_Test_Inlist *tmp;
78
79    tmp = malloc(sizeof(Eina_Test_Inlist));
80    fail_if(!tmp);
81    tmp->i = i;
82
83    return tmp;
84 }
85
86 START_TEST(eina_inlist_simple)
87 {
88    Eina_Inlist *lst = NULL;
89    Eina_Test_Inlist *tmp;
90    Eina_Test_Inlist *prev;
91    int i = 0;
92 #ifdef EINA_SAFETY_CHECKS
93    Eina_Inlist *bkp;
94    struct log_ctx ctx;
95 #endif
96
97    fail_if(!eina_init());
98
99    tmp = _eina_test_inlist_build(42);
100    lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
101    fail_if(!lst);
102
103    lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
104    lst = eina_inlist_prepend(lst, EINA_INLIST_GET(tmp));
105
106    tmp = _eina_test_inlist_build(1664);
107    lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
108    fail_if(!lst);
109    fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
110
111    prev = tmp;
112    tmp = _eina_test_inlist_build(3227);
113    lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(
114                                          tmp), EINA_INLIST_GET(prev));
115    fail_if(!lst);
116    fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42);
117
118    lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
119
120    lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst);
121    lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
122
123    lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), lst);
124
125    tmp = _eina_test_inlist_build(27);
126    lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), NULL);
127
128    tmp = _eina_test_inlist_build(81);
129    lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), NULL);
130
131    EINA_INLIST_FOREACH(lst, tmp)
132    {
133       switch (i)
134         {
135          case 0: fail_if(tmp->i != 27); break;
136
137          case 1: fail_if(tmp->i != 3227); break;
138
139          case 2: fail_if(tmp->i != 42); break;
140
141          case 3: fail_if(tmp->i != 1664); break;
142
143          case 4: fail_if(tmp->i != 81); break;
144         }
145
146       ++i;
147    }
148
149 #ifdef EINA_SAFETY_CHECKS
150    bkp = lst;
151    eina_log_print_cb_set(_eina_test_safety_print_cb, &ctx);
152
153 #define TEST_MAGIC_SAFETY(fn, _msg)              \
154    ctx.msg = _msg;                               \
155    ctx.fnc = fn;                                 \
156    ctx.did = EINA_FALSE
157
158 #ifdef SHOW_LOG
159    fprintf(stderr, "you should have a safety check failure below:\n");
160 #endif
161    {
162       Eina_Inlist *tmp2;
163
164       TEST_MAGIC_SAFETY("eina_inlist_remove",
165                         "safety check failed: list == NULL");
166
167       tmp2 = eina_inlist_remove(NULL, EINA_INLIST_GET(tmp));
168       fail_if(tmp2 != NULL);
169       fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
170       fail_unless(ctx.did);
171    }
172
173 #ifdef SHOW_LOG
174    fprintf(stderr, "you should have a safety check failure below:\n");
175 #endif
176    TEST_MAGIC_SAFETY("eina_inlist_remove",
177                      "safety check failed: item == NULL");
178    lst = eina_inlist_remove(lst, NULL);
179    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
180    fail_unless(ctx.did);
181
182 #ifdef SHOW_LOG
183    fprintf(stderr, "you should have a safety check failure below:\n");
184 #endif
185    TEST_MAGIC_SAFETY("eina_inlist_append",
186                      "safety check failed: new_l == NULL");
187    lst = eina_inlist_append(lst, NULL);
188    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
189    fail_unless(ctx.did);
190
191 #ifdef SHOW_LOG
192    fprintf(stderr, "you should have a safety check failure below:\n");
193 #endif
194    TEST_MAGIC_SAFETY("eina_inlist_append_relative",
195                      "safety check failed: new_l == NULL");
196    lst = eina_inlist_append_relative(lst, NULL, NULL);
197    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
198    fail_unless(ctx.did);
199
200 #ifdef SHOW_LOG
201    fprintf(stderr, "you should have a safety check failure below:\n");
202 #endif
203    TEST_MAGIC_SAFETY("eina_inlist_prepend",
204                      "safety check failed: new_l == NULL");
205    lst = eina_inlist_prepend(lst, NULL);
206    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
207    fail_unless(ctx.did);
208
209 #ifdef SHOW_LOG
210    fprintf(stderr, "you should have a safety check failure below:\n");
211 #endif
212    TEST_MAGIC_SAFETY("eina_inlist_prepend_relative",
213                      "safety check failed: new_l == NULL");
214    lst = eina_inlist_prepend_relative(lst, NULL, NULL);
215    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
216    fail_unless(ctx.did);
217
218 #ifdef SHOW_LOG
219    fprintf(stderr, "you should have a safety check failure below:\n");
220 #endif
221    TEST_MAGIC_SAFETY("eina_inlist_find",
222                      "safety check failed: item == NULL");
223    lst = eina_inlist_find(lst, NULL);
224    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
225    fail_unless(ctx.did);
226
227 #ifdef SHOW_LOG
228    fprintf(stderr, "you should have a safety check failure below:\n");
229 #endif
230    TEST_MAGIC_SAFETY("eina_inlist_demote",
231                      "safety check failed: list == NULL");
232    lst = eina_inlist_demote(NULL, NULL);
233    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
234    fail_unless(ctx.did);
235
236 #ifdef SHOW_LOG
237    fprintf(stderr, "you should have a safety check failure below:\n");
238 #endif
239    TEST_MAGIC_SAFETY("eina_inlist_demote",
240                      "safety check failed: item == NULL");
241    lst = eina_inlist_demote((void*)1L, NULL);
242    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
243    fail_unless(ctx.did);
244    lst = NULL;
245
246 #ifdef SHOW_LOG
247    fprintf(stderr, "you should have a safety check failure below:\n");
248 #endif
249    TEST_MAGIC_SAFETY("eina_inlist_promote",
250                      "safety check failed: list == NULL");
251    lst = eina_inlist_promote(NULL, NULL);
252    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
253    fail_unless(ctx.did);
254
255 #ifdef SHOW_LOG
256    fprintf(stderr, "you should have a safety check failure below:\n");
257 #endif
258    TEST_MAGIC_SAFETY("eina_inlist_promote",
259                      "safety check failed: item == NULL");
260    lst = eina_inlist_promote((void*)1L, NULL);
261    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
262    fail_unless(ctx.did);
263    lst = NULL;
264
265 #ifdef SHOW_LOG
266    fprintf(stderr, "you should have a safety check failure below:\n");
267 #endif
268    TEST_MAGIC_SAFETY("eina_inlist_sorted_insert",
269                      "safety check failed: item == NULL");
270    lst = eina_inlist_sorted_insert(NULL, NULL, NULL);
271    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
272    fail_unless(ctx.did);
273
274 #ifdef SHOW_LOG
275    fprintf(stderr, "you should have a safety check failure below:\n");
276 #endif
277    TEST_MAGIC_SAFETY("eina_inlist_sorted_insert",
278                      "safety check failed: func == NULL");
279    lst = eina_inlist_sorted_insert(NULL, (void*)1L, NULL);
280    fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED);
281    fail_unless(ctx.did);
282    lst = NULL;
283
284    eina_log_print_cb_set(eina_log_print_cb_stderr, NULL);
285    lst = bkp;
286 #endif
287
288    tmp = EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist);
289    lst = eina_inlist_demote(lst, lst);
290    fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist) == tmp);
291
292    lst = eina_inlist_promote(lst, EINA_INLIST_GET(tmp));
293    fail_if(lst != EINA_INLIST_GET(tmp));
294
295    tmp = EINA_INLIST_CONTAINER_GET(eina_inlist_find(lst, EINA_INLIST_GET(
296                                                        prev)), Eina_Test_Inlist);
297    lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp));
298    prev = (Eina_Test_Inlist *)eina_inlist_find(lst, EINA_INLIST_GET(tmp));
299    tmp = prev ? EINA_INLIST_CONTAINER_GET(prev, Eina_Test_Inlist) : NULL;
300    fail_if(tmp != NULL);
301
302    while (lst)
303       lst = eina_inlist_remove(lst, lst);
304
305    eina_shutdown();
306 }
307 END_TEST
308
309 typedef struct _Eina_Test_Inlist_Sorted Eina_Test_Inlist_Sorted;
310 struct _Eina_Test_Inlist_Sorted
311 {
312    EINA_INLIST;
313
314    int value;
315 };
316
317 static int
318 _eina_test_inlist_cmp(const void *d1, const void *d2)
319 {
320    const Eina_Test_Inlist_Sorted *t1 = d1;
321    const Eina_Test_Inlist_Sorted *t2 = d2;
322
323    return t1->value - t2->value;
324 }
325
326 static void
327 _eina_test_inlist_check(const Eina_Inlist *list)
328 {
329    const Eina_Test_Inlist_Sorted *t;
330    int last_value = 0;
331
332    EINA_INLIST_FOREACH(list, t)
333      {
334         fail_if(t->value < last_value);
335         last_value = t->value;
336      }
337 }
338
339 START_TEST(eina_inlist_sorted)
340 {
341    Eina_Test_Inlist_Sorted *tmp;
342    Eina_Inlist *list = NULL;
343    Eina_Inlist *sorted = NULL;
344    int i;
345
346    fail_if(!eina_init());
347
348    srand(time(NULL));
349
350    for (i = 0; i < 2000; ++i)
351      {
352         tmp = malloc(sizeof (Eina_Test_Inlist_Sorted));
353         if (!tmp) continue ;
354
355         tmp->value = rand();
356
357         list = eina_inlist_prepend(list, EINA_INLIST_GET(tmp));
358      }
359
360    list = eina_inlist_sort(list, _eina_test_inlist_cmp);
361
362    _eina_test_inlist_check(list);
363
364    EINA_INLIST_FOREACH(list, tmp)
365      tmp->value = rand();
366
367    i = 0;
368    while (list)
369      {
370         Eina_Inlist *p = list;
371
372         list = eina_inlist_remove(list, list);
373
374         sorted = eina_inlist_sorted_insert(sorted, p, _eina_test_inlist_cmp);
375         _eina_test_inlist_check(sorted);
376      }
377
378    _eina_test_inlist_check(sorted);
379
380    eina_shutdown();
381 }
382 END_TEST
383
384 START_TEST(eina_inlist_sorted_state)
385 {
386    Eina_Test_Inlist_Sorted *tmp;
387    Eina_Inlist_Sorted_State *state;
388    Eina_Inlist *list = NULL;
389    int i;
390
391    fail_if(!eina_init());
392
393    state = eina_inlist_sorted_state_new();
394    fail_if(!state);
395
396    for (i = 0; i < 2000; ++i)
397      {
398         tmp = malloc(sizeof (Eina_Test_Inlist_Sorted));
399         if (!tmp) continue ;
400
401         tmp->value = rand();
402
403         list = eina_inlist_sorted_state_insert(list, EINA_INLIST_GET(tmp), _eina_test_inlist_cmp, state);
404         _eina_test_inlist_check(list);
405      }
406
407    _eina_test_inlist_check(list);
408
409    eina_inlist_sorted_state_free(state);
410
411    eina_shutdown();
412 }
413 END_TEST
414
415 void
416 eina_test_inlist(TCase *tc)
417 {
418    tcase_add_test(tc, eina_inlist_simple);
419    tcase_add_test(tc, eina_inlist_sorted);
420    tcase_add_test(tc, eina_inlist_sorted_state);
421 }