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