1 | #include <stdlib.h> |
2 | #include <locale.h> |
3 | #include <libintl.h> |
4 | #include <unistd.h> |
5 | #include <sys/types.h> |
6 | #include <gio/gio.h> |
7 | #include <gstdio.h> |
8 | #define G_SETTINGS_ENABLE_BACKEND |
9 | #include <gio/gsettingsbackend.h> |
10 | |
11 | #include "testenum.h" |
12 | |
13 | static const gchar *locale_dir = "." ; |
14 | |
15 | static gboolean backend_set; |
16 | |
17 | /* These tests rely on the schemas in org.gtk.test.gschema.xml |
18 | * to be compiled and installed in the same directory. |
19 | */ |
20 | |
21 | typedef struct |
22 | { |
23 | gchar *tmp_dir; |
24 | } Fixture; |
25 | |
26 | static void |
27 | setup (Fixture *fixture, |
28 | gconstpointer user_data) |
29 | { |
30 | GError *error = NULL; |
31 | |
32 | fixture->tmp_dir = g_dir_make_tmp (tmpl: "gio-test-gsettings_XXXXXX" , error: &error); |
33 | g_assert_no_error (error); |
34 | |
35 | g_test_message (format: "Using temporary directory: %s" , fixture->tmp_dir); |
36 | } |
37 | |
38 | static void |
39 | teardown (Fixture *fixture, |
40 | gconstpointer user_data) |
41 | { |
42 | g_assert_no_errno (g_rmdir (fixture->tmp_dir)); |
43 | g_clear_pointer (&fixture->tmp_dir, g_free); |
44 | } |
45 | |
46 | static void |
47 | check_and_free (GVariant *value, |
48 | const gchar *expected) |
49 | { |
50 | gchar *printed; |
51 | |
52 | printed = g_variant_print (value, TRUE); |
53 | g_assert_cmpstr (printed, ==, expected); |
54 | g_free (mem: printed); |
55 | |
56 | g_variant_unref (value); |
57 | } |
58 | |
59 | |
60 | /* Just to get warmed up: Read and set a string, and |
61 | * verify that can read the changed string back |
62 | */ |
63 | static void |
64 | test_basic (void) |
65 | { |
66 | gchar *str = NULL; |
67 | GObject *b; |
68 | gchar *path; |
69 | gboolean has_unapplied; |
70 | gboolean delay_apply; |
71 | GSettings *settings; |
72 | |
73 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
74 | |
75 | g_object_get (object: settings, |
76 | first_property_name: "schema-id" , &str, |
77 | "backend" , &b, |
78 | "path" , &path, |
79 | "has-unapplied" , &has_unapplied, |
80 | "delay-apply" , &delay_apply, |
81 | NULL); |
82 | g_assert_cmpstr (str, ==, "org.gtk.test" ); |
83 | g_assert_nonnull (b); |
84 | g_assert_cmpstr (path, ==, "/tests/" ); |
85 | g_assert_false (has_unapplied); |
86 | g_assert_false (delay_apply); |
87 | g_free (mem: str); |
88 | g_object_unref (object: b); |
89 | g_free (mem: path); |
90 | |
91 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
92 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
93 | g_free (mem: str); |
94 | |
95 | g_settings_set (settings, key: "greeting" , format: "s" , "goodbye world" ); |
96 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
97 | g_assert_cmpstr (str, ==, "goodbye world" ); |
98 | g_free (mem: str); |
99 | str = NULL; |
100 | |
101 | if (!backend_set && g_test_undefined ()) |
102 | { |
103 | GSettings *tmp_settings = g_settings_new (schema_id: "org.gtk.test" ); |
104 | |
105 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_CRITICAL, |
106 | pattern: "*g_settings_set_value*expects type*" ); |
107 | g_settings_set (settings: tmp_settings, key: "greeting" , format: "i" , 555); |
108 | g_test_assert_expected_messages (); |
109 | |
110 | g_object_unref (object: tmp_settings); |
111 | } |
112 | |
113 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
114 | g_assert_cmpstr (str, ==, "goodbye world" ); |
115 | g_free (mem: str); |
116 | str = NULL; |
117 | |
118 | g_settings_reset (settings, key: "greeting" ); |
119 | str = g_settings_get_string (settings, key: "greeting" ); |
120 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
121 | g_free (mem: str); |
122 | |
123 | g_settings_set (settings, key: "greeting" , format: "s" , "this is the end" ); |
124 | g_object_unref (object: settings); |
125 | } |
126 | |
127 | /* Check that we get an error when getting a key |
128 | * that is not in the schema |
129 | */ |
130 | static void |
131 | test_unknown_key (void) |
132 | { |
133 | if (!g_test_undefined ()) |
134 | return; |
135 | |
136 | if (g_test_subprocess ()) |
137 | { |
138 | GSettings *settings; |
139 | GVariant *value; |
140 | |
141 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
142 | value = g_settings_get_value (settings, key: "no_such_key" ); |
143 | |
144 | g_assert_null (value); |
145 | |
146 | g_object_unref (object: settings); |
147 | return; |
148 | } |
149 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
150 | g_test_trap_assert_failed (); |
151 | g_test_trap_assert_stderr ("*does not contain*" ); |
152 | } |
153 | |
154 | /* Check that we get an error when the schema |
155 | * has not been installed |
156 | */ |
157 | static void |
158 | test_no_schema (void) |
159 | { |
160 | if (!g_test_undefined ()) |
161 | return; |
162 | |
163 | if (g_test_subprocess ()) |
164 | { |
165 | GSettings *settings; |
166 | |
167 | settings = g_settings_new (schema_id: "no.such.schema" ); |
168 | |
169 | g_assert_null (settings); |
170 | return; |
171 | } |
172 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
173 | g_test_trap_assert_failed (); |
174 | g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*" ); |
175 | } |
176 | |
177 | /* Check that we get an error when passing a type string |
178 | * that does not match the schema |
179 | */ |
180 | static void |
181 | test_wrong_type (void) |
182 | { |
183 | GSettings *settings; |
184 | gchar *str = NULL; |
185 | |
186 | if (!g_test_undefined ()) |
187 | return; |
188 | |
189 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
190 | |
191 | g_test_expect_message (log_domain: "GLib" , log_level: G_LOG_LEVEL_CRITICAL, |
192 | pattern: "*given value has a type of*" ); |
193 | g_test_expect_message (log_domain: "GLib" , log_level: G_LOG_LEVEL_CRITICAL, |
194 | pattern: "*valid_format_string*" ); |
195 | g_settings_get (settings, key: "greeting" , format: "o" , &str); |
196 | g_test_assert_expected_messages (); |
197 | |
198 | g_assert_null (str); |
199 | |
200 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_CRITICAL, |
201 | pattern: "*expects type 's'*" ); |
202 | g_settings_set (settings, key: "greeting" , format: "o" , "/a/path" ); |
203 | g_test_assert_expected_messages (); |
204 | |
205 | g_object_unref (object: settings); |
206 | } |
207 | |
208 | /* Check errors with explicit paths */ |
209 | static void |
210 | test_wrong_path (void) |
211 | { |
212 | if (!g_test_undefined ()) |
213 | return; |
214 | |
215 | if (g_test_subprocess ()) |
216 | { |
217 | GSettings *settings G_GNUC_UNUSED; |
218 | |
219 | settings = g_settings_new_with_path (schema_id: "org.gtk.test" , path: "/wrong-path/" ); |
220 | return; |
221 | } |
222 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
223 | g_test_trap_assert_failed (); |
224 | g_test_trap_assert_stderr ("*but path * specified by schema*" ); |
225 | } |
226 | |
227 | static void |
228 | test_no_path (void) |
229 | { |
230 | if (!g_test_undefined ()) |
231 | return; |
232 | |
233 | if (g_test_subprocess ()) |
234 | { |
235 | GSettings *settings G_GNUC_UNUSED; |
236 | |
237 | settings = g_settings_new (schema_id: "org.gtk.test.no-path" ); |
238 | return; |
239 | } |
240 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
241 | g_test_trap_assert_failed (); |
242 | g_test_trap_assert_stderr ("*attempting to create schema * without a path**" ); |
243 | } |
244 | |
245 | |
246 | /* Check that we can successfully read and set the full |
247 | * range of all basic types |
248 | */ |
249 | static void |
250 | test_basic_types (void) |
251 | { |
252 | GSettings *settings; |
253 | gboolean b; |
254 | guint8 byte; |
255 | gint16 i16; |
256 | guint16 u16; |
257 | gint32 i32; |
258 | guint32 u32; |
259 | gint64 i64; |
260 | guint64 u64; |
261 | gdouble d; |
262 | gchar *str; |
263 | |
264 | settings = g_settings_new (schema_id: "org.gtk.test.basic-types" ); |
265 | |
266 | g_settings_get (settings, key: "test-boolean" , format: "b" , &b); |
267 | g_assert_cmpint (b, ==, 1); |
268 | |
269 | g_settings_set (settings, key: "test-boolean" , format: "b" , 0); |
270 | g_settings_get (settings, key: "test-boolean" , format: "b" , &b); |
271 | g_assert_cmpint (b, ==, 0); |
272 | |
273 | g_settings_get (settings, key: "test-byte" , format: "y" , &byte); |
274 | g_assert_cmpint (byte, ==, 25); |
275 | |
276 | g_settings_set (settings, key: "test-byte" , format: "y" , G_MAXUINT8); |
277 | g_settings_get (settings, key: "test-byte" , format: "y" , &byte); |
278 | g_assert_cmpint (byte, ==, G_MAXUINT8); |
279 | |
280 | g_settings_get (settings, key: "test-int16" , format: "n" , &i16); |
281 | g_assert_cmpint (i16, ==, -1234); |
282 | |
283 | g_settings_set (settings, key: "test-int16" , format: "n" , G_MININT16); |
284 | g_settings_get (settings, key: "test-int16" , format: "n" , &i16); |
285 | g_assert_cmpint (i16, ==, G_MININT16); |
286 | |
287 | g_settings_set (settings, key: "test-int16" , format: "n" , G_MAXINT16); |
288 | g_settings_get (settings, key: "test-int16" , format: "n" , &i16); |
289 | g_assert_cmpint (i16, ==, G_MAXINT16); |
290 | |
291 | g_settings_get (settings, key: "test-uint16" , format: "q" , &u16); |
292 | g_assert_cmpuint (u16, ==, 1234); |
293 | |
294 | g_settings_set (settings, key: "test-uint16" , format: "q" , G_MAXUINT16); |
295 | g_settings_get (settings, key: "test-uint16" , format: "q" , &u16); |
296 | g_assert_cmpuint (u16, ==, G_MAXUINT16); |
297 | |
298 | g_settings_get (settings, key: "test-int32" , format: "i" , &i32); |
299 | g_assert_cmpint (i32, ==, -123456); |
300 | |
301 | g_settings_set (settings, key: "test-int32" , format: "i" , G_MININT32); |
302 | g_settings_get (settings, key: "test-int32" , format: "i" , &i32); |
303 | g_assert_cmpint (i32, ==, G_MININT32); |
304 | |
305 | g_settings_set (settings, key: "test-int32" , format: "i" , G_MAXINT32); |
306 | g_settings_get (settings, key: "test-int32" , format: "i" , &i32); |
307 | g_assert_cmpint (i32, ==, G_MAXINT32); |
308 | |
309 | g_settings_get (settings, key: "test-uint32" , format: "u" , &u32); |
310 | g_assert_cmpuint (u32, ==, 123456); |
311 | |
312 | g_settings_set (settings, key: "test-uint32" , format: "u" , G_MAXUINT32); |
313 | g_settings_get (settings, key: "test-uint32" , format: "u" , &u32); |
314 | g_assert_cmpuint (u32, ==, G_MAXUINT32); |
315 | |
316 | g_settings_get (settings, key: "test-int64" , format: "x" , &i64); |
317 | g_assert_cmpuint (i64, ==, -123456789); |
318 | |
319 | g_settings_set (settings, key: "test-int64" , format: "x" , G_MININT64); |
320 | g_settings_get (settings, key: "test-int64" , format: "x" , &i64); |
321 | g_assert_cmpuint (i64, ==, G_MININT64); |
322 | |
323 | g_settings_set (settings, key: "test-int64" , format: "x" , G_MAXINT64); |
324 | g_settings_get (settings, key: "test-int64" , format: "x" , &i64); |
325 | g_assert_cmpuint (i64, ==, G_MAXINT64); |
326 | |
327 | g_settings_get (settings, key: "test-uint64" , format: "t" , &u64); |
328 | g_assert_cmpuint (u64, ==, 123456789); |
329 | |
330 | g_settings_set (settings, key: "test-uint64" , format: "t" , G_MAXUINT64); |
331 | g_settings_get (settings, key: "test-uint64" , format: "t" , &u64); |
332 | g_assert_cmpuint (u64, ==, G_MAXUINT64); |
333 | |
334 | g_settings_get (settings, key: "test-double" , format: "d" , &d); |
335 | g_assert_cmpfloat (d, ==, 123.456); |
336 | |
337 | g_settings_set (settings, key: "test-double" , format: "d" , G_MINDOUBLE); |
338 | g_settings_get (settings, key: "test-double" , format: "d" , &d); |
339 | g_assert_cmpfloat (d, ==, G_MINDOUBLE); |
340 | |
341 | g_settings_set (settings, key: "test-double" , format: "d" , G_MAXDOUBLE); |
342 | g_settings_get (settings, key: "test-double" , format: "d" , &d); |
343 | g_assert_cmpfloat (d, ==, G_MAXDOUBLE); |
344 | |
345 | g_settings_get (settings, key: "test-string" , format: "s" , &str); |
346 | g_assert_cmpstr (str, ==, "a string, it seems" ); |
347 | g_free (mem: str); |
348 | str = NULL; |
349 | |
350 | g_settings_get (settings, key: "test-objectpath" , format: "o" , &str); |
351 | g_assert_cmpstr (str, ==, "/a/object/path" ); |
352 | g_object_unref (object: settings); |
353 | g_free (mem: str); |
354 | str = NULL; |
355 | } |
356 | |
357 | /* Check that we can read an set complex types like |
358 | * tuples, arrays and dictionaries |
359 | */ |
360 | static void |
361 | test_complex_types (void) |
362 | { |
363 | GSettings *settings; |
364 | gchar *s; |
365 | gint i1, i2; |
366 | GVariantIter *iter = NULL; |
367 | GVariant *v = NULL; |
368 | |
369 | settings = g_settings_new (schema_id: "org.gtk.test.complex-types" ); |
370 | |
371 | g_settings_get (settings, key: "test-tuple" , format: "(s(ii))" , &s, &i1, &i2); |
372 | g_assert_cmpstr (s, ==, "one" ); |
373 | g_assert_cmpint (i1,==, 2); |
374 | g_assert_cmpint (i2,==, 3); |
375 | g_free (mem: s) ; |
376 | s = NULL; |
377 | |
378 | g_settings_set (settings, key: "test-tuple" , format: "(s(ii))" , "none" , 0, 0); |
379 | g_settings_get (settings, key: "test-tuple" , format: "(s(ii))" , &s, &i1, &i2); |
380 | g_assert_cmpstr (s, ==, "none" ); |
381 | g_assert_cmpint (i1,==, 0); |
382 | g_assert_cmpint (i2,==, 0); |
383 | g_free (mem: s); |
384 | s = NULL; |
385 | |
386 | g_settings_get (settings, key: "test-array" , format: "ai" , &iter); |
387 | g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6); |
388 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
389 | g_assert_cmpint (i1, ==, 0); |
390 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
391 | g_assert_cmpint (i1, ==, 1); |
392 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
393 | g_assert_cmpint (i1, ==, 2); |
394 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
395 | g_assert_cmpint (i1, ==, 3); |
396 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
397 | g_assert_cmpint (i1, ==, 4); |
398 | g_assert_true (g_variant_iter_next (iter, "i" , &i1)); |
399 | g_assert_cmpint (i1, ==, 5); |
400 | g_assert_false (g_variant_iter_next (iter, "i" , &i1)); |
401 | g_variant_iter_free (iter); |
402 | |
403 | g_settings_get (settings, key: "test-dict" , format: "a{sau}" , &iter); |
404 | g_assert_cmpint (g_variant_iter_n_children (iter), ==, 2); |
405 | g_assert_true (g_variant_iter_next (iter, "{&s@au}" , &s, &v)); |
406 | g_assert_cmpstr (s, ==, "AC" ); |
407 | g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au" ); |
408 | g_variant_unref (value: v); |
409 | g_assert_true (g_variant_iter_next (iter, "{&s@au}" , &s, &v)); |
410 | g_assert_cmpstr (s, ==, "IV" ); |
411 | g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au" ); |
412 | g_variant_unref (value: v); |
413 | g_variant_iter_free (iter); |
414 | |
415 | v = g_settings_get_value (settings, key: "test-dict" ); |
416 | g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "a{sau}" ); |
417 | g_variant_unref (value: v); |
418 | |
419 | g_object_unref (object: settings); |
420 | } |
421 | |
422 | static gboolean changed_cb_called; |
423 | |
424 | static void |
425 | changed_cb (GSettings *settings, |
426 | const gchar *key, |
427 | gpointer data) |
428 | { |
429 | changed_cb_called = TRUE; |
430 | |
431 | g_assert_cmpstr (key, ==, data); |
432 | } |
433 | |
434 | /* Test that basic change notification with the changed signal works. |
435 | */ |
436 | static void |
437 | test_changes (void) |
438 | { |
439 | GSettings *settings; |
440 | GSettings *settings2; |
441 | |
442 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
443 | |
444 | g_signal_connect (settings, "changed" , |
445 | G_CALLBACK (changed_cb), "greeting" ); |
446 | |
447 | changed_cb_called = FALSE; |
448 | |
449 | g_settings_set (settings, key: "greeting" , format: "s" , "new greeting" ); |
450 | g_assert_true (changed_cb_called); |
451 | |
452 | settings2 = g_settings_new (schema_id: "org.gtk.test" ); |
453 | |
454 | changed_cb_called = FALSE; |
455 | |
456 | g_settings_set (settings: settings2, key: "greeting" , format: "s" , "hi" ); |
457 | g_assert_true (changed_cb_called); |
458 | |
459 | g_object_unref (object: settings2); |
460 | g_object_unref (object: settings); |
461 | } |
462 | |
463 | static gboolean changed_cb_called2; |
464 | |
465 | static void |
466 | changed_cb2 (GSettings *settings, |
467 | const gchar *key, |
468 | gpointer data) |
469 | { |
470 | gboolean *p = data; |
471 | |
472 | *p = TRUE; |
473 | } |
474 | |
475 | /* Test that changes done to a delay-mode instance |
476 | * don't appear to the outside world until apply. Also |
477 | * check that we get change notification when they are |
478 | * applied. |
479 | * Also test that the has-unapplied property is properly |
480 | * maintained. |
481 | */ |
482 | static void |
483 | test_delay_apply (void) |
484 | { |
485 | GSettings *settings; |
486 | GSettings *settings2; |
487 | gchar *str; |
488 | gboolean writable; |
489 | GVariant *v; |
490 | const gchar *s; |
491 | |
492 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
493 | settings2 = g_settings_new (schema_id: "org.gtk.test" ); |
494 | |
495 | g_settings_set (settings: settings2, key: "greeting" , format: "s" , "top o' the morning" ); |
496 | |
497 | changed_cb_called = FALSE; |
498 | changed_cb_called2 = FALSE; |
499 | |
500 | g_signal_connect (settings, "changed" , |
501 | G_CALLBACK (changed_cb2), &changed_cb_called); |
502 | g_signal_connect (settings2, "changed" , |
503 | G_CALLBACK (changed_cb2), &changed_cb_called2); |
504 | |
505 | g_settings_delay (settings); |
506 | |
507 | g_settings_set (settings, key: "greeting" , format: "s" , "greetings from test_delay_apply" ); |
508 | |
509 | g_assert_true (changed_cb_called); |
510 | g_assert_false (changed_cb_called2); |
511 | |
512 | /* Try resetting the key and ensure a notification is emitted on the delayed #GSettings object. */ |
513 | changed_cb_called = FALSE; |
514 | changed_cb_called2 = FALSE; |
515 | |
516 | g_settings_reset (settings, key: "greeting" ); |
517 | |
518 | g_assert_true (changed_cb_called); |
519 | g_assert_false (changed_cb_called2); |
520 | |
521 | /* Locally change the greeting again. */ |
522 | changed_cb_called = FALSE; |
523 | changed_cb_called2 = FALSE; |
524 | |
525 | g_settings_set (settings, key: "greeting" , format: "s" , "greetings from test_delay_apply" ); |
526 | |
527 | g_assert_true (changed_cb_called); |
528 | g_assert_false (changed_cb_called2); |
529 | |
530 | writable = g_settings_is_writable (settings, name: "greeting" ); |
531 | g_assert_true (writable); |
532 | |
533 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
534 | g_assert_cmpstr (str, ==, "greetings from test_delay_apply" ); |
535 | g_free (mem: str); |
536 | str = NULL; |
537 | |
538 | v = g_settings_get_user_value (settings, key: "greeting" ); |
539 | s = g_variant_get_string (value: v, NULL); |
540 | g_assert_cmpstr (s, ==, "greetings from test_delay_apply" ); |
541 | g_variant_unref (value: v); |
542 | |
543 | g_settings_get (settings: settings2, key: "greeting" , format: "s" , &str); |
544 | g_assert_cmpstr (str, ==, "top o' the morning" ); |
545 | g_free (mem: str); |
546 | str = NULL; |
547 | |
548 | g_assert_true (g_settings_get_has_unapplied (settings)); |
549 | g_assert_false (g_settings_get_has_unapplied (settings2)); |
550 | |
551 | changed_cb_called = FALSE; |
552 | changed_cb_called2 = FALSE; |
553 | |
554 | g_settings_apply (settings); |
555 | |
556 | g_assert_false (changed_cb_called); |
557 | g_assert_true (changed_cb_called2); |
558 | |
559 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
560 | g_assert_cmpstr (str, ==, "greetings from test_delay_apply" ); |
561 | g_free (mem: str); |
562 | str = NULL; |
563 | |
564 | g_settings_get (settings: settings2, key: "greeting" , format: "s" , &str); |
565 | g_assert_cmpstr (str, ==, "greetings from test_delay_apply" ); |
566 | g_free (mem: str); |
567 | str = NULL; |
568 | |
569 | g_assert_false (g_settings_get_has_unapplied (settings)); |
570 | g_assert_false (g_settings_get_has_unapplied (settings2)); |
571 | |
572 | g_settings_reset (settings, key: "greeting" ); |
573 | g_settings_apply (settings); |
574 | |
575 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
576 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
577 | g_free (mem: str); |
578 | |
579 | g_object_unref (object: settings2); |
580 | g_object_unref (object: settings); |
581 | } |
582 | |
583 | /* Test that reverting unapplied changes in a delay-apply |
584 | * settings instance works. |
585 | */ |
586 | static void |
587 | test_delay_revert (void) |
588 | { |
589 | GSettings *settings; |
590 | GSettings *settings2; |
591 | gchar *str; |
592 | |
593 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
594 | settings2 = g_settings_new (schema_id: "org.gtk.test" ); |
595 | |
596 | g_settings_set (settings: settings2, key: "greeting" , format: "s" , "top o' the morning" ); |
597 | |
598 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
599 | g_assert_cmpstr (str, ==, "top o' the morning" ); |
600 | g_free (mem: str); |
601 | |
602 | g_settings_delay (settings); |
603 | |
604 | g_settings_set (settings, key: "greeting" , format: "s" , "greetings from test_delay_revert" ); |
605 | |
606 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
607 | g_assert_cmpstr (str, ==, "greetings from test_delay_revert" ); |
608 | g_free (mem: str); |
609 | str = NULL; |
610 | |
611 | g_settings_get (settings: settings2, key: "greeting" , format: "s" , &str); |
612 | g_assert_cmpstr (str, ==, "top o' the morning" ); |
613 | g_free (mem: str); |
614 | str = NULL; |
615 | |
616 | g_assert_true (g_settings_get_has_unapplied (settings)); |
617 | |
618 | g_settings_revert (settings); |
619 | |
620 | g_assert_false (g_settings_get_has_unapplied (settings)); |
621 | |
622 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
623 | g_assert_cmpstr (str, ==, "top o' the morning" ); |
624 | g_free (mem: str); |
625 | str = NULL; |
626 | |
627 | g_settings_get (settings: settings2, key: "greeting" , format: "s" , &str); |
628 | g_assert_cmpstr (str, ==, "top o' the morning" ); |
629 | g_free (mem: str); |
630 | str = NULL; |
631 | |
632 | g_object_unref (object: settings2); |
633 | g_object_unref (object: settings); |
634 | } |
635 | |
636 | static void |
637 | test_delay_child (void) |
638 | { |
639 | GSettings *base; |
640 | GSettings *settings; |
641 | GSettings *child; |
642 | guint8 byte; |
643 | gboolean delay; |
644 | |
645 | base = g_settings_new (schema_id: "org.gtk.test.basic-types" ); |
646 | g_settings_set (settings: base, key: "test-byte" , format: "y" , 36); |
647 | |
648 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
649 | g_settings_delay (settings); |
650 | g_object_get (object: settings, first_property_name: "delay-apply" , &delay, NULL); |
651 | g_assert_true (delay); |
652 | |
653 | child = g_settings_get_child (settings, name: "basic-types" ); |
654 | g_assert_nonnull (child); |
655 | |
656 | g_object_get (object: child, first_property_name: "delay-apply" , &delay, NULL); |
657 | g_assert_false (delay); |
658 | |
659 | g_settings_get (settings: child, key: "test-byte" , format: "y" , &byte); |
660 | g_assert_cmpuint (byte, ==, 36); |
661 | |
662 | g_settings_set (settings: child, key: "test-byte" , format: "y" , 42); |
663 | |
664 | /* make sure the child was delayed too */ |
665 | g_settings_get (settings: base, key: "test-byte" , format: "y" , &byte); |
666 | g_assert_cmpuint (byte, ==, 36); |
667 | |
668 | g_object_unref (object: child); |
669 | g_object_unref (object: settings); |
670 | g_object_unref (object: base); |
671 | } |
672 | |
673 | static void |
674 | keys_changed_cb (GSettings *settings, |
675 | const GQuark *keys, |
676 | gint n_keys) |
677 | { |
678 | gchar *str; |
679 | |
680 | g_assert_cmpint (n_keys, ==, 2); |
681 | |
682 | g_assert_true ((keys[0] == g_quark_from_static_string ("greeting" ) && |
683 | keys[1] == g_quark_from_static_string ("farewell" )) || |
684 | (keys[1] == g_quark_from_static_string ("greeting" ) && |
685 | keys[0] == g_quark_from_static_string ("farewell" ))); |
686 | |
687 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
688 | g_assert_cmpstr (str, ==, "greetings from test_atomic" ); |
689 | g_free (mem: str); |
690 | str = NULL; |
691 | |
692 | g_settings_get (settings, key: "farewell" , format: "s" , &str); |
693 | g_assert_cmpstr (str, ==, "atomic bye-bye" ); |
694 | g_free (mem: str); |
695 | str = NULL; |
696 | } |
697 | |
698 | /* Check that delay-applied changes appear atomically. |
699 | * More specifically, verify that all changed keys appear |
700 | * with their new value while handling the change-event signal. |
701 | */ |
702 | static void |
703 | test_atomic (void) |
704 | { |
705 | GSettings *settings; |
706 | GSettings *settings2; |
707 | gchar *str; |
708 | |
709 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
710 | settings2 = g_settings_new (schema_id: "org.gtk.test" ); |
711 | |
712 | g_settings_set (settings: settings2, key: "greeting" , format: "s" , "top o' the morning" ); |
713 | |
714 | changed_cb_called = FALSE; |
715 | changed_cb_called2 = FALSE; |
716 | |
717 | g_signal_connect (settings2, "change-event" , |
718 | G_CALLBACK (keys_changed_cb), NULL); |
719 | |
720 | g_settings_delay (settings); |
721 | |
722 | g_settings_set (settings, key: "greeting" , format: "s" , "greetings from test_atomic" ); |
723 | g_settings_set (settings, key: "farewell" , format: "s" , "atomic bye-bye" ); |
724 | |
725 | g_settings_apply (settings); |
726 | |
727 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
728 | g_assert_cmpstr (str, ==, "greetings from test_atomic" ); |
729 | g_free (mem: str); |
730 | str = NULL; |
731 | |
732 | g_settings_get (settings, key: "farewell" , format: "s" , &str); |
733 | g_assert_cmpstr (str, ==, "atomic bye-bye" ); |
734 | g_free (mem: str); |
735 | str = NULL; |
736 | |
737 | g_settings_get (settings: settings2, key: "greeting" , format: "s" , &str); |
738 | g_assert_cmpstr (str, ==, "greetings from test_atomic" ); |
739 | g_free (mem: str); |
740 | str = NULL; |
741 | |
742 | g_settings_get (settings: settings2, key: "farewell" , format: "s" , &str); |
743 | g_assert_cmpstr (str, ==, "atomic bye-bye" ); |
744 | g_free (mem: str); |
745 | str = NULL; |
746 | |
747 | g_object_unref (object: settings2); |
748 | g_object_unref (object: settings); |
749 | } |
750 | |
751 | /* On Windows the interaction between the C library locale and libintl |
752 | * (from GNU gettext) is not like on POSIX, so just skip these tests |
753 | * for now. |
754 | * |
755 | * There are several issues: |
756 | * |
757 | * 1) The C library doesn't use LC_MESSAGES, that is implemented only |
758 | * in libintl (defined in its <libintl.h>). |
759 | * |
760 | * 2) The locale names that setlocale() accepts and returns aren't in |
761 | * the "de_DE" style, but like "German_Germany". |
762 | * |
763 | * 3) libintl looks at the Win32 thread locale and not the C library |
764 | * locale. (And even if libintl would use the C library's locale, as |
765 | * there are several alternative C library DLLs, libintl might be |
766 | * linked to a different one than the application code, so they |
767 | * wouldn't have the same C library locale anyway.) |
768 | */ |
769 | |
770 | /* Test that translations work for schema defaults. |
771 | * |
772 | * This test relies on the de.po file in the same directory |
773 | * to be compiled into ./de/LC_MESSAGES/test.mo |
774 | */ |
775 | static void |
776 | test_l10n (void) |
777 | { |
778 | GSettings *settings; |
779 | gchar *str; |
780 | gchar *locale; |
781 | |
782 | bindtextdomain (domainname: "test" , dirname: locale_dir); |
783 | bind_textdomain_codeset (domainname: "test" , codeset: "UTF-8" ); |
784 | |
785 | locale = g_strdup (str: setlocale (LC_MESSAGES, NULL)); |
786 | |
787 | settings = g_settings_new (schema_id: "org.gtk.test.localized" ); |
788 | |
789 | g_setenv (variable: "LC_MESSAGES" , value: "C" , TRUE); |
790 | setlocale (LC_MESSAGES, locale: "C" ); |
791 | str = g_settings_get_string (settings, key: "error-message" ); |
792 | g_setenv (variable: "LC_MESSAGES" , value: locale, TRUE); |
793 | setlocale (LC_MESSAGES, locale: locale); |
794 | |
795 | g_assert_cmpstr (str, ==, "Unnamed" ); |
796 | g_free (mem: str); |
797 | str = NULL; |
798 | |
799 | g_setenv (variable: "LC_MESSAGES" , value: "de_DE.UTF-8" , TRUE); |
800 | setlocale (LC_MESSAGES, locale: "de_DE.UTF-8" ); |
801 | /* Only do the test if translation is actually working... */ |
802 | if (g_str_equal (dgettext ("test" , "\"Unnamed\"" ), v2: "\"Unbenannt\"" )) |
803 | { |
804 | str = g_settings_get_string (settings, key: "error-message" ); |
805 | |
806 | g_assert_cmpstr (str, ==, "Unbenannt" ); |
807 | g_free (mem: str); |
808 | str = NULL; |
809 | } |
810 | else |
811 | g_printerr (format: "warning: translation is not working... skipping test. " ); |
812 | |
813 | g_setenv (variable: "LC_MESSAGES" , value: locale, TRUE); |
814 | setlocale (LC_MESSAGES, locale: locale); |
815 | g_free (mem: locale); |
816 | g_object_unref (object: settings); |
817 | } |
818 | |
819 | /* Test that message context works as expected with translated |
820 | * schema defaults. Also, verify that non-ASCII UTF-8 content |
821 | * works. |
822 | * |
823 | * This test relies on the de.po file in the same directory |
824 | * to be compiled into ./de/LC_MESSAGES/test.mo |
825 | */ |
826 | static void |
827 | test_l10n_context (void) |
828 | { |
829 | GSettings *settings; |
830 | gchar *str; |
831 | gchar *locale; |
832 | |
833 | bindtextdomain (domainname: "test" , dirname: locale_dir); |
834 | bind_textdomain_codeset (domainname: "test" , codeset: "UTF-8" ); |
835 | |
836 | locale = g_strdup (str: setlocale (LC_MESSAGES, NULL)); |
837 | |
838 | settings = g_settings_new (schema_id: "org.gtk.test.localized" ); |
839 | |
840 | g_setenv (variable: "LC_MESSAGES" , value: "C" , TRUE); |
841 | setlocale (LC_MESSAGES, locale: "C" ); |
842 | g_settings_get (settings, key: "backspace" , format: "s" , &str); |
843 | g_setenv (variable: "LC_MESSAGES" , value: locale, TRUE); |
844 | setlocale (LC_MESSAGES, locale: locale); |
845 | |
846 | g_assert_cmpstr (str, ==, "BackSpace" ); |
847 | g_free (mem: str); |
848 | str = NULL; |
849 | |
850 | g_setenv (variable: "LC_MESSAGES" , value: "de_DE.UTF-8" , TRUE); |
851 | setlocale (LC_MESSAGES, locale: "de_DE.UTF-8" ); |
852 | /* Only do the test if translation is actually working... */ |
853 | if (g_str_equal (dgettext ("test" , "\"Unnamed\"" ), v2: "\"Unbenannt\"" )) |
854 | { |
855 | g_settings_get (settings, key: "backspace" , format: "s" , &str); |
856 | |
857 | g_assert_cmpstr (str, ==, "Löschen" ); |
858 | g_free (mem: str); |
859 | str = NULL; |
860 | } |
861 | else |
862 | g_printerr (format: "warning: translation is not working... skipping test. " ); |
863 | |
864 | g_setenv (variable: "LC_MESSAGES" , value: locale, TRUE); |
865 | setlocale (LC_MESSAGES, locale: locale); |
866 | g_free (mem: locale); |
867 | g_object_unref (object: settings); |
868 | } |
869 | |
870 | enum |
871 | { |
872 | PROP_0, |
873 | PROP_BOOL, |
874 | PROP_ANTI_BOOL, |
875 | PROP_BYTE, |
876 | PROP_INT16, |
877 | PROP_UINT16, |
878 | PROP_INT, |
879 | PROP_UINT, |
880 | PROP_INT64, |
881 | PROP_UINT64, |
882 | PROP_DOUBLE, |
883 | PROP_STRING, |
884 | PROP_NO_READ, |
885 | PROP_NO_WRITE, |
886 | PROP_STRV, |
887 | PROP_ENUM, |
888 | PROP_FLAGS |
889 | }; |
890 | |
891 | typedef struct |
892 | { |
893 | GObject parent_instance; |
894 | |
895 | gboolean bool_prop; |
896 | gboolean anti_bool_prop; |
897 | gint8 byte_prop; |
898 | gint int16_prop; |
899 | guint16 uint16_prop; |
900 | gint int_prop; |
901 | guint uint_prop; |
902 | gint64 int64_prop; |
903 | guint64 uint64_prop; |
904 | gdouble double_prop; |
905 | gchar *string_prop; |
906 | gchar *no_read_prop; |
907 | gchar *no_write_prop; |
908 | gchar **strv_prop; |
909 | guint enum_prop; |
910 | guint flags_prop; |
911 | } TestObject; |
912 | |
913 | typedef struct |
914 | { |
915 | GObjectClass parent_class; |
916 | } TestObjectClass; |
917 | |
918 | static GType test_object_get_type (void); |
919 | G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT) |
920 | |
921 | static void |
922 | test_object_init (TestObject *object) |
923 | { |
924 | } |
925 | |
926 | static void |
927 | test_object_finalize (GObject *object) |
928 | { |
929 | TestObject *testo = (TestObject*)object; |
930 | g_strfreev (str_array: testo->strv_prop); |
931 | g_free (mem: testo->string_prop); |
932 | G_OBJECT_CLASS (test_object_parent_class)->finalize (object); |
933 | } |
934 | |
935 | static void |
936 | test_object_get_property (GObject *object, |
937 | guint prop_id, |
938 | GValue *value, |
939 | GParamSpec *pspec) |
940 | { |
941 | TestObject *test_object = (TestObject *)object; |
942 | |
943 | switch (prop_id) |
944 | { |
945 | case PROP_BOOL: |
946 | g_value_set_boolean (value, v_boolean: test_object->bool_prop); |
947 | break; |
948 | case PROP_ANTI_BOOL: |
949 | g_value_set_boolean (value, v_boolean: test_object->anti_bool_prop); |
950 | break; |
951 | case PROP_BYTE: |
952 | g_value_set_schar (value, v_char: test_object->byte_prop); |
953 | break; |
954 | case PROP_UINT16: |
955 | g_value_set_uint (value, v_uint: test_object->uint16_prop); |
956 | break; |
957 | case PROP_INT16: |
958 | g_value_set_int (value, v_int: test_object->int16_prop); |
959 | break; |
960 | case PROP_INT: |
961 | g_value_set_int (value, v_int: test_object->int_prop); |
962 | break; |
963 | case PROP_UINT: |
964 | g_value_set_uint (value, v_uint: test_object->uint_prop); |
965 | break; |
966 | case PROP_INT64: |
967 | g_value_set_int64 (value, v_int64: test_object->int64_prop); |
968 | break; |
969 | case PROP_UINT64: |
970 | g_value_set_uint64 (value, v_uint64: test_object->uint64_prop); |
971 | break; |
972 | case PROP_DOUBLE: |
973 | g_value_set_double (value, v_double: test_object->double_prop); |
974 | break; |
975 | case PROP_STRING: |
976 | g_value_set_string (value, v_string: test_object->string_prop); |
977 | break; |
978 | case PROP_NO_WRITE: |
979 | g_value_set_string (value, v_string: test_object->no_write_prop); |
980 | break; |
981 | case PROP_STRV: |
982 | g_value_set_boxed (value, v_boxed: test_object->strv_prop); |
983 | break; |
984 | case PROP_ENUM: |
985 | g_value_set_enum (value, v_enum: test_object->enum_prop); |
986 | break; |
987 | case PROP_FLAGS: |
988 | g_value_set_flags (value, v_flags: test_object->flags_prop); |
989 | break; |
990 | default: |
991 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
992 | break; |
993 | } |
994 | } |
995 | |
996 | static void |
997 | test_object_set_property (GObject *object, |
998 | guint prop_id, |
999 | const GValue *value, |
1000 | GParamSpec *pspec) |
1001 | { |
1002 | TestObject *test_object = (TestObject *)object; |
1003 | |
1004 | switch (prop_id) |
1005 | { |
1006 | case PROP_BOOL: |
1007 | test_object->bool_prop = g_value_get_boolean (value); |
1008 | break; |
1009 | case PROP_ANTI_BOOL: |
1010 | test_object->anti_bool_prop = g_value_get_boolean (value); |
1011 | break; |
1012 | case PROP_BYTE: |
1013 | test_object->byte_prop = g_value_get_schar (value); |
1014 | break; |
1015 | case PROP_INT16: |
1016 | test_object->int16_prop = g_value_get_int (value); |
1017 | break; |
1018 | case PROP_UINT16: |
1019 | test_object->uint16_prop = g_value_get_uint (value); |
1020 | break; |
1021 | case PROP_INT: |
1022 | test_object->int_prop = g_value_get_int (value); |
1023 | break; |
1024 | case PROP_UINT: |
1025 | test_object->uint_prop = g_value_get_uint (value); |
1026 | break; |
1027 | case PROP_INT64: |
1028 | test_object->int64_prop = g_value_get_int64 (value); |
1029 | break; |
1030 | case PROP_UINT64: |
1031 | test_object->uint64_prop = g_value_get_uint64 (value); |
1032 | break; |
1033 | case PROP_DOUBLE: |
1034 | test_object->double_prop = g_value_get_double (value); |
1035 | break; |
1036 | case PROP_STRING: |
1037 | g_free (mem: test_object->string_prop); |
1038 | test_object->string_prop = g_value_dup_string (value); |
1039 | break; |
1040 | case PROP_NO_READ: |
1041 | g_free (mem: test_object->no_read_prop); |
1042 | test_object->no_read_prop = g_value_dup_string (value); |
1043 | break; |
1044 | case PROP_STRV: |
1045 | g_strfreev (str_array: test_object->strv_prop); |
1046 | test_object->strv_prop = g_value_dup_boxed (value); |
1047 | break; |
1048 | case PROP_ENUM: |
1049 | test_object->enum_prop = g_value_get_enum (value); |
1050 | break; |
1051 | case PROP_FLAGS: |
1052 | test_object->flags_prop = g_value_get_flags (value); |
1053 | break; |
1054 | default: |
1055 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1056 | break; |
1057 | } |
1058 | } |
1059 | |
1060 | static GType |
1061 | test_enum_get_type (void) |
1062 | { |
1063 | static gsize define_type_id = 0; |
1064 | |
1065 | if (g_once_init_enter (&define_type_id)) |
1066 | { |
1067 | static const GEnumValue values[] = { |
1068 | { TEST_ENUM_FOO, "TEST_ENUM_FOO" , "foo" }, |
1069 | { TEST_ENUM_BAR, "TEST_ENUM_BAR" , "bar" }, |
1070 | { TEST_ENUM_BAZ, "TEST_ENUM_BAZ" , "baz" }, |
1071 | { TEST_ENUM_QUUX, "TEST_ENUM_QUUX" , "quux" }, |
1072 | { 0, NULL, NULL } |
1073 | }; |
1074 | |
1075 | GType type_id = g_enum_register_static (name: "TestEnum" , const_static_values: values); |
1076 | g_once_init_leave (&define_type_id, type_id); |
1077 | } |
1078 | |
1079 | return define_type_id; |
1080 | } |
1081 | |
1082 | static GType |
1083 | test_flags_get_type (void) |
1084 | { |
1085 | static gsize define_type_id = 0; |
1086 | |
1087 | if (g_once_init_enter (&define_type_id)) |
1088 | { |
1089 | static const GFlagsValue values[] = { |
1090 | { TEST_FLAGS_NONE, "TEST_FLAGS_NONE" , "none" }, |
1091 | { TEST_FLAGS_MOURNING, "TEST_FLAGS_MOURNING" , "mourning" }, |
1092 | { TEST_FLAGS_LAUGHING, "TEST_FLAGS_LAUGHING" , "laughing" }, |
1093 | { TEST_FLAGS_WALKING, "TEST_FLAGS_WALKING" , "walking" }, |
1094 | { 0, NULL, NULL } |
1095 | }; |
1096 | |
1097 | GType type_id = g_flags_register_static (name: "TestFlags" , const_static_values: values); |
1098 | g_once_init_leave (&define_type_id, type_id); |
1099 | } |
1100 | |
1101 | return define_type_id; |
1102 | } |
1103 | |
1104 | static void |
1105 | test_object_class_init (TestObjectClass *class) |
1106 | { |
1107 | GObjectClass *gobject_class = G_OBJECT_CLASS (class); |
1108 | |
1109 | gobject_class->get_property = test_object_get_property; |
1110 | gobject_class->set_property = test_object_set_property; |
1111 | gobject_class->finalize = test_object_finalize; |
1112 | |
1113 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_BOOL, |
1114 | pspec: g_param_spec_boolean (name: "bool" , nick: "" , blurb: "" , FALSE, flags: G_PARAM_READWRITE)); |
1115 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_ANTI_BOOL, |
1116 | pspec: g_param_spec_boolean (name: "anti-bool" , nick: "" , blurb: "" , FALSE, flags: G_PARAM_READWRITE)); |
1117 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_BYTE, |
1118 | pspec: g_param_spec_char (name: "byte" , nick: "" , blurb: "" , G_MININT8, G_MAXINT8, default_value: 0, flags: G_PARAM_READWRITE)); |
1119 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_INT16, |
1120 | pspec: g_param_spec_int (name: "int16" , nick: "" , blurb: "" , minimum: -G_MAXINT16, G_MAXINT16, default_value: 0, flags: G_PARAM_READWRITE)); |
1121 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_UINT16, |
1122 | pspec: g_param_spec_uint (name: "uint16" , nick: "" , blurb: "" , minimum: 0, G_MAXUINT16, default_value: 0, flags: G_PARAM_READWRITE)); |
1123 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_INT, |
1124 | pspec: g_param_spec_int (name: "int" , nick: "" , blurb: "" , G_MININT, G_MAXINT, default_value: 0, flags: G_PARAM_READWRITE)); |
1125 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_UINT, |
1126 | pspec: g_param_spec_uint (name: "uint" , nick: "" , blurb: "" , minimum: 0, G_MAXUINT, default_value: 0, flags: G_PARAM_READWRITE)); |
1127 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_INT64, |
1128 | pspec: g_param_spec_int64 (name: "int64" , nick: "" , blurb: "" , G_MININT64, G_MAXINT64, default_value: 0, flags: G_PARAM_READWRITE)); |
1129 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_UINT64, |
1130 | pspec: g_param_spec_uint64 (name: "uint64" , nick: "" , blurb: "" , minimum: 0, G_MAXUINT64, default_value: 0, flags: G_PARAM_READWRITE)); |
1131 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_DOUBLE, |
1132 | pspec: g_param_spec_double (name: "double" , nick: "" , blurb: "" , minimum: -G_MAXDOUBLE, G_MAXDOUBLE, default_value: 0.0, flags: G_PARAM_READWRITE)); |
1133 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_STRING, |
1134 | pspec: g_param_spec_string (name: "string" , nick: "" , blurb: "" , NULL, flags: G_PARAM_READWRITE)); |
1135 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_NO_WRITE, |
1136 | pspec: g_param_spec_string (name: "no-write" , nick: "" , blurb: "" , NULL, flags: G_PARAM_READABLE)); |
1137 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_NO_READ, |
1138 | pspec: g_param_spec_string (name: "no-read" , nick: "" , blurb: "" , NULL, flags: G_PARAM_WRITABLE)); |
1139 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_STRV, |
1140 | pspec: g_param_spec_boxed (name: "strv" , nick: "" , blurb: "" , G_TYPE_STRV, flags: G_PARAM_READWRITE)); |
1141 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_ENUM, |
1142 | pspec: g_param_spec_enum (name: "enum" , nick: "" , blurb: "" , enum_type: test_enum_get_type (), default_value: TEST_ENUM_FOO, flags: G_PARAM_READWRITE)); |
1143 | g_object_class_install_property (oclass: gobject_class, property_id: PROP_FLAGS, |
1144 | pspec: g_param_spec_flags (name: "flags" , nick: "" , blurb: "" , flags_type: test_flags_get_type (), default_value: TEST_FLAGS_NONE, flags: G_PARAM_READWRITE)); |
1145 | } |
1146 | |
1147 | static TestObject * |
1148 | test_object_new (void) |
1149 | { |
1150 | return (TestObject*)g_object_new (object_type: test_object_get_type (), NULL); |
1151 | } |
1152 | |
1153 | /* Test basic binding functionality for simple types. |
1154 | * Verify that with bidirectional bindings, changes on either side |
1155 | * are notified on the other end. |
1156 | */ |
1157 | static void |
1158 | test_simple_binding (void) |
1159 | { |
1160 | TestObject *obj; |
1161 | GSettings *settings; |
1162 | gboolean b; |
1163 | gchar y; |
1164 | gint i; |
1165 | guint u; |
1166 | gint16 n; |
1167 | guint16 q; |
1168 | gint n2; |
1169 | guint q2; |
1170 | gint64 i64; |
1171 | guint64 u64; |
1172 | gdouble d; |
1173 | gchar *s; |
1174 | GVariant *value; |
1175 | gchar **strv; |
1176 | |
1177 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1178 | obj = test_object_new (); |
1179 | |
1180 | g_settings_bind (settings, key: "bool" , object: obj, property: "bool" , flags: G_SETTINGS_BIND_DEFAULT); |
1181 | g_object_set (object: obj, first_property_name: "bool" , TRUE, NULL); |
1182 | g_assert_cmpint (g_settings_get_boolean (settings, "bool" ), ==, TRUE); |
1183 | |
1184 | g_settings_set_boolean (settings, key: "bool" , FALSE); |
1185 | b = TRUE; |
1186 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1187 | g_assert_cmpint (b, ==, FALSE); |
1188 | |
1189 | g_settings_bind (settings, key: "anti-bool" , object: obj, property: "anti-bool" , |
1190 | flags: G_SETTINGS_BIND_INVERT_BOOLEAN); |
1191 | g_object_set (object: obj, first_property_name: "anti-bool" , FALSE, NULL); |
1192 | g_assert_cmpint (g_settings_get_boolean (settings, "anti-bool" ), ==, TRUE); |
1193 | |
1194 | g_settings_set_boolean (settings, key: "anti-bool" , FALSE); |
1195 | b = FALSE; |
1196 | g_object_get (object: obj, first_property_name: "anti-bool" , &b, NULL); |
1197 | g_assert_cmpint (b, ==, TRUE); |
1198 | |
1199 | g_settings_bind (settings, key: "byte" , object: obj, property: "byte" , flags: G_SETTINGS_BIND_DEFAULT); |
1200 | |
1201 | g_object_set (object: obj, first_property_name: "byte" , 123, NULL); |
1202 | y = 'c'; |
1203 | g_settings_get (settings, key: "byte" , format: "y" , &y); |
1204 | g_assert_cmpint (y, ==, 123); |
1205 | |
1206 | g_settings_set (settings, key: "byte" , format: "y" , 54); |
1207 | y = 'c'; |
1208 | g_object_get (object: obj, first_property_name: "byte" , &y, NULL); |
1209 | g_assert_cmpint (y, ==, 54); |
1210 | |
1211 | g_settings_bind (settings, key: "int16" , object: obj, property: "int16" , flags: G_SETTINGS_BIND_DEFAULT); |
1212 | |
1213 | g_object_set (object: obj, first_property_name: "int16" , 1234, NULL); |
1214 | n = 4321; |
1215 | g_settings_get (settings, key: "int16" , format: "n" , &n); |
1216 | g_assert_cmpint (n, ==, 1234); |
1217 | |
1218 | g_settings_set (settings, key: "int16" , format: "n" , 4321); |
1219 | n2 = 1111; |
1220 | g_object_get (object: obj, first_property_name: "int16" , &n2, NULL); |
1221 | g_assert_cmpint (n2, ==, 4321); |
1222 | |
1223 | g_settings_bind (settings, key: "uint16" , object: obj, property: "uint16" , flags: G_SETTINGS_BIND_DEFAULT); |
1224 | |
1225 | g_object_set (object: obj, first_property_name: "uint16" , (guint16) G_MAXUINT16, NULL); |
1226 | q = 1111; |
1227 | g_settings_get (settings, key: "uint16" , format: "q" , &q); |
1228 | g_assert_cmpuint (q, ==, G_MAXUINT16); |
1229 | |
1230 | g_settings_set (settings, key: "uint16" , format: "q" , (guint16) G_MAXINT16); |
1231 | q2 = 1111; |
1232 | g_object_get (object: obj, first_property_name: "uint16" , &q2, NULL); |
1233 | g_assert_cmpuint (q2, ==, (guint16) G_MAXINT16); |
1234 | |
1235 | g_settings_bind (settings, key: "int" , object: obj, property: "int" , flags: G_SETTINGS_BIND_DEFAULT); |
1236 | |
1237 | g_object_set (object: obj, first_property_name: "int" , 12345, NULL); |
1238 | g_assert_cmpint (g_settings_get_int (settings, "int" ), ==, 12345); |
1239 | |
1240 | g_settings_set_int (settings, key: "int" , value: 54321); |
1241 | i = 1111; |
1242 | g_object_get (object: obj, first_property_name: "int" , &i, NULL); |
1243 | g_assert_cmpint (i, ==, 54321); |
1244 | |
1245 | g_settings_bind (settings, key: "uint" , object: obj, property: "uint" , flags: G_SETTINGS_BIND_DEFAULT); |
1246 | |
1247 | g_object_set (object: obj, first_property_name: "uint" , 12345, NULL); |
1248 | g_assert_cmpuint (g_settings_get_uint (settings, "uint" ), ==, 12345); |
1249 | |
1250 | g_settings_set_uint (settings, key: "uint" , value: 54321); |
1251 | u = 1111; |
1252 | g_object_get (object: obj, first_property_name: "uint" , &u, NULL); |
1253 | g_assert_cmpuint (u, ==, 54321); |
1254 | |
1255 | g_settings_bind (settings, key: "uint64" , object: obj, property: "uint64" , flags: G_SETTINGS_BIND_DEFAULT); |
1256 | |
1257 | g_object_set (object: obj, first_property_name: "uint64" , (guint64) 12345, NULL); |
1258 | g_assert_cmpuint (g_settings_get_uint64 (settings, "uint64" ), ==, 12345); |
1259 | |
1260 | g_settings_set_uint64 (settings, key: "uint64" , value: 54321); |
1261 | u64 = 1111; |
1262 | g_object_get (object: obj, first_property_name: "uint64" , &u64, NULL); |
1263 | g_assert_cmpuint (u64, ==, 54321); |
1264 | |
1265 | g_settings_bind (settings, key: "int64" , object: obj, property: "int64" , flags: G_SETTINGS_BIND_DEFAULT); |
1266 | |
1267 | g_object_set (object: obj, first_property_name: "int64" , (gint64) G_MAXINT64, NULL); |
1268 | i64 = 1111; |
1269 | g_settings_get (settings, key: "int64" , format: "x" , &i64); |
1270 | g_assert_cmpint (i64, ==, G_MAXINT64); |
1271 | |
1272 | g_settings_set (settings, key: "int64" , format: "x" , (gint64) G_MININT64); |
1273 | i64 = 1111; |
1274 | g_object_get (object: obj, first_property_name: "int64" , &i64, NULL); |
1275 | g_assert_cmpint (i64, ==, G_MININT64); |
1276 | |
1277 | g_settings_bind (settings, key: "uint64" , object: obj, property: "uint64" , flags: G_SETTINGS_BIND_DEFAULT); |
1278 | |
1279 | g_object_set (object: obj, first_property_name: "uint64" , (guint64) G_MAXUINT64, NULL); |
1280 | u64 = 1111; |
1281 | g_settings_get (settings, key: "uint64" , format: "t" , &u64); |
1282 | g_assert_cmpuint (u64, ==, G_MAXUINT64); |
1283 | |
1284 | g_settings_set (settings, key: "uint64" , format: "t" , (guint64) G_MAXINT64); |
1285 | u64 = 1111; |
1286 | g_object_get (object: obj, first_property_name: "uint64" , &u64, NULL); |
1287 | g_assert_cmpuint (u64, ==, (guint64) G_MAXINT64); |
1288 | |
1289 | g_settings_bind (settings, key: "string" , object: obj, property: "string" , flags: G_SETTINGS_BIND_DEFAULT); |
1290 | |
1291 | g_object_set (object: obj, first_property_name: "string" , "bu ba" , NULL); |
1292 | s = g_settings_get_string (settings, key: "string" ); |
1293 | g_assert_cmpstr (s, ==, "bu ba" ); |
1294 | g_free (mem: s); |
1295 | |
1296 | g_settings_set_string (settings, key: "string" , value: "bla bla" ); |
1297 | g_object_get (object: obj, first_property_name: "string" , &s, NULL); |
1298 | g_assert_cmpstr (s, ==, "bla bla" ); |
1299 | g_free (mem: s); |
1300 | |
1301 | g_settings_bind (settings, key: "chararray" , object: obj, property: "string" , flags: G_SETTINGS_BIND_DEFAULT); |
1302 | |
1303 | g_object_set (object: obj, first_property_name: "string" , "non-unicode:\315" , NULL); |
1304 | value = g_settings_get_value (settings, key: "chararray" ); |
1305 | g_assert_cmpstr (g_variant_get_bytestring (value), ==, "non-unicode:\315" ); |
1306 | g_variant_unref (value); |
1307 | |
1308 | g_settings_bind (settings, key: "double" , object: obj, property: "double" , flags: G_SETTINGS_BIND_DEFAULT); |
1309 | |
1310 | g_object_set (object: obj, first_property_name: "double" , G_MAXFLOAT, NULL); |
1311 | g_assert_cmpfloat (g_settings_get_double (settings, "double" ), ==, G_MAXFLOAT); |
1312 | |
1313 | g_settings_set_double (settings, key: "double" , G_MINFLOAT); |
1314 | d = 1.0; |
1315 | g_object_get (object: obj, first_property_name: "double" , &d, NULL); |
1316 | g_assert_cmpfloat (d, ==, G_MINFLOAT); |
1317 | |
1318 | g_object_set (object: obj, first_property_name: "double" , G_MAXDOUBLE, NULL); |
1319 | g_assert_cmpfloat (g_settings_get_double (settings, "double" ), ==, G_MAXDOUBLE); |
1320 | |
1321 | g_settings_set_double (settings, key: "double" , value: -G_MINDOUBLE); |
1322 | d = 1.0; |
1323 | g_object_get (object: obj, first_property_name: "double" , &d, NULL); |
1324 | g_assert_cmpfloat (d, ==, -G_MINDOUBLE); |
1325 | |
1326 | strv = g_strsplit (string: "plastic bag,middle class,polyethylene" , delimiter: "," , max_tokens: 0); |
1327 | g_settings_bind (settings, key: "strv" , object: obj, property: "strv" , flags: G_SETTINGS_BIND_DEFAULT); |
1328 | g_object_set (object: obj, first_property_name: "strv" , strv, NULL); |
1329 | g_strfreev (str_array: strv); |
1330 | strv = g_settings_get_strv (settings, key: "strv" ); |
1331 | s = g_strjoinv (separator: "," , str_array: strv); |
1332 | g_assert_cmpstr (s, ==, "plastic bag,middle class,polyethylene" ); |
1333 | g_strfreev (str_array: strv); |
1334 | g_free (mem: s); |
1335 | strv = g_strsplit (string: "decaffeinate,unleaded,keep all surfaces clean" , delimiter: "," , max_tokens: 0); |
1336 | g_settings_set_strv (settings, key: "strv" , value: (const gchar **) strv); |
1337 | g_strfreev (str_array: strv); |
1338 | g_object_get (object: obj, first_property_name: "strv" , &strv, NULL); |
1339 | s = g_strjoinv (separator: "," , str_array: strv); |
1340 | g_assert_cmpstr (s, ==, "decaffeinate,unleaded,keep all surfaces clean" ); |
1341 | g_strfreev (str_array: strv); |
1342 | g_free (mem: s); |
1343 | g_settings_set_strv (settings, key: "strv" , NULL); |
1344 | g_object_get (object: obj, first_property_name: "strv" , &strv, NULL); |
1345 | g_assert_nonnull (strv); |
1346 | g_assert_cmpint (g_strv_length (strv), ==, 0); |
1347 | g_strfreev (str_array: strv); |
1348 | |
1349 | g_settings_bind (settings, key: "enum" , object: obj, property: "enum" , flags: G_SETTINGS_BIND_DEFAULT); |
1350 | g_object_set (object: obj, first_property_name: "enum" , TEST_ENUM_BAZ, NULL); |
1351 | s = g_settings_get_string (settings, key: "enum" ); |
1352 | g_assert_cmpstr (s, ==, "baz" ); |
1353 | g_free (mem: s); |
1354 | g_assert_cmpint (g_settings_get_enum (settings, "enum" ), ==, TEST_ENUM_BAZ); |
1355 | |
1356 | g_settings_set_enum (settings, key: "enum" , value: TEST_ENUM_QUUX); |
1357 | i = 230; |
1358 | g_object_get (object: obj, first_property_name: "enum" , &i, NULL); |
1359 | g_assert_cmpint (i, ==, TEST_ENUM_QUUX); |
1360 | |
1361 | g_settings_set_string (settings, key: "enum" , value: "baz" ); |
1362 | i = 230; |
1363 | g_object_get (object: obj, first_property_name: "enum" , &i, NULL); |
1364 | g_assert_cmpint (i, ==, TEST_ENUM_BAZ); |
1365 | |
1366 | g_settings_bind (settings, key: "flags" , object: obj, property: "flags" , flags: G_SETTINGS_BIND_DEFAULT); |
1367 | g_object_set (object: obj, first_property_name: "flags" , TEST_FLAGS_MOURNING, NULL); |
1368 | strv = g_settings_get_strv (settings, key: "flags" ); |
1369 | g_assert_cmpint (g_strv_length (strv), ==, 1); |
1370 | g_assert_cmpstr (strv[0], ==, "mourning" ); |
1371 | g_strfreev (str_array: strv); |
1372 | |
1373 | g_assert_cmpint (g_settings_get_flags (settings, "flags" ), ==, TEST_FLAGS_MOURNING); |
1374 | |
1375 | g_settings_set_flags (settings, key: "flags" , value: TEST_FLAGS_MOURNING | TEST_FLAGS_WALKING); |
1376 | i = 230; |
1377 | g_object_get (object: obj, first_property_name: "flags" , &i, NULL); |
1378 | g_assert_cmpint (i, ==, TEST_FLAGS_MOURNING | TEST_FLAGS_WALKING); |
1379 | |
1380 | g_settings_bind (settings, key: "uint" , object: obj, property: "uint" , flags: G_SETTINGS_BIND_DEFAULT); |
1381 | |
1382 | g_object_set (object: obj, first_property_name: "uint" , 12345, NULL); |
1383 | g_assert_cmpuint (g_settings_get_uint (settings, "uint" ), ==, 12345); |
1384 | |
1385 | g_settings_set_uint (settings, key: "uint" , value: 54321); |
1386 | u = 1111; |
1387 | g_object_get (object: obj, first_property_name: "uint" , &u, NULL); |
1388 | g_assert_cmpuint (u, ==, 54321); |
1389 | |
1390 | g_settings_bind (settings, key: "range" , object: obj, property: "uint" , flags: G_SETTINGS_BIND_DEFAULT); |
1391 | g_object_set (object: obj, first_property_name: "uint" , 22, NULL); |
1392 | u = 1111; |
1393 | g_assert_cmpuint (g_settings_get_uint (settings, "range" ), ==, 22); |
1394 | g_object_get (object: obj, first_property_name: "uint" , &u, NULL); |
1395 | g_assert_cmpuint (u, ==, 22); |
1396 | |
1397 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_CRITICAL, |
1398 | pattern: "* is out of schema-specified range for*" ); |
1399 | g_object_set (object: obj, first_property_name: "uint" , 45, NULL); |
1400 | g_test_assert_expected_messages (); |
1401 | u = 1111; |
1402 | g_object_get (object: obj, first_property_name: "uint" , &u, NULL); |
1403 | g_assert_cmpuint (g_settings_get_uint (settings, "range" ), ==, 22); |
1404 | /* The value of the object is currently not reset back to its initial value |
1405 | g_assert_cmpuint (u, ==, 22); */ |
1406 | |
1407 | g_object_unref (object: obj); |
1408 | g_object_unref (object: settings); |
1409 | } |
1410 | |
1411 | static void |
1412 | test_unbind (void) |
1413 | { |
1414 | TestObject *obj; |
1415 | GSettings *settings; |
1416 | |
1417 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1418 | obj = test_object_new (); |
1419 | |
1420 | g_settings_bind (settings, key: "int" , object: obj, property: "int" , flags: G_SETTINGS_BIND_DEFAULT); |
1421 | |
1422 | g_object_set (object: obj, first_property_name: "int" , 12345, NULL); |
1423 | g_assert_cmpint (g_settings_get_int (settings, "int" ), ==, 12345); |
1424 | |
1425 | g_settings_unbind (object: obj, property: "int" ); |
1426 | |
1427 | g_object_set (object: obj, first_property_name: "int" , 54321, NULL); |
1428 | g_assert_cmpint (g_settings_get_int (settings, "int" ), ==, 12345); |
1429 | |
1430 | g_object_unref (object: obj); |
1431 | g_object_unref (object: settings); |
1432 | } |
1433 | |
1434 | static void |
1435 | test_bind_writable (void) |
1436 | { |
1437 | TestObject *obj; |
1438 | GSettings *settings; |
1439 | gboolean b; |
1440 | |
1441 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1442 | obj = test_object_new (); |
1443 | |
1444 | g_object_set (object: obj, first_property_name: "bool" , FALSE, NULL); |
1445 | |
1446 | g_settings_bind_writable (settings, key: "int" , object: obj, property: "bool" , FALSE); |
1447 | |
1448 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1449 | g_assert_true (b); |
1450 | |
1451 | g_settings_unbind (object: obj, property: "bool" ); |
1452 | |
1453 | g_settings_bind_writable (settings, key: "int" , object: obj, property: "bool" , TRUE); |
1454 | |
1455 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1456 | g_assert_false (b); |
1457 | |
1458 | g_object_unref (object: obj); |
1459 | g_object_unref (object: settings); |
1460 | } |
1461 | |
1462 | /* Test one-way bindings. |
1463 | * Verify that changes on one side show up on the other, |
1464 | * but not vice versa |
1465 | */ |
1466 | static void |
1467 | test_directional_binding (void) |
1468 | { |
1469 | TestObject *obj; |
1470 | GSettings *settings; |
1471 | gboolean b; |
1472 | gint i; |
1473 | |
1474 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1475 | obj = test_object_new (); |
1476 | |
1477 | g_object_set (object: obj, first_property_name: "bool" , FALSE, NULL); |
1478 | g_settings_set_boolean (settings, key: "bool" , FALSE); |
1479 | |
1480 | g_settings_bind (settings, key: "bool" , object: obj, property: "bool" , flags: G_SETTINGS_BIND_GET); |
1481 | |
1482 | g_settings_set_boolean (settings, key: "bool" , TRUE); |
1483 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1484 | g_assert_cmpint (b, ==, TRUE); |
1485 | |
1486 | g_object_set (object: obj, first_property_name: "bool" , FALSE, NULL); |
1487 | g_assert_cmpint (g_settings_get_boolean (settings, "bool" ), ==, TRUE); |
1488 | |
1489 | g_object_set (object: obj, first_property_name: "int" , 20, NULL); |
1490 | g_settings_set_int (settings, key: "int" , value: 20); |
1491 | |
1492 | g_settings_bind (settings, key: "int" , object: obj, property: "int" , flags: G_SETTINGS_BIND_SET); |
1493 | |
1494 | g_object_set (object: obj, first_property_name: "int" , 32, NULL); |
1495 | g_assert_cmpint (g_settings_get_int (settings, "int" ), ==, 32); |
1496 | |
1497 | g_settings_set_int (settings, key: "int" , value: 20); |
1498 | g_object_get (object: obj, first_property_name: "int" , &i, NULL); |
1499 | g_assert_cmpint (i, ==, 32); |
1500 | |
1501 | g_object_unref (object: obj); |
1502 | g_object_unref (object: settings); |
1503 | } |
1504 | |
1505 | /* Test that type mismatch is caught when creating a binding */ |
1506 | static void |
1507 | test_typesafe_binding (void) |
1508 | { |
1509 | if (!g_test_undefined ()) |
1510 | return; |
1511 | |
1512 | if (g_test_subprocess ()) |
1513 | { |
1514 | TestObject *obj; |
1515 | GSettings *settings; |
1516 | |
1517 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1518 | obj = test_object_new (); |
1519 | |
1520 | g_settings_bind (settings, key: "string" , object: obj, property: "int" , flags: G_SETTINGS_BIND_DEFAULT); |
1521 | |
1522 | g_object_unref (object: obj); |
1523 | g_object_unref (object: settings); |
1524 | return; |
1525 | } |
1526 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
1527 | g_test_trap_assert_failed (); |
1528 | g_test_trap_assert_stderr ("*not compatible*" ); |
1529 | } |
1530 | |
1531 | static gboolean |
1532 | string_to_bool (GValue *value, |
1533 | GVariant *variant, |
1534 | gpointer user_data) |
1535 | { |
1536 | const gchar *s; |
1537 | |
1538 | s = g_variant_get_string (value: variant, NULL); |
1539 | g_value_set_boolean (value, v_boolean: g_strcmp0 (str1: s, str2: "true" ) == 0); |
1540 | |
1541 | return TRUE; |
1542 | } |
1543 | |
1544 | static GVariant * |
1545 | bool_to_string (const GValue *value, |
1546 | const GVariantType *expected_type, |
1547 | gpointer user_data) |
1548 | { |
1549 | if (g_value_get_boolean (value)) |
1550 | return g_variant_new_string (string: "true" ); |
1551 | else |
1552 | return g_variant_new_string (string: "false" ); |
1553 | } |
1554 | |
1555 | static GVariant * |
1556 | bool_to_bool (const GValue *value, |
1557 | const GVariantType *expected_type, |
1558 | gpointer user_data) |
1559 | { |
1560 | return g_variant_new_boolean (value: g_value_get_boolean (value)); |
1561 | } |
1562 | |
1563 | /* Test custom bindings. |
1564 | * Translate strings to booleans and back |
1565 | */ |
1566 | static void |
1567 | test_custom_binding (void) |
1568 | { |
1569 | TestObject *obj; |
1570 | GSettings *settings; |
1571 | gchar *s; |
1572 | gboolean b; |
1573 | |
1574 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1575 | obj = test_object_new (); |
1576 | |
1577 | g_settings_set_string (settings, key: "string" , value: "true" ); |
1578 | |
1579 | g_settings_bind_with_mapping (settings, key: "string" , |
1580 | object: obj, property: "bool" , |
1581 | flags: G_SETTINGS_BIND_DEFAULT, |
1582 | get_mapping: string_to_bool, |
1583 | set_mapping: bool_to_string, |
1584 | NULL, NULL); |
1585 | |
1586 | g_settings_set_string (settings, key: "string" , value: "false" ); |
1587 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1588 | g_assert_cmpint (b, ==, FALSE); |
1589 | |
1590 | g_settings_set_string (settings, key: "string" , value: "not true" ); |
1591 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1592 | g_assert_cmpint (b, ==, FALSE); |
1593 | |
1594 | g_object_set (object: obj, first_property_name: "bool" , TRUE, NULL); |
1595 | s = g_settings_get_string (settings, key: "string" ); |
1596 | g_assert_cmpstr (s, ==, "true" ); |
1597 | g_free (mem: s); |
1598 | |
1599 | g_settings_bind_with_mapping (settings, key: "string" , |
1600 | object: obj, property: "bool" , |
1601 | flags: G_SETTINGS_BIND_DEFAULT, |
1602 | get_mapping: string_to_bool, set_mapping: bool_to_bool, |
1603 | NULL, NULL); |
1604 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_CRITICAL, |
1605 | pattern: "*binding mapping function for key 'string' returned" |
1606 | " GVariant of type 'b' when type 's' was requested*" ); |
1607 | g_object_set (object: obj, first_property_name: "bool" , FALSE, NULL); |
1608 | g_test_assert_expected_messages (); |
1609 | |
1610 | g_object_unref (object: obj); |
1611 | g_object_unref (object: settings); |
1612 | } |
1613 | |
1614 | /* Test that with G_SETTINGS_BIND_NO_CHANGES, the |
1615 | * initial settings value is transported to the object |
1616 | * side, but later settings changes do not affect the |
1617 | * object |
1618 | */ |
1619 | static void |
1620 | test_no_change_binding (void) |
1621 | { |
1622 | TestObject *obj; |
1623 | GSettings *settings; |
1624 | gboolean b; |
1625 | |
1626 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1627 | obj = test_object_new (); |
1628 | |
1629 | g_object_set (object: obj, first_property_name: "bool" , TRUE, NULL); |
1630 | g_settings_set_boolean (settings, key: "bool" , FALSE); |
1631 | |
1632 | g_settings_bind (settings, key: "bool" , object: obj, property: "bool" , flags: G_SETTINGS_BIND_GET_NO_CHANGES); |
1633 | |
1634 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1635 | g_assert_cmpint (b, ==, FALSE); |
1636 | |
1637 | g_settings_set_boolean (settings, key: "bool" , TRUE); |
1638 | g_object_get (object: obj, first_property_name: "bool" , &b, NULL); |
1639 | g_assert_cmpint (b, ==, FALSE); |
1640 | |
1641 | g_settings_set_boolean (settings, key: "bool" , FALSE); |
1642 | g_object_set (object: obj, first_property_name: "bool" , TRUE, NULL); |
1643 | b = g_settings_get_boolean (settings, key: "bool" ); |
1644 | g_assert_cmpint (b, ==, TRUE); |
1645 | |
1646 | g_object_unref (object: obj); |
1647 | g_object_unref (object: settings); |
1648 | } |
1649 | |
1650 | /* Test that binding a non-readable property only |
1651 | * works in 'GET' mode. |
1652 | */ |
1653 | static void |
1654 | test_no_read_binding_fail (void) |
1655 | { |
1656 | TestObject *obj; |
1657 | GSettings *settings; |
1658 | |
1659 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1660 | obj = test_object_new (); |
1661 | |
1662 | g_settings_bind (settings, key: "string" , object: obj, property: "no-read" , flags: 0); |
1663 | } |
1664 | |
1665 | static void |
1666 | test_no_read_binding_pass (void) |
1667 | { |
1668 | TestObject *obj; |
1669 | GSettings *settings; |
1670 | |
1671 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1672 | obj = test_object_new (); |
1673 | |
1674 | g_settings_bind (settings, key: "string" , object: obj, property: "no-read" , flags: G_SETTINGS_BIND_GET); |
1675 | |
1676 | exit (status: 0); |
1677 | } |
1678 | |
1679 | static void |
1680 | test_no_read_binding (void) |
1681 | { |
1682 | if (g_test_undefined ()) |
1683 | { |
1684 | g_test_trap_subprocess (test_path: "/gsettings/no-read-binding/subprocess/fail" , usec_timeout: 0, test_flags: 0); |
1685 | g_test_trap_assert_failed (); |
1686 | g_test_trap_assert_stderr ("*property*is not readable*" ); |
1687 | } |
1688 | |
1689 | g_test_trap_subprocess (test_path: "/gsettings/no-read-binding/subprocess/pass" , usec_timeout: 0, test_flags: 0); |
1690 | g_test_trap_assert_passed (); |
1691 | } |
1692 | |
1693 | /* Test that binding a non-writable property only |
1694 | * works in 'SET' mode. |
1695 | */ |
1696 | static void |
1697 | test_no_write_binding_fail (void) |
1698 | { |
1699 | TestObject *obj; |
1700 | GSettings *settings; |
1701 | |
1702 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1703 | obj = test_object_new (); |
1704 | |
1705 | g_settings_bind (settings, key: "string" , object: obj, property: "no-write" , flags: 0); |
1706 | } |
1707 | |
1708 | static void |
1709 | test_no_write_binding_pass (void) |
1710 | { |
1711 | TestObject *obj; |
1712 | GSettings *settings; |
1713 | |
1714 | settings = g_settings_new (schema_id: "org.gtk.test.binding" ); |
1715 | obj = test_object_new (); |
1716 | |
1717 | g_settings_bind (settings, key: "string" , object: obj, property: "no-write" , flags: G_SETTINGS_BIND_SET); |
1718 | |
1719 | exit (status: 0); |
1720 | } |
1721 | |
1722 | static void |
1723 | test_no_write_binding (void) |
1724 | { |
1725 | if (g_test_undefined ()) |
1726 | { |
1727 | g_test_trap_subprocess (test_path: "/gsettings/no-write-binding/subprocess/fail" , usec_timeout: 0, test_flags: 0); |
1728 | g_test_trap_assert_failed (); |
1729 | g_test_trap_assert_stderr ("*property*is not writable*" ); |
1730 | } |
1731 | |
1732 | g_test_trap_subprocess (test_path: "/gsettings/no-write-binding/subprocess/pass" , usec_timeout: 0, test_flags: 0); |
1733 | g_test_trap_assert_passed (); |
1734 | } |
1735 | |
1736 | static void |
1737 | key_changed_cb (GSettings *settings, const gchar *key, gpointer data) |
1738 | { |
1739 | gboolean *b = data; |
1740 | (*b) = TRUE; |
1741 | } |
1742 | |
1743 | typedef struct |
1744 | { |
1745 | const gchar *path; |
1746 | const gchar *root_group; |
1747 | const gchar *keyfile_group; |
1748 | const gchar *root_path; |
1749 | } KeyfileTestData; |
1750 | |
1751 | /* |
1752 | * Test that using a keyfile works |
1753 | */ |
1754 | static void |
1755 | test_keyfile (Fixture *fixture, |
1756 | gconstpointer user_data) |
1757 | { |
1758 | GSettingsBackend *kf_backend; |
1759 | GSettings *settings; |
1760 | GKeyFile *keyfile; |
1761 | gchar *str; |
1762 | gboolean writable; |
1763 | GError *error = NULL; |
1764 | gchar *data; |
1765 | gsize len; |
1766 | gboolean called = FALSE; |
1767 | gchar *keyfile_path = NULL, *store_path = NULL; |
1768 | |
1769 | keyfile_path = g_build_filename (first_element: fixture->tmp_dir, "keyfile" , NULL); |
1770 | store_path = g_build_filename (first_element: keyfile_path, "gsettings.store" , NULL); |
1771 | kf_backend = g_keyfile_settings_backend_new (filename: store_path, root_path: "/" , root_group: "root" ); |
1772 | settings = g_settings_new_with_backend (schema_id: "org.gtk.test" , backend: kf_backend); |
1773 | g_object_unref (object: kf_backend); |
1774 | |
1775 | g_settings_reset (settings, key: "greeting" ); |
1776 | str = g_settings_get_string (settings, key: "greeting" ); |
1777 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
1778 | g_free (mem: str); |
1779 | |
1780 | writable = g_settings_is_writable (settings, name: "greeting" ); |
1781 | g_assert_true (writable); |
1782 | g_settings_set (settings, key: "greeting" , format: "s" , "see if this works" ); |
1783 | |
1784 | str = g_settings_get_string (settings, key: "greeting" ); |
1785 | g_assert_cmpstr (str, ==, "see if this works" ); |
1786 | g_free (mem: str); |
1787 | |
1788 | g_settings_delay (settings); |
1789 | g_settings_set (settings, key: "farewell" , format: "s" , "cheerio" ); |
1790 | g_settings_apply (settings); |
1791 | |
1792 | keyfile = g_key_file_new (); |
1793 | g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); |
1794 | |
1795 | str = g_key_file_get_string (key_file: keyfile, group_name: "tests" , key: "greeting" , NULL); |
1796 | g_assert_cmpstr (str, ==, "'see if this works'" ); |
1797 | g_free (mem: str); |
1798 | |
1799 | str = g_key_file_get_string (key_file: keyfile, group_name: "tests" , key: "farewell" , NULL); |
1800 | g_assert_cmpstr (str, ==, "'cheerio'" ); |
1801 | g_free (mem: str); |
1802 | g_key_file_free (key_file: keyfile); |
1803 | |
1804 | g_settings_reset (settings, key: "greeting" ); |
1805 | g_settings_apply (settings); |
1806 | keyfile = g_key_file_new (); |
1807 | g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); |
1808 | |
1809 | str = g_key_file_get_string (key_file: keyfile, group_name: "tests" , key: "greeting" , NULL); |
1810 | g_assert_null (str); |
1811 | |
1812 | called = FALSE; |
1813 | g_signal_connect (settings, "changed::greeting" , G_CALLBACK (key_changed_cb), &called); |
1814 | |
1815 | g_key_file_set_string (key_file: keyfile, group_name: "tests" , key: "greeting" , string: "'howdy'" ); |
1816 | data = g_key_file_to_data (key_file: keyfile, length: &len, NULL); |
1817 | g_file_set_contents (filename: store_path, contents: data, length: len, error: &error); |
1818 | g_assert_no_error (error); |
1819 | while (!called) |
1820 | g_main_context_iteration (NULL, FALSE); |
1821 | g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); |
1822 | |
1823 | str = g_settings_get_string (settings, key: "greeting" ); |
1824 | g_assert_cmpstr (str, ==, "howdy" ); |
1825 | g_free (mem: str); |
1826 | |
1827 | /* Now check setting a string without quotes */ |
1828 | called = FALSE; |
1829 | g_signal_connect (settings, "changed::greeting" , G_CALLBACK (key_changed_cb), &called); |
1830 | |
1831 | g_key_file_set_string (key_file: keyfile, group_name: "tests" , key: "greeting" , string: "he\"l🤗uń" ); |
1832 | g_free (mem: data); |
1833 | data = g_key_file_to_data (key_file: keyfile, length: &len, NULL); |
1834 | g_file_set_contents (filename: store_path, contents: data, length: len, error: &error); |
1835 | g_assert_no_error (error); |
1836 | while (!called) |
1837 | g_main_context_iteration (NULL, FALSE); |
1838 | g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); |
1839 | |
1840 | str = g_settings_get_string (settings, key: "greeting" ); |
1841 | g_assert_cmpstr (str, ==, "he\"l🤗uń" ); |
1842 | g_free (mem: str); |
1843 | |
1844 | g_settings_set (settings, key: "farewell" , format: "s" , "cheerio" ); |
1845 | |
1846 | /* Check that empty keys/groups are not allowed. */ |
1847 | g_assert_false (g_settings_is_writable (settings, "" )); |
1848 | g_assert_false (g_settings_is_writable (settings, "/" )); |
1849 | |
1850 | /* When executing as root, changing the mode of the keyfile will have |
1851 | * no effect on the writability of the settings. |
1852 | */ |
1853 | if (geteuid () != 0) |
1854 | { |
1855 | called = FALSE; |
1856 | g_signal_connect (settings, "writable-changed::greeting" , |
1857 | G_CALLBACK (key_changed_cb), &called); |
1858 | |
1859 | g_assert_no_errno (g_chmod (keyfile_path, 0500)); |
1860 | while (!called) |
1861 | g_main_context_iteration (NULL, FALSE); |
1862 | g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); |
1863 | |
1864 | writable = g_settings_is_writable (settings, name: "greeting" ); |
1865 | g_assert_false (writable); |
1866 | } |
1867 | |
1868 | g_key_file_free (key_file: keyfile); |
1869 | g_free (mem: data); |
1870 | |
1871 | g_object_unref (object: settings); |
1872 | |
1873 | /* Clean up the temporary directory. */ |
1874 | g_assert_no_errno (g_chmod (keyfile_path, 0777)); |
1875 | g_assert_no_errno (g_remove (store_path)); |
1876 | g_assert_no_errno (g_rmdir (keyfile_path)); |
1877 | g_free (mem: store_path); |
1878 | g_free (mem: keyfile_path); |
1879 | } |
1880 | |
1881 | /* |
1882 | * Test that using a keyfile works with a schema with no path set. |
1883 | */ |
1884 | static void |
1885 | test_keyfile_no_path (Fixture *fixture, |
1886 | gconstpointer user_data) |
1887 | { |
1888 | const KeyfileTestData *test_data = user_data; |
1889 | GSettingsBackend *kf_backend; |
1890 | GSettings *settings; |
1891 | GKeyFile *keyfile; |
1892 | gboolean writable; |
1893 | gchar *key = NULL; |
1894 | GError *error = NULL; |
1895 | gchar *keyfile_path = NULL, *store_path = NULL; |
1896 | |
1897 | keyfile_path = g_build_filename (first_element: fixture->tmp_dir, "keyfile" , NULL); |
1898 | store_path = g_build_filename (first_element: keyfile_path, "gsettings.store" , NULL); |
1899 | kf_backend = g_keyfile_settings_backend_new (filename: store_path, root_path: test_data->root_path, root_group: test_data->root_group); |
1900 | settings = g_settings_new_with_backend_and_path (schema_id: "org.gtk.test.no-path" , backend: kf_backend, path: test_data->path); |
1901 | g_object_unref (object: kf_backend); |
1902 | |
1903 | g_settings_reset (settings, key: "test-boolean" ); |
1904 | g_assert_true (g_settings_get_boolean (settings, "test-boolean" )); |
1905 | |
1906 | writable = g_settings_is_writable (settings, name: "test-boolean" ); |
1907 | g_assert_true (writable); |
1908 | g_settings_set (settings, key: "test-boolean" , format: "b" , FALSE); |
1909 | |
1910 | g_assert_false (g_settings_get_boolean (settings, "test-boolean" )); |
1911 | |
1912 | g_settings_delay (settings); |
1913 | g_settings_set (settings, key: "test-boolean" , format: "b" , TRUE); |
1914 | g_settings_apply (settings); |
1915 | |
1916 | keyfile = g_key_file_new (); |
1917 | g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); |
1918 | |
1919 | g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean" , NULL)); |
1920 | |
1921 | g_key_file_free (key_file: keyfile); |
1922 | |
1923 | g_settings_reset (settings, key: "test-boolean" ); |
1924 | g_settings_apply (settings); |
1925 | keyfile = g_key_file_new (); |
1926 | g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL)); |
1927 | |
1928 | g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean" , &error)); |
1929 | g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); |
1930 | g_clear_error (err: &error); |
1931 | |
1932 | /* Check that empty keys/groups are not allowed. */ |
1933 | g_assert_false (g_settings_is_writable (settings, "" )); |
1934 | g_assert_false (g_settings_is_writable (settings, "/" )); |
1935 | |
1936 | /* Keys which ghost the root group name are not allowed. This can only be |
1937 | * tested when the path is `/` as otherwise it acts as a prefix and prevents |
1938 | * any ghosting. */ |
1939 | if (g_str_equal (v1: test_data->path, v2: "/" )) |
1940 | { |
1941 | key = g_strdup_printf (format: "%s/%s" , test_data->root_group, "" ); |
1942 | g_assert_false (g_settings_is_writable (settings, key)); |
1943 | g_free (mem: key); |
1944 | |
1945 | key = g_strdup_printf (format: "%s/%s" , test_data->root_group, "/" ); |
1946 | g_assert_false (g_settings_is_writable (settings, key)); |
1947 | g_free (mem: key); |
1948 | |
1949 | key = g_strdup_printf (format: "%s/%s" , test_data->root_group, "test-boolean" ); |
1950 | g_assert_false (g_settings_is_writable (settings, key)); |
1951 | g_free (mem: key); |
1952 | } |
1953 | |
1954 | g_key_file_free (key_file: keyfile); |
1955 | g_object_unref (object: settings); |
1956 | |
1957 | /* Clean up the temporary directory. */ |
1958 | g_assert_no_errno (g_chmod (keyfile_path, 0777)); |
1959 | g_assert_no_errno (g_remove (store_path)); |
1960 | g_assert_no_errno (g_rmdir (keyfile_path)); |
1961 | g_free (mem: store_path); |
1962 | g_free (mem: keyfile_path); |
1963 | } |
1964 | |
1965 | /* |
1966 | * Test that a keyfile rejects writes to keys outside its root path. |
1967 | */ |
1968 | static void |
1969 | test_keyfile_outside_root_path (Fixture *fixture, |
1970 | gconstpointer user_data) |
1971 | { |
1972 | GSettingsBackend *kf_backend; |
1973 | GSettings *settings; |
1974 | gchar *keyfile_path = NULL, *store_path = NULL; |
1975 | |
1976 | keyfile_path = g_build_filename (first_element: fixture->tmp_dir, "keyfile" , NULL); |
1977 | store_path = g_build_filename (first_element: keyfile_path, "gsettings.store" , NULL); |
1978 | kf_backend = g_keyfile_settings_backend_new (filename: store_path, root_path: "/tests/basic-types/" , root_group: "root" ); |
1979 | settings = g_settings_new_with_backend_and_path (schema_id: "org.gtk.test.no-path" , backend: kf_backend, path: "/tests/" ); |
1980 | g_object_unref (object: kf_backend); |
1981 | |
1982 | g_assert_false (g_settings_is_writable (settings, "test-boolean" )); |
1983 | |
1984 | g_object_unref (object: settings); |
1985 | |
1986 | /* Clean up the temporary directory. The keyfile probably doesn’t exist, so |
1987 | * don’t error on failure. */ |
1988 | g_remove (filename: store_path); |
1989 | g_assert_no_errno (g_rmdir (keyfile_path)); |
1990 | g_free (mem: store_path); |
1991 | g_free (mem: keyfile_path); |
1992 | } |
1993 | |
1994 | /* |
1995 | * Test that a keyfile rejects writes to keys in the root if no root group is set. |
1996 | */ |
1997 | static void |
1998 | test_keyfile_no_root_group (Fixture *fixture, |
1999 | gconstpointer user_data) |
2000 | { |
2001 | GSettingsBackend *kf_backend; |
2002 | GSettings *settings; |
2003 | gchar *keyfile_path = NULL, *store_path = NULL; |
2004 | |
2005 | keyfile_path = g_build_filename (first_element: fixture->tmp_dir, "keyfile" , NULL); |
2006 | store_path = g_build_filename (first_element: keyfile_path, "gsettings.store" , NULL); |
2007 | kf_backend = g_keyfile_settings_backend_new (filename: store_path, root_path: "/" , NULL); |
2008 | settings = g_settings_new_with_backend_and_path (schema_id: "org.gtk.test.no-path" , backend: kf_backend, path: "/" ); |
2009 | g_object_unref (object: kf_backend); |
2010 | |
2011 | g_assert_false (g_settings_is_writable (settings, "test-boolean" )); |
2012 | g_assert_true (g_settings_is_writable (settings, "child/test-boolean" )); |
2013 | |
2014 | g_object_unref (object: settings); |
2015 | |
2016 | /* Clean up the temporary directory. The keyfile probably doesn’t exist, so |
2017 | * don’t error on failure. */ |
2018 | g_remove (filename: store_path); |
2019 | g_assert_no_errno (g_rmdir (keyfile_path)); |
2020 | g_free (mem: store_path); |
2021 | g_free (mem: keyfile_path); |
2022 | } |
2023 | |
2024 | /* Test that getting child schemas works |
2025 | */ |
2026 | static void |
2027 | test_child_schema (void) |
2028 | { |
2029 | GSettings *settings; |
2030 | GSettings *child; |
2031 | guint8 byte; |
2032 | |
2033 | /* first establish some known conditions */ |
2034 | settings = g_settings_new (schema_id: "org.gtk.test.basic-types" ); |
2035 | g_settings_set (settings, key: "test-byte" , format: "y" , 36); |
2036 | |
2037 | g_settings_get (settings, key: "test-byte" , format: "y" , &byte); |
2038 | g_assert_cmpint (byte, ==, 36); |
2039 | |
2040 | g_object_unref (object: settings); |
2041 | |
2042 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
2043 | child = g_settings_get_child (settings, name: "basic-types" ); |
2044 | g_assert_nonnull (child); |
2045 | |
2046 | g_settings_get (settings: child, key: "test-byte" , format: "y" , &byte); |
2047 | g_assert_cmpint (byte, ==, 36); |
2048 | |
2049 | g_object_unref (object: child); |
2050 | g_object_unref (object: settings); |
2051 | } |
2052 | |
2053 | #include "../strinfo.c" |
2054 | |
2055 | static void |
2056 | test_strinfo (void) |
2057 | { |
2058 | /* "foo" has a value of 1 |
2059 | * "bar" has a value of 2 |
2060 | * "baz" is an alias for "bar" |
2061 | */ |
2062 | gchar array[] = |
2063 | "\1\0\0\0" "\xff" "foo" "\0\0\0\xff" "\2\0\0\0" |
2064 | "\xff" "bar" "\0\0\0\xff" "\3\0\0\0" "\xfe" "baz" |
2065 | "\0\0\0\xff" ; |
2066 | const guint32 *strinfo = (guint32 *) array; |
2067 | guint length = sizeof array / 4; |
2068 | guint result = 0; |
2069 | |
2070 | { |
2071 | /* build it and compare */ |
2072 | GString *builder; |
2073 | |
2074 | builder = g_string_new (NULL); |
2075 | strinfo_builder_append_item (builder, string: "foo" , value: 1); |
2076 | strinfo_builder_append_item (builder, string: "bar" , value: 2); |
2077 | g_assert_true (strinfo_builder_append_alias (builder, "baz" , "bar" )); |
2078 | g_assert_cmpmem (builder->str, builder->len, strinfo, length * 4); |
2079 | g_string_free (string: builder, TRUE); |
2080 | } |
2081 | |
2082 | g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "foo" ), |
2083 | ==, NULL); |
2084 | g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "bar" ), |
2085 | ==, NULL); |
2086 | g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "baz" ), |
2087 | ==, "bar" ); |
2088 | g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "quux" ), |
2089 | ==, NULL); |
2090 | |
2091 | g_assert_true (strinfo_enum_from_string (strinfo, length, "foo" , &result)); |
2092 | g_assert_cmpint (result, ==, 1); |
2093 | g_assert_true (strinfo_enum_from_string (strinfo, length, "bar" , &result)); |
2094 | g_assert_cmpint (result, ==, 2); |
2095 | g_assert_false (strinfo_enum_from_string (strinfo, length, "baz" , &result)); |
2096 | g_assert_false (strinfo_enum_from_string (strinfo, length, "quux" , &result)); |
2097 | |
2098 | g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 0), ==, NULL); |
2099 | g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 1), ==, "foo" ); |
2100 | g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 2), ==, "bar" ); |
2101 | g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 3), ==, NULL); |
2102 | |
2103 | g_assert_true (strinfo_is_string_valid (strinfo, length, "foo" )); |
2104 | g_assert_true (strinfo_is_string_valid (strinfo, length, "bar" )); |
2105 | g_assert_false (strinfo_is_string_valid (strinfo, length, "baz" )); |
2106 | g_assert_false (strinfo_is_string_valid (strinfo, length, "quux" )); |
2107 | } |
2108 | |
2109 | static void |
2110 | test_enums_non_enum_key (void) |
2111 | { |
2112 | GSettings *direct; |
2113 | |
2114 | direct = g_settings_new (schema_id: "org.gtk.test.enums.direct" ); |
2115 | g_settings_get_enum (settings: direct, key: "test" ); |
2116 | g_assert_not_reached (); |
2117 | } |
2118 | |
2119 | static void |
2120 | test_enums_non_enum_value (void) |
2121 | { |
2122 | GSettings *settings; |
2123 | |
2124 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2125 | g_settings_set_enum (settings, key: "test" , value: 42); |
2126 | g_assert_not_reached (); |
2127 | } |
2128 | |
2129 | static void |
2130 | test_enums_range (void) |
2131 | { |
2132 | GSettings *settings; |
2133 | |
2134 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2135 | g_settings_set_string (settings, key: "test" , value: "qux" ); |
2136 | g_assert_not_reached (); |
2137 | } |
2138 | |
2139 | static void |
2140 | test_enums_non_flags (void) |
2141 | { |
2142 | GSettings *settings; |
2143 | |
2144 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2145 | g_settings_get_flags (settings, key: "test" ); |
2146 | g_assert_not_reached (); |
2147 | } |
2148 | |
2149 | static void |
2150 | test_enums (void) |
2151 | { |
2152 | GSettings *settings, *direct; |
2153 | gchar *str; |
2154 | |
2155 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2156 | direct = g_settings_new (schema_id: "org.gtk.test.enums.direct" ); |
2157 | |
2158 | if (g_test_undefined () && !backend_set) |
2159 | { |
2160 | g_test_trap_subprocess (test_path: "/gsettings/enums/subprocess/non-enum-key" , usec_timeout: 0, test_flags: 0); |
2161 | g_test_trap_assert_failed (); |
2162 | g_test_trap_assert_stderr ("*not associated with an enum*" ); |
2163 | |
2164 | g_test_trap_subprocess (test_path: "/gsettings/enums/subprocess/non-enum-value" , usec_timeout: 0, test_flags: 0); |
2165 | g_test_trap_assert_failed (); |
2166 | g_test_trap_assert_stderr ("*invalid enum value 42*" ); |
2167 | |
2168 | g_test_trap_subprocess (test_path: "/gsettings/enums/subprocess/range" , usec_timeout: 0, test_flags: 0); |
2169 | g_test_trap_assert_failed (); |
2170 | g_test_trap_assert_stderr ("*g_settings_set_value*valid range*" ); |
2171 | |
2172 | g_test_trap_subprocess (test_path: "/gsettings/enums/subprocess/non-flags" , usec_timeout: 0, test_flags: 0); |
2173 | g_test_trap_assert_failed (); |
2174 | g_test_trap_assert_stderr ("*not associated with a flags*" ); |
2175 | } |
2176 | |
2177 | str = g_settings_get_string (settings, key: "test" ); |
2178 | g_assert_cmpstr (str, ==, "bar" ); |
2179 | g_free (mem: str); |
2180 | |
2181 | g_settings_set_enum (settings, key: "test" , value: TEST_ENUM_FOO); |
2182 | |
2183 | str = g_settings_get_string (settings, key: "test" ); |
2184 | g_assert_cmpstr (str, ==, "foo" ); |
2185 | g_free (mem: str); |
2186 | |
2187 | g_assert_cmpint (g_settings_get_enum (settings, "test" ), ==, TEST_ENUM_FOO); |
2188 | |
2189 | g_settings_set_string (settings: direct, key: "test" , value: "qux" ); |
2190 | |
2191 | str = g_settings_get_string (settings: direct, key: "test" ); |
2192 | g_assert_cmpstr (str, ==, "qux" ); |
2193 | g_free (mem: str); |
2194 | |
2195 | str = g_settings_get_string (settings, key: "test" ); |
2196 | g_assert_cmpstr (str, ==, "quux" ); |
2197 | g_free (mem: str); |
2198 | |
2199 | g_assert_cmpint (g_settings_get_enum (settings, "test" ), ==, TEST_ENUM_QUUX); |
2200 | |
2201 | g_object_unref (object: direct); |
2202 | g_object_unref (object: settings); |
2203 | } |
2204 | |
2205 | static void |
2206 | test_flags_non_flags_key (void) |
2207 | { |
2208 | GSettings *direct; |
2209 | |
2210 | direct = g_settings_new (schema_id: "org.gtk.test.enums.direct" ); |
2211 | g_settings_get_flags (settings: direct, key: "test" ); |
2212 | g_assert_not_reached (); |
2213 | } |
2214 | |
2215 | static void |
2216 | test_flags_non_flags_value (void) |
2217 | { |
2218 | GSettings *settings; |
2219 | |
2220 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2221 | g_settings_set_flags (settings, key: "f-test" , value: 0x42); |
2222 | g_assert_not_reached (); |
2223 | } |
2224 | |
2225 | static void |
2226 | test_flags_range (void) |
2227 | { |
2228 | GSettings *settings; |
2229 | |
2230 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2231 | g_settings_set_strv (settings, key: "f-test" , |
2232 | value: (const gchar **) g_strsplit (string: "rock" , delimiter: "," , max_tokens: 0)); |
2233 | g_assert_not_reached (); |
2234 | } |
2235 | |
2236 | static void |
2237 | test_flags_non_enum (void) |
2238 | { |
2239 | GSettings *settings; |
2240 | |
2241 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2242 | g_settings_get_enum (settings, key: "f-test" ); |
2243 | g_assert_not_reached (); |
2244 | } |
2245 | |
2246 | static void |
2247 | test_flags (void) |
2248 | { |
2249 | GSettings *settings, *direct; |
2250 | gchar **strv; |
2251 | gchar *str; |
2252 | |
2253 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2254 | direct = g_settings_new (schema_id: "org.gtk.test.enums.direct" ); |
2255 | |
2256 | if (g_test_undefined () && !backend_set) |
2257 | { |
2258 | g_test_trap_subprocess (test_path: "/gsettings/flags/subprocess/non-flags-key" , usec_timeout: 0, test_flags: 0); |
2259 | g_test_trap_assert_failed (); |
2260 | g_test_trap_assert_stderr ("*not associated with a flags*" ); |
2261 | |
2262 | g_test_trap_subprocess (test_path: "/gsettings/flags/subprocess/non-flags-value" , usec_timeout: 0, test_flags: 0); |
2263 | g_test_trap_assert_failed (); |
2264 | g_test_trap_assert_stderr ("*invalid flags value 0x00000042*" ); |
2265 | |
2266 | g_test_trap_subprocess (test_path: "/gsettings/flags/subprocess/range" , usec_timeout: 0, test_flags: 0); |
2267 | g_test_trap_assert_failed (); |
2268 | g_test_trap_assert_stderr ("*g_settings_set_value*valid range*" ); |
2269 | |
2270 | g_test_trap_subprocess (test_path: "/gsettings/flags/subprocess/non-enum" , usec_timeout: 0, test_flags: 0); |
2271 | g_test_trap_assert_failed (); |
2272 | g_test_trap_assert_stderr ("*not associated with an enum*" ); |
2273 | } |
2274 | |
2275 | strv = g_settings_get_strv (settings, key: "f-test" ); |
2276 | str = g_strjoinv (separator: "," , str_array: strv); |
2277 | g_assert_cmpstr (str, ==, "" ); |
2278 | g_strfreev (str_array: strv); |
2279 | g_free (mem: str); |
2280 | |
2281 | g_settings_set_flags (settings, key: "f-test" , |
2282 | value: TEST_FLAGS_WALKING | TEST_FLAGS_TALKING); |
2283 | |
2284 | strv = g_settings_get_strv (settings, key: "f-test" ); |
2285 | str = g_strjoinv (separator: "," , str_array: strv); |
2286 | g_assert_cmpstr (str, ==, "talking,walking" ); |
2287 | g_strfreev (str_array: strv); |
2288 | g_free (mem: str); |
2289 | |
2290 | g_assert_cmpint (g_settings_get_flags (settings, "f-test" ), ==, |
2291 | TEST_FLAGS_WALKING | TEST_FLAGS_TALKING); |
2292 | |
2293 | strv = g_strsplit (string: "speaking,laughing" , delimiter: "," , max_tokens: 0); |
2294 | g_settings_set_strv (settings: direct, key: "f-test" , value: (const gchar **) strv); |
2295 | g_strfreev (str_array: strv); |
2296 | |
2297 | strv = g_settings_get_strv (settings: direct, key: "f-test" ); |
2298 | str = g_strjoinv (separator: "," , str_array: strv); |
2299 | g_assert_cmpstr (str, ==, "speaking,laughing" ); |
2300 | g_strfreev (str_array: strv); |
2301 | g_free (mem: str); |
2302 | |
2303 | strv = g_settings_get_strv (settings, key: "f-test" ); |
2304 | str = g_strjoinv (separator: "," , str_array: strv); |
2305 | g_assert_cmpstr (str, ==, "talking,laughing" ); |
2306 | g_strfreev (str_array: strv); |
2307 | g_free (mem: str); |
2308 | |
2309 | g_assert_cmpint (g_settings_get_flags (settings, "f-test" ), ==, |
2310 | TEST_FLAGS_TALKING | TEST_FLAGS_LAUGHING); |
2311 | |
2312 | g_object_unref (object: direct); |
2313 | g_object_unref (object: settings); |
2314 | } |
2315 | |
2316 | static void |
2317 | test_range_high (void) |
2318 | { |
2319 | GSettings *settings; |
2320 | |
2321 | settings = g_settings_new (schema_id: "org.gtk.test.range" ); |
2322 | g_settings_set_int (settings, key: "val" , value: 45); |
2323 | g_assert_not_reached (); |
2324 | } |
2325 | |
2326 | static void |
2327 | test_range_low (void) |
2328 | { |
2329 | GSettings *settings; |
2330 | |
2331 | settings = g_settings_new (schema_id: "org.gtk.test.range" ); |
2332 | g_settings_set_int (settings, key: "val" , value: 1); |
2333 | g_assert_not_reached (); |
2334 | } |
2335 | |
2336 | static void |
2337 | test_range (void) |
2338 | { |
2339 | GSettings *settings, *direct; |
2340 | GVariant *value; |
2341 | |
2342 | settings = g_settings_new (schema_id: "org.gtk.test.range" ); |
2343 | direct = g_settings_new (schema_id: "org.gtk.test.range.direct" ); |
2344 | |
2345 | if (g_test_undefined () && !backend_set) |
2346 | { |
2347 | g_test_trap_subprocess (test_path: "/gsettings/range/subprocess/high" , usec_timeout: 0, test_flags: 0); |
2348 | g_test_trap_assert_failed (); |
2349 | g_test_trap_assert_stderr ("*g_settings_set_value*valid range*" ); |
2350 | |
2351 | g_test_trap_subprocess (test_path: "/gsettings/range/subprocess/low" , usec_timeout: 0, test_flags: 0); |
2352 | g_test_trap_assert_failed (); |
2353 | g_test_trap_assert_stderr ("*g_settings_set_value*valid range*" ); |
2354 | } |
2355 | |
2356 | g_assert_cmpint (g_settings_get_int (settings, "val" ), ==, 33); |
2357 | g_settings_set_int (settings: direct, key: "val" , value: 22); |
2358 | g_assert_cmpint (g_settings_get_int (direct, "val" ), ==, 22); |
2359 | g_assert_cmpint (g_settings_get_int (settings, "val" ), ==, 22); |
2360 | g_settings_set_int (settings: direct, key: "val" , value: 45); |
2361 | g_assert_cmpint (g_settings_get_int (direct, "val" ), ==, 45); |
2362 | g_assert_cmpint (g_settings_get_int (settings, "val" ), ==, 33); |
2363 | g_settings_set_int (settings: direct, key: "val" , value: 1); |
2364 | g_assert_cmpint (g_settings_get_int (direct, "val" ), ==, 1); |
2365 | g_assert_cmpint (g_settings_get_int (settings, "val" ), ==, 33); |
2366 | |
2367 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2368 | value = g_variant_new_int32 (value: 1); |
2369 | g_assert_false (g_settings_range_check (settings, "val" , value)); |
2370 | g_variant_unref (value); |
2371 | value = g_variant_new_int32 (value: 33); |
2372 | g_assert_true (g_settings_range_check (settings, "val" , value)); |
2373 | g_variant_unref (value); |
2374 | value = g_variant_new_int32 (value: 45); |
2375 | g_assert_false (g_settings_range_check (settings, "val" , value)); |
2376 | g_variant_unref (value); |
2377 | G_GNUC_END_IGNORE_DEPRECATIONS |
2378 | |
2379 | g_object_unref (object: direct); |
2380 | g_object_unref (object: settings); |
2381 | } |
2382 | |
2383 | static gboolean |
2384 | strv_has_string (gchar **haystack, |
2385 | const gchar *needle) |
2386 | { |
2387 | guint n; |
2388 | |
2389 | for (n = 0; haystack != NULL && haystack[n] != NULL; n++) |
2390 | { |
2391 | if (g_strcmp0 (str1: haystack[n], str2: needle) == 0) |
2392 | return TRUE; |
2393 | } |
2394 | return FALSE; |
2395 | } |
2396 | |
2397 | static gboolean |
2398 | strv_set_equal (gchar **strv, ...) |
2399 | { |
2400 | gint count; |
2401 | va_list list; |
2402 | const gchar *str; |
2403 | gboolean res; |
2404 | |
2405 | res = TRUE; |
2406 | count = 0; |
2407 | va_start (list, strv); |
2408 | while (1) |
2409 | { |
2410 | str = va_arg (list, const gchar *); |
2411 | if (str == NULL) |
2412 | break; |
2413 | if (!strv_has_string (haystack: strv, needle: str)) |
2414 | { |
2415 | res = FALSE; |
2416 | break; |
2417 | } |
2418 | count++; |
2419 | } |
2420 | va_end (list); |
2421 | |
2422 | if (res) |
2423 | res = g_strv_length (str_array: (gchar**)strv) == count; |
2424 | |
2425 | return res; |
2426 | } |
2427 | |
2428 | static void |
2429 | test_list_items (void) |
2430 | { |
2431 | GSettingsSchema *schema; |
2432 | GSettings *settings; |
2433 | gchar **children; |
2434 | gchar **keys; |
2435 | |
2436 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
2437 | g_object_get (object: settings, first_property_name: "settings-schema" , &schema, NULL); |
2438 | children = g_settings_list_children (settings); |
2439 | keys = g_settings_schema_list_keys (schema); |
2440 | |
2441 | g_assert_true (strv_set_equal (children, "basic-types" , "complex-types" , "localized" , NULL)); |
2442 | g_assert_true (strv_set_equal (keys, "greeting" , "farewell" , NULL)); |
2443 | |
2444 | g_strfreev (str_array: children); |
2445 | g_strfreev (str_array: keys); |
2446 | |
2447 | g_settings_schema_unref (schema); |
2448 | g_object_unref (object: settings); |
2449 | } |
2450 | |
2451 | static void |
2452 | test_list_schemas (void) |
2453 | { |
2454 | const gchar * const *schemas; |
2455 | const gchar * const *relocs; |
2456 | |
2457 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2458 | relocs = g_settings_list_relocatable_schemas (); |
2459 | schemas = g_settings_list_schemas (); |
2460 | G_GNUC_END_IGNORE_DEPRECATIONS |
2461 | |
2462 | g_assert_true (strv_set_equal ((gchar **)relocs, |
2463 | "org.gtk.test.no-path" , |
2464 | "org.gtk.test.extends.base" , |
2465 | "org.gtk.test.extends.extended" , |
2466 | NULL)); |
2467 | |
2468 | g_assert_true (strv_set_equal ((gchar **)schemas, |
2469 | "org.gtk.test" , |
2470 | "org.gtk.test.basic-types" , |
2471 | "org.gtk.test.complex-types" , |
2472 | "org.gtk.test.localized" , |
2473 | "org.gtk.test.binding" , |
2474 | "org.gtk.test.enums" , |
2475 | "org.gtk.test.enums.direct" , |
2476 | "org.gtk.test.range" , |
2477 | "org.gtk.test.range.direct" , |
2478 | "org.gtk.test.mapped" , |
2479 | "org.gtk.test.descriptions" , |
2480 | "org.gtk.test.per-desktop" , |
2481 | NULL)); |
2482 | } |
2483 | |
2484 | static gboolean |
2485 | map_func (GVariant *value, |
2486 | gpointer *result, |
2487 | gpointer user_data) |
2488 | { |
2489 | gint *state = user_data; |
2490 | gint v; |
2491 | |
2492 | if (value) |
2493 | v = g_variant_get_int32 (value); |
2494 | else |
2495 | v = -1; |
2496 | |
2497 | if (*state == 0) |
2498 | { |
2499 | g_assert_cmpint (v, ==, 1); |
2500 | (*state)++; |
2501 | return FALSE; |
2502 | } |
2503 | else if (*state == 1) |
2504 | { |
2505 | g_assert_cmpint (v, ==, 0); |
2506 | (*state)++; |
2507 | return FALSE; |
2508 | } |
2509 | else |
2510 | { |
2511 | g_assert_null (value); |
2512 | *result = g_variant_new_int32 (value: 5); |
2513 | return TRUE; |
2514 | } |
2515 | } |
2516 | |
2517 | static void |
2518 | test_get_mapped (void) |
2519 | { |
2520 | GSettings *settings; |
2521 | gint state; |
2522 | gpointer p; |
2523 | gint val; |
2524 | |
2525 | settings = g_settings_new (schema_id: "org.gtk.test.mapped" ); |
2526 | g_settings_set_int (settings, key: "val" , value: 1); |
2527 | |
2528 | state = 0; |
2529 | p = g_settings_get_mapped (settings, key: "val" , mapping: map_func, user_data: &state); |
2530 | val = g_variant_get_int32 (value: (GVariant*)p); |
2531 | g_assert_cmpint (val, ==, 5); |
2532 | |
2533 | g_variant_unref (value: p); |
2534 | g_object_unref (object: settings); |
2535 | } |
2536 | |
2537 | static void |
2538 | test_get_range (void) |
2539 | { |
2540 | GSettings *settings; |
2541 | GVariant *range; |
2542 | |
2543 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
2544 | settings = g_settings_new (schema_id: "org.gtk.test.range" ); |
2545 | range = g_settings_get_range (settings, key: "val" ); |
2546 | check_and_free (value: range, expected: "('range', <(2, 44)>)" ); |
2547 | g_object_unref (object: settings); |
2548 | |
2549 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2550 | range = g_settings_get_range (settings, key: "test" ); |
2551 | check_and_free (value: range, expected: "('enum', <['foo', 'bar', 'baz', 'quux']>)" ); |
2552 | g_object_unref (object: settings); |
2553 | |
2554 | settings = g_settings_new (schema_id: "org.gtk.test.enums" ); |
2555 | range = g_settings_get_range (settings, key: "f-test" ); |
2556 | check_and_free (value: range, expected: "('flags', " |
2557 | "<['mourning', 'laughing', 'talking', 'walking']>)" ); |
2558 | g_object_unref (object: settings); |
2559 | |
2560 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
2561 | range = g_settings_get_range (settings, key: "greeting" ); |
2562 | check_and_free (value: range, expected: "('type', <@as []>)" ); |
2563 | g_object_unref (object: settings); |
2564 | G_GNUC_END_IGNORE_DEPRECATIONS |
2565 | } |
2566 | |
2567 | static void |
2568 | test_schema_source (void) |
2569 | { |
2570 | GSettingsSchemaSource *parent; |
2571 | GSettingsSchemaSource *source; |
2572 | GSettingsBackend *backend; |
2573 | GSettingsSchema *schema; |
2574 | GError *error = NULL; |
2575 | GSettings *settings; |
2576 | gboolean enabled; |
2577 | |
2578 | backend = g_settings_backend_get_default (); |
2579 | |
2580 | /* make sure it fails properly */ |
2581 | parent = g_settings_schema_source_get_default (); |
2582 | source = g_settings_schema_source_new_from_directory (directory: "/path/that/does/not/exist" , parent, TRUE, error: &error); |
2583 | g_assert_null (source); |
2584 | g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); |
2585 | g_clear_error (err: &error); |
2586 | |
2587 | /* Test error handling of corrupt compiled files. */ |
2588 | source = g_settings_schema_source_new_from_directory (directory: "schema-source-corrupt" , parent, TRUE, error: &error); |
2589 | g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); |
2590 | g_assert_null (source); |
2591 | g_clear_error (err: &error); |
2592 | |
2593 | /* Test error handling of empty compiled files. */ |
2594 | source = g_settings_schema_source_new_from_directory (directory: "schema-source-empty" , parent, TRUE, error: &error); |
2595 | g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL); |
2596 | g_assert_null (source); |
2597 | g_clear_error (err: &error); |
2598 | |
2599 | /* create a source with the parent */ |
2600 | source = g_settings_schema_source_new_from_directory (directory: "schema-source" , parent, TRUE, error: &error); |
2601 | g_assert_no_error (error); |
2602 | g_assert_nonnull (source); |
2603 | |
2604 | /* check recursive lookups are working */ |
2605 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.test" , TRUE); |
2606 | g_assert_nonnull (schema); |
2607 | g_settings_schema_unref (schema); |
2608 | |
2609 | /* check recursive lookups for non-existent schemas */ |
2610 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.doesnotexist" , TRUE); |
2611 | g_assert_null (schema); |
2612 | |
2613 | /* check non-recursive for schema that only exists in lower layers */ |
2614 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.test" , FALSE); |
2615 | g_assert_null (schema); |
2616 | |
2617 | /* check non-recursive lookup for non-existent */ |
2618 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.doesnotexist" , FALSE); |
2619 | g_assert_null (schema); |
2620 | |
2621 | /* check non-recursive for schema that exists in toplevel */ |
2622 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.schemasourcecheck" , FALSE); |
2623 | g_assert_nonnull (schema); |
2624 | g_settings_schema_unref (schema); |
2625 | |
2626 | /* check recursive for schema that exists in toplevel */ |
2627 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.schemasourcecheck" , TRUE); |
2628 | g_assert_nonnull (schema); |
2629 | |
2630 | /* try to use it for something */ |
2631 | settings = g_settings_new_full (schema, backend, path: g_settings_schema_get_path (schema)); |
2632 | g_settings_schema_unref (schema); |
2633 | enabled = FALSE; |
2634 | g_settings_get (settings, key: "enabled" , format: "b" , &enabled); |
2635 | g_assert_true (enabled); |
2636 | g_object_unref (object: settings); |
2637 | |
2638 | g_settings_schema_source_unref (source); |
2639 | |
2640 | /* try again, but with no parent */ |
2641 | source = g_settings_schema_source_new_from_directory (directory: "schema-source" , NULL, FALSE, NULL); |
2642 | g_assert_nonnull (source); |
2643 | |
2644 | /* should not find it this time, even if recursive... */ |
2645 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.test" , FALSE); |
2646 | g_assert_null (schema); |
2647 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.test" , TRUE); |
2648 | g_assert_null (schema); |
2649 | |
2650 | /* should still find our own... */ |
2651 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.schemasourcecheck" , TRUE); |
2652 | g_assert_nonnull (schema); |
2653 | g_settings_schema_unref (schema); |
2654 | schema = g_settings_schema_source_lookup (source, schema_id: "org.gtk.schemasourcecheck" , FALSE); |
2655 | g_assert_nonnull (schema); |
2656 | g_settings_schema_unref (schema); |
2657 | |
2658 | g_settings_schema_source_unref (source); |
2659 | g_object_unref (object: backend); |
2660 | } |
2661 | |
2662 | static void |
2663 | test_schema_list_keys (void) |
2664 | { |
2665 | gchar **keys; |
2666 | GSettingsSchemaSource *src = g_settings_schema_source_get_default (); |
2667 | GSettingsSchema *schema = g_settings_schema_source_lookup (source: src, schema_id: "org.gtk.test" , TRUE); |
2668 | g_assert_nonnull (schema); |
2669 | |
2670 | keys = g_settings_schema_list_keys (schema); |
2671 | |
2672 | g_assert_true (strv_set_equal ((gchar **)keys, |
2673 | "greeting" , |
2674 | "farewell" , |
2675 | NULL)); |
2676 | |
2677 | g_strfreev (str_array: keys); |
2678 | g_settings_schema_unref (schema); |
2679 | } |
2680 | |
2681 | static void |
2682 | test_actions (void) |
2683 | { |
2684 | GAction *string, *toggle; |
2685 | gboolean c1, c2, c3; |
2686 | GSettings *settings; |
2687 | gchar *name; |
2688 | GVariantType *param_type; |
2689 | gboolean enabled; |
2690 | GVariantType *state_type; |
2691 | GVariant *state; |
2692 | |
2693 | settings = g_settings_new (schema_id: "org.gtk.test.basic-types" ); |
2694 | string = g_settings_create_action (settings, key: "test-string" ); |
2695 | toggle = g_settings_create_action (settings, key: "test-boolean" ); |
2696 | g_object_unref (object: settings); /* should be held by the actions */ |
2697 | |
2698 | g_signal_connect (settings, "changed" , G_CALLBACK (changed_cb2), &c1); |
2699 | g_signal_connect (string, "notify::state" , G_CALLBACK (changed_cb2), &c2); |
2700 | g_signal_connect (toggle, "notify::state" , G_CALLBACK (changed_cb2), &c3); |
2701 | |
2702 | c1 = c2 = c3 = FALSE; |
2703 | g_settings_set_string (settings, key: "test-string" , value: "hello world" ); |
2704 | check_and_free (value: g_action_get_state (action: string), expected: "'hello world'" ); |
2705 | g_assert_true (c1 && c2 && !c3); |
2706 | c1 = c2 = c3 = FALSE; |
2707 | |
2708 | g_action_activate (action: string, parameter: g_variant_new_string (string: "hihi" )); |
2709 | check_and_free (value: g_settings_get_value (settings, key: "test-string" ), expected: "'hihi'" ); |
2710 | g_assert_true (c1 && c2 && !c3); |
2711 | c1 = c2 = c3 = FALSE; |
2712 | |
2713 | g_action_change_state (action: string, value: g_variant_new_string (string: "kthxbye" )); |
2714 | check_and_free (value: g_settings_get_value (settings, key: "test-string" ), expected: "'kthxbye'" ); |
2715 | g_assert_true (c1 && c2 && !c3); |
2716 | c1 = c2 = c3 = FALSE; |
2717 | |
2718 | g_action_change_state (action: toggle, value: g_variant_new_boolean (TRUE)); |
2719 | g_assert_true (g_settings_get_boolean (settings, "test-boolean" )); |
2720 | g_assert_true (c1 && !c2 && c3); |
2721 | c1 = c2 = c3 = FALSE; |
2722 | |
2723 | g_action_activate (action: toggle, NULL); |
2724 | g_assert_false (g_settings_get_boolean (settings, "test-boolean" )); |
2725 | g_assert_true (c1 && !c2 && c3); |
2726 | |
2727 | g_object_get (object: string, |
2728 | first_property_name: "name" , &name, |
2729 | "parameter-type" , ¶m_type, |
2730 | "enabled" , &enabled, |
2731 | "state-type" , &state_type, |
2732 | "state" , &state, |
2733 | NULL); |
2734 | |
2735 | g_assert_cmpstr (name, ==, "test-string" ); |
2736 | g_assert_true (g_variant_type_equal (param_type, G_VARIANT_TYPE_STRING)); |
2737 | g_assert_true (enabled); |
2738 | g_assert_true (g_variant_type_equal (state_type, G_VARIANT_TYPE_STRING)); |
2739 | g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "kthxbye" ); |
2740 | |
2741 | g_free (mem: name); |
2742 | g_variant_type_free (type: param_type); |
2743 | g_variant_type_free (type: state_type); |
2744 | g_variant_unref (value: state); |
2745 | |
2746 | g_object_unref (object: string); |
2747 | g_object_unref (object: toggle); |
2748 | } |
2749 | |
2750 | static void |
2751 | test_null_backend (void) |
2752 | { |
2753 | GSettingsBackend *backend; |
2754 | GSettings *settings; |
2755 | gchar *str; |
2756 | gboolean writable; |
2757 | |
2758 | backend = g_null_settings_backend_new (); |
2759 | settings = g_settings_new_with_backend_and_path (schema_id: "org.gtk.test" , backend, path: "/tests/" ); |
2760 | |
2761 | g_object_get (object: settings, first_property_name: "schema-id" , &str, NULL); |
2762 | g_assert_cmpstr (str, ==, "org.gtk.test" ); |
2763 | g_free (mem: str); |
2764 | |
2765 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
2766 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
2767 | g_free (mem: str); |
2768 | |
2769 | g_settings_set (settings, key: "greeting" , format: "s" , "goodbye world" ); |
2770 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
2771 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
2772 | g_free (mem: str); |
2773 | |
2774 | writable = g_settings_is_writable (settings, name: "greeting" ); |
2775 | g_assert_false (writable); |
2776 | |
2777 | g_settings_reset (settings, key: "greeting" ); |
2778 | |
2779 | g_settings_delay (settings); |
2780 | g_settings_set (settings, key: "greeting" , format: "s" , "goodbye world" ); |
2781 | g_settings_apply (settings); |
2782 | g_settings_get (settings, key: "greeting" , format: "s" , &str); |
2783 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
2784 | g_free (mem: str); |
2785 | |
2786 | g_object_unref (object: settings); |
2787 | g_object_unref (object: backend); |
2788 | } |
2789 | |
2790 | static void |
2791 | test_memory_backend (void) |
2792 | { |
2793 | GSettingsBackend *backend; |
2794 | |
2795 | backend = g_memory_settings_backend_new (); |
2796 | g_assert_true (G_IS_SETTINGS_BACKEND (backend)); |
2797 | g_object_unref (object: backend); |
2798 | } |
2799 | |
2800 | static void |
2801 | test_read_descriptions (void) |
2802 | { |
2803 | GSettingsSchema *schema; |
2804 | GSettingsSchemaKey *key; |
2805 | GSettings *settings; |
2806 | |
2807 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
2808 | g_object_get (object: settings, first_property_name: "settings-schema" , &schema, NULL); |
2809 | key = g_settings_schema_get_key (schema, name: "greeting" ); |
2810 | |
2811 | g_assert_cmpstr (g_settings_schema_key_get_summary (key), ==, "A greeting" ); |
2812 | g_assert_cmpstr (g_settings_schema_key_get_description (key), ==, "Greeting of the invading martians" ); |
2813 | |
2814 | g_settings_schema_key_unref (key); |
2815 | g_settings_schema_unref (schema); |
2816 | |
2817 | g_object_unref (object: settings); |
2818 | |
2819 | settings = g_settings_new (schema_id: "org.gtk.test.descriptions" ); |
2820 | g_object_get (object: settings, first_property_name: "settings-schema" , &schema, NULL); |
2821 | key = g_settings_schema_get_key (schema, name: "a" ); |
2822 | |
2823 | g_assert_cmpstr (g_settings_schema_key_get_summary (key), ==, |
2824 | "a paragraph.\n\n" |
2825 | "with some whitespace.\n\n" |
2826 | "because not everyone has a great editor.\n\n" |
2827 | "lots of space is as one." ); |
2828 | |
2829 | g_settings_schema_key_unref (key); |
2830 | g_settings_schema_unref (schema); |
2831 | |
2832 | g_object_unref (object: settings); |
2833 | } |
2834 | |
2835 | static void |
2836 | test_default_value (void) |
2837 | { |
2838 | GSettings *settings; |
2839 | GSettingsSchema *schema; |
2840 | GSettingsSchemaKey *key; |
2841 | GVariant *v; |
2842 | const gchar *str; |
2843 | gchar *s; |
2844 | |
2845 | settings = g_settings_new (schema_id: "org.gtk.test" ); |
2846 | g_object_get (object: settings, first_property_name: "settings-schema" , &schema, NULL); |
2847 | key = g_settings_schema_get_key (schema, name: "greeting" ); |
2848 | g_settings_schema_unref (schema); |
2849 | g_settings_schema_key_ref (key); |
2850 | |
2851 | g_assert_true (g_variant_type_equal (g_settings_schema_key_get_value_type (key), G_VARIANT_TYPE_STRING)); |
2852 | |
2853 | v = g_settings_schema_key_get_default_value (key); |
2854 | str = g_variant_get_string (value: v, NULL); |
2855 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
2856 | g_variant_unref (value: v); |
2857 | |
2858 | g_settings_schema_key_unref (key); |
2859 | g_settings_schema_key_unref (key); |
2860 | |
2861 | g_settings_set (settings, key: "greeting" , format: "s" , "goodbye world" ); |
2862 | |
2863 | v = g_settings_get_user_value (settings, key: "greeting" ); |
2864 | str = g_variant_get_string (value: v, NULL); |
2865 | g_assert_cmpstr (str, ==, "goodbye world" ); |
2866 | g_variant_unref (value: v); |
2867 | |
2868 | v = g_settings_get_default_value (settings, key: "greeting" ); |
2869 | str = g_variant_get_string (value: v, NULL); |
2870 | g_assert_cmpstr (str, ==, "Hello, earthlings" ); |
2871 | g_variant_unref (value: v); |
2872 | |
2873 | g_settings_reset (settings, key: "greeting" ); |
2874 | |
2875 | v = g_settings_get_user_value (settings, key: "greeting" ); |
2876 | g_assert_null (v); |
2877 | |
2878 | s = g_settings_get_string (settings, key: "greeting" ); |
2879 | g_assert_cmpstr (s, ==, "Hello, earthlings" ); |
2880 | g_free (mem: s); |
2881 | |
2882 | g_object_unref (object: settings); |
2883 | } |
2884 | |
2885 | static gboolean |
2886 | string_map_func (GVariant *value, |
2887 | gpointer *result, |
2888 | gpointer user_data) |
2889 | { |
2890 | const gchar *str; |
2891 | |
2892 | str = g_variant_get_string (value, NULL); |
2893 | *result = g_variant_new_string (string: str); |
2894 | |
2895 | return TRUE; |
2896 | } |
2897 | |
2898 | /* Test that per-desktop values from org.gtk.test.gschema.override |
2899 | * does not change default value if current desktop is not listed in |
2900 | * $XDG_CURRENT_DESKTOP. |
2901 | */ |
2902 | static void |
2903 | test_per_desktop (void) |
2904 | { |
2905 | GSettings *settings; |
2906 | TestObject *obj; |
2907 | gpointer p; |
2908 | gchar *str; |
2909 | |
2910 | settings = g_settings_new (schema_id: "org.gtk.test.per-desktop" ); |
2911 | obj = test_object_new (); |
2912 | |
2913 | if (!g_test_subprocess ()) |
2914 | { |
2915 | g_test_trap_subprocess (test_path: "/gsettings/per-desktop/subprocess" , usec_timeout: 0, test_flags: 0); |
2916 | g_test_trap_assert_passed (); |
2917 | } |
2918 | |
2919 | str = g_settings_get_string (settings, key: "desktop" ); |
2920 | g_assert_cmpstr (str, ==, "GNOME" ); |
2921 | g_free (mem: str); |
2922 | |
2923 | p = g_settings_get_mapped (settings, key: "desktop" , mapping: string_map_func, NULL); |
2924 | |
2925 | str = g_variant_dup_string (value: p, NULL); |
2926 | g_assert_cmpstr (str, ==, "GNOME" ); |
2927 | g_free (mem: str); |
2928 | |
2929 | g_variant_unref (value: p); |
2930 | |
2931 | g_settings_bind (settings, key: "desktop" , object: obj, property: "string" , flags: G_SETTINGS_BIND_DEFAULT); |
2932 | |
2933 | g_object_get (object: obj, first_property_name: "string" , &str, NULL); |
2934 | g_assert_cmpstr (str, ==, "GNOME" ); |
2935 | g_free (mem: str); |
2936 | |
2937 | g_object_unref (object: settings); |
2938 | g_object_unref (object: obj); |
2939 | } |
2940 | |
2941 | /* Test that per-desktop values from org.gtk.test.gschema.override |
2942 | * are successfully loaded based on the value of $XDG_CURRENT_DESKTOP. |
2943 | */ |
2944 | static void |
2945 | test_per_desktop_subprocess (void) |
2946 | { |
2947 | GSettings *settings; |
2948 | TestObject *obj; |
2949 | gpointer p; |
2950 | gchar *str; |
2951 | |
2952 | g_setenv (variable: "XDG_CURRENT_DESKTOP" , value: "GNOME-Classic:GNOME" , TRUE); |
2953 | |
2954 | settings = g_settings_new (schema_id: "org.gtk.test.per-desktop" ); |
2955 | obj = test_object_new (); |
2956 | |
2957 | str = g_settings_get_string (settings, key: "desktop" ); |
2958 | g_assert_cmpstr (str, ==, "GNOME Classic" ); |
2959 | g_free (mem: str); |
2960 | |
2961 | p = g_settings_get_mapped (settings, key: "desktop" , mapping: string_map_func, NULL); |
2962 | |
2963 | str = g_variant_dup_string (value: p, NULL); |
2964 | g_assert_cmpstr (str, ==, "GNOME Classic" ); |
2965 | g_free (mem: str); |
2966 | |
2967 | g_variant_unref (value: p); |
2968 | |
2969 | g_settings_bind (settings, key: "desktop" , object: obj, property: "string" , flags: G_SETTINGS_BIND_DEFAULT); |
2970 | |
2971 | g_object_get (object: obj, first_property_name: "string" , &str, NULL); |
2972 | g_assert_cmpstr (str, ==, "GNOME Classic" ); |
2973 | g_free (mem: str); |
2974 | |
2975 | g_object_unref (object: settings); |
2976 | g_object_unref (object: obj); |
2977 | } |
2978 | |
2979 | static void |
2980 | test_extended_schema (void) |
2981 | { |
2982 | GSettingsSchema *schema; |
2983 | GSettings *settings; |
2984 | gchar **keys; |
2985 | |
2986 | settings = g_settings_new_with_path (schema_id: "org.gtk.test.extends.extended" , path: "/test/extendes/" ); |
2987 | g_object_get (object: settings, first_property_name: "settings-schema" , &schema, NULL); |
2988 | keys = g_settings_schema_list_keys (schema); |
2989 | g_assert_true (strv_set_equal (keys, "int32" , "string" , "another-int32" , NULL)); |
2990 | g_strfreev (str_array: keys); |
2991 | g_object_unref (object: settings); |
2992 | g_settings_schema_unref (schema); |
2993 | } |
2994 | |
2995 | int |
2996 | main (int argc, char *argv[]) |
2997 | { |
2998 | gchar *schema_text; |
2999 | gchar *override_text; |
3000 | gchar *enums; |
3001 | gint result; |
3002 | const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/" , "root" , "tests" , "/" }; |
3003 | const KeyfileTestData keyfile_test_data_empty_path = { "/" , "root" , "root" , "/" }; |
3004 | const KeyfileTestData keyfile_test_data_long_path = { |
3005 | "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/" , |
3006 | "root" , |
3007 | "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch" , |
3008 | "/" |
3009 | }; |
3010 | |
3011 | /* Meson build sets this */ |
3012 | #ifdef TEST_LOCALE_PATH |
3013 | if (g_str_has_suffix (TEST_LOCALE_PATH, suffix: "LC_MESSAGES" )) |
3014 | { |
3015 | locale_dir = TEST_LOCALE_PATH G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S ".." ; |
3016 | } |
3017 | #endif |
3018 | |
3019 | setlocale (LC_ALL, locale: "" ); |
3020 | |
3021 | g_test_init (argc: &argc, argv: &argv, NULL); |
3022 | |
3023 | if (!g_test_subprocess ()) |
3024 | { |
3025 | GError *local_error = NULL; |
3026 | /* A GVDB header is 6 guint32s, and requires a magic number in the first |
3027 | * two guint32s. A set of zero bytes of a greater length is considered |
3028 | * corrupt. */ |
3029 | const guint8 gschemas_compiled_corrupt[sizeof (guint32) * 7] = { 0, }; |
3030 | |
3031 | backend_set = g_getenv (variable: "GSETTINGS_BACKEND" ) != NULL; |
3032 | |
3033 | g_setenv (variable: "XDG_DATA_DIRS" , value: "." , TRUE); |
3034 | g_setenv (variable: "XDG_DATA_HOME" , value: "." , TRUE); |
3035 | g_setenv (variable: "GSETTINGS_SCHEMA_DIR" , value: "." , TRUE); |
3036 | g_setenv (variable: "XDG_CURRENT_DESKTOP" , value: "" , TRUE); |
3037 | |
3038 | if (!backend_set) |
3039 | g_setenv (variable: "GSETTINGS_BACKEND" , value: "memory" , TRUE); |
3040 | |
3041 | g_remove (filename: "org.gtk.test.enums.xml" ); |
3042 | /* #GLIB_MKENUMS is defined in meson.build */ |
3043 | g_assert_true (g_spawn_command_line_sync (GLIB_MKENUMS " " |
3044 | "--template " SRCDIR "/enums.xml.template " |
3045 | SRCDIR "/testenum.h" , |
3046 | &enums, NULL, &result, NULL)); |
3047 | g_assert_cmpint (result, ==, 0); |
3048 | g_assert_true (g_file_set_contents ("org.gtk.test.enums.xml" , enums, -1, NULL)); |
3049 | g_free (mem: enums); |
3050 | |
3051 | g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.xml.orig" , &schema_text, NULL, NULL)); |
3052 | g_assert_true (g_file_set_contents ("org.gtk.test.gschema.xml" , schema_text, -1, NULL)); |
3053 | g_free (mem: schema_text); |
3054 | |
3055 | g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.override.orig" , &override_text, NULL, NULL)); |
3056 | g_assert_true (g_file_set_contents ("org.gtk.test.gschema.override" , override_text, -1, NULL)); |
3057 | g_free (mem: override_text); |
3058 | |
3059 | g_remove (filename: "gschemas.compiled" ); |
3060 | /* #GLIB_COMPILE_SCHEMAS is defined in meson.build */ |
3061 | g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. " |
3062 | "--schema-file=org.gtk.test.enums.xml " |
3063 | "--schema-file=org.gtk.test.gschema.xml " |
3064 | "--override-file=org.gtk.test.gschema.override" , |
3065 | NULL, NULL, &result, NULL)); |
3066 | g_assert_cmpint (result, ==, 0); |
3067 | |
3068 | g_remove (filename: "schema-source/gschemas.compiled" ); |
3069 | g_mkdir (path: "schema-source" , mode: 0777); |
3070 | g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source " |
3071 | "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml" , |
3072 | NULL, NULL, &result, NULL)); |
3073 | g_assert_cmpint (result, ==, 0); |
3074 | |
3075 | g_remove (filename: "schema-source-corrupt/gschemas.compiled" ); |
3076 | g_mkdir (path: "schema-source-corrupt" , mode: 0777); |
3077 | g_file_set_contents (filename: "schema-source-corrupt/gschemas.compiled" , |
3078 | contents: (const gchar *) gschemas_compiled_corrupt, |
3079 | length: sizeof (gschemas_compiled_corrupt), |
3080 | error: &local_error); |
3081 | g_assert_no_error (local_error); |
3082 | |
3083 | g_remove (filename: "schema-source-empty/gschemas.compiled" ); |
3084 | g_mkdir (path: "schema-source-empty" , mode: 0777); |
3085 | g_file_set_contents (filename: "schema-source-empty/gschemas.compiled" , |
3086 | contents: "" , length: 0, |
3087 | error: &local_error); |
3088 | g_assert_no_error (local_error); |
3089 | } |
3090 | |
3091 | g_test_add_func (testpath: "/gsettings/basic" , test_func: test_basic); |
3092 | |
3093 | if (!backend_set) |
3094 | { |
3095 | g_test_add_func (testpath: "/gsettings/no-schema" , test_func: test_no_schema); |
3096 | g_test_add_func (testpath: "/gsettings/unknown-key" , test_func: test_unknown_key); |
3097 | g_test_add_func (testpath: "/gsettings/wrong-type" , test_func: test_wrong_type); |
3098 | g_test_add_func (testpath: "/gsettings/wrong-path" , test_func: test_wrong_path); |
3099 | g_test_add_func (testpath: "/gsettings/no-path" , test_func: test_no_path); |
3100 | } |
3101 | |
3102 | g_test_add_func (testpath: "/gsettings/basic-types" , test_func: test_basic_types); |
3103 | g_test_add_func (testpath: "/gsettings/complex-types" , test_func: test_complex_types); |
3104 | g_test_add_func (testpath: "/gsettings/changes" , test_func: test_changes); |
3105 | |
3106 | g_test_add_func (testpath: "/gsettings/l10n" , test_func: test_l10n); |
3107 | g_test_add_func (testpath: "/gsettings/l10n-context" , test_func: test_l10n_context); |
3108 | |
3109 | g_test_add_func (testpath: "/gsettings/delay-apply" , test_func: test_delay_apply); |
3110 | g_test_add_func (testpath: "/gsettings/delay-revert" , test_func: test_delay_revert); |
3111 | g_test_add_func (testpath: "/gsettings/delay-child" , test_func: test_delay_child); |
3112 | g_test_add_func (testpath: "/gsettings/atomic" , test_func: test_atomic); |
3113 | |
3114 | g_test_add_func (testpath: "/gsettings/simple-binding" , test_func: test_simple_binding); |
3115 | g_test_add_func (testpath: "/gsettings/directional-binding" , test_func: test_directional_binding); |
3116 | g_test_add_func (testpath: "/gsettings/custom-binding" , test_func: test_custom_binding); |
3117 | g_test_add_func (testpath: "/gsettings/no-change-binding" , test_func: test_no_change_binding); |
3118 | g_test_add_func (testpath: "/gsettings/unbinding" , test_func: test_unbind); |
3119 | g_test_add_func (testpath: "/gsettings/writable-binding" , test_func: test_bind_writable); |
3120 | |
3121 | if (!backend_set) |
3122 | { |
3123 | g_test_add_func (testpath: "/gsettings/typesafe-binding" , test_func: test_typesafe_binding); |
3124 | g_test_add_func (testpath: "/gsettings/no-read-binding" , test_func: test_no_read_binding); |
3125 | g_test_add_func (testpath: "/gsettings/no-read-binding/subprocess/fail" , test_func: test_no_read_binding_fail); |
3126 | g_test_add_func (testpath: "/gsettings/no-read-binding/subprocess/pass" , test_func: test_no_read_binding_pass); |
3127 | g_test_add_func (testpath: "/gsettings/no-write-binding" , test_func: test_no_write_binding); |
3128 | g_test_add_func (testpath: "/gsettings/no-write-binding/subprocess/fail" , test_func: test_no_write_binding_fail); |
3129 | g_test_add_func (testpath: "/gsettings/no-write-binding/subprocess/pass" , test_func: test_no_write_binding_pass); |
3130 | } |
3131 | |
3132 | g_test_add ("/gsettings/keyfile" , Fixture, NULL, setup, test_keyfile, teardown); |
3133 | g_test_add ("/gsettings/keyfile/explicit-path" , Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown); |
3134 | g_test_add ("/gsettings/keyfile/empty-path" , Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown); |
3135 | g_test_add ("/gsettings/keyfile/long-path" , Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown); |
3136 | g_test_add ("/gsettings/keyfile/outside-root-path" , Fixture, NULL, setup, test_keyfile_outside_root_path, teardown); |
3137 | g_test_add ("/gsettings/keyfile/no-root-group" , Fixture, NULL, setup, test_keyfile_no_root_group, teardown); |
3138 | g_test_add_func (testpath: "/gsettings/child-schema" , test_func: test_child_schema); |
3139 | g_test_add_func (testpath: "/gsettings/strinfo" , test_func: test_strinfo); |
3140 | g_test_add_func (testpath: "/gsettings/enums" , test_func: test_enums); |
3141 | g_test_add_func (testpath: "/gsettings/enums/subprocess/non-enum-key" , test_func: test_enums_non_enum_key); |
3142 | g_test_add_func (testpath: "/gsettings/enums/subprocess/non-enum-value" , test_func: test_enums_non_enum_value); |
3143 | g_test_add_func (testpath: "/gsettings/enums/subprocess/range" , test_func: test_enums_range); |
3144 | g_test_add_func (testpath: "/gsettings/enums/subprocess/non-flags" , test_func: test_enums_non_flags); |
3145 | g_test_add_func (testpath: "/gsettings/flags" , test_func: test_flags); |
3146 | g_test_add_func (testpath: "/gsettings/flags/subprocess/non-flags-key" , test_func: test_flags_non_flags_key); |
3147 | g_test_add_func (testpath: "/gsettings/flags/subprocess/non-flags-value" , test_func: test_flags_non_flags_value); |
3148 | g_test_add_func (testpath: "/gsettings/flags/subprocess/range" , test_func: test_flags_range); |
3149 | g_test_add_func (testpath: "/gsettings/flags/subprocess/non-enum" , test_func: test_flags_non_enum); |
3150 | g_test_add_func (testpath: "/gsettings/range" , test_func: test_range); |
3151 | g_test_add_func (testpath: "/gsettings/range/subprocess/high" , test_func: test_range_high); |
3152 | g_test_add_func (testpath: "/gsettings/range/subprocess/low" , test_func: test_range_low); |
3153 | g_test_add_func (testpath: "/gsettings/list-items" , test_func: test_list_items); |
3154 | g_test_add_func (testpath: "/gsettings/list-schemas" , test_func: test_list_schemas); |
3155 | g_test_add_func (testpath: "/gsettings/mapped" , test_func: test_get_mapped); |
3156 | g_test_add_func (testpath: "/gsettings/get-range" , test_func: test_get_range); |
3157 | g_test_add_func (testpath: "/gsettings/schema-source" , test_func: test_schema_source); |
3158 | g_test_add_func (testpath: "/gsettings/schema-list-keys" , test_func: test_schema_list_keys); |
3159 | g_test_add_func (testpath: "/gsettings/actions" , test_func: test_actions); |
3160 | g_test_add_func (testpath: "/gsettings/null-backend" , test_func: test_null_backend); |
3161 | g_test_add_func (testpath: "/gsettings/memory-backend" , test_func: test_memory_backend); |
3162 | g_test_add_func (testpath: "/gsettings/read-descriptions" , test_func: test_read_descriptions); |
3163 | g_test_add_func (testpath: "/gsettings/test-extended-schema" , test_func: test_extended_schema); |
3164 | g_test_add_func (testpath: "/gsettings/default-value" , test_func: test_default_value); |
3165 | g_test_add_func (testpath: "/gsettings/per-desktop" , test_func: test_per_desktop); |
3166 | g_test_add_func (testpath: "/gsettings/per-desktop/subprocess" , test_func: test_per_desktop_subprocess); |
3167 | |
3168 | result = g_test_run (); |
3169 | |
3170 | g_settings_sync (); |
3171 | |
3172 | /* FIXME: Due to the way #GSettings objects can be used without specifying a |
3173 | * backend, the default backend is leaked. In order to be able to run this |
3174 | * test under valgrind and get meaningful checking for real leaks, use this |
3175 | * hack to drop the final reference to the default #GSettingsBackend. |
3176 | * |
3177 | * This should not be used in production code. */ |
3178 | { |
3179 | GSettingsBackend *backend; |
3180 | |
3181 | backend = g_settings_backend_get_default (); |
3182 | g_object_unref (object: backend); /* reference from the *_get_default() call */ |
3183 | g_assert_finalize_object (backend); /* singleton reference owned by GLib */ |
3184 | } |
3185 | |
3186 | return result; |
3187 | } |
3188 | |