packaging: Bump to version 0.4.3
[platform/upstream/libxkbcommon.git] / test / context.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Author: Daniel Stone <daniel@fooishbar.org>
24  */
25
26 #include "config.h"
27
28 #include "test.h"
29 #include "context.h"
30
31 #include <sys/stat.h>
32 #include <sys/types.h>
33
34 /* keeps a cache of all makedir/maketmpdir directories so we can free and
35  * rmdir them in one go, see unmakedirs() */
36 char *dirnames[64];
37 int ndirs;
38
39 /* keeps a cache of all buffered env vars so we can restore
40  * them in one go, see restore_env() */
41 struct env {
42     char *key;
43     char *value;
44 } environment[64];
45 int nenviron;
46
47 static void buffer_env(const char *key)
48 {
49     char *v = getenv(key);
50
51     environment[nenviron].key = strdup(key);
52     environment[nenviron].value = v ? strdup(v) : NULL;
53     nenviron++;
54 }
55
56 static void restore_env(void)
57 {
58     for (int i = 0; i < nenviron; i++) {
59         char *key = environment[i].key,
60              *value = environment[i].value;
61
62         if (value)
63             setenv(key, value, 1);
64         else
65             unsetenv(key);
66
67         free(key);
68         free(value);
69     }
70     nenviron = 0;
71     memset(environment, 0, sizeof(environment));
72 }
73
74 static const char *makedir(const char *parent, const char *path)
75 {
76     char *dirname = test_makedir(parent, path);
77     dirnames[ndirs++] = dirname;
78     return dirname;
79 }
80
81 static const char *maketmpdir(void)
82 {
83     char *tmpdir = test_maketempdir("xkbcommon-test.XXXXXX");
84     dirnames[ndirs++] = tmpdir;
85     return tmpdir;
86 }
87
88 static void unmakedirs(void)
89 {
90     /* backwards order for rmdir to work */
91     for (int i = ndirs - 1; i >= 0; i--) {
92         char *dir = dirnames[i];
93         if (!dir)
94             break;
95         rmdir(dir);
96         free(dir);
97     }
98     ndirs = 0;
99     memset(dirnames, 0, sizeof(dirnames));
100 }
101
102 static void
103 test_config_root_include_path(void)
104 {
105     struct xkb_context *ctx;
106     const char *tmpdir;
107     const char *context_path;
108     int nincludes;
109
110     buffer_env("XKB_CONFIG_ROOT");
111     buffer_env("HOME");
112     buffer_env("XDG_CONFIG_HOME");
113
114     tmpdir = maketmpdir();
115     setenv("XKB_CONFIG_ROOT", tmpdir, 1);
116     unsetenv("HOME");
117     unsetenv("XDG_CONFIG_HOME");
118
119     /* built-in path is last */
120     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
121     nincludes = xkb_context_num_include_paths(ctx);
122     assert(nincludes >= 1);
123     context_path = xkb_context_include_path_get(ctx, nincludes - 1);
124     assert(strcmp(context_path, tmpdir) == 0);
125     xkb_context_unref(ctx);
126
127     unmakedirs();
128     restore_env();
129 }
130
131 static void
132 test_config_root_include_path_fallback(void)
133 {
134     struct xkb_context *ctx;
135     const char *xkbdir = DFLT_XKB_CONFIG_ROOT;
136     const char *context_path;
137     int nincludes;
138
139     /* quick and dirty check that the default directory exists.
140      * It may not on a vanilla test box if we just run the test
141      * suite, so where it's not there just skip this test. */
142     struct stat stat_buf;
143     int err = stat(xkbdir, &stat_buf);
144     if (err != 0)
145         return;
146     if (!S_ISDIR(stat_buf.st_mode))
147         return;
148
149     buffer_env("XKB_CONFIG_ROOT");
150     buffer_env("HOME");
151     buffer_env("XDG_CONFIG_HOME");
152
153     unsetenv("XKB_CONFIG_ROOT");
154     unsetenv("HOME");
155     unsetenv("XDG_CONFIG_HOME");
156
157     /* built-in path is last */
158     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
159     nincludes = xkb_context_num_include_paths(ctx);
160     assert(nincludes >= 1);
161     context_path = xkb_context_include_path_get(ctx, nincludes - 1);
162     assert(strcmp(context_path, xkbdir) == 0);
163     xkb_context_unref(ctx);
164
165     unmakedirs();
166     restore_env();
167 }
168
169 static void
170 test_xkbdir_include_path(void)
171 {
172     struct xkb_context *ctx;
173     const char *tmpdir;
174     const char *xkb_path;
175     const char *context_path;
176
177     buffer_env("HOME");
178     buffer_env("XDG_CONFIG_HOME");
179
180     tmpdir = maketmpdir();
181     xkb_path = makedir(tmpdir, ".xkb");
182     setenv("HOME", tmpdir, 1);
183     setenv("XDG_CONFIG_HOME", tmpdir, 1);
184
185     /* No XDG directory in our tmpdir, so we expect
186      * the $HOME/.xkb to be the first include path */
187     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
188     assert(xkb_context_num_include_paths(ctx) >= 1);
189     context_path = xkb_context_include_path_get(ctx, 0);
190     assert(strcmp(context_path, xkb_path) == 0);
191     xkb_context_unref(ctx);
192
193     unmakedirs();
194     restore_env();
195 }
196
197 static void
198 test_xdg_include_path(void)
199 {
200     struct xkb_context *ctx;
201     const char *tmpdir;
202     const char *xdg_path;
203     const char *context_path;
204
205     buffer_env("XDG_CONFIG_HOME");
206
207     tmpdir = maketmpdir();
208     xdg_path = makedir(tmpdir, "xkb");
209     setenv("XDG_CONFIG_HOME", tmpdir, 1);
210
211     /* XDG path is always first */
212     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
213     assert(xkb_context_num_include_paths(ctx) >= 1);
214     context_path = xkb_context_include_path_get(ctx, 0);
215     assert(strcmp(context_path, xdg_path) == 0);
216     xkb_context_unref(ctx);
217
218     unmakedirs();
219     restore_env();
220 }
221
222 static void
223 test_xdg_include_path_fallback(void)
224 {
225     struct xkb_context *ctx;
226     const char *tmpdir;
227     const char *xdg_root, *xdg_path;
228     const char *context_path;
229
230     buffer_env("XDG_CONFIG_HOME");
231     buffer_env("HOME");
232
233     tmpdir = maketmpdir();
234     xdg_root = makedir(tmpdir, ".config");
235     xdg_path = makedir(xdg_root, "xkb");
236     setenv("HOME", tmpdir, 1);
237     unsetenv("XDG_CONFIG_HOME");
238
239     /* XDG path is always first, even if fallback */
240     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
241     assert(xkb_context_num_include_paths(ctx) >= 1);
242     context_path = xkb_context_include_path_get(ctx, 0);
243     assert(strcmp(context_path, xdg_path) == 0);
244     xkb_context_unref(ctx);
245
246     unmakedirs();
247     restore_env();
248 }
249
250 static void
251 test_include_order(void)
252 {
253     struct xkb_context *ctx;
254     const char *tmpdir;
255     const char *xdg_path;
256     const char *xkb_home_path;
257     const char *xkb_root_path;
258     const char *context_path;
259
260     buffer_env("XKB_CONFIG_ROOT");
261     buffer_env("XDG_CONFIG_HOME");
262     buffer_env("HOME");
263
264     tmpdir = maketmpdir();
265     xdg_path = makedir(tmpdir, "xkb");
266     xkb_home_path = makedir(tmpdir, ".xkb");
267     xkb_root_path = makedir(tmpdir, "xkbroot");
268     setenv("HOME", tmpdir, 1);
269     setenv("XDG_CONFIG_HOME", tmpdir, 1);
270     setenv("XKB_CONFIG_ROOT", xkb_root_path, 1);
271
272     ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
273     assert(xkb_context_num_include_paths(ctx) >= 3);
274     /* XDG is first */
275     context_path = xkb_context_include_path_get(ctx, 0);
276     assert(strcmp(context_path, xdg_path) == 0);
277     /* $HOME/.xkb is second */
278     context_path = xkb_context_include_path_get(ctx, 1);
279     assert(strcmp(context_path, xkb_home_path) == 0);
280     /* CONFIG_ROOT is last */
281     context_path = xkb_context_include_path_get(ctx, 2);
282     assert(strcmp(context_path, xkb_root_path) == 0);
283
284     xkb_context_unref(ctx);
285
286     unmakedirs();
287     restore_env();
288 }
289
290 int
291 main(void)
292 {
293     struct xkb_context *context = test_get_context(0);
294     xkb_atom_t atom;
295
296     assert(context);
297
298     assert(xkb_context_num_include_paths(context) == 1);
299     assert(!xkb_context_include_path_append(context, "¡NONSENSE!"));
300     assert(xkb_context_num_include_paths(context) == 1);
301
302     atom = xkb_atom_intern(context, "HELLOjunkjunkjunk", 5);
303     assert(atom != XKB_ATOM_NONE);
304     assert(streq(xkb_atom_text(context, atom), "HELLO"));
305
306     atom = xkb_atom_intern_literal(context, "HELLOjunkjunkjunk");
307     assert(atom != XKB_ATOM_NONE);
308     assert(streq(xkb_atom_text(context, atom), "HELLOjunkjunkjunk"));
309
310     xkb_context_unref(context);
311
312     test_config_root_include_path();
313     test_config_root_include_path_fallback();
314     test_xkbdir_include_path();
315     test_xdg_include_path();
316     test_xdg_include_path_fallback();
317     test_include_order();
318
319     return 0;
320 }