GSettings: major refactor. Add enums, range.
[platform/upstream/glib.git] / gio / tests / gsettings.c
1 #include <stdlib.h>
2 #include <locale.h>
3 #include <libintl.h>
4 #include <gio/gio.h>
5 #include <gstdio.h>
6 #define G_SETTINGS_ENABLE_BACKEND
7 #include <gio/gsettingsbackend.h>
8
9 #include "testenum.h"
10
11 static gboolean backend_set;
12
13 /* These tests rely on the schemas in org.gtk.test.gschema.xml
14  * to be compiled and installed in the same directory.
15  */
16
17 /* Just to get warmed up: Read and set a string, and
18  * verify that can read the changed string back
19  */
20 static void
21 test_basic (void)
22 {
23   gchar *str = NULL;
24   GSettings *settings;
25
26   settings = g_settings_new ("org.gtk.test");
27
28   g_settings_get (settings, "greeting", "s", &str);
29   g_assert_cmpstr (str, ==, "Hello, earthlings");
30
31   g_settings_set (settings, "greeting", "s", "goodbye world");
32   g_settings_get (settings, "greeting", "s", &str);
33   g_assert_cmpstr (str, ==, "goodbye world");
34   g_free (str);
35   str = NULL;
36
37   if (!backend_set)
38     {
39       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
40         {
41           settings = g_settings_new ("org.gtk.test");
42           g_settings_set (settings, "greeting", "i", 555);
43           abort ();
44         }
45       g_test_trap_assert_failed ();
46       g_test_trap_assert_stderr ("*g_settings_type_check*");
47     }
48
49   g_settings_get (settings, "greeting", "s", &str);
50   g_assert_cmpstr (str, ==, "goodbye world");
51   g_free (str);
52   str = NULL;
53
54   g_settings_set (settings, "greeting", "s", "this is the end");
55   g_object_unref (settings);
56 }
57
58 /* Check that we get an error when getting a key
59  * that is not in the schema
60  */
61 static void
62 test_unknown_key (void)
63 {
64   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
65     {
66       GSettings *settings;
67       GVariant *value;
68
69       settings = g_settings_new ("org.gtk.test");
70       value = g_settings_get_value (settings, "no_such_key");
71
72       g_assert (value == NULL);
73
74       g_object_unref (settings);
75     }
76   g_test_trap_assert_failed ();
77   g_test_trap_assert_stderr ("*does not contain*");
78 }
79
80 /* Check that we get an error when the schema
81  * has not been installed
82  */
83 void
84 test_no_schema (void)
85 {
86   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
87     {
88       GSettings *settings;
89
90       settings = g_settings_new ("no.such.schema");
91
92       g_assert (settings == NULL);
93     }
94
95   g_test_trap_assert_failed ();
96   g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*");
97 }
98
99 /* Check that we get an error when passing a type string
100  * that does not match the schema
101  */
102 static void
103 test_wrong_type (void)
104 {
105   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
106     {
107       GSettings *settings;
108       gchar *str = NULL;
109
110       settings = g_settings_new ("org.gtk.test");
111
112       g_settings_get (settings, "greeting", "o", &str);
113
114       g_assert (str == NULL);
115     }
116   g_test_trap_assert_failed ();
117   g_test_trap_assert_stderr ("*CRITICAL*");
118
119   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
120     {
121       GSettings *settings;
122
123       settings = g_settings_new ("org.gtk.test");
124
125       g_settings_set (settings, "greeting", "o", "/a/path");
126     }
127   g_test_trap_assert_failed ();
128   g_test_trap_assert_stderr ("*CRITICAL*");
129 }
130
131 /* Check that we can successfully read and set the full
132  * range of all basic types
133  */
134 static void
135 test_basic_types (void)
136 {
137   GSettings *settings;
138   gboolean b;
139   guint8 byte;
140   gint16 i16;
141   guint16 u16;
142   gint32 i32;
143   guint32 u32;
144   gint64 i64;
145   guint64 u64;
146   gdouble d;
147   gchar *str;
148
149   settings = g_settings_new ("org.gtk.test.basic-types");
150
151   g_settings_get (settings, "test-boolean", "b", &b);
152   g_assert_cmpint (b, ==, 1);
153
154   g_settings_set (settings, "test-boolean", "b", 0);
155   g_settings_get (settings, "test-boolean", "b", &b);
156   g_assert_cmpint (b, ==, 0);
157
158   g_settings_get (settings, "test-byte", "y", &byte);
159   g_assert_cmpint (byte, ==, 25);
160
161   g_settings_set (settings, "test-byte", "y", G_MAXUINT8);
162   g_settings_get (settings, "test-byte", "y", &byte);
163   g_assert_cmpint (byte, ==, G_MAXUINT8);
164
165   g_settings_get (settings, "test-int16", "n", &i16);
166   g_assert_cmpint (i16, ==, -1234);
167
168   g_settings_set (settings, "test-int16", "n", G_MININT16);
169   g_settings_get (settings, "test-int16", "n", &i16);
170   g_assert_cmpint (i16, ==, G_MININT16);
171
172   g_settings_set (settings, "test-int16", "n", G_MAXINT16);
173   g_settings_get (settings, "test-int16", "n", &i16);
174   g_assert_cmpint (i16, ==, G_MAXINT16);
175
176   g_settings_get (settings, "test-uint16", "q", &u16);
177   g_assert_cmpuint (u16, ==, 1234);
178
179   g_settings_set (settings, "test-uint16", "q", G_MAXUINT16);
180   g_settings_get (settings, "test-uint16", "q", &u16);
181   g_assert_cmpuint (u16, ==, G_MAXUINT16);
182
183   g_settings_get (settings, "test-int32", "i", &i32);
184   g_assert_cmpint (i32, ==, -123456);
185
186   g_settings_set (settings, "test-int32", "i", G_MININT32);
187   g_settings_get (settings, "test-int32", "i", &i32);
188   g_assert_cmpint (i32, ==, G_MININT32);
189
190   g_settings_set (settings, "test-int32", "i", G_MAXINT32);
191   g_settings_get (settings, "test-int32", "i", &i32);
192   g_assert_cmpint (i32, ==, G_MAXINT32);
193
194   g_settings_get (settings, "test-uint32", "u", &u32);
195   g_assert_cmpuint (u32, ==, 123456);
196
197   g_settings_set (settings, "test-uint32", "u", G_MAXUINT32);
198   g_settings_get (settings, "test-uint32", "u", &u32);
199   g_assert_cmpuint (u32, ==, G_MAXUINT32);
200
201   g_settings_get (settings, "test-int64", "x", &i64);
202   g_assert_cmpuint (i64, ==, -123456789);
203
204   g_settings_set (settings, "test-int64", "x", G_MININT64);
205   g_settings_get (settings, "test-int64", "x", &i64);
206   g_assert_cmpuint (i64, ==, G_MININT64);
207
208   g_settings_set (settings, "test-int64", "x", G_MAXINT64);
209   g_settings_get (settings, "test-int64", "x", &i64);
210   g_assert_cmpuint (i64, ==, G_MAXINT64);
211
212   g_settings_get (settings, "test-uint64", "t", &u64);
213   g_assert_cmpuint (u64, ==, 123456789);
214
215   g_settings_set (settings, "test-uint64", "t", G_MAXUINT64);
216   g_settings_get (settings, "test-uint64", "t", &u64);
217   g_assert_cmpuint (u64, ==, G_MAXUINT64);
218
219   g_settings_get (settings, "test-double", "d", &d);
220   g_assert_cmpfloat (d, ==, 123.456);
221
222   g_settings_set (settings, "test-double", "d", G_MINDOUBLE);
223   g_settings_get (settings, "test-double", "d", &d);
224   g_assert_cmpfloat (d, ==, G_MINDOUBLE);
225
226   g_settings_set (settings, "test-double", "d", G_MAXDOUBLE);
227   g_settings_get (settings, "test-double", "d", &d);
228   g_assert_cmpfloat (d, ==, G_MAXDOUBLE);
229
230   g_settings_get (settings, "test-string", "s", &str);
231   g_assert_cmpstr (str, ==, "a string, it seems");
232   g_free (str);
233   str = NULL;
234
235   g_settings_get (settings, "test-objectpath", "o", &str);
236   g_assert_cmpstr (str, ==, "/a/object/path");
237   g_object_unref (settings);
238   g_free (str);
239   str = NULL;
240 }
241
242 /* Check that we can read an set complex types like
243  * tuples, arrays and dictionaries
244  */
245 static void
246 test_complex_types (void)
247 {
248   GSettings *settings;
249   gchar *s;
250   gint i1, i2;
251   GVariantIter *iter = NULL;
252
253   settings = g_settings_new ("org.gtk.test.complex-types");
254
255   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
256   g_assert_cmpstr (s, ==, "one");
257   g_assert_cmpint (i1,==, 2);
258   g_assert_cmpint (i2,==, 3);
259   g_free (s) ;
260   s = NULL;
261
262   g_settings_set (settings, "test-tuple", "(s(ii))", "none", 0, 0);
263   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
264   g_assert_cmpstr (s, ==, "none");
265   g_assert_cmpint (i1,==, 0);
266   g_assert_cmpint (i2,==, 0);
267   g_free (s);
268   s = NULL;
269
270   g_settings_get (settings, "test-array", "ai", &iter);
271   g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6);
272   g_assert (g_variant_iter_next (iter, "i", &i1));
273   g_assert_cmpint (i1, ==, 0);
274   g_assert (g_variant_iter_next (iter, "i", &i1));
275   g_assert_cmpint (i1, ==, 1);
276   g_assert (g_variant_iter_next (iter, "i", &i1));
277   g_assert_cmpint (i1, ==, 2);
278   g_assert (g_variant_iter_next (iter, "i", &i1));
279   g_assert_cmpint (i1, ==, 3);
280   g_assert (g_variant_iter_next (iter, "i", &i1));
281   g_assert_cmpint (i1, ==, 4);
282   g_assert (g_variant_iter_next (iter, "i", &i1));
283   g_assert_cmpint (i1, ==, 5);
284   g_assert (!g_variant_iter_next (iter, "i", &i1));
285   g_variant_iter_free (iter);
286
287   g_object_unref (settings);
288 }
289
290 static gboolean changed_cb_called;
291
292 static void
293 changed_cb (GSettings   *settings,
294             const gchar *key,
295             gpointer     data)
296 {
297   changed_cb_called = TRUE;
298
299   g_assert_cmpstr (key, ==, data);
300 }
301
302 /* Test that basic change notification with the changed signal works.
303  */
304 void
305 test_changes (void)
306 {
307   GSettings *settings;
308   GSettings *settings2;
309
310   settings = g_settings_new ("org.gtk.test");
311
312   g_signal_connect (settings, "changed",
313                     G_CALLBACK (changed_cb), "greeting");
314
315   changed_cb_called = FALSE;
316
317   g_settings_set (settings, "greeting", "s", "new greeting");
318   g_assert (changed_cb_called);
319
320   settings2 = g_settings_new ("org.gtk.test");
321
322   changed_cb_called = FALSE;
323
324   g_settings_set (settings2, "greeting", "s", "hi");
325   g_assert (changed_cb_called);
326
327   g_object_unref (settings2);
328   g_object_unref (settings);
329 }
330
331 static gboolean changed_cb_called2;
332
333 static void
334 changed_cb2 (GSettings   *settings,
335              const gchar *key,
336              gpointer     data)
337 {
338   gboolean *p = data;
339
340   *p = TRUE;
341 }
342
343 /* Test that changes done to a delay-mode instance
344  * don't appear to the outside world until apply. Also
345  * check that we get change notification when they are
346  * applied.
347  * Also test that the has-unapplied property is properly
348  * maintained.
349  */
350 void
351 test_delay_apply (void)
352 {
353   GSettings *settings;
354   GSettings *settings2;
355   gchar *str;
356
357   settings = g_settings_new ("org.gtk.test");
358   settings2 = g_settings_new ("org.gtk.test");
359
360   g_settings_set (settings2, "greeting", "s", "top o' the morning");
361
362   changed_cb_called = FALSE;
363   changed_cb_called2 = FALSE;
364
365   g_signal_connect (settings, "changed",
366                     G_CALLBACK (changed_cb2), &changed_cb_called);
367   g_signal_connect (settings2, "changed",
368                     G_CALLBACK (changed_cb2), &changed_cb_called2);
369
370   g_settings_delay (settings);
371
372   g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply");
373
374   g_assert (changed_cb_called);
375   g_assert (!changed_cb_called2);
376
377   g_settings_get (settings, "greeting", "s", &str);
378   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
379   g_free (str);
380   str = NULL;
381
382   g_settings_get (settings2, "greeting", "s", &str);
383   g_assert_cmpstr (str, ==, "top o' the morning");
384   g_free (str);
385   str = NULL;
386
387   g_assert (g_settings_get_has_unapplied (settings));
388   g_assert (!g_settings_get_has_unapplied (settings2));
389
390   changed_cb_called = FALSE;
391   changed_cb_called2 = FALSE;
392
393   g_settings_apply (settings);
394
395   g_assert (!changed_cb_called);
396   g_assert (changed_cb_called2);
397
398   g_settings_get (settings, "greeting", "s", &str);
399   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
400   g_free (str);
401   str = NULL;
402
403   g_settings_get (settings2, "greeting", "s", &str);
404   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
405   g_free (str);
406   str = NULL;
407
408   g_assert (!g_settings_get_has_unapplied (settings));
409   g_assert (!g_settings_get_has_unapplied (settings2));
410
411   g_object_unref (settings2);
412   g_object_unref (settings);
413 }
414
415 /* Test that reverting unapplied changes in a delay-apply
416  * settings instance works.
417  */
418 static void
419 test_delay_revert (void)
420 {
421   GSettings *settings;
422   GSettings *settings2;
423   gchar *str;
424
425   settings = g_settings_new ("org.gtk.test");
426   settings2 = g_settings_new ("org.gtk.test");
427
428   g_settings_set (settings2, "greeting", "s", "top o' the morning");
429
430   g_settings_delay (settings);
431
432   g_settings_set (settings, "greeting", "s", "greetings from test_delay_revert");
433
434   g_settings_get (settings, "greeting", "s", &str);
435   g_assert_cmpstr (str, ==, "greetings from test_delay_revert");
436   g_free (str);
437   str = NULL;
438
439   g_settings_get (settings2, "greeting", "s", &str);
440   g_assert_cmpstr (str, ==, "top o' the morning");
441   g_free (str);
442   str = NULL;
443
444   g_assert (g_settings_get_has_unapplied (settings));
445
446   g_settings_revert (settings);
447
448   g_assert (!g_settings_get_has_unapplied (settings));
449
450   g_settings_get (settings, "greeting", "s", &str);
451   g_assert_cmpstr (str, ==, "top o' the morning");
452   g_free (str);
453   str = NULL;
454
455   g_settings_get (settings2, "greeting", "s", &str);
456   g_assert_cmpstr (str, ==, "top o' the morning");
457   g_free (str);
458   str = NULL;
459
460   g_object_unref (settings2);
461   g_object_unref (settings);
462 }
463
464 static void
465 keys_changed_cb (GSettings    *settings,
466                  const GQuark *keys,
467                  gint          n_keys)
468 {
469   gchar *str;
470
471   g_assert_cmpint (n_keys, ==, 2);
472
473   g_assert ((keys[0] == g_quark_from_static_string ("greeting") &&
474              keys[1] == g_quark_from_static_string ("farewell")) ||
475             (keys[1] == g_quark_from_static_string ("greeting") &&
476              keys[0] == g_quark_from_static_string ("farewell")));
477
478   g_settings_get (settings, "greeting", "s", &str);
479   g_assert_cmpstr (str, ==, "greetings from test_atomic");
480   g_free (str);
481   str = NULL;
482
483   g_settings_get (settings, "farewell", "s", &str);
484   g_assert_cmpstr (str, ==, "atomic bye-bye");
485   g_free (str);
486   str = NULL;
487 }
488
489 /* Check that delay-applied changes appear atomically.
490  * More specifically, verify that all changed keys appear
491  * with their new value while handling the change-event signal.
492  */
493 static void
494 test_atomic (void)
495 {
496   GSettings *settings;
497   GSettings *settings2;
498   gchar *str;
499
500   settings = g_settings_new ("org.gtk.test");
501   settings2 = g_settings_new ("org.gtk.test");
502
503   g_settings_set (settings2, "greeting", "s", "top o' the morning");
504
505   changed_cb_called = FALSE;
506   changed_cb_called2 = FALSE;
507
508   g_signal_connect (settings2, "change-event",
509                     G_CALLBACK (keys_changed_cb), NULL);
510
511   g_settings_delay (settings);
512
513   g_settings_set (settings, "greeting", "s", "greetings from test_atomic");
514   g_settings_set (settings, "farewell", "s", "atomic bye-bye");
515
516   g_settings_apply (settings);
517
518   g_settings_get (settings, "greeting", "s", &str);
519   g_assert_cmpstr (str, ==, "greetings from test_atomic");
520   g_free (str);
521   str = NULL;
522
523   g_settings_get (settings, "farewell", "s", &str);
524   g_assert_cmpstr (str, ==, "atomic bye-bye");
525   g_free (str);
526   str = NULL;
527
528   g_settings_get (settings2, "greeting", "s", &str);
529   g_assert_cmpstr (str, ==, "greetings from test_atomic");
530   g_free (str);
531   str = NULL;
532
533   g_settings_get (settings2, "farewell", "s", &str);
534   g_assert_cmpstr (str, ==, "atomic bye-bye");
535   g_free (str);
536   str = NULL;
537
538   g_object_unref (settings2);
539   g_object_unref (settings);
540 }
541
542 /* On Windows the interaction between the C library locale and libintl
543  * (from GNU gettext) is not like on POSIX, so just skip these tests
544  * for now.
545  *
546  * There are several issues:
547  *
548  * 1) The C library doesn't use LC_MESSAGES, that is implemented only
549  * in libintl (defined in its <libintl.h>).
550  *
551  * 2) The locale names that setlocale() accepts and returns aren't in
552  * the "de_DE" style, but like "German_Germany".
553  *
554  * 3) libintl looks at the Win32 thread locale and not the C library
555  * locale. (And even if libintl would use the C library's locale, as
556  * there are several alternative C library DLLs, libintl might be
557  * linked to a different one than the application code, so they
558  * wouldn't have the same C library locale anyway.)
559  */
560
561 /* Test that translations work for schema defaults.
562  *
563  * This test relies on the de.po file in the same directory
564  * to be compiled into ./de/LC_MESSAGES/test.mo
565  */
566 static void
567 test_l10n (void)
568 {
569   GSettings *settings;
570   gchar *str;
571   gchar *locale;
572
573   bindtextdomain ("test", ".");
574   bind_textdomain_codeset ("test", "UTF-8");
575
576   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
577
578   settings = g_settings_new ("org.gtk.test.localized");
579
580   setlocale (LC_MESSAGES, "C");
581   str = g_settings_get_string (settings, "error-message");
582   setlocale (LC_MESSAGES, locale);
583
584   g_assert_cmpstr (str, ==, "Unnamed");
585   g_free (str);
586   str = NULL;
587
588   setlocale (LC_MESSAGES, "de_DE");
589   str = g_settings_get_string (settings, "error-message");
590   setlocale (LC_MESSAGES, locale);
591
592   g_assert_cmpstr (str, ==, "Unbenannt");
593   g_object_unref (settings);
594   g_free (str);
595   str = NULL;
596
597   g_free (locale);
598 }
599
600 /* Test that message context works as expected with translated
601  * schema defaults. Also, verify that non-ASCII UTF-8 content
602  * works.
603  *
604  * This test relies on the de.po file in the same directory
605  * to be compiled into ./de/LC_MESSAGES/test.mo
606  */
607 static void
608 test_l10n_context (void)
609 {
610   GSettings *settings;
611   gchar *str;
612   gchar *locale;
613
614   bindtextdomain ("test", ".");
615   bind_textdomain_codeset ("test", "UTF-8");
616
617   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
618
619   settings = g_settings_new ("org.gtk.test.localized");
620
621   setlocale (LC_MESSAGES, "C");
622   g_settings_get (settings, "backspace", "s", &str);
623   setlocale (LC_MESSAGES, locale);
624
625   g_assert_cmpstr (str, ==, "BackSpace");
626   g_free (str);
627   str = NULL;
628
629   setlocale (LC_MESSAGES, "de_DE");
630   g_settings_get (settings, "backspace", "s", &str);
631   setlocale (LC_MESSAGES, locale);
632
633   g_assert_cmpstr (str, ==, "Löschen");
634   g_object_unref (settings);
635   g_free (str);
636   str = NULL;
637
638   g_free (locale);
639 }
640
641 enum
642 {
643   PROP_0,
644   PROP_BOOL,
645   PROP_INT,
646   PROP_INT64,
647   PROP_UINT64,
648   PROP_DOUBLE,
649   PROP_STRING,
650   PROP_NO_READ,
651   PROP_NO_WRITE
652 };
653
654 typedef struct
655 {
656   GObject parent_instance;
657
658   gboolean bool_prop;
659   gint int_prop;
660   gint64 int64_prop;
661   guint64 uint64_prop;
662   gdouble double_prop;
663   gchar *string_prop;
664   gchar *no_read_prop;
665   gchar *no_write_prop;
666 } TestObject;
667
668 typedef struct
669 {
670   GObjectClass parent_class;
671 } TestObjectClass;
672
673 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
674
675 static void
676 test_object_init (TestObject *object)
677 {
678 }
679
680 static void
681 test_object_finalize (GObject *object)
682 {
683   TestObject *testo = (TestObject*)object;
684   g_free (testo->string_prop);
685   G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
686 }
687
688 static void
689 test_object_get_property (GObject    *object,
690                           guint       prop_id,
691                           GValue     *value,
692                           GParamSpec *pspec)
693 {
694   TestObject *test_object = (TestObject *)object;
695
696   switch (prop_id)
697     {
698     case PROP_BOOL:
699       g_value_set_boolean (value, test_object->bool_prop);
700       break;
701     case PROP_INT:
702       g_value_set_int (value, test_object->int_prop);
703       break;
704     case PROP_INT64:
705       g_value_set_int64 (value, test_object->int64_prop);
706       break;
707     case PROP_UINT64:
708       g_value_set_uint64 (value, test_object->uint64_prop);
709       break;
710     case PROP_DOUBLE:
711       g_value_set_double (value, test_object->double_prop);
712       break;
713     case PROP_STRING:
714       g_value_set_string (value, test_object->string_prop);
715       break;
716     case PROP_NO_WRITE:
717       g_value_set_string (value, test_object->no_write_prop);
718       break;
719     default:
720       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
721       break;
722     }
723 }
724
725 static void
726 test_object_set_property (GObject      *object,
727                           guint         prop_id,
728                           const GValue *value,
729                           GParamSpec   *pspec)
730 {
731   TestObject *test_object = (TestObject *)object;
732
733   switch (prop_id)
734     {
735     case PROP_BOOL:
736       test_object->bool_prop = g_value_get_boolean (value);
737       break;
738     case PROP_INT:
739       test_object->int_prop = g_value_get_int (value);
740       break;
741     case PROP_INT64:
742       test_object->int64_prop = g_value_get_int64 (value);
743       break;
744     case PROP_UINT64:
745       test_object->uint64_prop = g_value_get_uint64 (value);
746       break;
747     case PROP_DOUBLE:
748       test_object->double_prop = g_value_get_double (value);
749       break;
750     case PROP_STRING:
751       g_free (test_object->string_prop);
752       test_object->string_prop = g_value_dup_string (value);
753       break;
754     case PROP_NO_READ:
755       g_free (test_object->no_read_prop);
756       test_object->no_read_prop = g_value_dup_string (value);
757       break;
758     default:
759       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
760       break;
761     }
762 }
763
764 static void
765 test_object_class_init (TestObjectClass *class)
766 {
767   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
768
769   gobject_class->get_property = test_object_get_property;
770   gobject_class->set_property = test_object_set_property;
771   gobject_class->finalize = test_object_finalize;
772
773   g_object_class_install_property (gobject_class, PROP_BOOL,
774     g_param_spec_boolean ("bool", "", "", FALSE, G_PARAM_READWRITE));
775   g_object_class_install_property (gobject_class, PROP_INT,
776     g_param_spec_int ("int", "", "", -G_MAXINT, G_MAXINT, 0, G_PARAM_READWRITE));
777   g_object_class_install_property (gobject_class, PROP_INT64,
778     g_param_spec_int64 ("int64", "", "", G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE));
779   g_object_class_install_property (gobject_class, PROP_UINT64,
780     g_param_spec_uint64 ("uint64", "", "", 0, G_MAXUINT64, 0, G_PARAM_READWRITE));
781   g_object_class_install_property (gobject_class, PROP_DOUBLE,
782     g_param_spec_double ("double", "", "", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE));
783   g_object_class_install_property (gobject_class, PROP_STRING,
784     g_param_spec_string ("string", "", "", NULL, G_PARAM_READWRITE));
785   g_object_class_install_property (gobject_class, PROP_NO_WRITE,
786     g_param_spec_string ("no-write", "", "", NULL, G_PARAM_READABLE));
787   g_object_class_install_property (gobject_class, PROP_NO_READ,
788     g_param_spec_string ("no-read", "", "", NULL, G_PARAM_WRITABLE));
789 }
790
791 static TestObject *
792 test_object_new (void)
793 {
794   return (TestObject*)g_object_new (test_object_get_type (), NULL);
795 }
796
797 /* Test basic binding functionality for simple types.
798  * Verify that with bidirectional bindings, changes on either side
799  * are notified on the other end.
800  */
801 static void
802 test_simple_binding (void)
803 {
804   TestObject *obj;
805   GSettings *settings;
806   gboolean b;
807   gint i;
808   gint64 i64;
809   guint64 u64;
810   gdouble d;
811   gchar *s;
812
813   settings = g_settings_new ("org.gtk.test.binding");
814   obj = test_object_new ();
815
816   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_DEFAULT);
817
818   g_object_set (obj, "bool", TRUE, NULL);
819   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
820
821   g_settings_set_boolean (settings, "bool", FALSE);
822   g_object_get (obj, "bool", &b, NULL);
823   g_assert_cmpint (b, ==, FALSE);
824
825   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT);
826
827   g_object_set (obj, "int", 12345, NULL);
828   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345);
829
830   g_settings_set_int (settings, "int", 54321);
831   g_object_get (obj, "int", &i, NULL);
832   g_assert_cmpint (i, ==, 54321);
833
834   g_settings_bind (settings, "int64", obj, "int64", G_SETTINGS_BIND_DEFAULT);
835
836   g_object_set (obj, "int64", (gint64) G_MAXINT64, NULL);
837   g_settings_get (settings, "int64", "x", &i64);
838   g_assert_cmpint (i64, ==, G_MAXINT64);
839
840   g_settings_set (settings, "int64", "x", (gint64) G_MININT64);
841   g_object_get (obj, "int64", &i64, NULL);
842   g_assert_cmpint (i64, ==, G_MININT64);
843
844   g_settings_bind (settings, "uint64", obj, "uint64", G_SETTINGS_BIND_DEFAULT);
845
846   g_object_set (obj, "uint64", (guint64) G_MAXUINT64, NULL);
847   g_settings_get (settings, "uint64", "t", &u64);
848   g_assert_cmpuint (u64, ==, G_MAXUINT64);
849
850   g_settings_set (settings, "uint64", "t", (guint64) G_MAXINT64);
851   g_object_get (obj, "uint64", &u64, NULL);
852   g_assert_cmpuint (u64, ==, (guint64) G_MAXINT64);
853
854   g_settings_bind (settings, "string", obj, "string", G_SETTINGS_BIND_DEFAULT);
855
856   g_object_set (obj, "string", "bu ba", NULL);
857   s = g_settings_get_string (settings, "string");
858   g_assert_cmpstr (s, ==, "bu ba");
859   g_free (s);
860
861   g_settings_set_string (settings, "string", "bla bla");
862   g_object_get (obj, "string", &s, NULL);
863   g_assert_cmpstr (s, ==, "bla bla");
864   g_free (s);
865
866   g_settings_bind (settings, "double", obj, "double", G_SETTINGS_BIND_DEFAULT);
867
868   g_object_set (obj, "double", G_MAXFLOAT, NULL);
869   g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXFLOAT);
870
871   g_settings_set_double (settings, "double", G_MINFLOAT);
872   g_object_get (obj, "double", &d, NULL);
873   g_assert_cmpfloat (d, ==, G_MINFLOAT);
874
875   g_object_set (obj, "double", G_MAXDOUBLE, NULL);
876   g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXDOUBLE);
877
878   g_settings_set_double (settings, "double", -G_MINDOUBLE);
879   g_object_get (obj, "double", &d, NULL);
880   g_assert_cmpfloat (d, ==, -G_MINDOUBLE);
881   g_object_unref (obj);
882   g_object_unref (settings);
883 }
884
885 /* Test one-way bindings.
886  * Verify that changes on one side show up on the other,
887  * but not vice versa
888  */
889 static void
890 test_directional_binding (void)
891 {
892   TestObject *obj;
893   GSettings *settings;
894   gboolean b;
895   gint i;
896
897   settings = g_settings_new ("org.gtk.test.binding");
898   obj = test_object_new ();
899
900   g_object_set (obj, "bool", FALSE, NULL);
901   g_settings_set_boolean (settings, "bool", FALSE);
902
903   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET);
904
905   g_settings_set_boolean (settings, "bool", TRUE);
906   g_object_get (obj, "bool", &b, NULL);
907   g_assert_cmpint (b, ==, TRUE);
908
909   g_object_set (obj, "bool", FALSE, NULL);
910   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
911
912   g_object_set (obj, "int", 20, NULL);
913   g_settings_set_int (settings, "int", 20);
914
915   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_SET);
916
917   g_object_set (obj, "int", 32, NULL);
918   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 32);
919
920   g_settings_set_int (settings, "int", 20);
921   g_object_get (obj, "int", &i, NULL);
922   g_assert_cmpint (i, ==, 32);
923
924   g_object_unref (obj);
925   g_object_unref (settings);
926 }
927
928 /* Test that type mismatch is caught when creating a binding
929  */
930 static void
931 test_typesafe_binding (void)
932 {
933   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
934     {
935       TestObject *obj;
936       GSettings *settings;
937
938       settings = g_settings_new ("org.gtk.test.binding");
939       obj = test_object_new ();
940
941       g_settings_bind (settings, "string", obj, "int", G_SETTINGS_BIND_DEFAULT);
942
943       g_object_unref (obj);
944       g_object_unref (settings);
945     }
946   g_test_trap_assert_failed ();
947   g_test_trap_assert_stderr ("*not compatible*");
948 }
949
950 static gboolean
951 string_to_bool (GValue   *value,
952                 GVariant *variant,
953                 gpointer  user_data)
954 {
955   const gchar *s;
956
957   s = g_variant_get_string (variant, NULL);
958   g_value_set_boolean (value, g_strcmp0 (s, "true") == 0);
959
960   return TRUE;
961 }
962
963 static GVariant *
964 bool_to_string (const GValue       *value,
965                 const GVariantType *expected_type,
966                 gpointer            user_data)
967 {
968   if (g_value_get_boolean (value))
969     return g_variant_new_string ("true");
970   else
971     return g_variant_new_string ("false");
972 }
973
974 /* Test custom bindings.
975  * Translate strings to booleans and back
976  */
977 static void
978 test_custom_binding (void)
979 {
980   TestObject *obj;
981   GSettings *settings;
982   gchar *s;
983   gboolean b;
984
985   settings = g_settings_new ("org.gtk.test.binding");
986   obj = test_object_new ();
987
988   g_settings_set_string (settings, "string", "true");
989
990   g_settings_bind_with_mapping (settings, "string",
991                                 obj, "bool",
992                                 G_SETTINGS_BIND_DEFAULT,
993                                 string_to_bool,
994                                 bool_to_string,
995                                 NULL, NULL);
996
997   g_settings_set_string (settings, "string", "false");
998   g_object_get (obj, "bool", &b, NULL);
999   g_assert_cmpint (b, ==, FALSE);
1000
1001   g_settings_set_string (settings, "string", "not true");
1002   g_object_get (obj, "bool", &b, NULL);
1003   g_assert_cmpint (b, ==, FALSE);
1004
1005   g_object_set (obj, "bool", TRUE, NULL);
1006   s = g_settings_get_string (settings, "string");
1007   g_assert_cmpstr (s, ==, "true");
1008
1009   g_object_unref (obj);
1010   g_object_unref (settings);
1011 }
1012
1013 /* Test that with G_SETTINGS_BIND_NO_CHANGES, the
1014  * initial settings value is transported to the object
1015  * side, but later settings changes do not affect the
1016  * object
1017  */
1018 static void
1019 test_no_change_binding (void)
1020 {
1021   TestObject *obj;
1022   GSettings *settings;
1023   gboolean b;
1024
1025   settings = g_settings_new ("org.gtk.test.binding");
1026   obj = test_object_new ();
1027
1028   g_object_set (obj, "bool", TRUE, NULL);
1029   g_settings_set_boolean (settings, "bool", FALSE);
1030
1031   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET_NO_CHANGES);
1032
1033   g_object_get (obj, "bool", &b, NULL);
1034   g_assert_cmpint (b, ==, FALSE);
1035
1036   g_settings_set_boolean (settings, "bool", TRUE);
1037   g_object_get (obj, "bool", &b, NULL);
1038   g_assert_cmpint (b, ==, FALSE);
1039
1040   g_settings_set_boolean (settings, "bool", FALSE);
1041   g_object_set (obj, "bool", TRUE, NULL);
1042   b = g_settings_get_boolean (settings, "bool");
1043   g_assert_cmpint (b, ==, TRUE);
1044
1045   g_object_unref (obj);
1046   g_object_unref (settings);
1047 }
1048
1049 /* Test that binding a non-readable property only
1050  * works in 'GET' mode.
1051  */
1052 static void
1053 test_no_read_binding (void)
1054 {
1055   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1056     {
1057       TestObject *obj;
1058       GSettings *settings;
1059
1060       settings = g_settings_new ("org.gtk.test.binding");
1061       obj = test_object_new ();
1062
1063       g_settings_bind (settings, "string", obj, "no-read", 0);
1064     }
1065   g_test_trap_assert_failed ();
1066   g_test_trap_assert_stderr ("*property*is not readable*");
1067
1068   if (g_test_trap_fork (0, 0))
1069     {
1070       TestObject *obj;
1071       GSettings *settings;
1072
1073       settings = g_settings_new ("org.gtk.test.binding");
1074       obj = test_object_new ();
1075
1076       g_settings_bind (settings, "string", obj, "no-read", G_SETTINGS_BIND_GET);
1077
1078       exit (0);
1079     }
1080   g_test_trap_assert_passed ();
1081 }
1082
1083 /* Test that binding a non-writable property only
1084  * works in 'SET' mode.
1085  */
1086 static void
1087 test_no_write_binding (void)
1088 {
1089   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1090     {
1091       TestObject *obj;
1092       GSettings *settings;
1093
1094       settings = g_settings_new ("org.gtk.test.binding");
1095       obj = test_object_new ();
1096
1097       g_settings_bind (settings, "string", obj, "no-write", 0);
1098     }
1099   g_test_trap_assert_failed ();
1100   g_test_trap_assert_stderr ("*property*is not writable*");
1101
1102   if (g_test_trap_fork (0, 0))
1103     {
1104       TestObject *obj;
1105       GSettings *settings;
1106
1107       settings = g_settings_new ("org.gtk.test.binding");
1108       obj = test_object_new ();
1109
1110       g_settings_bind (settings, "string", obj, "no-write", G_SETTINGS_BIND_SET);
1111
1112       exit (0);
1113     }
1114   g_test_trap_assert_passed ();
1115 }
1116
1117 /*
1118  * Test that using a keyfile works
1119  */
1120 static void
1121 test_keyfile (void)
1122 {
1123   GSettings *settings;
1124   GKeyFile *keyfile;
1125   gchar *str;
1126
1127   g_remove ("gsettings.store");
1128
1129   g_settings_backend_setup_keyfile ("blah", "gsettings.store");
1130
1131   settings = g_settings_new_with_context ("org.gtk.test", "blah");
1132
1133   g_settings_set (settings, "greeting", "s", "see if this works");
1134
1135   keyfile = g_key_file_new ();
1136   g_assert (g_key_file_load_from_file (keyfile, "gsettings.store", 0, NULL));
1137
1138   str = g_key_file_get_string (keyfile, "/tests/", "greeting", NULL);
1139   g_assert_cmpstr (str, ==, "'see if this works'");
1140
1141   g_free (str);
1142   g_key_file_free (keyfile);
1143   g_object_unref (settings);
1144 }
1145
1146 /* Test that getting child schemas works
1147  */
1148 static void
1149 test_child_schema (void)
1150 {
1151   GSettings *settings;
1152   GSettings *child;
1153   guint8 byte;
1154
1155   /* first establish some known conditions */
1156   settings = g_settings_new ("org.gtk.test.basic-types");
1157   g_settings_set (settings, "test-byte", "y", 36);
1158
1159   g_settings_get (settings, "test-byte", "y", &byte);
1160   g_assert_cmpint (byte, ==, 36);
1161
1162   g_object_unref (settings);
1163
1164   settings = g_settings_new ("org.gtk.test");
1165   child = g_settings_get_child (settings, "basic-types");
1166   g_assert (child != NULL);
1167
1168   g_settings_get (child, "test-byte", "y", &byte);
1169   g_assert_cmpint (byte, ==, 36);
1170
1171   g_object_unref (child);
1172   g_object_unref (settings);
1173 }
1174
1175 static gboolean
1176 glib_translations_work (void)
1177 {
1178   gchar *locale;
1179   gchar *orig = "Unnamed";
1180   gchar *str;
1181
1182   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
1183   setlocale (LC_MESSAGES, "de");
1184   str = dgettext ("glib20", orig);
1185   setlocale (LC_MESSAGES, locale);
1186   g_free (locale);
1187
1188   return str != orig;
1189 }
1190
1191 #include "../strinfo.c"
1192
1193 static void
1194 test_strinfo (void)
1195 {
1196   /*  "foo" has a value of 1
1197    *  "bar" has a value of 2
1198    *  "baz" is an alias for "bar"
1199    */
1200   gchar array[] =
1201     "\1\0\0\0"      "\xff""foo"     "\0\0\0\xff"    "\2\0\0\0"
1202     "\xff" "bar"    "\0\0\0\xff"    "\3\0\0\0"      "\xfe""baz"
1203     "\0\0\0\xff";
1204   const guint32 *strinfo = (guint32 *) array;
1205   guint length = sizeof array / 4;
1206   guint result;
1207
1208   {
1209     /* build it and compare */
1210     GString *builder;
1211
1212     builder = g_string_new (NULL);
1213     strinfo_builder_append_item (builder, "foo", 1);
1214     strinfo_builder_append_item (builder, "bar", 2);
1215     g_assert (strinfo_builder_append_alias (builder, "baz", "bar"));
1216     g_assert_cmpint (builder->len % 4, ==, 0);
1217     g_assert_cmpint (builder->len / 4, ==, length);
1218     g_assert (memcmp (builder->str, strinfo, length * 4) == 0);
1219     g_string_free (builder, TRUE);
1220   }
1221
1222   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "foo"),
1223                    ==, NULL);
1224   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "bar"),
1225                    ==, NULL);
1226   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "baz"),
1227                    ==, "bar");
1228   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "quux"),
1229                    ==, NULL);
1230
1231   g_assert (strinfo_enum_from_string (strinfo, length, "foo", &result));
1232   g_assert_cmpint (result, ==, 1);
1233   g_assert (strinfo_enum_from_string (strinfo, length, "bar", &result));
1234   g_assert_cmpint (result, ==, 2);
1235   g_assert (!strinfo_enum_from_string (strinfo, length, "baz", &result));
1236   g_assert (!strinfo_enum_from_string (strinfo, length, "quux", &result));
1237
1238   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 0), ==, NULL);
1239   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 1), ==, "foo");
1240   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 2), ==, "bar");
1241   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 3), ==, NULL);
1242
1243   g_assert (strinfo_is_string_valid (strinfo, length, "foo"));
1244   g_assert (strinfo_is_string_valid (strinfo, length, "bar"));
1245   g_assert (!strinfo_is_string_valid (strinfo, length, "baz"));
1246   g_assert (!strinfo_is_string_valid (strinfo, length, "quux"));
1247 }
1248
1249 static void
1250 test_enums (void)
1251 {
1252   GSettings *settings, *direct;
1253
1254   settings = g_settings_new ("org.gtk.test.enums");
1255   direct = g_settings_new ("org.gtk.test.enums.direct");
1256
1257   if (!backend_set)
1258     {
1259       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1260         g_settings_get_enum (direct, "test");
1261       g_test_trap_assert_failed ();
1262       g_test_trap_assert_stderr ("*not associated with an enum*");
1263
1264       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1265         g_settings_set_enum (settings, "test", 42);
1266       g_test_trap_assert_failed ();
1267       g_test_trap_assert_stderr ("*invalid enum value 42*");
1268
1269       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1270         g_settings_set_string (settings, "test", "qux");
1271       g_test_trap_assert_failed ();
1272       g_test_trap_assert_stderr ("*g_settings_range_check*");
1273     }
1274
1275   g_assert_cmpstr (g_settings_get_string (settings, "test"), ==, "bar");
1276   g_settings_set_enum (settings, "test", TEST_ENUM_FOO);
1277   g_assert_cmpstr (g_settings_get_string (settings, "test"), ==, "foo");
1278   g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_FOO);
1279   g_settings_set_string (direct, "test", "qux");
1280   g_assert_cmpstr (g_settings_get_string (direct, "test"), ==, "qux");
1281   g_assert_cmpstr (g_settings_get_string (settings, "test"), ==, "quux");
1282   g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_QUUX);
1283 }
1284
1285 static void
1286 test_range (void)
1287 {
1288   GSettings *settings, *direct;
1289
1290   settings = g_settings_new ("org.gtk.test.range");
1291   direct = g_settings_new ("org.gtk.test.range.direct");
1292
1293   if (!backend_set)
1294     {
1295       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1296         g_settings_set_int (settings, "val", 45);
1297       g_test_trap_assert_failed ();
1298       g_test_trap_assert_stderr ("*g_settings_range_check*");
1299
1300       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1301         g_settings_set_int (settings, "val", 1);
1302       g_test_trap_assert_failed ();
1303       g_test_trap_assert_stderr ("*g_settings_range_check*");
1304     }
1305
1306   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1307   g_settings_set_int (direct, "val", 22);
1308   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 22);
1309   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 22);
1310   g_settings_set_int (direct, "val", 45);
1311   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 45);
1312   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1313   g_settings_set_int (direct, "val", 1);
1314   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 1);
1315   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1316 }
1317
1318 int
1319 main (int argc, char *argv[])
1320 {
1321   gchar *enums;
1322   gint result;
1323
1324   setlocale (LC_ALL, "");
1325
1326   backend_set = g_getenv ("GSETTINGS_BACKEND") != NULL;
1327
1328   g_setenv ("GSETTINGS_SCHEMA_DIR", ".", TRUE);
1329
1330   if (!backend_set)
1331     g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
1332
1333   g_type_init ();
1334   g_test_init (&argc, &argv, NULL);
1335
1336   g_remove ("org.gtk.test.enums.xml");
1337   g_assert (g_spawn_command_line_sync ("../../gobject/glib-mkenums "
1338                                        "--template enums.xml.template "
1339                                        SRCDIR "/testenum.h",
1340                                        &enums, NULL, &result, NULL));
1341   g_assert (result == 0);
1342   g_assert (g_file_set_contents ("org.gtk.test.enums.xml", enums, -1, NULL));
1343
1344   g_remove ("gschemas.compiled");
1345   g_assert (g_spawn_command_line_sync ("../glib-compile-schemas --targetdir=. " SRCDIR,
1346                                        NULL, NULL, &result, NULL));
1347   g_assert (result == 0);
1348
1349   g_test_add_func ("/gsettings/basic", test_basic);
1350
1351   if (!backend_set)
1352     {
1353       g_test_add_func ("/gsettings/no-schema", test_no_schema);
1354       g_test_add_func ("/gsettings/unknown-key", test_unknown_key);
1355       g_test_add_func ("/gsettings/wrong-type", test_wrong_type);
1356     }
1357
1358   g_test_add_func ("/gsettings/basic-types", test_basic_types);
1359   g_test_add_func ("/gsettings/complex-types", test_complex_types);
1360   g_test_add_func ("/gsettings/changes", test_changes);
1361
1362   if (glib_translations_work ())
1363     {
1364       g_test_add_func ("/gsettings/l10n", test_l10n);
1365       g_test_add_func ("/gsettings/l10n-context", test_l10n_context);
1366     }
1367
1368   g_test_add_func ("/gsettings/delay-apply", test_delay_apply);
1369   g_test_add_func ("/gsettings/delay-revert", test_delay_revert);
1370   g_test_add_func ("/gsettings/atomic", test_atomic);
1371   g_test_add_func ("/gsettings/simple-binding", test_simple_binding);
1372   g_test_add_func ("/gsettings/directional-binding", test_directional_binding);
1373   g_test_add_func ("/gsettings/custom-binding", test_custom_binding);
1374   g_test_add_func ("/gsettings/no-change-binding", test_no_change_binding);
1375
1376   if (!backend_set)
1377     {
1378       g_test_add_func ("/gsettings/typesafe-binding", test_typesafe_binding);
1379       g_test_add_func ("/gsettings/no-read-binding", test_no_read_binding);
1380       g_test_add_func ("/gsettings/no-write-binding", test_no_write_binding);
1381     }
1382
1383   g_test_add_func ("/gsettings/keyfile", test_keyfile);
1384   g_test_add_func ("/gsettings/child-schema", test_child_schema);
1385   g_test_add_func ("/gsettings/strinfo", test_strinfo);
1386   g_test_add_func ("/gsettings/enums", test_enums);
1387   g_test_add_func ("/gsettings/range", test_range);
1388
1389   result = g_test_run ();
1390
1391   g_settings_sync (NULL);
1392
1393   return result;
1394 }