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