1 /* Unit tests for GPathBuf
2 *
3 * SPDX-FileCopyrightText: 2023 Emmanuele Bassi
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7 #include "config.h"
8 #include <string.h>
9 #include <errno.h>
10
11 #include <glib.h>
12
13 #ifndef g_assert_path_buf_equal
14 #define g_assert_path_buf_equal(p1,p2) \
15 G_STMT_START { \
16 if (g_path_buf_equal ((p1), (p2))) ; else { \
17 char *__p1 = g_path_buf_to_path ((p1)); \
18 char *__p2 = g_path_buf_to_path ((p2)); \
19 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
20 #p1 " == " #p2, __p1, "==", __p2); \
21 g_free (__p1); \
22 g_free (__p2); \
23 } \
24 } G_STMT_END
25 #endif
26
27 static void
28 test_pathbuf_init (void)
29 {
30 #ifdef G_OS_UNIX
31 GPathBuf buf, cmp;
32 char *path;
33
34 g_test_message ("Initializing empty path buf");
35 g_path_buf_init (&buf);
36 g_assert_null (g_path_buf_to_path (&buf));
37 g_path_buf_clear (&buf);
38
39 g_test_message ("Initializing with empty path");
40 g_path_buf_init_from_path (&buf, NULL);
41 g_assert_null (g_path_buf_to_path (&buf));
42 g_path_buf_clear (&buf);
43
44 g_test_message ("Initializing with full path");
45 g_path_buf_init_from_path (&buf, "/usr/bin/echo");
46 path = g_path_buf_clear_to_path (&buf);
47 g_assert_nonnull (path);
48 g_assert_cmpstr (path, ==, "/usr/bin/echo");
49 g_free (path);
50
51 g_test_message ("Initializing with no path");
52 g_path_buf_init (&buf);
53 g_assert_null (g_path_buf_to_path (&buf));
54 g_path_buf_clear (&buf);
55
56 g_test_message ("Allocating GPathBuf on the heap");
57 GPathBuf *allocated = g_path_buf_new ();
58 g_assert_null (g_path_buf_to_path (allocated));
59 g_path_buf_clear (allocated);
60
61 g_path_buf_init_from_path (allocated, "/bin/sh");
62 path = g_path_buf_to_path (allocated);
63 g_assert_cmpstr (path, ==, "/bin/sh");
64 g_free (path);
65
66 g_path_buf_clear (allocated);
67 g_assert_null (g_path_buf_to_path (allocated));
68 g_assert_null (g_path_buf_free_to_path (allocated));
69
70 allocated = g_path_buf_new_from_path ("/bin/sh");
71 g_path_buf_init_from_path (&cmp, "/bin/sh");
72 g_assert_path_buf_equal (allocated, &cmp);
73 g_path_buf_clear (&cmp);
74 g_path_buf_free (allocated);
75
76 g_path_buf_init_from_path (&buf, "/usr/bin/bash");
77 allocated = g_path_buf_copy (&buf);
78 g_assert_path_buf_equal (allocated, allocated);
79 g_assert_path_buf_equal (allocated, &buf);
80 g_path_buf_clear (&buf);
81
82 g_path_buf_init_from_path (&cmp, "/usr/bin/bash");
83 g_assert_path_buf_equal (allocated, &cmp);
84 g_path_buf_clear (&cmp);
85
86 g_path_buf_free (allocated);
87 #elif defined(G_OS_WIN32)
88 GPathBuf buf;
89 char *path;
90
91 /* Forward slashes and backslashes are treated as interchangeable
92 * on input... */
93 g_path_buf_init_from_path (&buf, "C:\\windows/system32.dll");
94 path = g_path_buf_clear_to_path (&buf);
95 g_assert_nonnull (path);
96 /* ... and normalized to backslashes on output */
97 g_assert_cmpstr (path, ==, "C:\\windows\\system32.dll");
98 g_free (path);
99
100 g_path_buf_init (&buf);
101 g_assert_null (g_path_buf_to_path (&buf));
102 g_path_buf_clear (&buf);
103
104 g_test_message ("Allocating GPathBuf on the heap");
105 GPathBuf *allocated = g_path_buf_new ();
106 g_assert_null (g_path_buf_to_path (allocated));
107 g_path_buf_clear (allocated);
108
109 g_path_buf_init_from_path (allocated, "C:\\does-not-exist.txt");
110 path = g_path_buf_to_path (allocated);
111 g_assert_cmpstr (path, ==, "C:\\does-not-exist.txt");
112 g_free (path);
113
114 g_path_buf_clear (allocated);
115 g_assert_null (g_path_buf_to_path (allocated));
116 g_assert_null (g_path_buf_free_to_path (allocated));
117 #else
118 g_test_skip ("Unsupported platform"):
119 #endif
120 }
121
122 static void
123 test_pathbuf_push_pop (void)
124 {
125 #ifdef G_OS_UNIX
126 GPathBuf buf, cmp;
127
128 g_test_message ("Pushing relative path component");
129 g_path_buf_init_from_path (&buf, "/tmp");
130 g_path_buf_push (&buf, ".X11-unix/X0");
131
132 g_path_buf_init_from_path (&cmp, "/tmp/.X11-unix/X0");
133 g_assert_path_buf_equal (&buf, &cmp);
134 g_path_buf_clear (&cmp);
135
136 g_test_message ("Pushing absolute path component");
137 g_path_buf_push (&buf, "/etc/locale.conf");
138 g_path_buf_init_from_path (&cmp, "/etc/locale.conf");
139 g_assert_path_buf_equal (&buf, &cmp);
140 g_path_buf_clear (&cmp);
141 g_path_buf_clear (&buf);
142
143 g_test_message ("Popping a path component");
144 g_path_buf_init_from_path (&buf, "/bin/sh");
145
146 g_assert_true (g_path_buf_pop (&buf));
147 g_path_buf_init_from_path (&cmp, "/bin");
148 g_assert_path_buf_equal (&buf, &cmp);
149 g_path_buf_clear (&cmp);
150
151 g_assert_true (g_path_buf_pop (&buf));
152 g_path_buf_init_from_path (&cmp, "/");
153 g_assert_path_buf_equal (&buf, &cmp);
154 g_path_buf_clear (&cmp);
155
156 g_test_message ("Can't pop the last element of a path buffer");
157 g_assert_false (g_path_buf_pop (&buf));
158
159 g_path_buf_clear (&buf);
160 g_path_buf_clear (&cmp);
161 #elif defined(G_OS_WIN32)
162 GPathBuf buf, cmp;
163
164 g_test_message ("Pushing relative path component");
165 g_path_buf_init_from_path (&buf, "C:\\");
166 g_path_buf_push (&buf, "windows");
167 g_path_buf_push (&buf, "system32.dll");
168
169 g_test_message ("Popping a path component");
170 g_path_buf_init_from_path (&cmp, "C:\\windows/system32.dll");
171 g_assert_path_buf_equal (&buf, &cmp);
172 g_path_buf_clear (&cmp);
173
174 g_assert_true (g_path_buf_pop (&buf));
175 g_path_buf_init_from_path (&cmp, "C:\\windows");
176 g_assert_path_buf_equal (&buf, &cmp);
177 g_path_buf_clear (&cmp);
178
179 g_assert_true (g_path_buf_pop (&buf));
180 g_path_buf_init_from_path (&cmp, "C:");
181 g_assert_path_buf_equal (&buf, &cmp);
182 g_path_buf_clear (&cmp);
183
184 g_test_message ("Can't pop the last element of a path buffer");
185 g_assert_false (g_path_buf_pop (&buf));
186
187 g_path_buf_clear (&buf);
188 g_path_buf_clear (&cmp);
189 #else
190 g_test_skip ("Unsupported platform"):
191 #endif
192 }
193
194 static void
195 test_pathbuf_filename_extension (void)
196 {
197 #ifdef G_OS_UNIX
198 GPathBuf buf, cmp;
199
200 g_path_buf_init (&buf);
201 g_assert_false (g_path_buf_set_filename (&buf, "foo"));
202 g_assert_false (g_path_buf_set_extension (&buf, "txt"));
203 g_assert_null (g_path_buf_to_path (&buf));
204 g_path_buf_clear (&buf);
205
206 g_path_buf_init_from_path (&buf, "/");
207 g_path_buf_set_filename (&buf, "bar");
208
209 g_path_buf_init_from_path (&cmp, "/bar");
210 g_assert_path_buf_equal (&buf, &cmp);
211 g_path_buf_clear (&cmp);
212
213 g_path_buf_set_filename (&buf, "baz.txt");
214 g_path_buf_init_from_path (&cmp, "/baz.txt");
215 g_assert_path_buf_equal (&buf, &cmp);
216 g_path_buf_clear (&cmp);
217
218 g_path_buf_push (&buf, "/usr");
219 g_path_buf_push (&buf, "lib64");
220 g_path_buf_push (&buf, "libc");
221 g_assert_true (g_path_buf_set_extension (&buf, "so.6"));
222
223 g_path_buf_init_from_path (&cmp, "/usr/lib64/libc.so.6");
224 g_assert_path_buf_equal (&buf, &cmp);
225 g_path_buf_clear (&cmp);
226
227 g_path_buf_clear (&buf);
228 #elif defined(G_OS_WIN32)
229 GPathBuf buf, cmp;
230
231 g_path_buf_init_from_path (&buf, "C:\\");
232 g_path_buf_push (&buf, "windows");
233 g_path_buf_push (&buf, "system32");
234 g_assert_true (g_path_buf_set_extension (&buf, "dll"));
235
236 g_path_buf_init_from_path (&cmp, "C:\\windows\\system32.dll");
237 g_assert_path_buf_equal (&buf, &cmp);
238 g_path_buf_clear (&cmp);
239
240 g_path_buf_clear (&buf);
241 #else
242 g_test_skip ("Unsupported platform"):
243 #endif
244 }
245
246 int
247 main (int argc,
248 char *argv[])
249 {
250 g_setenv ("LC_ALL", "C", TRUE);
251 g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
252
253 g_test_add_func ("/pathbuf/init", test_pathbuf_init);
254 g_test_add_func ("/pathbuf/push-pop", test_pathbuf_push_pop);
255 g_test_add_func ("/pathbuf/filename-extension", test_pathbuf_filename_extension);
256
257 return g_test_run ();
258 }