Imported Upstream version 2.66.1
[platform/upstream/glib.git] / glib / tests / collate.c
1 #include "config.h"
2
3 #include <glib.h>
4 #include <locale.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 static gboolean missing_locale = FALSE;
9
10 typedef struct {
11   const gchar **input;
12   const gchar **sorted;
13   const gchar **file_sorted;
14 } CollateTest;
15
16 typedef struct {
17   gchar *key;
18   const gchar *str;
19 } Line;
20
21 static void
22 clear_line (Line *line)
23 {
24   g_free (line->key);
25 }
26
27 static int
28 compare_collate (const void *a, const void *b)
29 {
30   const Line *line_a = a;
31   const Line *line_b = b;
32
33   return g_utf8_collate (line_a->str, line_b->str);
34 }
35
36 static int
37 compare_key (const void *a, const void *b)
38 {
39   const Line *line_a = a;
40   const Line *line_b = b;
41
42   return strcmp (line_a->key, line_b->key);
43 }
44
45 static void
46 do_collate (gboolean for_file, gboolean use_key, const CollateTest *test)
47 {
48   GArray *line_array;
49   Line line;
50   gint i;
51
52   if (missing_locale)
53     {
54       g_test_skip ("no en_US locale");
55       return;
56     }
57
58   line_array = g_array_new (FALSE, FALSE, sizeof(Line));
59   g_array_set_clear_func (line_array, (GDestroyNotify)clear_line);
60
61   for (i = 0; test->input[i]; i++)
62     {
63       line.str = test->input[i];
64       if (for_file)
65         line.key = g_utf8_collate_key_for_filename (line.str, -1);
66       else
67         line.key = g_utf8_collate_key (line.str, -1);
68
69       g_array_append_val (line_array, line);
70     }
71
72   qsort (line_array->data, line_array->len, sizeof (Line), use_key ? compare_key : compare_collate);
73
74   for (i = 0; test->input[i]; i++)
75     {
76       const gchar *str;
77       str = g_array_index (line_array, Line, i).str;
78       if (for_file)
79         g_assert_cmpstr (str, ==, test->file_sorted[i]);
80       else
81         g_assert_cmpstr (str, ==, test->sorted[i]);
82     }
83
84   g_array_free (line_array, TRUE);
85 }
86
87 static void
88 test_collate (gconstpointer d)
89 {
90   const CollateTest *test = d;
91   do_collate (FALSE, FALSE, test);
92 }
93
94 static void
95 test_collate_key (gconstpointer d)
96 {
97   const CollateTest *test = d;
98   do_collate (FALSE, TRUE, test);
99 }
100
101 static void
102 test_collate_file (gconstpointer d)
103 {
104   const CollateTest *test = d;
105   do_collate (TRUE, TRUE, test);
106 }
107
108 const gchar *input0[] = {
109   "z",
110   "c",
111   "eer34",
112   "223",
113   "er1",
114   "üĠണ",
115   "foo",
116   "bar",
117   "baz",
118   "GTK+",
119   NULL
120 };
121
122 const gchar *sorted0[] = {
123   "223",
124   "bar",
125   "baz",
126   "c",
127   "eer34",
128   "er1",
129   "foo",
130   "GTK+",
131   "üĠണ",
132   "z",
133   NULL
134 };
135
136 const gchar *file_sorted0[] = {
137   "223",
138   "bar",
139   "baz",
140   "c",
141   "eer34",
142   "er1",
143   "foo",
144   "GTK+",
145   "üĠണ",
146   "z",
147   NULL
148 };
149
150 const gchar *input1[] = {
151   "file.txt",
152   "file2.bla",
153   "file.c",
154   "file3.xx",
155   "bla001",
156   "bla02",
157   "bla03",
158   "bla4",
159   "bla10",
160   "bla100",
161   "event.c",
162   "eventgenerator.c",
163   "event.h",
164   NULL
165 };
166
167 const gchar *sorted1[] = {
168   "bla001",
169   "bla02",
170   "bla03",
171   "bla10",
172   "bla100",
173   "bla4",
174   "event.c",
175   "eventgenerator.c",
176   "event.h",
177   "file2.bla",
178   "file3.xx",
179   "file.c",
180   "file.txt",
181   NULL
182 };
183
184 const gchar *file_sorted1[] = {
185   "bla001",
186   "bla02",
187   "bla03",
188   "bla4",
189   "bla10",
190   "bla100",
191   "event.c",
192   "event.h",
193   "eventgenerator.c",
194   "file.c",
195   "file.txt",
196   "file2.bla",
197   "file3.xx",
198   NULL
199 };
200
201 const gchar *input2[] = {
202   "file26",
203   "file100",
204   "file1",
205   "file:foo",
206   "a.a",
207   "file027",
208   "file10",
209   "aa.a",
210   "file5",
211   "file0027",
212   "a-.a",
213   "file0000",
214   "file000x",
215   NULL
216 };
217
218 const gchar *sorted2[] = {
219   "a-.a",
220   "a.a",
221   "aa.a",
222   "file0000",
223   "file000x",
224   "file0027",
225   "file027",
226   "file1",
227   "file10",
228   "file100",
229   "file26",
230   "file5",
231   "file:foo",
232   NULL
233 };
234
235 const gchar *file_sorted2[] = {
236   /* Filename collation in OS X follows Finder style which gives
237    * a slightly different order from usual Linux locales. */
238 #ifdef HAVE_CARBON
239   "a-.a",
240   "a.a",
241   "aa.a",
242   "file:foo",
243   "file0000",
244   "file000x",
245   "file1",
246   "file5",
247   "file10",
248   "file26",
249   "file0027",
250   "file027",
251   "file100",
252 #else
253   "a.a",
254   "a-.a",
255   "aa.a",
256   "file0000",
257   "file000x",
258   "file1",
259   "file5",
260   "file10",
261   "file26",
262   "file027",
263   "file0027",
264   "file100",
265   "file:foo",
266 #endif
267   NULL
268 };
269
270 int
271 main (int argc, char *argv[])
272 {
273   gchar *path;
274   guint i;
275   const gchar *locale;
276   CollateTest test[3];
277
278   g_test_init (&argc, &argv, NULL);
279
280   g_setenv ("LC_ALL", "en_US", TRUE);
281   locale = setlocale (LC_ALL, "");
282   if (locale == NULL || strcmp (locale, "en_US") != 0)
283     {
284       g_test_message ("No suitable locale, skipping tests");
285       missing_locale = TRUE;
286       /* let the tests run to completion so they show up as SKIP'd in TAP
287        * output */
288     }
289
290   test[0].input = input0;
291   test[0].sorted = sorted0;
292   test[0].file_sorted = file_sorted0;
293   test[1].input = input1;
294   test[1].sorted = sorted1;
295   test[1].file_sorted = file_sorted1;
296   test[2].input = input2;
297   test[2].sorted = sorted2;
298   test[2].file_sorted = file_sorted2;
299
300   for (i = 0; i < G_N_ELEMENTS (test); i++)
301     {
302       path = g_strdup_printf ("/unicode/collate/%d", i);
303       g_test_add_data_func (path, &test[i], test_collate);
304       g_free (path);
305       path = g_strdup_printf ("/unicode/collate-key/%d", i);
306       g_test_add_data_func (path, &test[i], test_collate_key);
307       g_free (path);
308       path = g_strdup_printf ("/unicode/collate-filename/%d", i);
309       g_test_add_data_func (path, &test[i], test_collate_file);
310       g_free (path);
311     }
312
313   return g_test_run ();
314 }