]> Pileus Git - ~andy/gtk/blob - gtk/tests/bitmask.c
Change FSF Address
[~andy/gtk] / gtk / tests / bitmask.c
1 /* GtkRBTree tests.
2  *
3  * Copyright (C) 2011, Red Hat, Inc.
4  * Authors: Benjamin Otte <otte@gnome.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <locale.h>
21
22 #include "../gtkbitmaskprivate.h"
23
24 #include <string.h>
25
26 /* how often we run the random tests */
27 #define N_RUNS 20
28
29 /* how many tries we do in our random tests */
30 #define N_TRIES 100
31
32 /* the maximum index we use for bitmask values */
33 #define MAX_INDEX 1000
34
35 /* UTILITIES */
36
37 static GtkBitmask *
38 gtk_bitmask_new_parse (const char *string)
39 {
40   guint i, length;
41   GtkBitmask *mask;
42
43   length = strlen (string);
44   mask = _gtk_bitmask_new ();
45
46   for (i = 0; i < length; i++)
47     {
48       if (string[i] == '0')
49         _gtk_bitmask_set (mask, length - i - 1, FALSE);
50       else if (string[i] == '1')
51         _gtk_bitmask_set (mask, length - i - 1, TRUE);
52       else
53         g_assert_not_reached ();
54     }
55
56   return mask;
57 }
58
59 #define assert_cmpmasks(mask,other) G_STMT_START { \
60   if (G_UNLIKELY (!_gtk_bitmask_equals (mask, other))) \
61     { \
62       char *mask_string = _gtk_bitmask_to_string (mask); \
63       char *other_string = _gtk_bitmask_to_string (other); \
64       char *msg = g_strdup_printf ("%s (%s) != %s (%s)", \
65                                    G_STRINGIFY (mask), mask_string, \
66                                    G_STRINGIFY (other), other_string); \
67       g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); \
68       g_free (msg); \
69       g_free (mask_string); \
70       g_free (other_string); \
71     } \
72 }G_STMT_END
73
74 static const char *tests[] = {
75                                                                                                                                    "0",
76                                                                                                                                    "1",
77                                                                     "1000000000000000000000000000000000000000000000000000000000000000",
78                                                                    "10000000000000000000000000000000000000000000000000000000000000000",
79   "1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010",
80   "1000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000",
81   "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
82 };
83
84 static GtkBitmask *masks[G_N_ELEMENTS (tests)];
85
86 /* TEST */
87
88 static void
89 test_to_string (void)
90 {
91   guint i;
92   char *to_string;
93
94   for (i = 0; i < G_N_ELEMENTS (tests); i++)
95     {
96       to_string = _gtk_bitmask_to_string (masks[i]);
97       g_assert_cmpstr (to_string, ==, tests[i]);
98       g_free (to_string);
99     }
100 }
101
102 static void
103 test_is_empty (void)
104 {
105   guint i;
106
107   for (i = 0; i < G_N_ELEMENTS (tests); i++)
108     {
109       g_assert_cmpint (_gtk_bitmask_is_empty (masks[i]), ==, i == 0);
110     }
111 }
112
113 static void
114 test_equals (void)
115 {
116   guint i, j;
117
118   for (i = 0; i < G_N_ELEMENTS (tests); i++)
119     {
120       for (j = 0; j < G_N_ELEMENTS (tests); j++)
121         {
122           g_assert_cmpint (_gtk_bitmask_equals (masks[i], masks[j]), ==, i == j);
123         }
124     }
125 }
126
127 static void
128 test_set (void)
129 {
130   guint i, j;
131   guint indexes[N_TRIES];
132   GtkBitmask *copy;
133   const GtkBitmask *mask;
134
135   for (i = 0; i < N_RUNS; i++)
136     {
137       mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
138       copy = _gtk_bitmask_copy (mask);
139
140       for (j = 0; j < N_TRIES; j++)
141         {
142           indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
143           _gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
144         }
145
146       for (j = 0; j < N_TRIES; j++)
147         {
148           _gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
149         }
150
151       assert_cmpmasks (copy, mask);
152       _gtk_bitmask_free (copy);
153     }
154 }
155
156 static void
157 test_union (void)
158 {
159   GtkBitmask *left, *right, *expected;
160   guint run, try, n_tries;
161
162   for (run = 0; run < N_RUNS; run++)
163     {
164       left = _gtk_bitmask_new ();
165       right = _gtk_bitmask_new ();
166       expected = _gtk_bitmask_new ();
167
168       n_tries = g_test_perf () ? N_TRIES : g_test_rand_int_range (0, N_TRIES);
169       for (try = 0; try < n_tries; try++)
170         {
171           guint id = g_test_rand_int_range (0, MAX_INDEX);
172
173           if (g_test_rand_bit ())
174             _gtk_bitmask_set (left, id, TRUE);
175           else
176             _gtk_bitmask_set (right, id, TRUE);
177
178           _gtk_bitmask_set (expected, id, TRUE);
179         }
180
181       _gtk_bitmask_union (left, right);
182       _gtk_bitmask_union (right, left);
183
184       assert_cmpmasks (left, expected);
185       assert_cmpmasks (right, expected);
186       _gtk_bitmask_free (left);
187       _gtk_bitmask_free (right);
188       _gtk_bitmask_free (expected);
189     }
190 }
191
192 static void
193 test_intersect (void)
194 {
195   GtkBitmask *left, *right, *expected;
196   guint run, try;
197   gboolean intersects;
198
199   for (run = 0; run < N_RUNS; run++)
200     {
201       left = _gtk_bitmask_new ();
202       right = _gtk_bitmask_new ();
203       expected = _gtk_bitmask_new ();
204
205       for (try = 0; try < N_TRIES; try++)
206         {
207           guint id = g_test_rand_int_range (0, MAX_INDEX);
208           gboolean set = g_test_rand_bit ();
209
210           if (g_test_rand_bit ())
211             {
212               _gtk_bitmask_set (left, id, set);
213               _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
214             }
215           else
216             {
217               _gtk_bitmask_set (right, id, set);
218               _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
219             }
220         }
221
222       intersects = _gtk_bitmask_intersects (left, right);
223       g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
224       g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
225
226       _gtk_bitmask_intersect (left, right);
227       _gtk_bitmask_intersect (right, left);
228
229       assert_cmpmasks (left, expected);
230       assert_cmpmasks (right, expected);
231       _gtk_bitmask_free (left);
232       _gtk_bitmask_free (right);
233       _gtk_bitmask_free (expected);
234     }
235 }
236
237 #define SWAP(_a, _b) G_STMT_START{ \
238   guint _tmp = _a; \
239   _a = _b; \
240   _b = _tmp; \
241 }G_STMT_END
242
243 static void
244 test_invert_range (void)
245 {
246   GtkBitmask *left, *right, *intersection, *expected;
247   guint run;
248   guint left_start, left_end, right_start, right_end, start, end;
249
250   for (run = 0; run < N_RUNS; run++)
251     {
252       left = _gtk_bitmask_new ();
253       right = _gtk_bitmask_new ();
254       expected = _gtk_bitmask_new ();
255
256       left_start = g_test_rand_int_range (0, MAX_INDEX);
257       left_end = g_test_rand_int_range (0, MAX_INDEX);
258       if (left_start > left_end)
259         SWAP (left_start, left_end);
260       right_start = g_test_rand_int_range (0, MAX_INDEX);
261       right_end = g_test_rand_int_range (0, MAX_INDEX);
262       if (right_start > right_end)
263         SWAP (right_start, right_end);
264       start = MAX (left_start, right_start);
265       end = MIN (left_end, right_end);
266
267       if (left_start != left_end)
268         _gtk_bitmask_invert_range (left, left_start, left_end);
269       if (right_start != right_end)
270         _gtk_bitmask_invert_range (right, right_start, right_end);
271       if (start < end)
272         _gtk_bitmask_invert_range (expected, start, end);
273
274       intersection = _gtk_bitmask_copy (left);
275       _gtk_bitmask_intersect (intersection, right);
276
277       assert_cmpmasks (intersection, expected);
278
279       if (start < end)
280         _gtk_bitmask_invert_range (expected, start, end);
281
282       g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
283
284       _gtk_bitmask_free (left);
285       _gtk_bitmask_free (right);
286       _gtk_bitmask_free (intersection);
287       _gtk_bitmask_free (expected);
288     }
289 }
290
291 /* SETUP & RUNNING */
292
293 static void
294 create_masks (void)
295 {
296   guint i;
297
298   for (i = 0; i < G_N_ELEMENTS (tests); i++)
299     masks[i] = gtk_bitmask_new_parse (tests[i]);
300 }
301
302 static void
303 free_masks (void)
304 {
305   guint i;
306
307   for (i = 0; i < G_N_ELEMENTS (tests); i++)
308     {
309       _gtk_bitmask_free (masks[i]);
310       masks[i] = NULL;
311     }
312 }
313
314 int
315 main (int argc, char *argv[])
316 {
317   int result;
318
319   g_test_init (&argc, &argv, NULL);
320   setlocale (LC_ALL, "C");
321   g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
322
323   create_masks ();
324
325   g_test_add_func ("/bitmask/to_string", test_to_string);
326   g_test_add_func ("/bitmask/is_empty", test_is_empty);
327   g_test_add_func ("/bitmask/equals", test_equals);
328   g_test_add_func ("/bitmask/set", test_set);
329   g_test_add_func ("/bitmask/union", test_union);
330   g_test_add_func ("/bitmask/intersect", test_intersect);
331   g_test_add_func ("/bitmask/invert_range", test_invert_range);
332
333   result = g_test_run ();
334
335   free_masks ();
336
337   return result;
338 }