Merge GSettings tests
[platform/upstream/glib.git] / gio / tests / gsettings.c
1 #include <stdlib.h>
2 #include <locale.h>
3 #include <libintl.h>
4 #include <gio.h>
5 #include <gstdio.h>
6
7 static void
8 test_basic (void)
9 {
10   gchar *str = NULL;
11   GSettings *settings;
12
13   settings = g_settings_new ("org.gtk.test");
14
15   g_settings_get (settings, "greeting", "s", &str);
16   g_assert_cmpstr (str, ==, "Hello, earthlings");
17
18   g_settings_set (settings, "greeting", "s", "goodbye world");
19   g_settings_get (settings, "greeting", "s", &str);
20   g_assert_cmpstr (str, ==, "goodbye world");
21   g_free (str);
22   str = NULL;
23
24   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
25     {
26       settings = g_settings_new ("org.gtk.test");
27       g_settings_set (settings, "greeting", "i", 555);
28       abort ();
29     }
30   g_test_trap_assert_failed ();
31   g_test_trap_assert_stderr ("*correct_type*");
32
33   g_settings_get (settings, "greeting", "s", &str);
34   g_assert_cmpstr (str, ==, "goodbye world");
35   g_free (str);
36   str = NULL;
37
38   g_settings_set (settings, "greeting", "s", "this is the end");
39   g_object_unref (settings);
40 }
41
42 static void
43 test_unknown_key (void)
44 {
45   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
46     {
47       GSettings *settings;
48       GVariant *value;
49
50       settings = g_settings_new ("org.gtk.test");
51       value = g_settings_get_value (settings, "no_such_key");
52
53       g_assert (value == NULL);
54
55       g_object_unref (settings);
56     }
57   g_test_trap_assert_failed ();
58   g_test_trap_assert_stderr ("*does not contain*");
59 }
60
61 void
62 test_no_schema (void)
63 {
64   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
65     {
66       GSettings *settings;
67
68       settings = g_settings_new ("no.such.schema");
69
70       g_assert (settings == NULL);
71     }
72
73   g_test_trap_assert_failed ();
74   g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*");
75 }
76
77 static void
78 test_wrong_type (void)
79 {
80   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
81     {
82       GSettings *settings;
83       gchar *str = NULL;
84
85       settings = g_settings_new ("org.gtk.test");
86
87       g_settings_get (settings, "greeting", "o", &str);
88
89       g_assert (str == NULL);
90     }
91   g_test_trap_assert_failed ();
92   g_test_trap_assert_stderr ("*CRITICAL*");
93
94   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
95     {
96       GSettings *settings;
97
98       settings = g_settings_new ("org.gtk.test");
99
100       g_settings_set (settings, "greetings", "o", "/a/path");
101     }
102   g_test_trap_assert_failed ();
103   g_test_trap_assert_stderr ("*CRITICAL*");
104 }
105
106 static void
107 test_basic_types (void)
108 {
109   GSettings *settings;
110   gboolean b;
111   guint8 byte;
112   gint16 i16;
113   guint16 u16;
114   gint32 i32;
115   guint32 u32;
116   gint64 i64;
117   guint64 u64;
118   gdouble d;
119   gchar *str;
120
121   settings = g_settings_new ("org.gtk.test.basic-types");
122
123   g_settings_get (settings, "test-boolean", "b", &b);
124   g_assert_cmpint (b, ==, 1);
125
126   g_settings_set (settings, "test-boolean", "b", 0);
127   g_settings_get (settings, "test-boolean", "b", &b);
128   g_assert_cmpint (b, ==, 0);
129
130   g_settings_get (settings, "test-byte", "y", &byte);
131   g_assert_cmpint (byte, ==, 25);
132
133   g_settings_set (settings, "test-byte", "y", G_MAXUINT8);
134   g_settings_get (settings, "test-byte", "y", &byte);
135   g_assert_cmpint (byte, ==, G_MAXUINT8);
136
137   g_settings_get (settings, "test-int16", "n", &i16);
138   g_assert_cmpint (i16, ==, -1234);
139
140   g_settings_set (settings, "test-int16", "n", G_MININT16);
141   g_settings_get (settings, "test-int16", "n", &i16);
142   g_assert_cmpint (i16, ==, G_MININT16);
143
144   g_settings_set (settings, "test-int16", "n", G_MAXINT16);
145   g_settings_get (settings, "test-int16", "n", &i16);
146   g_assert_cmpint (i16, ==, G_MAXINT16);
147
148   g_settings_get (settings, "test-uint16", "q", &u16);
149   g_assert_cmpuint (u16, ==, 1234);
150
151   g_settings_set (settings, "test-uint16", "q", G_MAXUINT16);
152   g_settings_get (settings, "test-uint16", "q", &u16);
153   g_assert_cmpuint (u16, ==, G_MAXUINT16);
154
155   g_settings_get (settings, "test-int32", "i", &i32);
156   g_assert_cmpint (i32, ==, -123456);
157
158   g_settings_set (settings, "test-int32", "i", G_MININT32);
159   g_settings_get (settings, "test-int32", "i", &i32);
160   g_assert_cmpint (i32, ==, G_MININT32);
161
162   g_settings_set (settings, "test-int32", "i", G_MAXINT32);
163   g_settings_get (settings, "test-int32", "i", &i32);
164   g_assert_cmpint (i32, ==, G_MAXINT32);
165
166   g_settings_get (settings, "test-uint32", "u", &u32);
167   g_assert_cmpuint (u32, ==, 123456);
168
169   g_settings_set (settings, "test-uint32", "u", G_MAXUINT32);
170   g_settings_get (settings, "test-uint32", "u", &u32);
171   g_assert_cmpuint (u32, ==, G_MAXUINT32);
172
173   g_settings_get (settings, "test-int64", "x", &i64);
174   g_assert_cmpuint (i64, ==, -123456789);
175
176   g_settings_set (settings, "test-int64", "x", G_MININT64);
177   g_settings_get (settings, "test-int64", "x", &i64);
178   g_assert_cmpuint (i64, ==, G_MININT64);
179
180   g_settings_set (settings, "test-int64", "x", G_MAXINT64);
181   g_settings_get (settings, "test-int64", "x", &i64);
182   g_assert_cmpuint (i64, ==, G_MAXINT64);
183
184   g_settings_get (settings, "test-uint64", "t", &u64);
185   g_assert_cmpuint (u64, ==, 123456789);
186
187   g_settings_set (settings, "test-uint64", "t", G_MAXUINT64);
188   g_settings_get (settings, "test-uint64", "t", &u64);
189   g_assert_cmpuint (u64, ==, G_MAXUINT64);
190
191   g_settings_get (settings, "test-double", "d", &d);
192   g_assert_cmpfloat (d, ==, 123.456);
193
194   g_settings_set (settings, "test-double", "d", G_MINDOUBLE);
195   g_settings_get (settings, "test-double", "d", &d);
196   g_assert_cmpfloat (d, ==, G_MINDOUBLE);
197
198   g_settings_set (settings, "test-double", "d", G_MAXDOUBLE);
199   g_settings_get (settings, "test-double", "d", &d);
200   g_assert_cmpfloat (d, ==, G_MAXDOUBLE);
201
202   g_settings_get (settings, "test-string", "s", &str);
203   g_assert_cmpstr (str, ==, "a string, it seems");
204   g_free (str);
205   str = NULL;
206
207   g_settings_get (settings, "test-objectpath", "o", &str);
208   g_assert_cmpstr (str, ==, "/a/object/path");
209   g_object_unref (settings);
210   g_free (str);
211   str = NULL;
212 }
213
214 static void
215 test_complex_types (void)
216 {
217   GSettings *settings;
218   gchar *s;
219   gint i1, i2;
220   GVariantIter *iter = NULL;
221
222   settings = g_settings_new ("org.gtk.test.complex-types");
223
224   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
225   g_assert_cmpstr (s, ==, "one");
226   g_assert_cmpint (i1,==, 2);
227   g_assert_cmpint (i2,==, 3);
228   g_free (s) ;
229   s = NULL;
230
231   g_settings_set (settings, "test-tuple", "(s(ii))", "none", 0, 0);
232   g_settings_get (settings, "test-tuple", "(s(ii))", &s, &i1, &i2);
233   g_assert_cmpstr (s, ==, "none");
234   g_assert_cmpint (i1,==, 0);
235   g_assert_cmpint (i2,==, 0);
236   g_free (s);
237   s = NULL;
238
239   g_settings_get (settings, "test-array", "ai", &iter);
240   g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6);
241   g_assert (g_variant_iter_next (iter, "i", &i1));
242   g_assert_cmpint (i1, ==, 0);
243   g_assert (g_variant_iter_next (iter, "i", &i1));
244   g_assert_cmpint (i1, ==, 1);
245   g_assert (g_variant_iter_next (iter, "i", &i1));
246   g_assert_cmpint (i1, ==, 2);
247   g_assert (g_variant_iter_next (iter, "i", &i1));
248   g_assert_cmpint (i1, ==, 3);
249   g_assert (g_variant_iter_next (iter, "i", &i1));
250   g_assert_cmpint (i1, ==, 4);
251   g_assert (g_variant_iter_next (iter, "i", &i1));
252   g_assert_cmpint (i1, ==, 5);
253   g_assert (!g_variant_iter_next (iter, "i", &i1));
254   g_variant_iter_free (iter);
255
256   g_object_unref (settings);
257 }
258
259 static gboolean changed_cb_called;
260
261 static void
262 changed_cb (GSettings   *settings,
263             const gchar *key,
264             gpointer     data)
265 {
266   changed_cb_called = TRUE;
267
268   g_assert_cmpstr (key, ==, data);
269 }
270
271 void
272 test_changes (void)
273 {
274   GSettings *settings;
275   GSettings *settings2;
276
277   settings = g_settings_new ("org.gtk.test");
278
279   g_signal_connect (settings, "changed",
280                     G_CALLBACK (changed_cb), "greeting");
281
282   changed_cb_called = FALSE;
283
284   g_settings_set (settings, "greeting", "s", "new greeting");
285   g_assert (changed_cb_called);
286
287   settings2 = g_settings_new ("org.gtk.test");
288
289   changed_cb_called = FALSE;
290
291   g_settings_set (settings2, "greeting", "s", "hi");
292   g_assert (changed_cb_called);
293
294   g_object_unref (settings2);
295   g_object_unref (settings);
296 }
297
298 static gboolean changed_cb_called2;
299
300 static void
301 changed_cb2 (GSettings   *settings,
302              const gchar *key,
303              gpointer     data)
304 {
305   gboolean *p = data;
306
307   *p = TRUE;
308 }
309
310
311 void
312 test_delay_apply (void)
313 {
314   GSettings *settings;
315   GSettings *settings2;
316   gchar *str;
317
318   settings = g_settings_new ("org.gtk.test");
319   settings2 = g_settings_new ("org.gtk.test");
320
321   g_settings_set (settings2, "greeting", "s", "top o' the morning");
322
323   changed_cb_called = FALSE;
324   changed_cb_called2 = FALSE;
325
326   g_signal_connect (settings, "changed",
327                     G_CALLBACK (changed_cb2), &changed_cb_called);
328   g_signal_connect (settings2, "changed",
329                     G_CALLBACK (changed_cb2), &changed_cb_called2);
330
331   g_settings_delay (settings);
332
333   g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply");
334
335   g_assert (changed_cb_called);
336   g_assert (!changed_cb_called2);
337
338   g_settings_get (settings, "greeting", "s", &str);
339   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
340   g_free (str);
341   str = NULL;
342
343   g_settings_get (settings2, "greeting", "s", &str);
344   g_assert_cmpstr (str, ==, "top o' the morning");
345   g_free (str);
346   str = NULL;
347
348   g_assert (g_settings_get_has_unapplied (settings));
349   g_assert (!g_settings_get_has_unapplied (settings2));
350
351   changed_cb_called = FALSE;
352   changed_cb_called2 = FALSE;
353
354   g_settings_apply (settings);
355
356   g_assert (!changed_cb_called);
357   g_assert (changed_cb_called2);
358
359   g_settings_get (settings, "greeting", "s", &str);
360   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
361   g_free (str);
362   str = NULL;
363
364   g_settings_get (settings2, "greeting", "s", &str);
365   g_assert_cmpstr (str, ==, "greetings from test_delay_apply");
366   g_free (str);
367   str = NULL;
368
369   g_assert (!g_settings_get_has_unapplied (settings));
370   g_assert (!g_settings_get_has_unapplied (settings2));
371
372   g_object_unref (settings2);
373   g_object_unref (settings);
374 }
375
376 static void
377 test_delay_revert (void)
378 {
379   GSettings *settings;
380   GSettings *settings2;
381   gchar *str;
382
383   settings = g_settings_new ("org.gtk.test");
384   settings2 = g_settings_new ("org.gtk.test");
385
386   g_settings_set (settings2, "greeting", "s", "top o' the morning");
387
388   g_settings_delay (settings);
389
390   g_settings_set (settings, "greeting", "s", "greetings from test_delay_revert");
391
392   g_settings_get (settings, "greeting", "s", &str);
393   g_assert_cmpstr (str, ==, "greetings from test_delay_revert");
394   g_free (str);
395   str = NULL;
396
397   g_settings_get (settings2, "greeting", "s", &str);
398   g_assert_cmpstr (str, ==, "top o' the morning");
399   g_free (str);
400   str = NULL;
401
402   g_settings_revert (settings);
403
404   g_settings_get (settings, "greeting", "s", &str);
405   g_assert_cmpstr (str, ==, "top o' the morning");
406   g_free (str);
407   str = NULL;
408
409   g_settings_get (settings2, "greeting", "s", &str);
410   g_assert_cmpstr (str, ==, "top o' the morning");
411   g_free (str);
412   str = NULL;
413
414   g_object_unref (settings2);
415   g_object_unref (settings);
416 }
417
418 static void
419 keys_changed_cb (GSettings    *settings,
420                  const GQuark *keys,
421                  gint          n_keys)
422 {
423   gchar *str;
424
425   g_assert_cmpint (n_keys, ==, 2);
426
427   g_assert ((keys[0] == g_quark_from_static_string ("greeting") &&
428              keys[1] == g_quark_from_static_string ("farewell")) ||
429             (keys[1] == g_quark_from_static_string ("greeting") &&
430              keys[0] == g_quark_from_static_string ("farewell")));
431
432   g_settings_get (settings, "greeting", "s", &str);
433   g_assert_cmpstr (str, ==, "greetings from test_atomic");
434   g_free (str);
435   str = NULL;
436
437   g_settings_get (settings, "farewell", "s", &str);
438   g_assert_cmpstr (str, ==, "atomic bye-bye");
439   g_free (str);
440   str = NULL;
441 }
442
443 static void
444 test_atomic (void)
445 {
446   GSettings *settings;
447   GSettings *settings2;
448   gchar *str;
449
450   settings = g_settings_new ("org.gtk.test");
451   settings2 = g_settings_new ("org.gtk.test");
452
453   g_settings_set (settings2, "greeting", "s", "top o' the morning");
454
455   changed_cb_called = FALSE;
456   changed_cb_called2 = FALSE;
457
458   g_signal_connect (settings2, "change-event",
459                     G_CALLBACK (keys_changed_cb), NULL);
460
461   g_settings_delay (settings);
462
463   g_settings_set (settings, "greeting", "s", "greetings from test_atomic");
464   g_settings_set (settings, "farewell", "s", "atomic bye-bye");
465
466   g_settings_apply (settings);
467
468   g_settings_get (settings, "greeting", "s", &str);
469   g_assert_cmpstr (str, ==, "greetings from test_atomic");
470   g_free (str);
471   str = NULL;
472
473   g_settings_get (settings, "farewell", "s", &str);
474   g_assert_cmpstr (str, ==, "atomic bye-bye");
475   g_free (str);
476   str = NULL;
477
478   g_settings_get (settings2, "greeting", "s", &str);
479   g_assert_cmpstr (str, ==, "greetings from test_atomic");
480   g_free (str);
481   str = NULL;
482
483   g_settings_get (settings2, "farewell", "s", &str);
484   g_assert_cmpstr (str, ==, "atomic bye-bye");
485   g_free (str);
486   str = NULL;
487
488   g_object_unref (settings2);
489   g_object_unref (settings);
490 }
491
492 static void
493 test_l10n (void)
494 {
495   GSettings *settings;
496   gchar *str;
497   gchar *locale;
498
499   bindtextdomain ("test", ".");
500   bind_textdomain_codeset ("test", "UTF-8");
501
502   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
503
504   settings = g_settings_new ("org.gtk.test.localized");
505
506   setlocale (LC_MESSAGES, "C");
507   str = g_settings_get_string (settings, "error-message");
508   setlocale (LC_MESSAGES, locale);
509
510   g_assert_cmpstr (str, ==, "Unnamed");
511   g_free (str);
512   str = NULL;
513
514   setlocale (LC_MESSAGES, "de_DE");
515   str = g_settings_get_string (settings, "error-message");
516   setlocale (LC_MESSAGES, locale);
517
518   g_assert_cmpstr (str, ==, "Unbenannt");
519   g_object_unref (settings);
520   g_free (str);
521   str = NULL;
522
523   g_free (locale);
524 }
525
526 static void
527 test_l10n_context (void)
528 {
529   GSettings *settings;
530   gchar *str;
531   gchar *locale;
532
533   bindtextdomain ("test", ".");
534   bind_textdomain_codeset ("test", "UTF-8");
535
536   locale = g_strdup (setlocale (LC_MESSAGES, NULL));
537
538   settings = g_settings_new ("org.gtk.test.localized");
539
540   setlocale (LC_MESSAGES, "C");
541   g_settings_get (settings, "backspace", "s", &str);
542   setlocale (LC_MESSAGES, locale);
543
544   g_assert_cmpstr (str, ==, "BackSpace");
545   g_free (str);
546   str = NULL;
547
548   setlocale (LC_MESSAGES, "de_DE");
549   g_settings_get (settings, "backspace", "s", &str);
550   setlocale (LC_MESSAGES, locale);
551
552   g_assert_cmpstr (str, ==, "Löschen");
553   g_object_unref (settings);
554   g_free (str);
555   str = NULL;
556
557   g_free (locale);
558 }
559
560 enum
561 {
562   PROP_0,
563   PROP_BOOL,
564   PROP_INT,
565   PROP_DOUBLE,
566   PROP_STRING
567 };
568
569 typedef struct
570 {
571   GObject parent_instance;
572
573   gboolean bool_prop;
574   gint int_prop;
575   gdouble double_prop;
576   gchar *string_prop;
577 } TestObject;
578
579 typedef struct
580 {
581   GObjectClass parent_class;
582 } TestObjectClass;
583
584 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
585
586 static void
587 test_object_init (TestObject *object)
588 {
589 }
590
591 static void
592 test_object_finalize (GObject *object)
593 {
594   TestObject *testo = (TestObject*)object;
595   g_free (testo->string_prop);
596   G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
597 }
598
599 static void
600 test_object_get_property (GObject    *object,
601                           guint       prop_id,
602                           GValue     *value,
603                           GParamSpec *pspec)
604 {
605   TestObject *test_object = (TestObject *)object;
606
607   switch (prop_id)
608     {
609     case PROP_BOOL:
610       g_value_set_boolean (value, test_object->bool_prop);
611       break;
612     case PROP_INT:
613       g_value_set_int (value, test_object->int_prop);
614       break;
615     case PROP_DOUBLE:
616       g_value_set_double (value, test_object->double_prop);
617       break;
618     case PROP_STRING:
619       g_value_set_string (value, test_object->string_prop);
620       break;
621     default:
622       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
623       break;
624     }
625 }
626
627 static void
628 test_object_set_property (GObject      *object,
629                           guint         prop_id,
630                           const GValue *value,
631                           GParamSpec   *pspec)
632 {
633   TestObject *test_object = (TestObject *)object;
634
635   switch (prop_id)
636     {
637     case PROP_BOOL:
638       test_object->bool_prop = g_value_get_boolean (value);
639       break;
640     case PROP_INT:
641       test_object->int_prop = g_value_get_int (value);
642       break;
643     case PROP_DOUBLE:
644       test_object->double_prop = g_value_get_double (value);
645       break;
646     case PROP_STRING:
647       g_free (test_object->string_prop);
648       test_object->string_prop = g_value_dup_string (value);
649       break;
650     default:
651       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
652       break;
653     }
654 }
655
656 static void
657 test_object_class_init (TestObjectClass *class)
658 {
659   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
660
661   gobject_class->get_property = test_object_get_property;
662   gobject_class->set_property = test_object_set_property;
663   gobject_class->finalize = test_object_finalize;
664
665   g_object_class_install_property (gobject_class, PROP_BOOL,
666     g_param_spec_boolean ("bool", "", "", FALSE, G_PARAM_READWRITE));
667   g_object_class_install_property (gobject_class, PROP_INT,
668     g_param_spec_int ("int", "", "", -G_MAXINT, G_MAXINT, 0, G_PARAM_READWRITE));
669   g_object_class_install_property (gobject_class, PROP_DOUBLE,
670     g_param_spec_double ("double", "", "", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE));
671   g_object_class_install_property (gobject_class, PROP_STRING,
672     g_param_spec_string ("string", "", "", NULL, G_PARAM_READWRITE));
673 }
674
675 static TestObject *
676 test_object_new (void)
677 {
678   return (TestObject*)g_object_new (test_object_get_type (), NULL);
679 }
680
681 static void
682 test_simple_binding (void)
683 {
684   TestObject *obj;
685   GSettings *settings;
686   gboolean b;
687   gint i;
688   gdouble d;
689   gchar *s;
690
691   settings = g_settings_new ("org.gtk.test.binding");
692   obj = test_object_new ();
693
694   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_DEFAULT);
695
696   g_object_set (obj, "bool", TRUE, NULL);
697   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
698
699   g_settings_set_boolean (settings, "bool", FALSE);
700   g_object_get (obj, "bool", &b, NULL);
701   g_assert_cmpint (b, ==, FALSE);
702
703   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_DEFAULT);
704
705   g_object_set (obj, "int", 12345, NULL);
706   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 12345);
707
708   g_settings_set_int (settings, "int", 54321);
709   g_object_get (obj, "int", &i, NULL);
710   g_assert_cmpint (i, ==, 54321);
711
712   g_settings_bind (settings, "string", obj, "string", G_SETTINGS_BIND_DEFAULT);
713
714   g_object_set (obj, "string", "bu ba", NULL);
715   s = g_settings_get_string (settings, "string");
716   g_assert_cmpstr (s, ==, "bu ba");
717   g_free (s);
718
719   g_settings_set_string (settings, "string", "bla bla");
720   g_object_get (obj, "string", &s, NULL);
721   g_assert_cmpstr (s, ==, "bla bla");
722   g_free (s);
723
724   g_settings_bind (settings, "double", obj, "double", G_SETTINGS_BIND_DEFAULT);
725
726   g_object_set (obj, "double", 203e7, NULL);
727   g_assert_cmpfloat (g_settings_get_double (settings, "double"), ==, 203e7);
728
729   g_settings_set_double (settings, "double", 207e3);
730   g_object_get (obj, "double", &d, NULL);
731   g_assert_cmpfloat (d, ==, 207e3);
732
733   g_object_unref (obj);
734   g_object_unref (settings);
735 }
736
737 static void
738 test_directional_binding (void)
739 {
740   TestObject *obj;
741   GSettings *settings;
742   gboolean b;
743   gint i;
744
745   settings = g_settings_new ("org.gtk.test.binding");
746   obj = test_object_new ();
747
748   g_object_set (obj, "bool", FALSE, NULL);
749   g_settings_set_boolean (settings, "bool", FALSE);
750
751   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET);
752
753   g_settings_set_boolean (settings, "bool", TRUE);
754   g_object_get (obj, "bool", &b, NULL);
755   g_assert_cmpint (b, ==, TRUE);
756
757   g_object_set (obj, "bool", FALSE, NULL);
758   g_assert_cmpint (g_settings_get_boolean (settings, "bool"), ==, TRUE);
759
760   g_object_set (obj, "int", 20, NULL);
761   g_settings_set_int (settings, "int", 20);
762
763   g_settings_bind (settings, "int", obj, "int", G_SETTINGS_BIND_SET);
764
765   g_object_set (obj, "int", 32, NULL);
766   g_assert_cmpint (g_settings_get_int (settings, "int"), ==, 32);
767
768   g_settings_set_int (settings, "int", 20);
769   g_object_get (obj, "int", &i, NULL);
770   g_assert_cmpint (i, ==, 32);
771
772   g_object_unref (obj);
773   g_object_unref (settings);
774 }
775
776 static void
777 test_typesafe_binding (void)
778 {
779   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
780     {
781       TestObject *obj;
782       GSettings *settings;
783
784       settings = g_settings_new ("org.gtk.test.binding");
785       obj = test_object_new ();
786
787       g_settings_bind (settings, "string", obj, "int", G_SETTINGS_BIND_DEFAULT);
788
789       g_object_unref (obj);
790       g_object_unref (settings);
791     }
792   g_test_trap_assert_failed ();
793   g_test_trap_assert_stderr ("*not compatible*");
794 }
795
796 static gboolean
797 string_to_bool (GValue   *value,
798                 GVariant *variant,
799                 gpointer  user_data)
800 {
801   const gchar *s;
802
803   s = g_variant_get_string (variant, NULL);
804   g_value_set_boolean (value, g_strcmp0 (s, "true") == 0);
805
806   return TRUE;
807 }
808
809 static GVariant *
810 bool_to_string (const GValue       *value,
811                 const GVariantType *expected_type,
812                 gpointer            user_data)
813 {
814   if (g_value_get_boolean (value))
815     return g_variant_new_string ("true");
816   else
817     return g_variant_new_string ("false");
818 }
819
820 static void
821 test_custom_binding (void)
822 {
823   TestObject *obj;
824   GSettings *settings;
825   gchar *s;
826   gboolean b;
827
828   settings = g_settings_new ("org.gtk.test.binding");
829   obj = test_object_new ();
830
831   g_settings_set_string (settings, "string", "true");
832
833   g_settings_bind_with_mapping (settings, "string",
834                                 obj, "bool",
835                                 G_SETTINGS_BIND_DEFAULT,
836                                 string_to_bool,
837                                 bool_to_string,
838                                 NULL, NULL);
839
840   g_settings_set_string (settings, "string", "false");
841   g_object_get (obj, "bool", &b, NULL);
842   g_assert_cmpint (b, ==, FALSE);
843
844   g_settings_set_string (settings, "string", "not true");
845   g_object_get (obj, "bool", &b, NULL);
846   g_assert_cmpint (b, ==, FALSE);
847
848   g_object_set (obj, "bool", TRUE, NULL);
849   s = g_settings_get_string (settings, "string");
850   g_assert_cmpstr (s, ==, "true");
851
852   g_object_unref (obj);
853   g_object_unref (settings);
854 }
855
856 static void
857 test_no_change_binding (void)
858 {
859   TestObject *obj;
860   GSettings *settings;
861   gboolean b;
862
863   settings = g_settings_new ("org.gtk.test.binding");
864   obj = test_object_new ();
865
866   g_object_set (obj, "bool", TRUE, NULL);
867   g_settings_set_boolean (settings, "bool", FALSE);
868
869   g_settings_bind (settings, "bool", obj, "bool", G_SETTINGS_BIND_GET_NO_CHANGES);
870
871   g_object_get (obj, "bool", &b, NULL);
872   g_assert_cmpint (b, ==, FALSE);
873
874   g_settings_set_boolean (settings, "bool", TRUE);
875   g_object_get (obj, "bool", &b, NULL);
876   g_assert_cmpint (b, ==, FALSE);
877
878   g_settings_set_boolean (settings, "bool", FALSE);
879   g_object_set (obj, "bool", TRUE, NULL);
880   b = g_settings_get_boolean (settings, "bool");
881   g_assert_cmpint (b, ==, TRUE);
882
883   g_object_unref (obj);
884   g_object_unref (settings);
885 }
886
887 int
888 main (int argc, char *argv[])
889 {
890   g_setenv ("GSETTINGS_SCHEMA_DIR", ".", TRUE);
891   g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
892
893   g_remove ("./store");
894
895   g_type_init ();
896   g_test_init (&argc, &argv, NULL);
897
898   g_test_add_func ("/gsettings/basic", test_basic);
899   g_test_add_func ("/gsettings/no-schema", test_no_schema);
900   g_test_add_func ("/gsettings/unknown-key", test_unknown_key);
901   g_test_add_func ("/gsettings/wrong-type", test_wrong_type);
902   g_test_add_func ("/gsettings/basic-types", test_basic_types);
903   g_test_add_func ("/gsettings/complex-types", test_complex_types);
904   g_test_add_func ("/gsettings/changes", test_changes);
905   g_test_add_func ("/gsettings/l10n", test_l10n);
906   g_test_add_func ("/gsettings/l10n-context", test_l10n_context);
907   g_test_add_func ("/gsettings/delay-apply", test_delay_apply);
908   g_test_add_func ("/gsettings/delay-revert", test_delay_revert);
909   g_test_add_func ("/gsettings/atomic", test_atomic);
910   g_test_add_func ("/gsettings/simple-binding", test_simple_binding);
911   g_test_add_func ("/gsettings/directional-binding", test_directional_binding);
912   g_test_add_func ("/gsettings/typesafe-binding", test_typesafe_binding);
913   g_test_add_func ("/gsettings/custom-binding", test_custom_binding);
914   g_test_add_func ("/gsettings/no-change-binding", test_no_change_binding);
915
916   return g_test_run ();
917 }