dconf 0.23.1
[dconf.git] / tests / changeset.c
blob90b8de69fbcf5e34c0faf748754e4bb66d91e49f
1 #include "../common/dconf-changeset.h"
3 static gboolean
4 should_not_run (const gchar *key,
5 GVariant *value,
6 gpointer user_data)
8 g_assert_not_reached ();
11 static gboolean
12 is_null (const gchar *key,
13 GVariant *value,
14 gpointer user_data)
16 return value == NULL;
19 static gboolean
20 is_not_null (const gchar *key,
21 GVariant *value,
22 gpointer user_data)
24 return value != NULL;
27 static void
28 test_basic (void)
30 DConfChangeset *changeset;
31 gboolean result;
32 GVariant *value;
33 gint n_items;
35 changeset = dconf_changeset_new ();
36 dconf_changeset_ref (changeset);
37 dconf_changeset_all (changeset, should_not_run, NULL);
38 n_items = dconf_changeset_describe (changeset, NULL, NULL, NULL);
39 g_assert_cmpint (n_items, ==, 0);
40 dconf_changeset_unref (changeset);
41 dconf_changeset_unref (changeset);
43 changeset = dconf_changeset_new_write ("/value/a", NULL);
44 result = dconf_changeset_all (changeset, is_null, NULL);
45 g_assert (result);
46 result = dconf_changeset_all (changeset, is_not_null, NULL);
47 g_assert (!result);
49 result = dconf_changeset_get (changeset, "/value/a", &value);
50 g_assert (result);
51 g_assert (value == NULL);
53 result = dconf_changeset_get (changeset, "/value/b", &value);
54 g_assert (!result);
56 dconf_changeset_set (changeset, "/value/b", g_variant_new_int32 (123));
57 result = dconf_changeset_all (changeset, is_null, NULL);
58 g_assert (!result);
59 result = dconf_changeset_all (changeset, is_not_null, NULL);
60 g_assert (!result);
62 result = dconf_changeset_get (changeset, "/value/a", &value);
63 g_assert (result);
64 g_assert (value == NULL);
66 result = dconf_changeset_get (changeset, "/value/b", &value);
67 g_assert (result);
68 g_assert_cmpint (g_variant_get_int32 (value), ==, 123);
69 g_variant_unref (value);
71 dconf_changeset_set (changeset, "/value/a", g_variant_new_string ("a string"));
72 result = dconf_changeset_all (changeset, is_null, NULL);
73 g_assert (!result);
74 result = dconf_changeset_all (changeset, is_not_null, NULL);
75 g_assert (result);
77 result = dconf_changeset_get (changeset, "/value/a", &value);
78 g_assert (result);
79 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "a string");
80 g_variant_unref (value);
82 result = dconf_changeset_get (changeset, "/value/b", &value);
83 g_assert (result);
84 g_assert_cmpint (g_variant_get_int32 (value), ==, 123);
85 g_variant_unref (value);
87 dconf_changeset_unref (changeset);
90 static void
91 test_similarity (void)
93 DConfChangeset *a, *b;
95 a = dconf_changeset_new ();
96 b = dconf_changeset_new ();
98 g_assert (dconf_changeset_is_similar_to (a, b));
99 g_assert (dconf_changeset_is_similar_to (b, a));
101 dconf_changeset_set (a, "/value/a", g_variant_new_int32 (0));
102 g_assert (!dconf_changeset_is_similar_to (a, b));
103 g_assert (!dconf_changeset_is_similar_to (b, a));
105 /* different values for the same key are still the same */
106 dconf_changeset_set (b, "/value/a", g_variant_new_int32 (1));
107 g_assert (dconf_changeset_is_similar_to (a, b));
108 g_assert (dconf_changeset_is_similar_to (b, a));
110 /* make sure even a NULL is counted as different */
111 dconf_changeset_set (a, "/value/b", NULL);
112 g_assert (!dconf_changeset_is_similar_to (a, b));
113 g_assert (!dconf_changeset_is_similar_to (b, a));
115 dconf_changeset_set (b, "/value/b", NULL);
116 g_assert (dconf_changeset_is_similar_to (a, b));
117 g_assert (dconf_changeset_is_similar_to (b, a));
119 /* different types are still the same */
120 dconf_changeset_set (b, "/value/a", g_variant_new_uint32 (222));
121 g_assert (dconf_changeset_is_similar_to (a, b));
122 g_assert (dconf_changeset_is_similar_to (b, a));
124 dconf_changeset_set (a, "/value/c", NULL);
125 dconf_changeset_set (b, "/value/d", NULL);
126 g_assert (!dconf_changeset_is_similar_to (a, b));
127 g_assert (!dconf_changeset_is_similar_to (b, a));
129 dconf_changeset_unref (a);
130 dconf_changeset_unref (b);
133 static void
134 test_describe (void)
136 DConfChangeset *changeset;
137 const gchar * const *keys;
138 GVariant * const *values;
139 const gchar *prefix;
140 gint n_items;
141 gint i;
143 /* test zero items */
144 changeset = dconf_changeset_new ();
145 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
146 g_assert_cmpint (n_items, ==, 0);
147 dconf_changeset_unref (changeset);
149 /* test one NULL item */
150 changeset = dconf_changeset_new_write ("/value/a", NULL);
151 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
152 g_assert_cmpint (n_items, ==, 1);
153 g_assert_cmpstr (prefix, ==, "/value/a");
154 g_assert_cmpstr (keys[0], ==, "");
155 g_assert (keys[1] == NULL);
156 g_assert (values[0] == NULL);
159 /* Check again */
160 prefix = NULL;
161 keys = NULL;
162 values = NULL;
163 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
164 g_assert_cmpint (n_items, ==, 1);
165 g_assert_cmpstr (prefix, ==, "/value/a");
166 g_assert_cmpstr (keys[0], ==, "");
167 g_assert (keys[1] == NULL);
168 g_assert (values[0] == NULL);
169 dconf_changeset_unref (changeset);
171 /* test one non-NULL item */
172 changeset = dconf_changeset_new_write ("/value/a", g_variant_new_int32 (55));
173 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
174 g_assert_cmpint (n_items, ==, 1);
175 g_assert_cmpstr (prefix, ==, "/value/a");
176 g_assert_cmpstr (keys[0], ==, "");
177 g_assert (keys[1] == NULL);
178 g_assert_cmpint (g_variant_get_int32 (values[0]), ==, 55);
179 dconf_changeset_unref (changeset);
181 /* test many items */
182 changeset = dconf_changeset_new ();
183 for (i = 0; i < 100; i++)
185 gchar key[80];
187 g_snprintf (key, sizeof key, "/test/value/%2d", i);
189 dconf_changeset_set (changeset, key, g_variant_new_int32 (i));
192 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
193 g_assert_cmpint (n_items, ==, i);
194 g_assert_cmpstr (prefix, ==, "/test/value/");
195 for (i = 0; i < 100; i++)
197 gchar key[80];
199 g_snprintf (key, sizeof key, "%2d", i);
201 g_assert_cmpstr (keys[i], ==, key);
202 g_assert_cmpint (g_variant_get_int32 (values[i]), ==, i);
204 g_assert (keys[n_items] == NULL);
205 dconf_changeset_unref (changeset);
207 /* test many items with common names */
208 changeset = dconf_changeset_new ();
209 for (i = 0; i < 100; i++)
211 gchar key[80];
213 g_snprintf (key, sizeof key, "/test/value/aaa%02d", i);
215 dconf_changeset_set (changeset, key, g_variant_new_int32 (i));
218 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
219 g_assert_cmpint (n_items, ==, i);
220 g_assert_cmpstr (prefix, ==, "/test/value/");
221 for (i = 0; i < 100; i++)
223 gchar key[80];
225 g_snprintf (key, sizeof key, "aaa%02d", i);
227 g_assert_cmpstr (keys[i], ==, key);
228 g_assert_cmpint (g_variant_get_int32 (values[i]), ==, i);
230 g_assert (keys[n_items] == NULL);
231 dconf_changeset_unref (changeset);
233 /* test several values in different directories */
234 changeset = dconf_changeset_new ();
235 dconf_changeset_set (changeset, "/value/reset/", NULL);
236 dconf_changeset_set (changeset, "/value/int/a", g_variant_new_int32 (123));
237 dconf_changeset_set (changeset, "/value/string", g_variant_new_string ("bar"));
238 dconf_changeset_set (changeset, "/value/string/a", g_variant_new_string ("foo"));
239 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
240 g_assert_cmpint (n_items, ==, 4);
241 g_assert_cmpstr (prefix, ==, "/value/");
242 g_assert_cmpstr (keys[0], ==, "int/a");
243 g_assert_cmpint (g_variant_get_int32 (values[0]), ==, 123);
244 g_assert_cmpstr (keys[1], ==, "reset/");
245 g_assert (values[1] == NULL);
246 g_assert_cmpstr (keys[2], ==, "string");
247 g_assert_cmpstr (g_variant_get_string (values[2], NULL), ==, "bar");
248 g_assert_cmpstr (keys[3], ==, "string/a");
249 g_assert_cmpstr (g_variant_get_string (values[3], NULL), ==, "foo");
250 g_assert (keys[4] == NULL);
251 dconf_changeset_unref (changeset);
253 /* test a couple of values in very different directories */
254 changeset = dconf_changeset_new_write ("/a/deep/directory/", NULL);
255 dconf_changeset_set (changeset, "/another/deep/directory/", NULL);
256 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
257 g_assert_cmpint (n_items, ==, 2);
258 g_assert_cmpstr (prefix, ==, "/");
259 g_assert_cmpstr (keys[0], ==, "a/deep/directory/");
260 g_assert_cmpstr (keys[1], ==, "another/deep/directory/");
261 g_assert (keys[2] == NULL);
262 g_assert (values[0] == NULL);
263 g_assert (values[1] == NULL);
264 dconf_changeset_unref (changeset);
266 /* one more similar case, but with the first letter different */
267 changeset = dconf_changeset_new_write ("/deep/directory/", NULL);
268 dconf_changeset_set (changeset, "/another/deep/directory/", NULL);
269 n_items = dconf_changeset_describe (changeset, &prefix, &keys, &values);
270 g_assert_cmpint (n_items, ==, 2);
271 g_assert_cmpstr (prefix, ==, "/");
272 g_assert_cmpstr (keys[0], ==, "another/deep/directory/");
273 g_assert_cmpstr (keys[1], ==, "deep/directory/");
274 g_assert (keys[2] == NULL);
275 g_assert (values[0] == NULL);
276 g_assert (values[1] == NULL);
277 dconf_changeset_unref (changeset);
280 static void
281 test_reset (void)
283 DConfChangeset *changeset;
285 changeset = dconf_changeset_new ();
286 g_assert (!dconf_changeset_get (changeset, "/value/a", NULL));
288 /* set a value */
289 dconf_changeset_set (changeset, "/value/a", g_variant_new_boolean (TRUE));
290 g_assert (dconf_changeset_get (changeset, "/value/a", NULL));
292 /* record the reset */
293 dconf_changeset_set (changeset, "/value/", NULL);
294 g_assert (!dconf_changeset_get (changeset, "/value/a", NULL));
296 /* write it back */
297 dconf_changeset_set (changeset, "/value/a", g_variant_new_boolean (TRUE));
298 g_assert (dconf_changeset_get (changeset, "/value/a", NULL));
300 /* reset again */
301 dconf_changeset_set (changeset, "/value/", NULL);
302 g_assert (!dconf_changeset_get (changeset, "/value/a", NULL));
304 /* write again */
305 dconf_changeset_set (changeset, "/value/a", g_variant_new_boolean (TRUE));
306 g_assert (dconf_changeset_get (changeset, "/value/a", NULL));
308 /* reset a different way */
309 dconf_changeset_set (changeset, "/value/a", g_variant_new_boolean (TRUE));
310 g_assert (dconf_changeset_get (changeset, "/value/a", NULL));
312 /* write last time */
313 dconf_changeset_set (changeset, "/value/a", g_variant_new_boolean (TRUE));
314 g_assert (dconf_changeset_get (changeset, "/value/a", NULL));
316 dconf_changeset_unref (changeset);
319 static gboolean
320 has_same_value (const gchar *key,
321 GVariant *value,
322 gpointer user_data)
324 DConfChangeset *other = user_data;
325 GVariant *other_value;
326 gboolean success;
328 success = dconf_changeset_get (other, key, &other_value);
329 g_assert (success);
331 if (value == NULL)
332 g_assert (other_value == NULL);
333 else
335 g_assert (g_variant_equal (value, other_value));
336 g_variant_unref (other_value);
339 return TRUE;
342 static void
343 test_serialisation (DConfChangeset *changes)
345 GVariant *serialised;
346 DConfChangeset *copy;
348 serialised = dconf_changeset_serialise (changes);
349 copy = dconf_changeset_deserialise (serialised);
350 g_variant_unref (serialised);
352 g_assert (dconf_changeset_is_similar_to (copy, changes));
353 g_assert (dconf_changeset_is_similar_to (changes, copy));
354 g_assert (dconf_changeset_all (copy, has_same_value, changes));
355 g_assert (dconf_changeset_all (changes, has_same_value, copy));
357 dconf_changeset_unref (copy);
360 static void
361 test_serialiser (void)
363 DConfChangeset *changeset;
365 changeset = dconf_changeset_new ();
366 test_serialisation (changeset);
368 dconf_changeset_set (changeset, "/some/value", g_variant_new_int32 (333));
369 test_serialisation (changeset);
371 dconf_changeset_set (changeset, "/other/value", NULL);
372 test_serialisation (changeset);
374 dconf_changeset_set (changeset, "/other/value", g_variant_new_int32 (55));
375 test_serialisation (changeset);
377 dconf_changeset_set (changeset, "/other/", NULL);
378 test_serialisation (changeset);
380 dconf_changeset_set (changeset, "/", NULL);
381 test_serialisation (changeset);
383 dconf_changeset_unref (changeset);
386 static void
387 test_change (void)
389 DConfChangeset *deltaa, *deltab;
390 DConfChangeset *dba, *dbb;
392 dba = dconf_changeset_new_database (NULL);
393 dbb = dconf_changeset_new_database (dba);
394 g_assert (dconf_changeset_is_empty (dbb));
395 dconf_changeset_unref (dbb);
397 deltaa = dconf_changeset_new ();
398 dconf_changeset_change (dba, deltaa);
399 g_assert (dconf_changeset_is_empty (dba));
400 dconf_changeset_unref (deltaa);
402 deltaa = dconf_changeset_new_write ("/some/value", NULL);
403 dconf_changeset_change (dba, deltaa);
404 g_assert (dconf_changeset_is_empty (dba));
405 dconf_changeset_unref (deltaa);
407 deltaa = dconf_changeset_new ();
408 deltab = dconf_changeset_new_write ("/some/value", g_variant_new_int32 (123));
409 dconf_changeset_change (deltaa, deltab);
410 g_assert (!dconf_changeset_is_empty (deltaa));
411 dconf_changeset_change (dba, deltab);
412 g_assert (!dconf_changeset_is_empty (dba));
413 dconf_changeset_unref (deltaa);
414 dconf_changeset_unref (deltab);
416 deltaa = dconf_changeset_new ();
417 deltab = dconf_changeset_new_write ("/other/value", g_variant_new_int32 (123));
418 dconf_changeset_change (deltaa, deltab);
419 g_assert (!dconf_changeset_is_empty (deltaa));
420 dconf_changeset_unref (deltab);
421 deltab = dconf_changeset_new_write ("/other/", NULL);
422 dconf_changeset_change (deltaa, deltab);
423 g_assert (!dconf_changeset_is_empty (deltaa));
424 dconf_changeset_change (dba, deltaa);
425 g_assert (!dconf_changeset_is_empty (dba));
427 dbb = dconf_changeset_new_database (dba);
428 g_assert (!dconf_changeset_is_empty (dbb));
430 dconf_changeset_set (dba, "/some/", NULL);
432 dconf_changeset_set (dba, "/other/value", g_variant_new_int32 (123));
433 g_assert (!dconf_changeset_is_empty (dba));
434 dconf_changeset_change (dba, deltaa);
435 g_assert (dconf_changeset_is_empty (dba));
436 g_assert (!dconf_changeset_is_empty (dbb));
438 dconf_changeset_unref (deltaa);
439 dconf_changeset_unref (deltab);
440 dconf_changeset_unref (dbb);
441 dconf_changeset_unref (dba);
444 static void
445 assert_diff_change_invariant (DConfChangeset *from,
446 DConfChangeset *to)
448 DConfChangeset *copy;
449 DConfChangeset *diff;
451 /* Verify this promise from the docs:
453 * Applying the returned changeset to @from using
454 * dconf_changeset_change() will result in the two changesets being
455 * equal.
458 copy = dconf_changeset_new_database (from);
459 diff = dconf_changeset_diff (from, to);
460 if (diff)
462 dconf_changeset_change (copy, diff);
463 dconf_changeset_unref (diff);
466 /* Make sure they are now equal */
467 diff = dconf_changeset_diff (copy, to);
468 g_assert (diff == NULL);
470 /* Why not try it the other way too? */
471 diff = dconf_changeset_diff (to, copy);
472 g_assert (diff == NULL);
474 dconf_changeset_unref (copy);
477 static gchar *
478 create_random_key (void)
480 GString *key;
481 gint i, n;
483 key = g_string_new (NULL);
484 n = g_test_rand_int_range (1, 5);
485 for (i = 0; i < n; i++)
487 gint j;
489 g_string_append_c (key, '/');
490 for (j = 0; j < 5; j++)
491 g_string_append_c (key, g_test_rand_int_range ('a', 'z' + 1));
494 return g_string_free (key, FALSE);
497 static GVariant *
498 create_random_value (void)
500 return g_variant_new_take_string (create_random_key ());
503 static DConfChangeset *
504 create_random_db (void)
506 DConfChangeset *set;
507 gint i, n;
509 set = dconf_changeset_new_database (NULL);
510 n = g_test_rand_int_range (0, 20);
511 for (i = 0; i < n; i++)
513 GVariant *value = create_random_value ();
514 gchar *key = create_random_key ();
516 dconf_changeset_set (set, key, value);
517 g_free (key);
520 return set;
523 static void
524 test_diff (void)
526 DConfChangeset *a, *b;
527 gint i;
529 /* Check diff between two empties */
530 a = dconf_changeset_new_database (NULL);
531 b = dconf_changeset_new_database (NULL);
532 assert_diff_change_invariant (a, b);
533 dconf_changeset_unref (a);
534 dconf_changeset_unref (b);
536 /* Check diff between two non-empties that are equal */
537 a = create_random_db ();
538 b = dconf_changeset_new_database (a);
539 assert_diff_change_invariant (a, b);
540 dconf_changeset_unref (a);
541 dconf_changeset_unref (b);
543 /* Check diff between two random databases that are probably unequal */
544 for (i = 0; i < 1000; i++)
546 a = create_random_db ();
547 b = create_random_db ();
548 assert_diff_change_invariant (a, b);
549 dconf_changeset_unref (a);
550 dconf_changeset_unref (b);
555 main (int argc, char **argv)
557 g_test_init (&argc, &argv, NULL);
559 g_test_add_func ("/changeset/basic", test_basic);
560 g_test_add_func ("/changeset/similarity", test_similarity);
561 g_test_add_func ("/changeset/describe", test_describe);
562 g_test_add_func ("/changeset/reset", test_reset);
563 g_test_add_func ("/changeset/serialiser", test_serialiser);
564 g_test_add_func ("/changeset/change", test_change);
565 g_test_add_func ("/changeset/diff", test_diff);
567 return g_test_run ();