schema source: avoid introspection confusion
[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 static void
18 check_and_free (GVariant    *value,
19                 const gchar *expected)
20 {
21   gchar *printed;
22
23   printed = g_variant_print (value, TRUE);
24   g_assert_cmpstr (printed, ==, expected);
25   g_free (printed);
26
27   g_variant_unref (value);
28 }
29
30
31 /* Just to get warmed up: Read and set a string, and
32  * verify that can read the changed string back
33  */
34 static void
35 test_basic (void)
36 {
37   gchar *str = NULL;
38   GSettings *settings;
39
40   settings = g_settings_new ("org.gtk.test");
41
42   g_object_get (settings, "schema", &str, NULL);
43   g_assert_cmpstr (str, ==, "org.gtk.test");
44   g_free (str);
45
46   g_settings_get (settings, "greeting", "s", &str);
47   g_assert_cmpstr (str, ==, "Hello, earthlings");
48   g_free (str);
49
50   g_settings_set (settings, "greeting", "s", "goodbye world");
51   g_settings_get (settings, "greeting", "s", &str);
52   g_assert_cmpstr (str, ==, "goodbye world");
53   g_free (str);
54   str = NULL;
55
56   if (!backend_set)
57     {
58       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
59         {
60           settings = g_settings_new ("org.gtk.test");
61           g_settings_set (settings, "greeting", "i", 555);
62           abort ();
63         }
64       g_test_trap_assert_failed ();
65       g_test_trap_assert_stderr ("*g_settings_set_value*expects type*");
66     }
67
68   g_settings_get (settings, "greeting", "s", &str);
69   g_assert_cmpstr (str, ==, "goodbye world");
70   g_free (str);
71   str = NULL;
72
73   g_settings_reset (settings, "greeting");
74   str = g_settings_get_string (settings, "greeting");
75   g_assert_cmpstr (str, ==, "Hello, earthlings");
76   g_free (str);
77
78   g_settings_set (settings, "greeting", "s", "this is the end");
79   g_object_unref (settings);
80 }
81
82 /* Check that we get an error when getting a key
83  * that is not in the schema
84  */
85 static void
86 test_unknown_key (void)
87 {
88   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
89     {
90       GSettings *settings;
91       GVariant *value;
92
93       settings = g_settings_new ("org.gtk.test");
94       value = g_settings_get_value (settings, "no_such_key");
95
96       g_assert (value == NULL);
97
98       g_object_unref (settings);
99     }
100   g_test_trap_assert_failed ();
101   g_test_trap_assert_stderr ("*does not contain*");
102 }
103
104 /* Check that we get an error when the schema
105  * has not been installed
106  */
107 static void
108 test_no_schema (void)
109 {
110   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
111     {
112       GSettings *settings;
113
114       settings = g_settings_new ("no.such.schema");
115
116       g_assert (settings == NULL);
117     }
118
119   g_test_trap_assert_failed ();
120   g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*");
121 }
122
123 /* Check that we get an error when passing a type string
124  * that does not match the schema
125  */
126 static void
127 test_wrong_type (void)
128 {
129   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
130     {
131       GSettings *settings;
132       gchar *str = NULL;
133
134       settings = g_settings_new ("org.gtk.test");
135
136       g_settings_get (settings, "greeting", "o", &str);
137
138       g_assert (str == NULL);
139     }
140   g_test_trap_assert_failed ();
141   g_test_trap_assert_stderr ("*CRITICAL*");
142
143   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
144     {
145       GSettings *settings;
146
147       settings = g_settings_new ("org.gtk.test");
148
149       g_settings_set (settings, "greeting", "o", "/a/path");
150     }
151   g_test_trap_assert_failed ();
152   g_test_trap_assert_stderr ("*CRITICAL*");
153 }
154
155 /* Check errors with explicit paths */
156 static void
157 test_wrong_path (void)
158 {
159   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
160     {
161       GSettings *settings G_GNUC_UNUSED;
162
163       settings = g_settings_new_with_path ("org.gtk.test", "/wrong-path/");
164     }
165
166   g_test_trap_assert_failed ();
167   g_test_trap_assert_stderr ("*but path * specified by schema*");
168 }
169
170 static void
171 test_no_path (void)
172 {
173   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
174     {
175       GSettings *settings G_GNUC_UNUSED;
176
177       settings = g_settings_new ("org.gtk.test.no-path");
178     }
179
180   g_test_trap_assert_failed ();
181   g_test_trap_assert_stderr ("*attempting to create schema * without a path**");
182 }
183
184
185 /* Check that we can successfully read and set the full
186  * range of all basic types
187  */
188 static void
189 test_basic_types (void)
190 {
191   GSettings *settings;
192   gboolean b;
193   guint8 byte;
194   gint16 i16;
195   guint16 u16;
196   gint32 i32;
197   guint32 u32;
198   gint64 i64;
199   guint64 u64;
200   gdouble d;
201   gchar *str;
202
203   settings = g_settings_new ("org.gtk.test.basic-types");
204
205   g_settings_get (settings, "test-boolean", "b", &b);
206   g_assert_cmpint (b, ==, 1);
207
208   g_settings_set (settings, "test-boolean", "b", 0);
209   g_settings_get (settings, "test-boolean", "b", &b);
210   g_assert_cmpint (b, ==, 0);
211
212   g_settings_get (settings, "test-byte", "y", &byte);
213   g_assert_cmpint (byte, ==, 25);
214
215   g_settings_set (settings, "test-byte", "y", G_MAXUINT8);
216   g_settings_get (settings, "test-byte", "y", &byte);
217   g_assert_cmpint (byte, ==, G_MAXUINT8);
218
219   g_settings_get (settings, "test-int16", "n", &i16);
220   g_assert_cmpint (i16, ==, -1234);
221
222   g_settings_set (settings, "test-int16", "n", G_MININT16);
223   g_settings_get (settings, "test-int16", "n", &i16);
224   g_assert_cmpint (i16, ==, G_MININT16);
225
226   g_settings_set (settings, "test-int16", "n", G_MAXINT16);
227   g_settings_get (settings, "test-int16", "n", &i16);
228   g_assert_cmpint (i16, ==, G_MAXINT16);
229
230   g_settings_get (settings, "test-uint16", "q", &u16);
231   g_assert_cmpuint (u16, ==, 1234);
232
233   g_settings_set (settings, "test-uint16", "q", G_MAXUINT16);
234   g_settings_get (settings, "test-uint16", "q", &u16);
235   g_assert_cmpuint (u16, ==, G_MAXUINT16);
236
237   g_settings_get (settings, "test-int32", "i", &i32);
238   g_assert_cmpint (i32, ==, -123456);
239
240   g_settings_set (settings, "test-int32", "i", G_MININT32);
241   g_settings_get (settings, "test-int32", "i", &i32);
242   g_assert_cmpint (i32, ==, G_MININT32);
243
244   g_settings_set (settings, "test-int32", "i", G_MAXINT32);
245   g_settings_get (settings, "test-int32", "i", &i32);
246   g_assert_cmpint (i32, ==, G_MAXINT32);
247
248   g_settings_get (settings, "test-uint32", "u", &u32);
249   g_assert_cmpuint (u32, ==, 123456);
250
251   g_settings_set (settings, "test-uint32", "u", G_MAXUINT32);
252   g_settings_get (settings, "test-uint32", "u", &u32);
253   g_assert_cmpuint (u32, ==, G_MAXUINT32);
254
255   g_settings_get (settings, "test-int64", "x", &i64);
256   g_assert_cmpuint (i64, ==, -123456789);
257
258   g_settings_set (settings, "test-int64", "x", G_MININT64);
259   g_settings_get (settings, "test-int64", "x", &i64);
260   g_assert_cmpuint (i64, ==, G_MININT64);
261
262   g_settings_set (settings, "test-int64", "x", G_MAXINT64);
263   g_settings_get (settings, "test-int64", "x", &i64);
264   g_assert_cmpuint (i64, ==, G_MAXINT64);
265
266   g_settings_get (settings, "test-uint64", "t", &u64);
267   g_assert_cmpuint (u64, ==, 123456789);
268
269   g_settings_set (settings, "test-uint64", "t", G_MAXUINT64);
270   g_settings_get (settings, "test-uint64", "t", &u64);
271   g_assert_cmpuint (u64, ==, G_MAXUINT64);
272
273   g_settings_get (settings, "test-double", "d", &d);
274   g_assert_cmpfloat (d, ==, 123.456);
275
276   g_settings_set (settings, "test-double", "d", G_MINDOUBLE);
277   g_settings_get (settings, "test-double", "d", &d);
278   g_assert_cmpfloat (d, ==, G_MINDOUBLE);
279
280   g_settings_set (settings, "test-double", "d", G_MAXDOUBLE);
281   g_settings_get (settings, "test-double", "d", &d);
282   g_assert_cmpfloat (d, ==, G_MAXDOUBLE);
283
284   g_settings_get (settings, "test-string", "s", &str);
285   g_assert_cmpstr (str, ==, "a string, it seems");
286   g_free (str);
287   str = NULL;
288
289   g_settings_get (settings, "test-objectpath", "o", &str);
290   g_assert_cmpstr (str, ==, "/a/object/path");
291   g_object_unref (settings);
292   g_free (str);
293   str = NULL;
294 }
295
296 /* Check that we can read an set complex types like
297  * tuples, arrays and dictionaries
298  */
299 static void
300 test_complex_types (void)
301 {
302   GSettings *settings;
303   gchar *s;
304   gint i1, i2;
305   GVariantIter *iter = NULL;
306
307   settings = g_settings_new ("org.gtk.test.complex-types");
308
309   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
310   g_assert_cmpstr (s, ==, "one");
311   g_assert_cmpint (i1,==, 2);
312   g_assert_cmpint (i2,==, 3);
313   g_free (s) ;
314   s = NULL;
315
316   g_settings_set (settings, "test-tuple", "(s(ii))", "none", 0, 0);
317   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
318   g_assert_cmpstr (s, ==, "none");
319   g_assert_cmpint (i1,==, 0);
320   g_assert_cmpint (i2,==, 0);
321   g_free (s);
322   s = NULL;
323
324   g_settings_get (settings, "test-array", "ai", &iter);
325   g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6);
326   g_assert (g_variant_iter_next (iter, "i", &i1));
327   g_assert_cmpint (i1, ==, 0);
328   g_assert (g_variant_iter_next (iter, "i", &i1));
329   g_assert_cmpint (i1, ==, 1);
330   g_assert (g_variant_iter_next (iter, "i", &i1));
331   g_assert_cmpint (i1, ==, 2);
332   g_assert (g_variant_iter_next (iter, "i", &i1));
333   g_assert_cmpint (i1, ==, 3);
334   g_assert (g_variant_iter_next (iter, "i", &i1));
335   g_assert_cmpint (i1, ==, 4);
336   g_assert (g_variant_iter_next (iter, "i", &i1));
337   g_assert_cmpint (i1, ==, 5);
338   g_assert (!g_variant_iter_next (iter, "i", &i1));
339   g_variant_iter_free (iter);
340
341   g_object_unref (settings);
342 }
343
344 static gboolean changed_cb_called;
345
346 static void
347 changed_cb (GSettings   *settings,
348             const gchar *key,
349             gpointer     data)
350 {
351   changed_cb_called = TRUE;
352
353   g_assert_cmpstr (key, ==, data);
354 }
355
356 /* Test that basic change notification with the changed signal works.
357  */
358 static void
359 test_changes (void)
360 {
361   GSettings *settings;
362   GSettings *settings2;
363
364   settings = g_settings_new ("org.gtk.test");
365
366   g_signal_connect (settings, "changed",
367                     G_CALLBACK (changed_cb), "greeting");
368
369   changed_cb_called = FALSE;
370
371   g_settings_set (settings, "greeting", "s", "new greeting");
372   g_assert (changed_cb_called);
373
374   settings2 = g_settings_new ("org.gtk.test");
375
376   changed_cb_called = FALSE;
377
378   g_settings_set (settings2, "greeting", "s", "hi");
379   g_assert (changed_cb_called);
380
381   g_object_unref (settings2);
382   g_object_unref (settings);
383 }
384
385 static gboolean changed_cb_called2;
386
387 static void
388 changed_cb2 (GSettings   *settings,
389              const gchar *key,
390              gpointer     data)
391 {
392   gboolean *p = data;
393
394   *p = TRUE;
395 }
396
397 /* Test that changes done to a delay-mode instance
398  * don't appear to the outside world until apply. Also
399  * check that we get change notification when they are
400  * applied.
401  * Also test that the has-unapplied property is properly
402  * maintained.
403  */
404 static void
405 test_delay_apply (void)
406 {
407   GSettings *settings;
408   GSettings *settings2;
409   gchar *str;
410
411   settings = g_settings_new ("org.gtk.test");
412   settings2 = g_settings_new ("org.gtk.test");
413
414   g_settings_set (settings2, "greeting", "s", "top o' the morning");
415
416   changed_cb_called = FALSE;
417   changed_cb_called2 = FALSE;
418
419   g_signal_connect (settings, "changed",
420                     G_CALLBACK (changed_cb2), &changed_cb_called);
421   g_signal_connect (settings2, "changed",
422                     G_CALLBACK (changed_cb2), &changed_cb_called2);
423
424   g_settings_delay (settings);
425
426   g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply");
427
428   g_assert (changed_cb_called);
429   g_assert (!changed_cb_called2);
430
431   g_settings_get (settings, "greeting", "s", &str);
432   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
433   g_free (str);
434   str = NULL;
435
436   g_settings_get (settings2, "greeting", "s", &str);
437   g_assert_cmpstr (str, ==, "top o' the morning");
438   g_free (str);
439   str = NULL;
440
441   g_assert (g_settings_get_has_unapplied (settings));
442   g_assert (!g_settings_get_has_unapplied (settings2));
443
444   changed_cb_called = FALSE;
445   changed_cb_called2 = FALSE;
446
447   g_settings_apply (settings);
448
449   g_assert (!changed_cb_called);
450   g_assert (changed_cb_called2);
451
452   g_settings_get (settings, "greeting", "s", &str);
453   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
454   g_free (str);
455   str = NULL;
456
457   g_settings_get (settings2, "greeting", "s", &str);
458   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
459   g_free (str);
460   str = NULL;
461
462   g_assert (!g_settings_get_has_unapplied (settings));
463   g_assert (!g_settings_get_has_unapplied (settings2));
464
465   g_object_unref (settings2);
466   g_object_unref (settings);
467 }
468
469 /* Test that reverting unapplied changes in a delay-apply
470  * settings instance works.
471  */
472 static void
473 test_delay_revert (void)
474 {
475   GSettings *settings;
476   GSettings *settings2;
477   gchar *str;
478
479   settings = g_settings_new ("org.gtk.test");
480   settings2 = g_settings_new ("org.gtk.test");
481
482   g_settings_set (settings2, "greeting", "s", "top o' the morning");
483
484   g_settings_delay (settings);
485
486   g_settings_set (settings, "greeting", "s", "greetings from test_delay_revert");
487
488   g_settings_get (settings, "greeting", "s", &str);
489   g_assert_cmpstr (str, ==, "greetings from test_delay_revert");
490   g_free (str);
491   str = NULL;
492
493   g_settings_get (settings2, "greeting", "s", &str);
494   g_assert_cmpstr (str, ==, "top o' the morning");
495   g_free (str);
496   str = NULL;
497
498   g_assert (g_settings_get_has_unapplied (settings));
499
500   g_settings_revert (settings);
501
502   g_assert (!g_settings_get_has_unapplied (settings));
503
504   g_settings_get (settings, "greeting", "s", &str);
505   g_assert_cmpstr (str, ==, "top o' the morning");
506   g_free (str);
507   str = NULL;
508
509   g_settings_get (settings2, "greeting", "s", &str);
510   g_assert_cmpstr (str, ==, "top o' the morning");
511   g_free (str);
512   str = NULL;
513
514   g_object_unref (settings2);
515   g_object_unref (settings);
516 }
517
518 static void
519 keys_changed_cb (GSettings    *settings,
520                  const GQuark *keys,
521                  gint          n_keys)
522 {
523   gchar *str;
524
525   g_assert_cmpint (n_keys, ==, 2);
526
527   g_assert ((keys[0] == g_quark_from_static_string ("greeting") &&
528              keys[1] == g_quark_from_static_string ("farewell")) ||
529             (keys[1] == g_quark_from_static_string ("greeting") &&
530              keys[0] == g_quark_from_static_string ("farewell")));
531
532   g_settings_get (settings, "greeting", "s", &str);
533   g_assert_cmpstr (str, ==, "greetings from test_atomic");
534   g_free (str);
535   str = NULL;
536
537   g_settings_get (settings, "farewell", "s", &str);
538   g_assert_cmpstr (str, ==, "atomic bye-bye");
539   g_free (str);
540   str = NULL;
541 }
542
543 /* Check that delay-applied changes appear atomically.
544  * More specifically, verify that all changed keys appear
545  * with their new value while handling the change-event signal.
546  */
547 static void
548 test_atomic (void)
549 {
550   GSettings *settings;
551   GSettings *settings2;
552   gchar *str;
553
554   settings = g_settings_new ("org.gtk.test");
555   settings2 = g_settings_new ("org.gtk.test");
556
557   g_settings_set (settings2, "greeting", "s", "top o' the morning");
558
559   changed_cb_called = FALSE;
560   changed_cb_called2 = FALSE;
561
562   g_signal_connect (settings2, "change-event",
563                     G_CALLBACK (keys_changed_cb), NULL);
564
565   g_settings_delay (settings);
566
567   g_settings_set (settings, "greeting", "s", "greetings from test_atomic");
568   g_settings_set (settings, "farewell", "s", "atomic bye-bye");
569
570   g_settings_apply (settings);
571
572   g_settings_get (settings, "greeting", "s", &str);
573   g_assert_cmpstr (str, ==, "greetings from test_atomic");
574   g_free (str);
575   str = NULL;
576
577   g_settings_get (settings, "farewell", "s", &str);
578   g_assert_cmpstr (str, ==, "atomic bye-bye");
579   g_free (str);
580   str = NULL;
581
582   g_settings_get (settings2, "greeting", "s", &str);
583   g_assert_cmpstr (str, ==, "greetings from test_atomic");
584   g_free (str);
585   str = NULL;
586
587   g_settings_get (settings2, "farewell", "s", &str);
588   g_assert_cmpstr (str, ==, "atomic bye-bye");
589   g_free (str);
590   str = NULL;
591
592   g_object_unref (settings2);
593   g_object_unref (settings);
594 }
595
596 /* On Windows the interaction between the C library locale and libintl
597  * (from GNU gettext) is not like on POSIX, so just skip these tests
598  * for now.
599  *
600  * There are several issues:
601  *
602  * 1) The C library doesn't use LC_MESSAGES, that is implemented only
603  * in libintl (defined in its <libintl.h>).
604  *
605  * 2) The locale names that setlocale() accepts and returns aren't in
606  * the "de_DE" style, but like "German_Germany".
607  *
608  * 3) libintl looks at the Win32 thread locale and not the C library
609  * locale. (And even if libintl would use the C library's locale, as
610  * there are several alternative C library DLLs, libintl might be
611  * linked to a different one than the application code, so they
612  * wouldn't have the same C library locale anyway.)
613  */
614
615 /* Test that translations work for schema defaults.
616  *
617  * This test relies on the de.po file in the same directory
618  * to be compiled into ./de/LC_MESSAGES/test.mo
619  */
620 static void
621 test_l10n (void)
622 {
623   GSettings *settings;
624   gchar *str;
625   gchar *locale;
626
627   bindtextdomain ("test", ".");
628   bind_textdomain_codeset ("test", "UTF-8");
629
630   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
631
632   settings = g_settings_new ("org.gtk.test.localized");
633
634   setlocale (LC_MESSAGES, "C");
635   str = g_settings_get_string (settings, "error-message");
636   setlocale (LC_MESSAGES, locale);
637
638   g_assert_cmpstr (str, ==, "Unnamed");
639   g_free (str);
640   str = NULL;
641
642   setlocale (LC_MESSAGES, "de_DE");
643   str = g_settings_get_string (settings, "error-message");
644   setlocale (LC_MESSAGES, locale);
645
646   g_assert_cmpstr (str, ==, "Unbenannt");
647   g_object_unref (settings);
648   g_free (str);
649   str = NULL;
650
651   g_free (locale);
652 }
653
654 /* Test that message context works as expected with translated
655  * schema defaults. Also, verify that non-ASCII UTF-8 content
656  * works.
657  *
658  * This test relies on the de.po file in the same directory
659  * to be compiled into ./de/LC_MESSAGES/test.mo
660  */
661 static void
662 test_l10n_context (void)
663 {
664   GSettings *settings;
665   gchar *str;
666   gchar *locale;
667
668   bindtextdomain ("test", ".");
669   bind_textdomain_codeset ("test", "UTF-8");
670
671   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
672
673   settings = g_settings_new ("org.gtk.test.localized");
674
675   setlocale (LC_MESSAGES, "C");
676   g_settings_get (settings, "backspace", "s", &str);
677   setlocale (LC_MESSAGES, locale);
678
679   g_assert_cmpstr (str, ==, "BackSpace");
680   g_free (str);
681   str = NULL;
682
683   setlocale (LC_MESSAGES, "de_DE");
684   g_settings_get (settings, "backspace", "s", &str);
685   setlocale (LC_MESSAGES, locale);
686
687   g_assert_cmpstr (str, ==, "Löschen");
688   g_object_unref (settings);
689   g_free (str);
690   str = NULL;
691
692   g_free (locale);
693 }
694
695 enum
696 {
697   PROP_0,
698   PROP_BOOL,
699   PROP_ANTI_BOOL,
700   PROP_BYTE,
701   PROP_INT16,
702   PROP_UINT16,
703   PROP_INT,
704   PROP_UINT,
705   PROP_INT64,
706   PROP_UINT64,
707   PROP_DOUBLE,
708   PROP_STRING,
709   PROP_NO_READ,
710   PROP_NO_WRITE,
711   PROP_STRV,
712   PROP_ENUM
713 };
714
715 typedef struct
716 {
717   GObject parent_instance;
718
719   gboolean bool_prop;
720   gboolean anti_bool_prop;
721   gint8 byte_prop;
722   gint int16_prop;
723   guint16 uint16_prop;
724   gint int_prop;
725   guint uint_prop;
726   gint64 int64_prop;
727   guint64 uint64_prop;
728   gdouble double_prop;
729   gchar *string_prop;
730   gchar *no_read_prop;
731   gchar *no_write_prop;
732   gchar **strv_prop;
733   guint enum_prop;
734 } TestObject;
735
736 typedef struct
737 {
738   GObjectClass parent_class;
739 } TestObjectClass;
740
741 static GType test_object_get_type (void);
742 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
743
744 static void
745 test_object_init (TestObject *object)
746 {
747 }
748
749 static void
750 test_object_finalize (GObject *object)
751 {
752   TestObject *testo = (TestObject*)object;
753   g_strfreev (testo->strv_prop);
754   g_free (testo->string_prop);
755   G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
756 }
757
758 static void
759 test_object_get_property (GObject    *object,
760                           guint       prop_id,
761                           GValue     *value,
762                           GParamSpec *pspec)
763 {
764   TestObject *test_object = (TestObject *)object;
765
766   switch (prop_id)
767     {
768     case PROP_BOOL:
769       g_value_set_boolean (value, test_object->bool_prop);
770       break;
771     case PROP_ANTI_BOOL:
772       g_value_set_boolean (value, test_object->anti_bool_prop);
773       break;
774     case PROP_BYTE:
775       g_value_set_schar (value, test_object->byte_prop);
776       break;
777     case PROP_UINT16:
778       g_value_set_uint (value, test_object->uint16_prop);
779       break;
780     case PROP_INT16:
781       g_value_set_int (value, test_object->int16_prop);
782       break;
783     case PROP_INT:
784       g_value_set_int (value, test_object->int_prop);
785       break;
786     case PROP_UINT:
787       g_value_set_uint (value, test_object->uint_prop);
788       break;
789     case PROP_INT64:
790       g_value_set_int64 (value, test_object->int64_prop);
791       break;
792     case PROP_UINT64:
793       g_value_set_uint64 (value, test_object->uint64_prop);
794       break;
795     case PROP_DOUBLE:
796       g_value_set_double (value, test_object->double_prop);
797       break;
798     case PROP_STRING:
799       g_value_set_string (value, test_object->string_prop);
800       break;
801     case PROP_NO_WRITE:
802       g_value_set_string (value, test_object->no_write_prop);
803       break;
804     case PROP_STRV:
805       g_value_set_boxed (value, test_object->strv_prop);
806       break;
807     case PROP_ENUM:
808       g_value_set_enum (value, test_object->enum_prop);
809       break;
810     default:
811       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
812       break;
813     }
814 }
815
816 static void
817 test_object_set_property (GObject      *object,
818                           guint         prop_id,
819                           const GValue *value,
820                           GParamSpec   *pspec)
821 {
822   TestObject *test_object = (TestObject *)object;
823
824   switch (prop_id)
825     {
826     case PROP_BOOL:
827       test_object->bool_prop = g_value_get_boolean (value);
828       break;
829     case PROP_ANTI_BOOL:
830       test_object->anti_bool_prop = g_value_get_boolean (value);
831       break;
832     case PROP_BYTE:
833       test_object->byte_prop = g_value_get_schar (value);
834       break;
835     case PROP_INT16:
836       test_object->int16_prop = g_value_get_int (value);
837       break;
838     case PROP_UINT16:
839       test_object->uint16_prop = g_value_get_uint (value);
840       break;
841     case PROP_INT:
842       test_object->int_prop = g_value_get_int (value);
843       break;
844     case PROP_UINT:
845       test_object->uint_prop = g_value_get_uint (value);
846       break;
847     case PROP_INT64:
848       test_object->int64_prop = g_value_get_int64 (value);
849       break;
850     case PROP_UINT64:
851       test_object->uint64_prop = g_value_get_uint64 (value);
852       break;
853     case PROP_DOUBLE:
854       test_object->double_prop = g_value_get_double (value);
855       break;
856     case PROP_STRING:
857       g_free (test_object->string_prop);
858       test_object->string_prop = g_value_dup_string (value);
859       break;
860     case PROP_NO_READ:
861       g_free (test_object->no_read_prop);
862       test_object->no_read_prop = g_value_dup_string (value);
863       break;
864     case PROP_STRV:
865       g_strfreev (test_object->strv_prop);
866       test_object->strv_prop = g_value_dup_boxed (value);
867       break;
868     case PROP_ENUM:
869       test_object->enum_prop = g_value_get_enum (value);
870       break;
871     default:
872       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
873       break;
874     }
875 }
876
877 static GType
878 test_enum_get_type (void)
879 {
880   static volatile gsize define_type_id = 0;
881
882   if (g_once_init_enter (&define_type_id))
883     {
884       static const GEnumValue values[] = {
885         { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
886         { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
887         { TEST_ENUM_BAZ, "TEST_ENUM_BAZ", "baz" },
888         { TEST_ENUM_QUUX, "TEST_ENUM_QUUX", "quux" },
889         { 0, NULL, NULL }
890       };
891
892       GType type_id = g_enum_register_static ("TestEnum", values);
893       g_once_init_leave (&define_type_id, type_id);
894     }
895
896   return define_type_id;
897 }
898
899 static void
900 test_object_class_init (TestObjectClass *class)
901 {
902   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
903
904   gobject_class->get_property = test_object_get_property;
905   gobject_class->set_property = test_object_set_property;
906   gobject_class->finalize = test_object_finalize;
907
908   g_object_class_install_property (gobject_class, PROP_BOOL,
909     g_param_spec_boolean ("bool", "", "", FALSE, G_PARAM_READWRITE));
910   g_object_class_install_property (gobject_class, PROP_ANTI_BOOL,
911     g_param_spec_boolean ("anti-bool", "", "", FALSE, G_PARAM_READWRITE));
912   g_object_class_install_property (gobject_class, PROP_BYTE,
913     g_param_spec_char ("byte", "", "", G_MININT8, G_MAXINT8, 0, G_PARAM_READWRITE));
914   g_object_class_install_property (gobject_class, PROP_INT16,
915     g_param_spec_int ("int16", "", "", -G_MAXINT16, G_MAXINT16, 0, G_PARAM_READWRITE));
916   g_object_class_install_property (gobject_class, PROP_UINT16,
917     g_param_spec_uint ("uint16", "", "", 0, G_MAXUINT16, 0, G_PARAM_READWRITE));
918   g_object_class_install_property (gobject_class, PROP_INT,
919     g_param_spec_int ("int", "", "", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
920   g_object_class_install_property (gobject_class, PROP_UINT,
921     g_param_spec_uint ("uint", "", "", 0, G_MAXUINT, 0, G_PARAM_READWRITE));
922   g_object_class_install_property (gobject_class, PROP_INT64,
923     g_param_spec_int64 ("int64", "", "", G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE));
924   g_object_class_install_property (gobject_class, PROP_UINT64,
925     g_param_spec_uint64 ("uint64", "", "", 0, G_MAXUINT64, 0, G_PARAM_READWRITE));
926   g_object_class_install_property (gobject_class, PROP_DOUBLE,
927     g_param_spec_double ("double", "", "", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE));
928   g_object_class_install_property (gobject_class, PROP_STRING,
929     g_param_spec_string ("string", "", "", NULL, G_PARAM_READWRITE));
930   g_object_class_install_property (gobject_class, PROP_NO_WRITE,
931     g_param_spec_string ("no-write", "", "", NULL, G_PARAM_READABLE));
932   g_object_class_install_property (gobject_class, PROP_NO_READ,
933     g_param_spec_string ("no-read", "", "", NULL, G_PARAM_WRITABLE));
934   g_object_class_install_property (gobject_class, PROP_STRV,
935     g_param_spec_boxed ("strv", "", "", G_TYPE_STRV, G_PARAM_READWRITE));
936   g_object_class_install_property (gobject_class, PROP_ENUM,
937     g_param_spec_enum ("enum", "", "", test_enum_get_type (), TEST_ENUM_FOO, G_PARAM_READWRITE));
938 }
939
940 static TestObject *
941 test_object_new (void)
942 {
943   return (TestObject*)g_object_new (test_object_get_type (), NULL);
944 }
945
946 /* Test basic binding functionality for simple types.
947  * Verify that with bidirectional bindings, changes on either side
948  * are notified on the other end.
949  */
950 static void
951 test_simple_binding (void)
952 {
953   TestObject *obj;
954   GSettings *settings;
955   gboolean b;
956   gchar y;
957   gint i;
958   gint16 n;
959   guint16 q;
960   gint n2;
961   guint q2;
962   gint64 i64;
963   guint64 u64;
964   gdouble d;
965   gchar *s;
966   GVariant *value;
967   gchar **strv;
968
969   settings = g_settings_new ("org.gtk.test.binding");
970   obj = test_object_new ();
971
972   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_DEFAULT);
973   g_object_set (obj, "bool", TRUE, NULL);
974   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
975
976   g_settings_set_boolean (settings, "bool", FALSE);
977   b = TRUE;
978   g_object_get (obj, "bool", &b, NULL);
979   g_assert_cmpint (b, ==, FALSE);
980
981   g_settings_bind (settings, "anti-bool", obj, "anti-bool",
982                    G_SETTINGS_BIND_INVERT_BOOLEAN);
983   g_object_set (obj, "anti-bool", FALSE, NULL);
984   g_assert_cmpint (g_settings_get_boolean (settings, "anti-bool"), ==, TRUE);
985
986   g_settings_set_boolean (settings, "anti-bool", FALSE);
987   b = FALSE;
988   g_object_get (obj, "anti-bool", &b, NULL);
989   g_assert_cmpint (b, ==, TRUE);
990
991   g_settings_bind (settings, "byte", obj, "byte", G_SETTINGS_BIND_DEFAULT);
992
993   g_object_set (obj, "byte", 123, NULL);
994   y = 'c';
995   g_settings_get (settings, "byte", "y", &y);
996   g_assert_cmpint (y, ==, 123);
997
998   g_settings_set (settings, "byte", "y", 54);
999   y = 'c';
1000   g_object_get (obj, "byte", &y, NULL);
1001   g_assert_cmpint (y, ==, 54);
1002
1003   g_settings_bind (settings, "int16", obj, "int16", G_SETTINGS_BIND_DEFAULT);
1004
1005   g_object_set (obj, "int16", 1234, NULL);
1006   n = 4321;
1007   g_settings_get (settings, "int16", "n", &n);
1008   g_assert_cmpint (n, ==, 1234);
1009
1010   g_settings_set (settings, "int16", "n", 4321);
1011   n2 = 1111;
1012   g_object_get (obj, "int16", &n2, NULL);
1013   g_assert_cmpint (n2, ==, 4321);
1014
1015   g_settings_bind (settings, "uint16", obj, "uint16", G_SETTINGS_BIND_DEFAULT);
1016
1017   g_object_set (obj, "uint16", (guint16) G_MAXUINT16, NULL);
1018   q = 1111;
1019   g_settings_get (settings, "uint16", "q", &q);
1020   g_assert_cmpuint (q, ==, G_MAXUINT16);
1021
1022   g_settings_set (settings, "uint16", "q", (guint16) G_MAXINT16);
1023   q2 = 1111;
1024   g_object_get (obj, "uint16", &q2, NULL);
1025   g_assert_cmpuint (q2, ==, (guint16) G_MAXINT16);
1026
1027   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT);
1028
1029   g_object_set (obj, "int", 12345, NULL);
1030   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345);
1031
1032   g_settings_set_int (settings, "int", 54321);
1033   i = 1111;
1034   g_object_get (obj, "int", &i, NULL);
1035   g_assert_cmpint (i, ==, 54321);
1036
1037   g_settings_bind (settings, "int64", obj, "int64", G_SETTINGS_BIND_DEFAULT);
1038
1039   g_object_set (obj, "int64", (gint64) G_MAXINT64, NULL);
1040   i64 = 1111;
1041   g_settings_get (settings, "int64", "x", &i64);
1042   g_assert_cmpint (i64, ==, G_MAXINT64);
1043
1044   g_settings_set (settings, "int64", "x", (gint64) G_MININT64);
1045   i64 = 1111;
1046   g_object_get (obj, "int64", &i64, NULL);
1047   g_assert_cmpint (i64, ==, G_MININT64);
1048
1049   g_settings_bind (settings, "uint64", obj, "uint64", G_SETTINGS_BIND_DEFAULT);
1050
1051   g_object_set (obj, "uint64", (guint64) G_MAXUINT64, NULL);
1052   u64 = 1111;
1053   g_settings_get (settings, "uint64", "t", &u64);
1054   g_assert_cmpuint (u64, ==, G_MAXUINT64);
1055
1056   g_settings_set (settings, "uint64", "t", (guint64) G_MAXINT64);
1057   u64 = 1111;
1058   g_object_get (obj, "uint64", &u64, NULL);
1059   g_assert_cmpuint (u64, ==, (guint64) G_MAXINT64);
1060
1061   g_settings_bind (settings, "string", obj, "string", G_SETTINGS_BIND_DEFAULT);
1062
1063   g_object_set (obj, "string", "bu ba", NULL);
1064   s = g_settings_get_string (settings, "string");
1065   g_assert_cmpstr (s, ==, "bu ba");
1066   g_free (s);
1067
1068   g_settings_set_string (settings, "string", "bla bla");
1069   g_object_get (obj, "string", &s, NULL);
1070   g_assert_cmpstr (s, ==, "bla bla");
1071   g_free (s);
1072
1073   g_settings_bind (settings, "chararray", obj, "string", G_SETTINGS_BIND_DEFAULT);
1074
1075   g_object_set (obj, "string", "non-unicode:\315", NULL);
1076   value = g_settings_get_value (settings, "chararray");
1077   g_assert_cmpstr (g_variant_get_bytestring (value), ==, "non-unicode:\315");
1078   g_variant_unref (value);
1079
1080   g_settings_bind (settings, "double", obj, "double", G_SETTINGS_BIND_DEFAULT);
1081
1082   g_object_set (obj, "double", G_MAXFLOAT, NULL);
1083   g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXFLOAT);
1084
1085   g_settings_set_double (settings, "double", G_MINFLOAT);
1086   d = 1.0;
1087   g_object_get (obj, "double", &d, NULL);
1088   g_assert_cmpfloat (d, ==, G_MINFLOAT);
1089
1090   g_object_set (obj, "double", G_MAXDOUBLE, NULL);
1091   g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, G_MAXDOUBLE);
1092
1093   g_settings_set_double (settings, "double", -G_MINDOUBLE);
1094   d = 1.0;
1095   g_object_get (obj, "double", &d, NULL);
1096   g_assert_cmpfloat (d, ==, -G_MINDOUBLE);
1097
1098   strv = g_strsplit ("plastic bag,middle class,polyethylene", ",", 0);
1099   g_settings_bind (settings, "strv", obj, "strv", G_SETTINGS_BIND_DEFAULT);
1100   g_object_set (obj, "strv", strv, NULL);
1101   g_strfreev (strv);
1102   strv = g_settings_get_strv (settings, "strv");
1103   s = g_strjoinv (",", strv);
1104   g_assert_cmpstr (s, ==, "plastic bag,middle class,polyethylene");
1105   g_strfreev (strv);
1106   g_free (s);
1107   strv = g_strsplit ("decaffeinate,unleaded,keep all surfaces clean", ",", 0);
1108   g_settings_set_strv (settings, "strv", (const gchar **) strv);
1109   g_strfreev (strv);
1110   g_object_get (obj, "strv", &strv, NULL);
1111   s = g_strjoinv (",", strv);
1112   g_assert_cmpstr (s, ==, "decaffeinate,unleaded,keep all surfaces clean");
1113   g_strfreev (strv);
1114   g_free (s);
1115
1116   g_settings_bind (settings, "enum", obj, "enum", G_SETTINGS_BIND_DEFAULT);
1117   g_object_set (obj, "enum", TEST_ENUM_BAZ, NULL);
1118   s = g_settings_get_string (settings, "enum");
1119   g_assert_cmpstr (s, ==, "baz");
1120   g_free (s);
1121   g_assert_cmpint (g_settings_get_enum (settings, "enum"), ==, TEST_ENUM_BAZ);
1122
1123   g_settings_set_enum (settings, "enum", TEST_ENUM_QUUX);
1124   i = 230;
1125   g_object_get (obj, "enum", &i, NULL);
1126   g_assert_cmpint (i, ==, TEST_ENUM_QUUX);
1127
1128   g_settings_set_string (settings, "enum", "baz");
1129   i = 230;
1130   g_object_get (obj, "enum", &i, NULL);
1131   g_assert_cmpint (i, ==, TEST_ENUM_BAZ);
1132
1133   g_object_unref (obj);
1134   g_object_unref (settings);
1135 }
1136
1137 static void
1138 test_unbind (void)
1139 {
1140   TestObject *obj;
1141   GSettings *settings;
1142
1143   settings = g_settings_new ("org.gtk.test.binding");
1144   obj = test_object_new ();
1145
1146   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT);
1147
1148   g_object_set (obj, "int", 12345, NULL);
1149   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345);
1150
1151   g_settings_unbind (obj, "int");
1152
1153   g_object_set (obj, "int", 54321, NULL);
1154   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345);
1155
1156   g_object_unref (obj);
1157   g_object_unref (settings);
1158 }
1159
1160 static void
1161 test_bind_writable (void)
1162 {
1163   TestObject *obj;
1164   GSettings *settings;
1165   gboolean b;
1166
1167   settings = g_settings_new ("org.gtk.test.binding");
1168   obj = test_object_new ();
1169
1170   g_object_set (obj, "bool", FALSE, NULL);
1171
1172   g_settings_bind_writable (settings, "int", obj, "bool", FALSE);
1173
1174   g_object_get (obj, "bool", &b, NULL);
1175   g_assert (b);
1176
1177   g_settings_unbind (obj, "bool");
1178
1179   g_settings_bind_writable (settings, "int", obj, "bool", TRUE);
1180
1181   g_object_get (obj, "bool", &b, NULL);
1182   g_assert (!b);
1183
1184   g_object_unref (obj);
1185   g_object_unref (settings);
1186 }
1187
1188 /* Test one-way bindings.
1189  * Verify that changes on one side show up on the other,
1190  * but not vice versa
1191  */
1192 static void
1193 test_directional_binding (void)
1194 {
1195   TestObject *obj;
1196   GSettings *settings;
1197   gboolean b;
1198   gint i;
1199
1200   settings = g_settings_new ("org.gtk.test.binding");
1201   obj = test_object_new ();
1202
1203   g_object_set (obj, "bool", FALSE, NULL);
1204   g_settings_set_boolean (settings, "bool", FALSE);
1205
1206   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET);
1207
1208   g_settings_set_boolean (settings, "bool", TRUE);
1209   g_object_get (obj, "bool", &b, NULL);
1210   g_assert_cmpint (b, ==, TRUE);
1211
1212   g_object_set (obj, "bool", FALSE, NULL);
1213   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
1214
1215   g_object_set (obj, "int", 20, NULL);
1216   g_settings_set_int (settings, "int", 20);
1217
1218   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_SET);
1219
1220   g_object_set (obj, "int", 32, NULL);
1221   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 32);
1222
1223   g_settings_set_int (settings, "int", 20);
1224   g_object_get (obj, "int", &i, NULL);
1225   g_assert_cmpint (i, ==, 32);
1226
1227   g_object_unref (obj);
1228   g_object_unref (settings);
1229 }
1230
1231 /* Test that type mismatch is caught when creating a binding
1232  */
1233 static void
1234 test_typesafe_binding (void)
1235 {
1236   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1237     {
1238       TestObject *obj;
1239       GSettings *settings;
1240
1241       settings = g_settings_new ("org.gtk.test.binding");
1242       obj = test_object_new ();
1243
1244       g_settings_bind (settings, "string", obj, "int", G_SETTINGS_BIND_DEFAULT);
1245
1246       g_object_unref (obj);
1247       g_object_unref (settings);
1248     }
1249   g_test_trap_assert_failed ();
1250   g_test_trap_assert_stderr ("*not compatible*");
1251 }
1252
1253 static gboolean
1254 string_to_bool (GValue   *value,
1255                 GVariant *variant,
1256                 gpointer  user_data)
1257 {
1258   const gchar *s;
1259
1260   s = g_variant_get_string (variant, NULL);
1261   g_value_set_boolean (value, g_strcmp0 (s, "true") == 0);
1262
1263   return TRUE;
1264 }
1265
1266 static GVariant *
1267 bool_to_string (const GValue       *value,
1268                 const GVariantType *expected_type,
1269                 gpointer            user_data)
1270 {
1271   if (g_value_get_boolean (value))
1272     return g_variant_new_string ("true");
1273   else
1274     return g_variant_new_string ("false");
1275 }
1276
1277 /* Test custom bindings.
1278  * Translate strings to booleans and back
1279  */
1280 static void
1281 test_custom_binding (void)
1282 {
1283   TestObject *obj;
1284   GSettings *settings;
1285   gchar *s;
1286   gboolean b;
1287
1288   settings = g_settings_new ("org.gtk.test.binding");
1289   obj = test_object_new ();
1290
1291   g_settings_set_string (settings, "string", "true");
1292
1293   g_settings_bind_with_mapping (settings, "string",
1294                                 obj, "bool",
1295                                 G_SETTINGS_BIND_DEFAULT,
1296                                 string_to_bool,
1297                                 bool_to_string,
1298                                 NULL, NULL);
1299
1300   g_settings_set_string (settings, "string", "false");
1301   g_object_get (obj, "bool", &b, NULL);
1302   g_assert_cmpint (b, ==, FALSE);
1303
1304   g_settings_set_string (settings, "string", "not true");
1305   g_object_get (obj, "bool", &b, NULL);
1306   g_assert_cmpint (b, ==, FALSE);
1307
1308   g_object_set (obj, "bool", TRUE, NULL);
1309   s = g_settings_get_string (settings, "string");
1310   g_assert_cmpstr (s, ==, "true");
1311   g_free (s);
1312
1313   g_object_unref (obj);
1314   g_object_unref (settings);
1315 }
1316
1317 /* Test that with G_SETTINGS_BIND_NO_CHANGES, the
1318  * initial settings value is transported to the object
1319  * side, but later settings changes do not affect the
1320  * object
1321  */
1322 static void
1323 test_no_change_binding (void)
1324 {
1325   TestObject *obj;
1326   GSettings *settings;
1327   gboolean b;
1328
1329   settings = g_settings_new ("org.gtk.test.binding");
1330   obj = test_object_new ();
1331
1332   g_object_set (obj, "bool", TRUE, NULL);
1333   g_settings_set_boolean (settings, "bool", FALSE);
1334
1335   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET_NO_CHANGES);
1336
1337   g_object_get (obj, "bool", &b, NULL);
1338   g_assert_cmpint (b, ==, FALSE);
1339
1340   g_settings_set_boolean (settings, "bool", TRUE);
1341   g_object_get (obj, "bool", &b, NULL);
1342   g_assert_cmpint (b, ==, FALSE);
1343
1344   g_settings_set_boolean (settings, "bool", FALSE);
1345   g_object_set (obj, "bool", TRUE, NULL);
1346   b = g_settings_get_boolean (settings, "bool");
1347   g_assert_cmpint (b, ==, TRUE);
1348
1349   g_object_unref (obj);
1350   g_object_unref (settings);
1351 }
1352
1353 /* Test that binding a non-readable property only
1354  * works in 'GET' mode.
1355  */
1356 static void
1357 test_no_read_binding (void)
1358 {
1359   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1360     {
1361       TestObject *obj;
1362       GSettings *settings;
1363
1364       settings = g_settings_new ("org.gtk.test.binding");
1365       obj = test_object_new ();
1366
1367       g_settings_bind (settings, "string", obj, "no-read", 0);
1368     }
1369   g_test_trap_assert_failed ();
1370   g_test_trap_assert_stderr ("*property*is not readable*");
1371
1372   if (g_test_trap_fork (0, 0))
1373     {
1374       TestObject *obj;
1375       GSettings *settings;
1376
1377       settings = g_settings_new ("org.gtk.test.binding");
1378       obj = test_object_new ();
1379
1380       g_settings_bind (settings, "string", obj, "no-read", G_SETTINGS_BIND_GET);
1381
1382       exit (0);
1383     }
1384   g_test_trap_assert_passed ();
1385 }
1386
1387 /* Test that binding a non-writable property only
1388  * works in 'SET' mode.
1389  */
1390 static void
1391 test_no_write_binding (void)
1392 {
1393   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1394     {
1395       TestObject *obj;
1396       GSettings *settings;
1397
1398       settings = g_settings_new ("org.gtk.test.binding");
1399       obj = test_object_new ();
1400
1401       g_settings_bind (settings, "string", obj, "no-write", 0);
1402     }
1403   g_test_trap_assert_failed ();
1404   g_test_trap_assert_stderr ("*property*is not writable*");
1405
1406   if (g_test_trap_fork (0, 0))
1407     {
1408       TestObject *obj;
1409       GSettings *settings;
1410
1411       settings = g_settings_new ("org.gtk.test.binding");
1412       obj = test_object_new ();
1413
1414       g_settings_bind (settings, "string", obj, "no-write", G_SETTINGS_BIND_SET);
1415
1416       exit (0);
1417     }
1418   g_test_trap_assert_passed ();
1419 }
1420
1421 /*
1422  * Test that using a keyfile works
1423  */
1424 static void
1425 test_keyfile (void)
1426 {
1427   GSettingsBackend *kf_backend;
1428   GSettings *settings;
1429   GKeyFile *keyfile;
1430   gchar *str;
1431
1432   g_remove ("gsettings.store");
1433
1434   kf_backend = g_keyfile_settings_backend_new ("gsettings.store", "/", "root");
1435   settings = g_settings_new_with_backend ("org.gtk.test", kf_backend);
1436   g_object_unref (kf_backend);
1437
1438   g_settings_set (settings, "greeting", "s", "see if this works");
1439
1440   keyfile = g_key_file_new ();
1441   g_assert (g_key_file_load_from_file (keyfile, "gsettings.store", 0, NULL));
1442
1443   str = g_key_file_get_string (keyfile, "tests", "greeting", NULL);
1444   g_assert_cmpstr (str, ==, "'see if this works'");
1445
1446   g_free (str);
1447   g_key_file_free (keyfile);
1448   g_object_unref (settings);
1449 }
1450
1451 /* Test that getting child schemas works
1452  */
1453 static void
1454 test_child_schema (void)
1455 {
1456   GSettings *settings;
1457   GSettings *child;
1458   guint8 byte;
1459
1460   /* first establish some known conditions */
1461   settings = g_settings_new ("org.gtk.test.basic-types");
1462   g_settings_set (settings, "test-byte", "y", 36);
1463
1464   g_settings_get (settings, "test-byte", "y", &byte);
1465   g_assert_cmpint (byte, ==, 36);
1466
1467   g_object_unref (settings);
1468
1469   settings = g_settings_new ("org.gtk.test");
1470   child = g_settings_get_child (settings, "basic-types");
1471   g_assert (child != NULL);
1472
1473   g_settings_get (child, "test-byte", "y", &byte);
1474   g_assert_cmpint (byte, ==, 36);
1475
1476   g_object_unref (child);
1477   g_object_unref (settings);
1478 }
1479
1480 static gboolean
1481 glib_translations_work (void)
1482 {
1483   gboolean works;
1484   gchar *locale;
1485   gchar *orig = "Unnamed";
1486
1487   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
1488   if (!setlocale (LC_MESSAGES, "de"))
1489     works = FALSE;
1490   else
1491     works = dgettext ("glib20", orig) != orig;
1492   setlocale (LC_MESSAGES, locale);
1493   g_free (locale);
1494
1495   return works;
1496 }
1497
1498 #include "../strinfo.c"
1499
1500 static void
1501 test_strinfo (void)
1502 {
1503   /*  "foo" has a value of 1
1504    *  "bar" has a value of 2
1505    *  "baz" is an alias for "bar"
1506    */
1507   gchar array[] =
1508     "\1\0\0\0"      "\xff""foo"     "\0\0\0\xff"    "\2\0\0\0"
1509     "\xff" "bar"    "\0\0\0\xff"    "\3\0\0\0"      "\xfe""baz"
1510     "\0\0\0\xff";
1511   const guint32 *strinfo = (guint32 *) array;
1512   guint length = sizeof array / 4;
1513   guint result;
1514
1515   {
1516     /* build it and compare */
1517     GString *builder;
1518
1519     builder = g_string_new (NULL);
1520     strinfo_builder_append_item (builder, "foo", 1);
1521     strinfo_builder_append_item (builder, "bar", 2);
1522     g_assert (strinfo_builder_append_alias (builder, "baz", "bar"));
1523     g_assert_cmpint (builder->len % 4, ==, 0);
1524     g_assert_cmpint (builder->len / 4, ==, length);
1525     g_assert (memcmp (builder->str, strinfo, length * 4) == 0);
1526     g_string_free (builder, TRUE);
1527   }
1528
1529   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "foo"),
1530                    ==, NULL);
1531   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "bar"),
1532                    ==, NULL);
1533   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "baz"),
1534                    ==, "bar");
1535   g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "quux"),
1536                    ==, NULL);
1537
1538   g_assert (strinfo_enum_from_string (strinfo, length, "foo", &result));
1539   g_assert_cmpint (result, ==, 1);
1540   g_assert (strinfo_enum_from_string (strinfo, length, "bar", &result));
1541   g_assert_cmpint (result, ==, 2);
1542   g_assert (!strinfo_enum_from_string (strinfo, length, "baz", &result));
1543   g_assert (!strinfo_enum_from_string (strinfo, length, "quux", &result));
1544
1545   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 0), ==, NULL);
1546   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 1), ==, "foo");
1547   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 2), ==, "bar");
1548   g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 3), ==, NULL);
1549
1550   g_assert (strinfo_is_string_valid (strinfo, length, "foo"));
1551   g_assert (strinfo_is_string_valid (strinfo, length, "bar"));
1552   g_assert (!strinfo_is_string_valid (strinfo, length, "baz"));
1553   g_assert (!strinfo_is_string_valid (strinfo, length, "quux"));
1554 }
1555
1556 static void
1557 test_enums (void)
1558 {
1559   GSettings *settings, *direct;
1560   gchar *str;
1561
1562   settings = g_settings_new ("org.gtk.test.enums");
1563   direct = g_settings_new ("org.gtk.test.enums.direct");
1564
1565   if (!backend_set)
1566     {
1567       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1568         g_settings_get_enum (direct, "test");
1569       g_test_trap_assert_failed ();
1570       g_test_trap_assert_stderr ("*not associated with an enum*");
1571
1572       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1573         g_settings_set_enum (settings, "test", 42);
1574       g_test_trap_assert_failed ();
1575       g_test_trap_assert_stderr ("*invalid enum value 42*");
1576
1577       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1578         g_settings_set_string (settings, "test", "qux");
1579       g_test_trap_assert_failed ();
1580       g_test_trap_assert_stderr ("*g_settings_set_value*valid range*");
1581
1582       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1583         g_settings_get_flags (settings, "test");
1584       g_test_trap_assert_failed ();
1585       g_test_trap_assert_stderr ("*not associated with a flags*");
1586     }
1587
1588   str = g_settings_get_string (settings, "test");
1589   g_assert_cmpstr (str, ==, "bar");
1590   g_free (str);
1591
1592   g_settings_set_enum (settings, "test", TEST_ENUM_FOO);
1593
1594   str = g_settings_get_string (settings, "test");
1595   g_assert_cmpstr (str, ==, "foo");
1596   g_free (str);
1597
1598   g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_FOO);
1599
1600   g_settings_set_string (direct, "test", "qux");
1601
1602   str = g_settings_get_string (direct, "test");
1603   g_assert_cmpstr (str, ==, "qux");
1604   g_free (str);
1605
1606   str = g_settings_get_string (settings, "test");
1607   g_assert_cmpstr (str, ==, "quux");
1608   g_free (str);
1609
1610   g_assert_cmpint (g_settings_get_enum (settings, "test"), ==, TEST_ENUM_QUUX);
1611 }
1612
1613 static void
1614 test_flags (void)
1615 {
1616   GSettings *settings, *direct;
1617   gchar **strv;
1618   gchar *str;
1619
1620   settings = g_settings_new ("org.gtk.test.enums");
1621   direct = g_settings_new ("org.gtk.test.enums.direct");
1622
1623   if (!backend_set)
1624     {
1625       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1626         g_settings_get_flags (direct, "test");
1627       g_test_trap_assert_failed ();
1628       g_test_trap_assert_stderr ("*not associated with a flags*");
1629
1630       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1631         g_settings_set_flags (settings, "f-test", 0x42);
1632       g_test_trap_assert_failed ();
1633       g_test_trap_assert_stderr ("*invalid flags value 0x00000042*");
1634
1635       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1636         g_settings_set_strv (settings, "f-test",
1637                              (const gchar **) g_strsplit ("rock", ",", 0));
1638       g_test_trap_assert_failed ();
1639       g_test_trap_assert_stderr ("*g_settings_set_value*valid range*");
1640
1641       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1642         g_settings_get_enum (settings, "f-test");
1643       g_test_trap_assert_failed ();
1644       g_test_trap_assert_stderr ("*not associated with an enum*");
1645     }
1646
1647   strv = g_settings_get_strv (settings, "f-test");
1648   str = g_strjoinv (",", strv);
1649   g_assert_cmpstr (str, ==, "");
1650   g_strfreev (strv);
1651   g_free (str);
1652
1653   g_settings_set_flags (settings, "f-test",
1654                         TEST_FLAGS_WALKING | TEST_FLAGS_TALKING);
1655
1656   strv = g_settings_get_strv (settings, "f-test");
1657   str = g_strjoinv (",", strv);
1658   g_assert_cmpstr (str, ==, "talking,walking");
1659   g_strfreev (strv);
1660   g_free (str);
1661
1662   g_assert_cmpint (g_settings_get_flags (settings, "f-test"), ==,
1663                    TEST_FLAGS_WALKING | TEST_FLAGS_TALKING);
1664
1665   strv = g_strsplit ("speaking,laughing", ",", 0);
1666   g_settings_set_strv (direct, "f-test", (const gchar **) strv);
1667   g_strfreev (strv);
1668
1669   strv = g_settings_get_strv (direct, "f-test");
1670   str = g_strjoinv (",", strv);
1671   g_assert_cmpstr (str, ==, "speaking,laughing");
1672   g_strfreev (strv);
1673   g_free (str);
1674
1675   strv = g_settings_get_strv (settings, "f-test");
1676   str = g_strjoinv (",", strv);
1677   g_assert_cmpstr (str, ==, "talking,laughing");
1678   g_strfreev (strv);
1679   g_free (str);
1680
1681   g_assert_cmpint (g_settings_get_flags (settings, "f-test"), ==,
1682                    TEST_FLAGS_TALKING | TEST_FLAGS_LAUGHING);
1683 }
1684
1685 static void
1686 test_range (void)
1687 {
1688   GSettings *settings, *direct;
1689
1690   settings = g_settings_new ("org.gtk.test.range");
1691   direct = g_settings_new ("org.gtk.test.range.direct");
1692
1693   if (!backend_set)
1694     {
1695       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1696         g_settings_set_int (settings, "val", 45);
1697       g_test_trap_assert_failed ();
1698       g_test_trap_assert_stderr ("*g_settings_set_value*valid range*");
1699
1700       if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1701         g_settings_set_int (settings, "val", 1);
1702       g_test_trap_assert_failed ();
1703       g_test_trap_assert_stderr ("*g_settings_set_value*valid range*");
1704     }
1705
1706   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1707   g_settings_set_int (direct, "val", 22);
1708   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 22);
1709   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 22);
1710   g_settings_set_int (direct, "val", 45);
1711   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 45);
1712   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1713   g_settings_set_int (direct, "val", 1);
1714   g_assert_cmpint (g_settings_get_int (direct, "val"), ==, 1);
1715   g_assert_cmpint (g_settings_get_int (settings, "val"), ==, 33);
1716 }
1717
1718 static gboolean
1719 strv_has_string (gchar       **haystack,
1720                  const gchar  *needle)
1721 {
1722   guint n;
1723
1724   for (n = 0; haystack != NULL && haystack[n] != NULL; n++)
1725     {
1726       if (g_strcmp0 (haystack[n], needle) == 0)
1727         return TRUE;
1728     }
1729   return FALSE;
1730 }
1731
1732 static gboolean
1733 strv_set_equal (gchar **strv, ...)
1734 {
1735   gint count;
1736   va_list list;
1737   const gchar *str;
1738   gboolean res;
1739
1740   res = TRUE;
1741   count = 0;
1742   va_start (list, strv);
1743   while (1)
1744     {
1745       str = va_arg (list, const gchar *);
1746       if (str == NULL)
1747         break;
1748       if (!strv_has_string (strv, str))
1749         {
1750           res = FALSE;
1751           break;
1752         }
1753       count++;
1754     }
1755   va_end (list);
1756
1757   if (res)
1758     res = g_strv_length ((gchar**)strv) == count;
1759
1760   return res;
1761 }
1762
1763 static void
1764 test_list_items (void)
1765 {
1766   GSettings *settings;
1767   gchar **children;
1768   gchar **keys;
1769
1770   settings = g_settings_new ("org.gtk.test");
1771   children = g_settings_list_children (settings);
1772   keys = g_settings_list_keys (settings);
1773
1774   g_assert (strv_set_equal (children, "basic-types", "complex-types", "localized", NULL));
1775   g_assert (strv_set_equal (keys, "greeting", "farewell", NULL));
1776
1777   g_strfreev (children);
1778   g_strfreev (keys);
1779
1780   g_object_unref (settings);
1781 }
1782
1783 static void
1784 test_list_schemas (void)
1785 {
1786   const gchar * const *schemas;
1787   const gchar * const *relocs;
1788
1789   relocs = g_settings_list_relocatable_schemas ();
1790   schemas = g_settings_list_schemas ();
1791
1792   g_assert (strv_set_equal ((gchar **)relocs,
1793                             "org.gtk.test.no-path",
1794                             NULL));
1795
1796   g_assert (strv_set_equal ((gchar **)schemas,
1797                             "org.gtk.test",
1798                             "org.gtk.test.basic-types",
1799                             "org.gtk.test.complex-types",
1800                             "org.gtk.test.localized",
1801                             "org.gtk.test.binding",
1802                             "org.gtk.test.enums",
1803                             "org.gtk.test.enums.direct",
1804                             "org.gtk.test.range",
1805                             "org.gtk.test.range.direct",
1806                             "org.gtk.test.mapped",
1807                             NULL));
1808 }
1809
1810 static gboolean
1811 map_func (GVariant *value,
1812           gpointer *result,
1813           gpointer  user_data)
1814 {
1815   gint *state = user_data;
1816   gint v;
1817
1818   if (value)
1819     v = g_variant_get_int32 (value);
1820   else
1821     v = -1;
1822
1823   if (*state == 0)
1824     {
1825       g_assert_cmpint (v, ==, 1);
1826       (*state)++;
1827       return FALSE;
1828     }
1829   else if (*state == 1)
1830     {
1831       g_assert_cmpint (v, ==, 0);
1832       (*state)++;
1833       return FALSE;
1834     }
1835   else
1836     {
1837       g_assert (value == NULL);
1838       *result = g_variant_new_int32 (5);
1839       return TRUE;
1840     }
1841 }
1842
1843 static void
1844 test_get_mapped (void)
1845 {
1846   GSettings *settings;
1847   gint state;
1848   gpointer p;
1849   gint val;
1850
1851   settings = g_settings_new ("org.gtk.test.mapped");
1852   g_settings_set_int (settings, "val", 1);
1853
1854   state = 0;
1855   p = g_settings_get_mapped (settings, "val", map_func, &state);
1856   val = g_variant_get_int32 ((GVariant*)p);
1857   g_assert_cmpint (val, ==, 5);
1858
1859   g_variant_unref (p);
1860   g_object_unref (settings);
1861 }
1862
1863 static void
1864 test_get_range (void)
1865 {
1866   GSettings *settings;
1867   GVariant *range;
1868
1869   settings = g_settings_new ("org.gtk.test.range");
1870   range = g_settings_get_range (settings, "val");
1871   check_and_free (range, "('range', <(2, 44)>)");
1872   g_object_unref (settings);
1873
1874   settings = g_settings_new ("org.gtk.test.enums");
1875   range = g_settings_get_range (settings, "test");
1876   check_and_free (range, "('enum', <['foo', 'bar', 'baz', 'quux']>)");
1877   g_object_unref (settings);
1878
1879   settings = g_settings_new ("org.gtk.test.enums");
1880   range = g_settings_get_range (settings, "f-test");
1881   check_and_free (range, "('flags', "
1882                   "<['mourning', 'laughing', 'talking', 'walking']>)");
1883   g_object_unref (settings);
1884
1885   settings = g_settings_new ("org.gtk.test");
1886   range = g_settings_get_range (settings, "greeting");
1887   check_and_free (range, "('type', <@as []>)");
1888   g_object_unref (settings);
1889 }
1890
1891 static void
1892 test_schema_source (void)
1893 {
1894   GSettingsSchemaSource *parent;
1895   GSettingsSchemaSource *source;
1896   GSettingsBackend *backend;
1897   GSettingsSchema *schema;
1898   GError *error = NULL;
1899   GSettings *settings;
1900   gboolean enabled;
1901
1902   backend = g_settings_backend_get_default ();
1903
1904   /* make sure it fails properly */
1905   parent = g_settings_schema_source_get_default ();
1906   source = g_settings_schema_source_new_from_directory ("/path/that/does/not/exist", parent,  TRUE, &error);
1907   g_assert (source == NULL);
1908   g_clear_error (&error);
1909
1910   /* create a source with the parent */
1911   source = g_settings_schema_source_new_from_directory ("schema-source", parent, TRUE, &error);
1912   g_assert_no_error (error);
1913   g_assert (source != NULL);
1914
1915   /* check recursive lookups are working */
1916   schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
1917   g_assert (schema != NULL);
1918   g_settings_schema_unref (schema);
1919
1920   /* check recursive lookups for non-existent schemas */
1921   schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE);
1922   g_assert (schema == NULL);
1923
1924   /* check non-recursive for schema that only exists in lower layers */
1925   schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
1926   g_assert (schema == NULL);
1927
1928   /* check non-recursive lookup for non-existent */
1929   schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE);
1930   g_assert (schema == NULL);
1931
1932   /* check non-recursive for schema that exists in toplevel */
1933   schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
1934   g_assert (schema != NULL);
1935   g_settings_schema_unref (schema);
1936
1937   /* check recursive for schema that exists in toplevel */
1938   schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
1939   g_assert (schema != NULL);
1940
1941   /* try to use it for something */
1942   settings = g_settings_new_full (schema, backend, g_settings_schema_get_path (schema));
1943   g_settings_schema_unref (schema);
1944   enabled = FALSE;
1945   g_settings_get (settings, "enabled", "b", &enabled);
1946   g_assert (enabled);
1947   g_object_unref (settings);
1948
1949   g_settings_schema_source_unref (source);
1950
1951   /* try again, but with no parent */
1952   source = g_settings_schema_source_new_from_directory ("schema-source", NULL, FALSE, NULL);
1953   g_assert (source != NULL);
1954
1955   /* should not find it this time, even if recursive... */
1956   schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE);
1957   g_assert (schema == NULL);
1958   schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE);
1959   g_assert (schema == NULL);
1960
1961   /* should still find our own... */
1962   schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE);
1963   g_assert (schema != NULL);
1964   g_settings_schema_unref (schema);
1965   schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE);
1966   g_assert (schema != NULL);
1967   g_settings_schema_unref (schema);
1968
1969   g_settings_schema_source_unref (source);
1970 }
1971
1972 int
1973 main (int argc, char *argv[])
1974 {
1975   gchar *enums;
1976   gint result;
1977
1978   setlocale (LC_ALL, "");
1979
1980   backend_set = g_getenv ("GSETTINGS_BACKEND") != NULL;
1981
1982   g_setenv ("XDG_DATA_DIRS", ".", TRUE);
1983   g_setenv ("GSETTINGS_SCHEMA_DIR", ".", TRUE);
1984
1985   if (!backend_set)
1986     g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
1987
1988   g_type_init ();
1989   g_test_init (&argc, &argv, NULL);
1990
1991   g_remove ("org.gtk.test.enums.xml");
1992   g_assert (g_spawn_command_line_sync ("../../gobject/glib-mkenums "
1993                                        "--template " SRCDIR "/enums.xml.template "
1994                                        SRCDIR "/testenum.h",
1995                                        &enums, NULL, &result, NULL));
1996   g_assert (result == 0);
1997   g_assert (g_file_set_contents ("org.gtk.test.enums.xml", enums, -1, NULL));
1998   g_free (enums);
1999
2000   g_remove ("gschemas.compiled");
2001   g_assert (g_spawn_command_line_sync ("../glib-compile-schemas --targetdir=. "
2002                                        "--schema-file=org.gtk.test.enums.xml "
2003                                        "--schema-file=" SRCDIR "/org.gtk.test.gschema.xml",
2004                                        NULL, NULL, &result, NULL));
2005   g_assert (result == 0);
2006
2007   g_remove ("schema-source/gschemas.compiled");
2008   g_mkdir ("schema-source", 0777);
2009   g_assert (g_spawn_command_line_sync ("../glib-compile-schemas --targetdir=schema-source "
2010                                        "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml",
2011                                        NULL, NULL, &result, NULL));
2012   g_assert (result == 0);
2013
2014   g_test_add_func ("/gsettings/basic", test_basic);
2015
2016   if (!backend_set)
2017     {
2018       g_test_add_func ("/gsettings/no-schema", test_no_schema);
2019       g_test_add_func ("/gsettings/unknown-key", test_unknown_key);
2020       g_test_add_func ("/gsettings/wrong-type", test_wrong_type);
2021       g_test_add_func ("/gsettings/wrong-path", test_wrong_path);
2022       g_test_add_func ("/gsettings/no-path", test_no_path);
2023     }
2024
2025   g_test_add_func ("/gsettings/basic-types", test_basic_types);
2026   g_test_add_func ("/gsettings/complex-types", test_complex_types);
2027   g_test_add_func ("/gsettings/changes", test_changes);
2028
2029   if (glib_translations_work ())
2030     {
2031       g_test_add_func ("/gsettings/l10n", test_l10n);
2032       g_test_add_func ("/gsettings/l10n-context", test_l10n_context);
2033     }
2034
2035   g_test_add_func ("/gsettings/delay-apply", test_delay_apply);
2036   g_test_add_func ("/gsettings/delay-revert", test_delay_revert);
2037   g_test_add_func ("/gsettings/atomic", test_atomic);
2038
2039   g_test_add_func ("/gsettings/simple-binding", test_simple_binding);
2040   g_test_add_func ("/gsettings/directional-binding", test_directional_binding);
2041   g_test_add_func ("/gsettings/custom-binding", test_custom_binding);
2042   g_test_add_func ("/gsettings/no-change-binding", test_no_change_binding);
2043   g_test_add_func ("/gsettings/unbinding", test_unbind);
2044   g_test_add_func ("/gsettings/writable-binding", test_bind_writable);
2045
2046   if (!backend_set)
2047     {
2048       g_test_add_func ("/gsettings/typesafe-binding", test_typesafe_binding);
2049       g_test_add_func ("/gsettings/no-read-binding", test_no_read_binding);
2050       g_test_add_func ("/gsettings/no-write-binding", test_no_write_binding);
2051     }
2052
2053   g_test_add_func ("/gsettings/keyfile", test_keyfile);
2054   g_test_add_func ("/gsettings/child-schema", test_child_schema);
2055   g_test_add_func ("/gsettings/strinfo", test_strinfo);
2056   g_test_add_func ("/gsettings/enums", test_enums);
2057   g_test_add_func ("/gsettings/flags", test_flags);
2058   g_test_add_func ("/gsettings/range", test_range);
2059   g_test_add_func ("/gsettings/list-items", test_list_items);
2060   g_test_add_func ("/gsettings/list-schemas", test_list_schemas);
2061   g_test_add_func ("/gsettings/mapped", test_get_mapped);
2062   g_test_add_func ("/gsettings/get-range", test_get_range);
2063   g_test_add_func ("/gsettings/schema-source", test_schema_source);
2064
2065   result = g_test_run ();
2066
2067   g_settings_sync ();
2068
2069   return result;
2070 }