Improve charset test coverage
[platform/upstream/glib.git] / glib / tests / utils.c
1 /* Unit tests for utilities
2  * Copyright (C) 2010 Red Hat, Inc.
3  *
4  * This work is provided "as is"; redistribution and modification
5  * in whole or in part, in any medium, physical or electronic is
6  * permitted without restriction.
7  *
8  * This work is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * In no event shall the authors or contributors be liable for any
13  * direct, indirect, incidental, special, exemplary, or consequential
14  * damages (including, but not limited to, procurement of substitute
15  * goods or services; loss of use, data, or profits; or business
16  * interruption) however caused and on any theory of liability, whether
17  * in contract, strict liability, or tort (including negligence or
18  * otherwise) arising in any way out of the use of this software, even
19  * if advised of the possibility of such damage.
20  *
21  * Author: Matthias Clasen
22  */
23
24 #define GLIB_DISABLE_DEPRECATION_WARNINGS
25
26 #include "glib.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdarg.h>
31
32 static gboolean
33 strv_check (const gchar * const *strv, ...)
34 {
35   va_list args;
36   gchar *s;
37   gint i;
38
39   va_start (args, strv);
40   for (i = 0; strv[i]; i++)
41     {
42       s = va_arg (args, gchar*);
43       if (g_strcmp0 (strv[i], s) != 0)
44         {
45           va_end (args);
46           return FALSE;
47         }
48     }
49
50   va_end (args);
51
52   return TRUE;
53 }
54
55 static void
56 test_language_names (void)
57 {
58   const gchar * const *names;
59
60   g_setenv ("LANGUAGE", "de:en_US", TRUE);
61   names = g_get_language_names ();
62   g_assert (strv_check (names, "de", "en_US", "en", "C", NULL));
63
64   g_setenv ("LANGUAGE", "tt_RU.UTF-8@iqtelif", TRUE);
65   names = g_get_language_names ();
66   g_assert (strv_check (names,
67                         "tt_RU.UTF-8@iqtelif",
68                         "tt_RU@iqtelif",
69                         "tt.UTF-8@iqtelif",
70                         "tt@iqtelif",
71                         "tt_RU.UTF-8",
72                         "tt_RU",
73                         "tt.UTF-8",
74                         "tt",
75                         "C",
76                         NULL));
77 }
78
79 static void
80 test_locale_variants (void)
81 {
82   char **v;
83
84   v = g_get_locale_variants ("fr_BE");
85   g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL));
86   g_strfreev (v);
87
88   v = g_get_locale_variants ("sr_SR@latin");
89   g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL));
90   g_strfreev (v);
91 }
92
93 static void
94 test_version (void)
95 {
96   if (g_test_verbose ())
97     g_print ("(header %d.%d.%d library %d.%d.%d) ",
98               GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
99               glib_major_version, glib_minor_version, glib_micro_version);
100
101   g_assert (glib_check_version (GLIB_MAJOR_VERSION,
102                                 GLIB_MINOR_VERSION,
103                                 GLIB_MICRO_VERSION) == NULL);
104   g_assert (glib_check_version (GLIB_MAJOR_VERSION,
105                                 GLIB_MINOR_VERSION,
106                                 0) == NULL);
107   g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1,
108                                 0,
109                                 0) != NULL);
110   g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1,
111                                 0,
112                                 0) != NULL);
113   g_assert (glib_check_version (GLIB_MAJOR_VERSION,
114                                 GLIB_MINOR_VERSION + 1,
115                                 0) != NULL);
116   /* don't use + 1 here, since a +/-1 difference can
117    * happen due to post-release version bumps in git
118    */
119   g_assert (glib_check_version (GLIB_MAJOR_VERSION,
120                                 GLIB_MINOR_VERSION,
121                                 GLIB_MICRO_VERSION + 3) != NULL);
122 }
123
124 static const gchar *argv0;
125
126 static void
127 test_appname (void)
128 {
129   const gchar *prgname;
130   const gchar *appname;
131
132   prgname = g_get_prgname ();
133   appname = g_get_application_name ();
134   g_assert_cmpstr (prgname, ==, argv0);
135   g_assert_cmpstr (appname, ==, prgname);
136
137   g_set_prgname ("prgname");
138
139   prgname = g_get_prgname ();
140   appname = g_get_application_name ();
141   g_assert_cmpstr (prgname, ==, "prgname");
142   g_assert_cmpstr (appname, ==, "prgname");
143
144   g_set_application_name ("appname");
145
146   prgname = g_get_prgname ();
147   appname = g_get_application_name ();
148   g_assert_cmpstr (prgname, ==, "prgname");
149   g_assert_cmpstr (appname, ==, "appname");
150 }
151
152 static void
153 test_tmpdir (void)
154 {
155   g_test_bug ("627969");
156   g_assert_cmpstr (g_get_tmp_dir (), !=, "");
157 }
158
159 static void
160 test_bits (void)
161 {
162   gulong mask;
163   gint max_bit;
164   gint i, pos;
165
166   pos = g_bit_nth_lsf (0, -1);
167   g_assert_cmpint (pos, ==, -1);
168
169   max_bit = sizeof (gulong) * 8;
170   for (i = 0; i < max_bit; i++)
171     {
172       mask = 1UL << i;
173
174       pos = g_bit_nth_lsf (mask, -1);
175       g_assert_cmpint (pos, ==, i);
176
177       pos = g_bit_nth_lsf (mask, i - 3);
178       g_assert_cmpint (pos , ==, i);
179
180       pos = g_bit_nth_lsf (mask, i);
181       g_assert_cmpint (pos , ==, -1);
182
183       pos = g_bit_nth_lsf (mask, i + 1);
184       g_assert_cmpint (pos , ==, -1);
185     }
186
187   pos = g_bit_nth_msf (0, -1);
188   g_assert_cmpint (pos, ==, -1);
189
190   for (i = 0; i < max_bit; i++)
191     {
192       mask = 1UL << i;
193
194       pos = g_bit_nth_msf (mask, -1);
195       g_assert_cmpint (pos, ==, i);
196
197       pos = g_bit_nth_msf (mask, i + 3);
198       g_assert_cmpint (pos , ==, i);
199
200       pos = g_bit_nth_msf (mask, i);
201       g_assert_cmpint (pos , ==, -1);
202
203       if (i > 0)
204         {
205           pos = g_bit_nth_msf (mask, i - 1);
206           g_assert_cmpint (pos , ==, -1);
207         }
208     }
209 }
210
211 static void
212 test_swap (void)
213 {
214   guint16 a16, b16;
215   guint32 a32, b32;
216   guint64 a64, b64;
217
218   a16 = 0xaabb;
219   b16 = 0xbbaa;
220
221   g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16);
222
223   a32 = 0xaaaabbbb;
224   b32 = 0xbbbbaaaa;
225
226   g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32);
227
228   a64 = G_GUINT64_CONSTANT(0xaaaaaaaabbbbbbbb);
229   b64 = G_GUINT64_CONSTANT(0xbbbbbbbbaaaaaaaa);
230
231   g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64);
232 }
233
234 static void
235 test_find_program (void)
236 {
237   gchar *res;
238
239 #ifdef G_OS_UNIX
240   res = g_find_program_in_path ("sh");
241   g_assert (res != NULL);
242   g_free (res);
243
244   res = g_find_program_in_path ("/bin/sh");
245   g_assert (res != NULL);
246   g_free (res);
247 #else
248   /* There's not a lot we can search for that would reliably work both
249    * on real Windows and mingw.
250    */
251 #endif
252
253   res = g_find_program_in_path ("this_program_does_not_exit");
254   g_assert (res == NULL);
255
256   res = g_find_program_in_path ("/bin");
257   g_assert (res == NULL);
258
259   res = g_find_program_in_path ("/etc/passwd");
260   g_assert (res == NULL);
261 }
262
263 static void
264 test_debug (void)
265 {
266   GDebugKey keys[] = {
267     { "key1", 1 },
268     { "key2", 2 },
269     { "key3", 4 },
270   };
271   guint res;
272
273   res = g_parse_debug_string (NULL, keys, G_N_ELEMENTS (keys));
274   g_assert_cmpint (res, ==, 0);
275
276   res = g_parse_debug_string ("foobabla;#!%!$%112 223", keys, G_N_ELEMENTS (keys));
277   g_assert_cmpint (res, ==, 0);
278
279   res = g_parse_debug_string ("key1:key2", keys, G_N_ELEMENTS (keys));
280   g_assert_cmpint (res, ==, 3);
281
282   res = g_parse_debug_string ("key1;key2", keys, G_N_ELEMENTS (keys));
283   g_assert_cmpint (res, ==, 3);
284
285   res = g_parse_debug_string ("key1,key2", keys, G_N_ELEMENTS (keys));
286   g_assert_cmpint (res, ==, 3);
287
288   res = g_parse_debug_string ("key1   key2", keys, G_N_ELEMENTS (keys));
289   g_assert_cmpint (res, ==, 3);
290
291   res = g_parse_debug_string ("key1\tkey2", keys, G_N_ELEMENTS (keys));
292   g_assert_cmpint (res, ==, 3);
293
294   res = g_parse_debug_string ("all", keys, G_N_ELEMENTS (keys));
295   g_assert_cmpint (res, ==, 7);
296
297   if (g_test_subprocess ())
298     {
299       res = g_parse_debug_string ("help", keys, G_N_ELEMENTS (keys));
300       g_assert_cmpint (res, ==, 0);
301       return;
302     }
303   g_test_trap_subprocess (NULL, 0, 0);
304   g_test_trap_assert_passed ();
305   g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*");
306 }
307
308 static void
309 test_codeset (void)
310 {
311   gchar *c;
312   const gchar *c2;
313
314   c = g_get_codeset ();
315   g_get_charset (&c2);
316
317   g_assert_cmpstr (c, ==, c2);
318
319   g_free (c);
320 }
321
322 static void
323 test_codeset2 (void)
324 {
325   if (g_test_subprocess ())
326     {
327       const gchar *c;
328       g_setenv ("CHARSET", "UTF-8", TRUE);
329       g_get_charset (&c);
330       g_assert_cmpstr (c, ==, "UTF-8");
331       return;
332     }
333   g_test_trap_subprocess (NULL, 0, 0);
334   g_test_trap_assert_passed ();
335 }
336
337 static void
338 test_basename (void)
339 {
340   const gchar *path = "/path/to/a/file/deep/down.sh";
341   const gchar *b;
342
343   b = g_basename (path);
344
345   g_assert_cmpstr (b, ==, "down.sh");
346 }
347
348 extern const gchar *glib_pgettext (const gchar *msgidctxt, gsize msgidoffset);
349
350 static void
351 test_gettext (void)
352 {
353   const gchar *am0, *am1, *am2, *am3;
354
355   am0 = glib_pgettext ("GDateTime\004AM", strlen ("GDateTime") + 1);
356   am1 = g_dpgettext ("glib20", "GDateTime\004AM", strlen ("GDateTime") + 1);
357   am2 = g_dpgettext ("glib20", "GDateTime|AM", 0);
358   am3 = g_dpgettext2 ("glib20", "GDateTime", "AM");
359
360   g_assert_cmpstr (am0, ==, am1);
361   g_assert_cmpstr (am1, ==, am2);
362   g_assert_cmpstr (am2, ==, am3);
363 }
364
365 static void
366 test_username (void)
367 {
368   const gchar *name;
369
370   name = g_get_user_name ();
371
372   g_assert (name != NULL);
373 }
374
375 static void
376 test_realname (void)
377 {
378   const gchar *name;
379
380   name = g_get_real_name ();
381
382   g_assert (name != NULL);
383 }
384
385 static void
386 test_hostname (void)
387 {
388   const gchar *name;
389
390   name = g_get_host_name ();
391
392   g_assert (name != NULL);
393 }
394
395 #ifdef G_OS_UNIX
396 static void
397 test_xdg_dirs (void)
398 {
399   gchar *xdg;
400   const gchar *dir;
401   const gchar * const *dirs;
402   gchar *s;
403
404   xdg = g_strdup (g_getenv ("XDG_CONFIG_HOME"));
405   if (!xdg)
406     xdg = g_build_filename (g_get_home_dir (), ".config", NULL);
407
408   dir = g_get_user_config_dir ();
409
410   g_assert_cmpstr (dir, ==, xdg);
411   g_free (xdg);
412
413   xdg = g_strdup (g_getenv ("XDG_DATA_HOME"));
414   if (!xdg)
415     xdg = g_build_filename (g_get_home_dir (), ".local", "share", NULL);
416
417   dir = g_get_user_data_dir ();
418
419   g_assert_cmpstr (dir, ==, xdg);
420   g_free (xdg);
421
422   xdg = g_strdup (g_getenv ("XDG_CACHE_HOME"));
423   if (!xdg)
424     xdg = g_build_filename (g_get_home_dir (), ".cache", NULL);
425
426   dir = g_get_user_cache_dir ();
427
428   g_assert_cmpstr (dir, ==, xdg);
429   g_free (xdg);
430
431   xdg = g_strdup (g_getenv ("XDG_RUNTIME_DIR"));
432   if (!xdg)
433     xdg = g_strdup (g_get_user_cache_dir ());
434
435   dir = g_get_user_runtime_dir ();
436
437   g_assert_cmpstr (dir, ==, xdg);
438   g_free (xdg);
439
440   xdg = (gchar *)g_getenv ("XDG_CONFIG_DIRS");
441   if (!xdg)
442     xdg = "/etc/xdg";
443
444   dirs = g_get_system_config_dirs ();
445
446   s = g_strjoinv (":", (gchar **)dirs);
447
448   g_assert_cmpstr (s, ==, xdg);
449
450   g_free (s);
451 }
452 #endif
453
454 static void
455 test_special_dir (void)
456 {
457   const gchar *dir, *dir2;
458
459   dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
460   g_reload_user_special_dirs_cache ();
461   dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
462
463   g_assert_cmpstr (dir, ==, dir2);
464 }
465
466 static void
467 test_desktop_special_dir (void)
468 {
469   const gchar *dir, *dir2;
470
471   dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
472   g_assert (dir != NULL);
473
474   g_reload_user_special_dirs_cache ();
475   dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
476   g_assert (dir2 != NULL);
477 }
478
479 static void
480 test_clear_pointer (void)
481 {
482   gpointer a;
483
484   a = g_malloc (5);
485   g_clear_pointer (&a, g_free);
486   g_assert (a == NULL);
487
488   a = g_malloc (5);
489   (g_clear_pointer) (&a, g_free);
490   g_assert (a == NULL);
491 }
492
493 static void
494 test_misc_mem (void)
495 {
496   gpointer a;
497
498   a = g_try_malloc (0);
499   g_assert (a == NULL);
500
501   a = g_try_malloc0 (0);
502   g_assert (a == NULL);
503
504   a = g_malloc (16);
505   a = g_try_realloc (a, 20);
506   a = g_try_realloc (a, 0);
507
508   g_assert (a == NULL);
509 }
510
511 static void
512 test_nullify (void)
513 {
514   gpointer p = &test_nullify;
515
516   g_assert (p != NULL);
517
518   g_nullify_pointer (&p);
519
520   g_assert (p == NULL);
521 }
522
523 static void
524 atexit_func (void)
525 {
526   g_print ("atexit called");
527 }
528
529 static void
530 test_atexit (void)
531 {
532   if (g_test_subprocess ())
533     {
534       g_atexit (atexit_func);
535       return;
536     }
537   g_test_trap_subprocess (NULL, 0, 0);
538   g_test_trap_assert_passed ();
539   g_test_trap_assert_stdout ("*atexit called*");
540 }
541
542 int
543 main (int   argc,
544       char *argv[])
545 {
546   argv0 = argv[0];
547
548   /* for tmpdir test, need to do this early before g_get_any_init */
549   g_setenv ("TMPDIR", "", TRUE);
550   g_unsetenv ("TMP");
551   g_unsetenv ("TEMP");
552
553   /* g_test_init() only calls g_set_prgname() if g_get_prgname()
554    * returns %NULL, but g_get_prgname() on Windows never returns NULL.
555    * So we need to do this by hand to make test_appname() work on
556    * Windows.
557    */
558   g_set_prgname (argv[0]);
559
560   g_test_init (&argc, &argv, NULL);
561   g_test_bug_base ("http://bugzilla.gnome.org/");
562
563   g_test_add_func ("/utils/language-names", test_language_names);
564   g_test_add_func ("/utils/locale-variants", test_locale_variants);
565   g_test_add_func ("/utils/version", test_version);
566   g_test_add_func ("/utils/appname", test_appname);
567   g_test_add_func ("/utils/tmpdir", test_tmpdir);
568   g_test_add_func ("/utils/bits", test_bits);
569   g_test_add_func ("/utils/swap", test_swap);
570   g_test_add_func ("/utils/find-program", test_find_program);
571   g_test_add_func ("/utils/debug", test_debug);
572   g_test_add_func ("/utils/codeset", test_codeset);
573   g_test_add_func ("/utils/codeset2", test_codeset2);
574   g_test_add_func ("/utils/basename", test_basename);
575   g_test_add_func ("/utils/gettext", test_gettext);
576   g_test_add_func ("/utils/username", test_username);
577   g_test_add_func ("/utils/realname", test_realname);
578   g_test_add_func ("/utils/hostname", test_hostname);
579 #ifdef G_OS_UNIX
580   g_test_add_func ("/utils/xdgdirs", test_xdg_dirs);
581 #endif
582   g_test_add_func ("/utils/specialdir", test_special_dir);
583   g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
584   g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
585   g_test_add_func ("/utils/misc-mem", test_misc_mem);
586   g_test_add_func ("/utils/nullify", test_nullify);
587   g_test_add_func ("/utils/atexit", test_atexit);
588
589   return g_test_run ();
590 }