3 * Copyright (C) 2011, Red Hat, Inc.
4 * Authors: Benjamin Otte <otte@gnome.org>
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.
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.
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/>.
22 #include "../gtkbitmaskprivate.h"
26 /* how often we run the random tests */
29 /* how many tries we do in our random tests */
32 /* the maximum index we use for bitmask values */
33 #define MAX_INDEX 1000
38 gtk_bitmask_new_parse (const char *string)
43 length = strlen (string);
44 mask = _gtk_bitmask_new ();
46 for (i = 0; i < length; i++)
49 mask = _gtk_bitmask_set (mask, length - i - 1, FALSE);
50 else if (string[i] == '1')
51 mask = _gtk_bitmask_set (mask, length - i - 1, TRUE);
53 g_assert_not_reached ();
59 #define assert_cmpmasks(mask,other) G_STMT_START { \
60 if (G_UNLIKELY (!_gtk_bitmask_equals (mask, other))) \
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); \
69 g_free (mask_string); \
70 g_free (other_string); \
74 static const char *tests[] = {
77 "1000000000000000000000000000000",
78 "10000000000000000000000000000000",
79 "100000000000000000000000000000000000000000000000000000000000000",
80 "1000000000000000000000000000000000000000000000000000000000000000",
81 "10000000000000000000000000000000000000000000000000000000000000000",
82 "1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010",
83 "1000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000",
84 "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
87 static GtkBitmask *masks[G_N_ELEMENTS (tests)];
97 for (i = 0; i < G_N_ELEMENTS (tests); i++)
99 to_string = _gtk_bitmask_to_string (masks[i]);
100 g_assert_cmpstr (to_string, ==, tests[i]);
110 for (i = 0; i < G_N_ELEMENTS (tests); i++)
112 g_assert_cmpint (_gtk_bitmask_is_empty (masks[i]), ==, i == 0);
121 for (i = 0; i < G_N_ELEMENTS (tests); i++)
123 for (j = 0; j < G_N_ELEMENTS (tests); j++)
125 g_assert_cmpint (_gtk_bitmask_equals (masks[i], masks[j]), ==, i == j);
134 guint indexes[N_TRIES];
136 const GtkBitmask *mask;
138 for (i = 0; i < N_RUNS; i++)
140 mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
141 copy = _gtk_bitmask_copy (mask);
143 for (j = 0; j < N_TRIES; j++)
145 indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
146 copy = _gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
149 for (j = 0; j < N_TRIES; j++)
151 copy = _gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
154 assert_cmpmasks (copy, mask);
155 _gtk_bitmask_free (copy);
162 GtkBitmask *left, *right, *expected;
163 guint run, try, n_tries;
165 for (run = 0; run < N_RUNS; run++)
167 left = _gtk_bitmask_new ();
168 right = _gtk_bitmask_new ();
169 expected = _gtk_bitmask_new ();
171 n_tries = g_test_perf () ? N_TRIES : g_test_rand_int_range (0, N_TRIES);
172 for (try = 0; try < n_tries; try++)
174 guint id = g_test_rand_int_range (0, MAX_INDEX);
176 if (g_test_rand_bit ())
177 left = _gtk_bitmask_set (left, id, TRUE);
179 right = _gtk_bitmask_set (right, id, TRUE);
181 expected = _gtk_bitmask_set (expected, id, TRUE);
184 left = _gtk_bitmask_union (left, right);
185 right = _gtk_bitmask_union (right, left);
187 assert_cmpmasks (left, expected);
188 assert_cmpmasks (right, expected);
189 _gtk_bitmask_free (left);
190 _gtk_bitmask_free (right);
191 _gtk_bitmask_free (expected);
196 test_intersect (void)
198 GtkBitmask *left, *right, *expected;
202 for (run = 0; run < N_RUNS; run++)
204 left = _gtk_bitmask_new ();
205 right = _gtk_bitmask_new ();
206 expected = _gtk_bitmask_new ();
208 for (try = 0; try < N_TRIES; try++)
210 guint id = g_test_rand_int_range (0, MAX_INDEX);
211 gboolean set = g_test_rand_bit ();
213 if (g_test_rand_bit ())
215 left = _gtk_bitmask_set (left, id, set);
216 expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
220 right = _gtk_bitmask_set (right, id, set);
221 expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
225 intersects = _gtk_bitmask_intersects (left, right);
226 g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
227 g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
229 left = _gtk_bitmask_intersect (left, right);
230 right = _gtk_bitmask_intersect (right, left);
232 assert_cmpmasks (left, expected);
233 assert_cmpmasks (right, expected);
234 _gtk_bitmask_free (left);
235 _gtk_bitmask_free (right);
236 _gtk_bitmask_free (expected);
241 test_intersect_hardcoded (void)
243 GtkBitmask *left, *right, *intersection, *expected;
244 const char *left_str, *right_str;
245 guint left_len, right_len;
248 for (l = 0; l < G_N_ELEMENTS (tests); l++)
250 for (r = 0; r < G_N_ELEMENTS (tests); r++)
255 right_str = tests[r];
256 left_len = strlen (tests[l]);
257 right_len = strlen (tests[r]);
259 expected = _gtk_bitmask_new ();
260 if (left_len > right_len)
261 left_str += left_len - right_len;
262 if (right_len > left_len)
263 right_str += right_len - left_len;
264 i = MIN (right_len, left_len);
267 expected = _gtk_bitmask_set (expected, i, left_str[0] == '1' && right_str[0] == '1');
272 intersection = _gtk_bitmask_intersect (_gtk_bitmask_copy (left), right);
274 assert_cmpmasks (intersection, expected);
275 g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, !_gtk_bitmask_intersects (left, right));
277 _gtk_bitmask_free (intersection);
278 _gtk_bitmask_free (expected);
283 #define SWAP(_a, _b) G_STMT_START{ \
290 test_invert_range (void)
292 GtkBitmask *left, *right, *intersection, *expected;
294 guint left_start, left_end, right_start, right_end, start, end;
296 for (run = 0; run < N_RUNS; run++)
298 left = _gtk_bitmask_new ();
299 right = _gtk_bitmask_new ();
300 expected = _gtk_bitmask_new ();
302 left_start = g_test_rand_int_range (0, MAX_INDEX);
303 left_end = g_test_rand_int_range (0, MAX_INDEX);
304 if (left_start > left_end)
305 SWAP (left_start, left_end);
306 right_start = g_test_rand_int_range (0, MAX_INDEX);
307 right_end = g_test_rand_int_range (0, MAX_INDEX);
308 if (right_start > right_end)
309 SWAP (right_start, right_end);
310 start = MAX (left_start, right_start);
311 end = MIN (left_end, right_end);
313 if (left_start != left_end)
314 left = _gtk_bitmask_invert_range (left, left_start, left_end);
315 if (right_start != right_end)
316 right = _gtk_bitmask_invert_range (right, right_start, right_end);
318 expected = _gtk_bitmask_invert_range (expected, start, end);
320 intersection = _gtk_bitmask_copy (left);
321 intersection = _gtk_bitmask_intersect (intersection, right);
323 assert_cmpmasks (intersection, expected);
326 expected = _gtk_bitmask_invert_range (expected, start, end);
328 g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
330 _gtk_bitmask_free (left);
331 _gtk_bitmask_free (right);
332 _gtk_bitmask_free (intersection);
333 _gtk_bitmask_free (expected);
337 /* SETUP & RUNNING */
344 for (i = 0; i < G_N_ELEMENTS (tests); i++)
345 masks[i] = gtk_bitmask_new_parse (tests[i]);
353 for (i = 0; i < G_N_ELEMENTS (tests); i++)
355 _gtk_bitmask_free (masks[i]);
361 main (int argc, char *argv[])
365 g_test_init (&argc, &argv, NULL);
366 setlocale (LC_ALL, "C");
367 g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
371 g_test_add_func ("/bitmask/to_string", test_to_string);
372 g_test_add_func ("/bitmask/is_empty", test_is_empty);
373 g_test_add_func ("/bitmask/equals", test_equals);
374 g_test_add_func ("/bitmask/set", test_set);
375 g_test_add_func ("/bitmask/union", test_union);
376 g_test_add_func ("/bitmask/intersect", test_intersect);
377 g_test_add_func ("/bitmask/intersect_hardcoded", test_intersect_hardcoded);
378 g_test_add_func ("/bitmask/invert_range", test_invert_range);
380 result = g_test_run ();