If the group is already there, make it current. (#385910, Joe Halliwell)
[platform/upstream/glib.git] / tests / keyfile-test.c
1 #include <glib.h>
2 #include <locale.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 static GKeyFile *
7 load_data (const gchar   *data, 
8            GKeyFileFlags  flags)
9 {
10   GKeyFile *keyfile;
11   GError *error = NULL;
12
13   keyfile = g_key_file_new ();
14   g_key_file_load_from_data (keyfile, data, -1, flags, &error);
15   if (error)
16     {
17       g_print ("Could not load data: %s\n", error->message);
18       exit (1);
19     }
20   
21   return keyfile;
22 }
23
24 static void
25 check_error (GError **error,
26              GQuark   domain,
27              gint     code)
28 {
29   if (*error == NULL)
30     {
31       g_print ("Missing an error\n");
32       exit (1);
33     }
34   
35   if ((*error)->domain != domain)
36     {
37       g_print ("Wrong error domain: got %s, expected %s\n",
38                g_quark_to_string ((*error)->domain),
39                g_quark_to_string (domain));
40       exit (1);
41     }
42   
43   if ((*error)->code != code)
44     {
45       g_print ("Wrong error code: got %d, expected %d\n",
46                (*error)->code, code);
47       exit (1);
48     }
49
50   g_error_free (*error);
51   *error = NULL;
52 }
53
54 static void 
55 check_no_error (GError **error)
56 {
57   if (*error != NULL)
58     {
59       g_print ("Unexpected error: (%s, %d) %s\n",
60                g_quark_to_string ((*error)->domain),
61                (*error)->code, (*error)->message);
62       exit (1);
63     }
64 }
65
66 static void
67 check_string_value (GKeyFile    *keyfile,
68                     const gchar *group,
69                     const gchar *key,
70                     const gchar *expected) 
71 {
72   GError *error = NULL;
73   gchar *value;
74
75   value = g_key_file_get_string (keyfile, group, key, &error);
76   check_no_error (&error);
77   g_assert (value != NULL);
78
79   if (strcmp (value, expected) != 0)
80     {
81       g_print ("Group %s key %s: "
82                "expected string value '%s', actual value '%s'\n",
83                group, key, expected, value);      
84       exit (1);
85     }
86
87   g_free (value);
88 }
89
90 static void
91 check_locale_string_value (GKeyFile    *keyfile,
92                            const gchar *group,
93                            const gchar *key,
94                            const gchar *locale,
95                            const gchar *expected) 
96 {
97   GError *error = NULL;
98   gchar *value;
99
100   value = g_key_file_get_locale_string (keyfile, group, key, locale, &error);
101   check_no_error (&error);
102   g_assert (value != NULL);
103
104   if (strcmp (value, expected) != 0)
105     {
106       g_print ("Group %s key %s locale %s: "
107                "expected string value '%s', actual value '%s'\n",
108                group, key, locale, expected, value);      
109       exit (1);
110     }
111
112   g_free (value);
113 }
114
115 static void
116 check_string_list_value (GKeyFile    *keyfile,
117                          const gchar *group,
118                          const gchar *key,
119                          ...)
120 {
121   gint i;
122   gchar *v, **value;
123   va_list args;
124   gsize len;
125   GError *error = NULL;
126
127   value = g_key_file_get_string_list (keyfile, group, key, &len, &error);
128   check_no_error (&error);
129   g_assert (value != NULL);
130   
131   va_start (args, key);
132   i = 0;
133   v = va_arg (args, gchar*);
134   while (v)
135     {
136       if (value[i] == NULL)
137         {
138           g_print ("Group %s key %s: list too short (%d)\n", 
139                    group, key, i);      
140           exit (1);
141         }
142       if (strcmp (v, value[i]) != 0)
143         {
144           g_print ("Group %s key %s: mismatch at %d, expected %s, got %s\n", 
145                    group, key, i, v, value[i]);      
146           exit (1);
147         }
148
149       i++;
150       v = va_arg (args, gchar*);
151     }
152
153   va_end (args);
154   
155   g_strfreev (value);
156 }
157
158 static void
159 check_integer_list_value (GKeyFile    *keyfile,
160                           const gchar *group,
161                           const gchar *key,
162                           ...)
163 {
164   gint i;
165   gint v, *value;
166   va_list args;
167   gsize len;
168   GError *error = NULL;
169
170   value = g_key_file_get_integer_list (keyfile, group, key, &len, &error);
171   check_no_error (&error);
172   g_assert (value != NULL);
173   
174   va_start (args, key);
175   i = 0;
176   v = va_arg (args, gint);
177   while (v != -100)
178     {
179       if (i == len)
180         {
181           g_print ("Group %s key %s: list too short (%d)\n", 
182                    group, key, i);      
183           exit (1);
184         }
185       if (value[i] != v)
186         {
187           g_print ("Group %s key %s: mismatch at %d, expected %d, got %d\n", 
188                    group, key, i, v, value[i]);      
189           exit (1);
190         }
191
192       i++;
193       v = va_arg (args, gint);
194     }
195
196   va_end (args);
197   
198   g_free (value);
199 }
200
201 static void
202 check_double_list_value (GKeyFile    *keyfile,
203                           const gchar *group,
204                           const gchar *key,
205                           ...)
206 {
207   gint i;
208   gdouble v, *value;
209   va_list args;
210   gsize len;
211   GError *error = NULL;
212
213   value = g_key_file_get_double_list (keyfile, group, key, &len, &error);
214   check_no_error (&error);
215   g_assert (value != NULL);
216   
217   va_start (args, key);
218   i = 0;
219   v = va_arg (args, gdouble);
220   while (v != -100)
221     {
222       if (i == len)
223         {
224           g_print ("Group %s key %s: list too short (%d)\n", 
225                    group, key, i);      
226           exit (1);
227         }
228       if (value[i] != v)
229         {
230           g_print ("Group %s key %s: mismatch at %d, expected %e, got %e\n", 
231                    group, key, i, v, value[i]);      
232           exit (1);
233         }
234
235       i++;
236       v = va_arg (args, gdouble);
237     }
238
239   va_end (args);
240   
241   g_free (value);
242 }
243
244 static void
245 check_boolean_list_value (GKeyFile    *keyfile,
246                           const gchar *group,
247                           const gchar *key,
248                           ...)
249 {
250   gint i;
251   gboolean v, *value;
252   va_list args;
253   gsize len;
254   GError *error = NULL;
255
256   value = g_key_file_get_boolean_list (keyfile, group, key, &len, &error);
257   check_no_error (&error);
258   g_assert (value != NULL);
259   
260   va_start (args, key);
261   i = 0;
262   v = va_arg (args, gboolean);
263   while (v != -100)
264     {
265       if (i == len)
266         {
267           g_print ("Group %s key %s: list too short (%d)\n", 
268                    group, key, i);      
269           exit (1);
270         }
271       if (value[i] != v)
272         {
273           g_print ("Group %s key %s: mismatch at %d, expected %d, got %d\n", 
274                    group, key, i, v, value[i]);      
275           exit (1);
276         }
277
278       i++;
279       v = va_arg (args, gboolean);
280     }
281
282   va_end (args);
283   
284   g_free (value);
285 }
286
287 static void
288 check_boolean_value (GKeyFile    *keyfile,
289                      const gchar *group,
290                      const gchar *key,
291                      gboolean     expected) 
292 {
293   GError *error = NULL;
294   gboolean value;
295
296   value = g_key_file_get_boolean (keyfile, group, key, &error);
297   check_no_error (&error);
298
299   if (value != expected)
300     {
301       g_print ("Group %s key %s: "
302                "expected boolean value '%s', actual value '%s'\n",
303                group, key, 
304                expected ? "true" : "false", 
305                value ? "true" : "false");      
306       exit (1);
307     }
308 }
309
310 static void
311 check_integer_value (GKeyFile    *keyfile,
312                      const gchar *group,
313                      const gchar *key,
314                      gint         expected) 
315 {
316   GError *error = NULL;
317   gint value;
318
319   value = g_key_file_get_integer (keyfile, group, key, &error);
320   check_no_error (&error);
321
322   if (value != expected)
323     {
324       g_print ("Group %s key %s: "
325                "expected integer value %d, actual value %d\n",
326                group, key, expected, value);      
327       exit (1);
328     }
329 }
330
331 static void
332 check_double_value (GKeyFile    *keyfile,
333                      const gchar *group,
334                      const gchar *key,
335                      gdouble      expected) 
336 {
337   GError *error = NULL;
338   gdouble value;
339
340   value = g_key_file_get_double (keyfile, group, key, &error);
341   check_no_error (&error);
342
343   if (value != expected)
344     {
345       g_print ("Group %s key %s: "
346                "expected integer value %e, actual value %e\n",
347                group, key, expected, value);      
348       exit (1);
349     }
350 }
351
352 static void
353 check_name (const gchar *what,
354             const gchar *value,
355             const gchar *expected,
356             gint         position)
357 {
358   if (!value || strcmp (expected, value) != 0)
359     {
360       g_print ("Wrong %s returned: got '%s' at %d, expected '%s'\n",
361                what, value, position, expected);
362       exit (1);
363     }
364 }
365
366 static void
367 check_length (const gchar *what,
368               gint         n_items,
369               gint         length,
370               gint         expected)
371 {
372   if (n_items != length || length != expected)
373     {
374       g_print ("Wrong number of %s returned: got %d items, length %d, expected %d\n",
375                what, n_items, length, expected);
376       exit (1);
377     }
378 }
379
380
381 /* check that both \n and \r\n are accepted as line ends,
382  * and that stray \r are passed through
383  */
384 static void
385 test_line_ends (void)
386 {
387   GKeyFile *keyfile;
388
389   const gchar *data = 
390     "[group1]\n"
391     "key1=value1\n"
392     "key2=value2\r\n"
393     "[group2]\r\n"
394     "key3=value3\r\r\n"
395     "key4=value4\n";
396
397   keyfile = load_data (data, 0);
398
399   check_string_value (keyfile, "group1", "key1", "value1");
400   check_string_value (keyfile, "group1", "key2", "value2");
401   check_string_value (keyfile, "group2", "key3", "value3\r");
402   check_string_value (keyfile, "group2", "key4", "value4");
403
404   g_key_file_free (keyfile);
405 }
406
407 /* check handling of whitespace 
408  */
409 static void
410 test_whitespace (void)
411 {
412   GKeyFile *keyfile;
413
414   const gchar *data = 
415     "[group1]\n"
416     "key1 = value1\n"
417     "key2\t=\tvalue2\n"
418     " [ group2 ] \n"
419     "key3  =  value3  \n"
420     "key4  =  value \t4\n"
421     "  key5  =  value5\n";
422   
423   keyfile = load_data (data, 0);
424
425   check_string_value (keyfile, "group1", "key1", "value1");
426   check_string_value (keyfile, "group1", "key2", "value2");
427   check_string_value (keyfile, " group2 ", "key3", "value3  ");
428   check_string_value (keyfile, " group2 ", "key4", "value \t4");
429   check_string_value (keyfile, " group2 ", "key5", "value5");
430
431   g_key_file_free (keyfile);
432 }
433
434 /* check handling of comments
435  */
436 static void
437 test_comments (void)
438 {
439   GKeyFile *keyfile;
440   gchar **names;
441   gsize len;
442   GError *error = NULL;
443   gchar *comment;
444
445   const gchar *data = 
446     "# top comment\n"
447     "# top comment, continued\n"
448     "[group1]\n"
449     "key1 = value1\n"
450     "# key comment\n"
451     "# key comment, continued\n"
452     "key2 = value2\n"
453     "# line end check\r\n"
454     "key3 = value3\n"
455     "key4 = value4\n"
456     "# group comment\n"
457     "# group comment, continued\n"
458     "[group2]\n";
459
460   const gchar *top_comment= " top comment\n top comment, continued\n";
461   const gchar *group_comment= " group comment\n group comment, continued\n";
462   const gchar *key_comment= " key comment\n key comment, continued\n";
463   
464   keyfile = load_data (data, 0);
465
466   check_string_value (keyfile, "group1", "key1", "value1");
467   check_string_value (keyfile, "group1", "key2", "value2");
468   check_string_value (keyfile, "group1", "key3", "value3");
469   check_string_value (keyfile, "group1", "key4", "value4");
470
471   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
472   check_no_error (&error);
473
474   check_length ("keys", g_strv_length (names), len, 4);
475   check_name ("key", names[0], "key1", 0);
476   check_name ("key", names[1], "key2", 1);
477   check_name ("key", names[2], "key3", 2);
478   check_name ("key", names[3], "key4", 3);
479
480   g_strfreev (names);
481
482   g_key_file_free (keyfile);
483
484   keyfile = load_data (data, G_KEY_FILE_KEEP_COMMENTS);
485
486   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
487   check_no_error (&error);
488
489   check_length ("keys", g_strv_length (names), len, 4);
490   check_name ("key", names[0], "key1", 0);
491   check_name ("key", names[1], "key2", 1);
492   check_name ("key", names[2], "key3", 2);
493   check_name ("key", names[3], "key4", 3);
494
495   g_strfreev (names);
496
497   comment = g_key_file_get_comment (keyfile, NULL, NULL, &error);
498   check_no_error (&error);
499   check_name ("top comment", comment, top_comment, 0);
500   g_free (comment);
501
502   comment = g_key_file_get_comment (keyfile, "group1", "key2", &error);
503   check_no_error (&error);
504   check_name ("key comment", comment, key_comment, 0);
505   g_free (comment);
506
507   comment = g_key_file_get_comment (keyfile, "group2", NULL, &error);
508   check_no_error (&error);
509   check_name ("group comment", comment, group_comment, 0);
510   g_free (comment);
511
512   comment = g_key_file_get_comment (keyfile, "group3", NULL, &error);
513   check_error (&error, 
514                G_KEY_FILE_ERROR,
515                G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
516   g_assert (comment == NULL);
517
518   g_key_file_free (keyfile);
519 }
520
521
522 /* check key and group listing */
523 static void
524 test_listing (void)
525 {
526   GKeyFile *keyfile;
527   gchar **names;
528   gsize len;
529   gchar *start;
530   GError *error = NULL;
531
532   const gchar *data = 
533     "[group1]\n"
534     "key1=value1\n"
535     "key2=value2\n"
536     "[group2]\n"
537     "key3=value3\n"
538     "key4=value4\n";
539   
540   keyfile = load_data (data, 0);
541
542   names = g_key_file_get_groups (keyfile, &len);
543   if (names == NULL)
544     {
545       g_print ("Error listing groups\n");
546       exit (1);
547     }
548
549   check_length ("groups", g_strv_length (names), len, 2);
550   check_name ("group name", names[0], "group1", 0);
551   check_name ("group name", names[1], "group2", 1);
552   
553   g_strfreev (names);
554   
555   names = g_key_file_get_keys (keyfile, "group1", &len, &error);
556   check_no_error (&error);
557
558   check_length ("keys", g_strv_length (names), len, 2);
559   check_name ("key", names[0], "key1", 0);
560   check_name ("key", names[1], "key2", 1);
561
562   g_strfreev (names);
563
564   names = g_key_file_get_keys (keyfile, "no-such-group", &len, &error);
565   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
566
567   g_strfreev (names);
568
569   if (!g_key_file_has_group (keyfile, "group1") ||
570       !g_key_file_has_group (keyfile, "group2") ||
571       g_key_file_has_group (keyfile, "group10") ||
572       g_key_file_has_group (keyfile, "group2 "))      
573     {
574       g_print ("Group finding trouble\n");
575       exit (1);      
576     }
577
578   start = g_key_file_get_start_group (keyfile);
579   if (!start || strcmp (start, "group1") != 0)
580     {
581       g_print ("Start group finding trouble\n");
582       exit (1);
583     }
584   g_free (start);
585
586   if (!g_key_file_has_key (keyfile, "group1", "key1", &error) ||
587       !g_key_file_has_key (keyfile, "group2", "key3", &error) ||
588       g_key_file_has_key (keyfile, "group2", "no-such-key", &error))
589     {
590       g_print ("Key finding trouble\n");
591       exit (1);      
592     }
593   check_no_error (&error);
594   
595   g_key_file_has_key (keyfile, "no-such-group", "key", &error);
596   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
597
598   g_key_file_free (keyfile);
599 }
600
601 /* check parsing of string values */
602 static void
603 test_string (void)
604 {
605   GKeyFile *keyfile;
606   GError *error = NULL;
607   gchar *value;
608
609   const gchar *data = 
610     "[valid]\n"
611     "key1=\\s\\n\\t\\r\\\\\n"
612     "key2=\"quoted\"\n"
613     "key3='quoted'\n"
614     "key4=\xe2\x89\xa0\xe2\x89\xa0\n"
615     "[invalid]\n"
616     "key1=\\a\\b\\0800xff\n"
617     "key2=blabla\\\n";
618   
619   keyfile = load_data (data, 0);
620
621   check_string_value (keyfile, "valid", "key1", " \n\t\r\\");
622   check_string_value (keyfile, "valid", "key2", "\"quoted\"");
623   check_string_value (keyfile, "valid", "key3", "'quoted'");  
624   check_string_value (keyfile, "valid", "key4", "\xe2\x89\xa0\xe2\x89\xa0");  
625   
626   value = g_key_file_get_string (keyfile, "invalid", "key1", &error);
627   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
628   g_free (value);
629
630   value = g_key_file_get_string (keyfile, "invalid", "key2", &error);
631   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
632   g_free (value);
633   
634   g_key_file_free (keyfile);
635 }
636
637 /* check parsing of boolean values */
638 static void
639 test_boolean (void)
640 {
641   GKeyFile *keyfile;
642   GError *error = NULL;
643
644   const gchar *data = 
645     "[valid]\n"
646     "key1=true\n"
647     "key2=false\n"
648     "key3=1\n"
649     "key4=0\n"
650     "[invalid]\n"
651     "key1=t\n"
652     "key2=f\n"
653     "key3=yes\n"
654     "key4=no\n";
655   
656   keyfile = load_data (data, 0);
657
658   check_boolean_value (keyfile, "valid", "key1", TRUE);
659   check_boolean_value (keyfile, "valid", "key2", FALSE);
660   check_boolean_value (keyfile, "valid", "key3", TRUE);
661   check_boolean_value (keyfile, "valid", "key4", FALSE);
662
663   g_key_file_get_boolean (keyfile, "invalid", "key1", &error);
664   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
665
666   g_key_file_get_boolean (keyfile, "invalid", "key2", &error);
667   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
668
669   g_key_file_get_boolean (keyfile, "invalid", "key3", &error);
670   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
671
672   g_key_file_get_boolean (keyfile, "invalid", "key4", &error);
673   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
674
675   g_key_file_free (keyfile);
676 }
677
678 /* check parsing of integer and double values */
679 static void
680 test_number (void)
681 {
682   GKeyFile *keyfile;
683   GError *error = NULL;
684
685   const gchar *data = 
686     "[valid]\n"
687     "key1=0\n"
688     "key2=1\n"
689     "key3=-1\n"
690     "key4=2324431\n"
691     "key5=-2324431\n"
692     "key6=000111\n"
693     "dkey1=000111\n"
694     "dkey2=145.45\n"
695     "dkey3=-3453.7\n"
696     "[invalid]\n"
697     "key1=0xffff\n"
698     "key2=0.5\n"
699     "key3=1e37\n"
700     "key4=ten\n"
701     "key5=\n"
702     "key6=1.0.0\n"
703     "key7=2x2\n"
704     "key8=abc\n";
705   
706   keyfile = load_data (data, 0);
707
708   check_integer_value (keyfile, "valid", "key1", 0);
709   check_integer_value (keyfile, "valid", "key2", 1);
710   check_integer_value (keyfile, "valid", "key3", -1);
711   check_integer_value (keyfile, "valid", "key4", 2324431);
712   check_integer_value (keyfile, "valid", "key5", -2324431);
713   check_integer_value (keyfile, "valid", "key6", 111);
714   check_double_value (keyfile, "valid", "dkey1", 111.0);
715   check_double_value (keyfile, "valid", "dkey2", 145.45);
716   check_double_value (keyfile, "valid", "dkey3", -3453.7);
717
718   g_key_file_get_integer (keyfile, "invalid", "key1", &error);
719   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
720
721   g_key_file_get_integer (keyfile, "invalid", "key2", &error);
722   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
723
724   g_key_file_get_integer (keyfile, "invalid", "key3", &error);
725   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
726
727   g_key_file_get_integer (keyfile, "invalid", "key4", &error);
728   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
729
730   g_key_file_get_double (keyfile, "invalid", "key5", &error);
731   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
732
733   g_key_file_get_double (keyfile, "invalid", "key6", &error);
734   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
735
736   g_key_file_get_double (keyfile, "invalid", "key7", &error);
737   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
738
739   g_key_file_get_double (keyfile, "invalid", "key8", &error);
740   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
741
742   g_key_file_free (keyfile);
743 }
744
745 /* check handling of translated strings */
746 static void
747 test_locale_string (void)
748 {
749   GKeyFile *keyfile;
750   GError *error = NULL;
751   gchar *value;
752
753   const gchar *data = 
754     "[valid]\n"
755     "key1=v1\n"
756     "key1[de]=v1-de\n"
757     "key1[de_DE]=v1-de_DE\n"
758     "key1[de_DE.UTF8]=v1-de_DE.UTF8\n"
759     "key1[fr]=v1-fr\n"
760     "key1[en] =v1-en\n"
761     "[invalid]\n"
762     "key1[de=v1\n"
763     "key1[fr]]=v2\n"
764     "key1 [en]=v3\n";  
765   
766   keyfile = load_data (data, G_KEY_FILE_KEEP_TRANSLATIONS);
767
768   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
769   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
770   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de_DE");
771   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de_DE.UTF8");
772   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1-fr");
773   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1-fr");
774   check_locale_string_value (keyfile, "valid", "key1", "en", "v1-en");
775   
776   value = g_key_file_get_locale_string (keyfile, "invalid", "key1", "de", &error);
777   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
778   g_free (value);
779
780   value = g_key_file_get_locale_string (keyfile, "invalid", "key1", "fr", &error);
781   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
782   g_free (value);
783
784   value = g_key_file_get_locale_string (keyfile, "invalid", "key1", "en", &error);
785   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
786   g_free (value);
787   
788   g_key_file_free (keyfile);
789
790   /* now test that translations are thrown away */
791
792   g_setenv ("LANGUAGE", "de", TRUE);
793   setlocale (LC_ALL, "");
794
795   keyfile = load_data (data, 0);
796
797   check_locale_string_value (keyfile, "valid", "key1", "it", "v1");
798   check_locale_string_value (keyfile, "valid", "key1", "de", "v1-de");
799   check_locale_string_value (keyfile, "valid", "key1", "de_DE", "v1-de");
800   check_locale_string_value (keyfile, "valid", "key1", "de_DE.UTF8", "v1-de");
801   check_locale_string_value (keyfile, "valid", "key1", "fr", "v1");
802   check_locale_string_value (keyfile, "valid", "key1", "fr_FR", "v1");
803   check_locale_string_value (keyfile, "valid", "key1", "en", "v1");
804
805   g_key_file_free (keyfile);  
806 }
807
808 static void
809 test_lists (void)
810 {
811   GKeyFile *keyfile;
812
813   const gchar *data = 
814     "[valid]\n"
815     "key1=v1;v2\n"
816     "key2=v1;v2;\n"
817     "key3=v1,v2\n"
818     "key4=v1\\;v2\n"
819     "key5=true;false\n"
820     "key6=1;0;-1\n"
821     "key7= 1 ; 0 ; -1 \n"
822     "key8=v1\\,v2\n"
823     "key9=0;1.3456;-76532.456\n";
824   
825   keyfile = load_data (data, 0);
826
827   check_string_list_value (keyfile, "valid", "key1", "v1", "v2", NULL);
828   check_string_list_value (keyfile, "valid", "key2", "v1", "v2", NULL);
829   check_string_list_value (keyfile, "valid", "key3", "v1,v2", NULL);
830   check_string_list_value (keyfile, "valid", "key4", "v1;v2", NULL);
831   check_boolean_list_value (keyfile, "valid", "key5", TRUE, FALSE, -100);
832   check_integer_list_value (keyfile, "valid", "key6", 1, 0, -1, -100);
833   check_double_list_value (keyfile, "valid", "key9", 0.0, 1.3456, -76532.456, -100.0);
834   /* maybe these should be valid */
835   /* check_integer_list_value (keyfile, "valid", "key7", 1, 0, -1, -100);*/
836   /* check_string_list_value (keyfile, "valid", "key8", "v1\\,v2", NULL);*/
837
838   g_key_file_free (keyfile);  
839
840   /* Now check an alternate separator */
841
842   keyfile = load_data (data, 0);
843   g_key_file_set_list_separator (keyfile, ',');
844
845   check_string_list_value (keyfile, "valid", "key1", "v1;v2", NULL);
846   check_string_list_value (keyfile, "valid", "key2", "v1;v2;", NULL);
847   check_string_list_value (keyfile, "valid", "key3", "v1", "v2", NULL);
848
849   g_key_file_free (keyfile);  
850 }
851
852 /* http://bugzilla.gnome.org/show_bug.cgi?id=165887 */
853 static void 
854 test_group_remove (void)
855 {
856   GKeyFile *keyfile;
857   gchar **names;
858   gsize len;
859   GError *error = NULL;
860
861   const gchar *data = 
862     "[group1]\n"
863     "[group2]\n"
864     "key1=bla\n"
865     "key2=bla\n"
866     "[group3]\n"
867     "key1=bla\n"
868     "key2=bla\n";
869   
870   keyfile = load_data (data, 0);
871   
872   names = g_key_file_get_groups (keyfile, &len);
873   if (names == NULL)
874     {
875       g_print ("Error listing groups\n");
876       exit (1);
877     }
878
879   check_length ("groups", g_strv_length (names), len, 3);
880   check_name ("group name", names[0], "group1", 0);
881   check_name ("group name", names[1], "group2", 1);
882   check_name ("group name", names[2], "group3", 2);
883
884   g_key_file_remove_group (keyfile, "group1", &error);
885   check_no_error (&error);
886   
887   g_strfreev (names);
888
889   names = g_key_file_get_groups (keyfile, &len);
890   if (names == NULL)
891     {
892       g_print ("Error listing groups\n");
893       exit (1);
894     }
895
896   check_length ("groups", g_strv_length (names), len, 2);
897   check_name ("group name", names[0], "group2", 0);
898   check_name ("group name", names[1], "group3", 1);
899
900   g_key_file_remove_group (keyfile, "group2", &error);
901   check_no_error (&error);
902   
903   g_strfreev (names);
904
905   names = g_key_file_get_groups (keyfile, &len);
906   if (names == NULL)
907     {
908       g_print ("Error listing groups\n");
909       exit (1);
910     }
911
912   check_length ("groups", g_strv_length (names), len, 1);
913   check_name ("group name", names[0], "group3", 0);
914
915   g_key_file_remove_group (keyfile, "no such group", &error);
916   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
917
918   g_strfreev (names);
919
920   g_key_file_free (keyfile);
921 }
922
923 /* http://bugzilla.gnome.org/show_bug.cgi?id=165980 */
924 static void 
925 test_key_remove (void)
926 {
927   GKeyFile *keyfile;
928   gchar *value;
929   GError *error = NULL;
930
931   const gchar *data = 
932     "[group1]\n"
933     "key1=bla\n"
934     "key2=bla\n";
935   
936   keyfile = load_data (data, 0);
937   
938   check_string_value (keyfile, "group1", "key1", "bla");
939
940   g_key_file_remove_key (keyfile, "group1", "key1", &error);
941   check_no_error (&error);
942
943   value = g_key_file_get_string (keyfile, "group1", "key1", &error);
944   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
945   g_free (value);
946   
947   g_key_file_remove_key (keyfile, "group1", "key1", &error);
948   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
949
950   g_key_file_remove_key (keyfile, "no such group", "key1", &error);
951   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND);
952
953   g_key_file_free (keyfile);
954 }
955
956
957 /* http://bugzilla.gnome.org/show_bug.cgi?id=316309 */
958 static void
959 test_groups (void)
960 {
961   GKeyFile *keyfile;
962
963   const gchar *data = 
964     "[1]\n"
965     "key1=123\n"
966     "[2]\n"
967     "key2=123\n";
968   
969   keyfile = load_data (data, 0);
970
971   check_string_value (keyfile, "1", "key1", "123");
972   check_string_value (keyfile, "2", "key2", "123");
973
974   g_key_file_free (keyfile);  
975 }
976
977 static void
978 test_duplicate_keys (void)
979 {
980   GKeyFile *keyfile;
981   const gchar *data = 
982     "[1]\n"
983     "key1=123\n"
984     "key1=345\n";
985
986   keyfile = load_data (data, 0);
987   check_string_value (keyfile, "1", "key1", "345");
988
989   g_key_file_free (keyfile);  
990 }
991
992 /* http://bugzilla.gnome.org/show_bug.cgi?id=157877 */
993 static void
994 test_duplicate_groups (void)
995 {
996   GKeyFile *keyfile;
997   const gchar *data = 
998     "[Desktop Entry]\n"
999     "key1=123\n"
1000     "[Desktop Entry]\n"
1001     "key2=123\n";
1002   
1003   keyfile = load_data (data, 0);
1004   check_string_value (keyfile, "Desktop Entry", "key1", "123");
1005   check_string_value (keyfile, "Desktop Entry", "key2", "123");
1006
1007   g_key_file_free (keyfile);  
1008 }
1009
1010 /* http://bugzilla.gnome.org/show_bug.cgi?id=385910 */
1011 static void
1012 test_duplicate_groups2 (void)
1013 {
1014   GKeyFile *keyfile;
1015   const gchar *data = 
1016     "[A]\n"
1017     "foo=bar\n"
1018     "[B]\n"
1019     "foo=baz\n"
1020     "[A]\n"
1021     "foo=bang\n";
1022   
1023   keyfile = load_data (data, 0);
1024   check_string_value (keyfile, "A", "foo", "bang");
1025   check_string_value (keyfile, "B", "foo", "baz");
1026
1027   g_key_file_free (keyfile);  
1028 }
1029
1030 int
1031 main (int argc, char *argv[])
1032 {
1033   test_line_ends ();
1034   test_whitespace ();
1035   test_comments ();
1036   test_listing ();
1037   test_string ();
1038   test_boolean ();
1039   test_number ();
1040   test_locale_string ();
1041   test_lists ();
1042   test_group_remove ();
1043   test_key_remove ();
1044   test_groups ();
1045   test_duplicate_keys ();
1046   test_duplicate_groups ();
1047   test_duplicate_groups2 ();
1048   
1049   return 0;
1050 }