Branch data Line data Source code
1 : : #include <glib.h>
2 : :
3 : : #include "glib-private.h"
4 : :
5 : : static void
6 : 1 : test_overwrite (void)
7 : : {
8 : : GError *error, *dest, *src;
9 : :
10 : 1 : if (!g_test_undefined ())
11 : 0 : return;
12 : :
13 : 1 : error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
14 : :
15 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
16 : : "*set over the top*");
17 : 1 : g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
18 : 1 : g_test_assert_expected_messages ();
19 : :
20 : 1 : g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
21 : 1 : g_error_free (error);
22 : :
23 : :
24 : 1 : error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
25 : :
26 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
27 : : "*set over the top*");
28 : 1 : g_set_error (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
29 : 1 : g_test_assert_expected_messages ();
30 : :
31 : 1 : g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
32 : 1 : g_error_free (error);
33 : :
34 : :
35 : 1 : dest = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
36 : 1 : src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
37 : :
38 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
39 : : "*set over the top*");
40 : 1 : g_propagate_error (&dest, src);
41 : 1 : g_test_assert_expected_messages ();
42 : :
43 : 1 : g_assert_error (dest, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
44 : 1 : g_error_free (dest);
45 : : }
46 : :
47 : : static void
48 : 1 : test_prefix (void)
49 : : {
50 : : GError *error;
51 : : GError *dest, *src;
52 : :
53 : 1 : error = NULL;
54 : 1 : g_prefix_error (&error, "foo %d %s: ", 1, "two");
55 : 1 : g_assert (error == NULL);
56 : :
57 : 1 : error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
58 : 1 : g_prefix_error (&error, "foo %d %s: ", 1, "two");
59 : 1 : g_assert_cmpstr (error->message, ==, "foo 1 two: bla");
60 : 1 : g_error_free (error);
61 : :
62 : 1 : dest = NULL;
63 : 1 : src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
64 : 1 : g_propagate_prefixed_error (&dest, src, "foo %d %s: ", 1, "two");
65 : 1 : g_assert_cmpstr (dest->message, ==, "foo 1 two: bla");
66 : 1 : g_error_free (dest);
67 : :
68 : 1 : src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
69 : 1 : g_propagate_prefixed_error (NULL, src, "foo %d %s: ", 1, "two");
70 : 1 : }
71 : :
72 : : static void
73 : 1 : test_prefix_literal (void)
74 : : {
75 : 1 : GError *error = NULL;
76 : :
77 : 1 : g_prefix_error_literal (NULL, "foo: ");
78 : :
79 : 1 : g_prefix_error_literal (&error, "foo: ");
80 : 1 : g_assert_null (error);
81 : :
82 : 1 : error = NULL;
83 : 1 : g_prefix_error_literal (&error, "foo: ");
84 : 1 : g_assert_null (error);
85 : :
86 : 1 : error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
87 : 1 : g_assert_nonnull (error);
88 : 1 : g_prefix_error_literal (&error, "foo: ");
89 : 1 : g_assert_cmpstr (error->message, ==, "foo: bla");
90 : 1 : g_error_free (error);
91 : 1 : }
92 : :
93 : : static void
94 : 1 : test_literal (void)
95 : : {
96 : : GError *error;
97 : :
98 : 1 : error = NULL;
99 : 1 : g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
100 : 1 : g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
101 : 1 : g_assert_cmpstr (error->message, ==, "%s %d %x");
102 : 1 : g_error_free (error);
103 : 1 : }
104 : :
105 : : static void
106 : 1 : test_copy (void)
107 : : {
108 : : GError *error;
109 : : GError *copy;
110 : :
111 : 1 : error = NULL;
112 : 1 : g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
113 : 1 : copy = g_error_copy (error);
114 : :
115 : 1 : g_assert_error (copy, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
116 : 1 : g_assert_cmpstr (copy->message, ==, "%s %d %x");
117 : :
118 : 1 : g_error_free (error);
119 : 1 : g_error_free (copy);
120 : 1 : }
121 : :
122 : : static void
123 : 1 : test_new_valist_invalid_va (gpointer dummy,
124 : : ...)
125 : : {
126 : : #if defined(__linux__) && defined(__GLIBC__)
127 : : /* Only worth testing this on Linux with glibc; if other platforms regress on
128 : : * this legacy behaviour, we don’t care. In particular, calling
129 : : * g_error_new_valist() with a %NULL format will crash on FreeBSD as its
130 : : * implementation of vasprintf() is less forgiving than Linux’s. That’s
131 : : * fine: it’s a programmer error in either case. */
132 : :
133 : 1 : g_test_summary ("Test that g_error_new_valist() rejects invalid input");
134 : :
135 : 1 : if (!g_test_undefined ())
136 : : {
137 : 0 : g_test_skip ("Not testing response to programmer error");
138 : 0 : return;
139 : : }
140 : :
141 : : {
142 : 1 : GError *error = NULL;
143 : : va_list ap;
144 : :
145 : 1 : va_start (ap, dummy);
146 : :
147 : : #pragma GCC diagnostic push
148 : : #pragma GCC diagnostic ignored "-Wformat-nonliteral"
149 : : #pragma GCC diagnostic ignored "-Wformat-extra-args"
150 : :
151 : 1 : g_test_expect_message (G_LOG_DOMAIN,
152 : : G_LOG_LEVEL_CRITICAL,
153 : : "*g_error_new_valist: assertion 'format != NULL' failed*");
154 : 1 : error = g_error_new_valist (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, NULL, ap);
155 : 1 : g_test_assert_expected_messages ();
156 : 1 : g_assert_null (error);
157 : :
158 : : #pragma GCC diagnostic pop
159 : :
160 : 1 : va_end (ap);
161 : : }
162 : :
163 : : {
164 : 1 : GError *error = NULL, *error_copy = NULL;
165 : : va_list ap;
166 : :
167 : 1 : va_start (ap, dummy);
168 : :
169 : : #pragma GCC diagnostic push
170 : : #pragma GCC diagnostic ignored "-Wformat-nonliteral"
171 : :
172 : 1 : g_test_expect_message (G_LOG_DOMAIN,
173 : : G_LOG_LEVEL_WARNING,
174 : : "*g_error_new_valist: runtime check failed*");
175 : 1 : error = g_error_new_valist (0, G_MARKUP_ERROR_EMPTY, "Message", ap);
176 : 1 : g_test_assert_expected_messages ();
177 : 1 : g_assert_nonnull (error);
178 : :
179 : : #pragma GCC diagnostic pop
180 : :
181 : 1 : g_test_expect_message (G_LOG_DOMAIN,
182 : : G_LOG_LEVEL_WARNING,
183 : : "*g_error_copy: runtime check failed*");
184 : 1 : error_copy = g_error_copy (error);
185 : 1 : g_test_assert_expected_messages ();
186 : 1 : g_assert_nonnull (error_copy);
187 : :
188 : 1 : g_clear_error (&error);
189 : 1 : g_clear_error (&error_copy);
190 : :
191 : 1 : va_end (ap);
192 : : }
193 : : #else /* if !__linux__ || !__GLIBC__ */
194 : : g_test_skip ("g_error_new_valist() programmer error handling is only relevant on Linux with glibc");
195 : : #endif /* !__linux__ || ! __GLIBC__ */
196 : : }
197 : :
198 : : static void
199 : 1 : test_new_valist_invalid (void)
200 : : {
201 : : /* We need a wrapper function so we can build a va_list */
202 : 1 : test_new_valist_invalid_va (NULL);
203 : 1 : }
204 : :
205 : : static void
206 : 1 : test_matches (void)
207 : : {
208 : 1 : GError *error = NULL;
209 : :
210 : 1 : g_test_summary ("Test g_error_matches()");
211 : :
212 : 1 : error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
213 : :
214 : 1 : g_assert_true (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
215 : 1 : g_assert_false (g_error_matches (NULL, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
216 : 1 : g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE)); /* same numeric value as G_MARKUP_ERROR_EMPTY */
217 : 1 : g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED)); /* different numeric value from G_MARKUP_ERROR_EMPTY */
218 : 1 : g_assert_false (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_BAD_UTF8));
219 : :
220 : 1 : g_error_free (error);
221 : 1 : }
222 : :
223 : : static void
224 : 1 : test_clear (void)
225 : : {
226 : 1 : GError *error = NULL;
227 : :
228 : 1 : g_test_summary ("Test g_error_clear()");
229 : :
230 : 1 : g_clear_error (&error);
231 : 1 : g_assert_null (error);
232 : :
233 : 1 : g_clear_error (NULL);
234 : :
235 : 1 : error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
236 : 1 : g_clear_error (&error);
237 : 1 : g_assert_null (error);
238 : 1 : }
239 : :
240 : : typedef struct
241 : : {
242 : : int init_called;
243 : : int copy_called;
244 : : int free_called;
245 : : } TestErrorCheck;
246 : :
247 : : static TestErrorCheck *init_check;
248 : :
249 : : GQuark test_error_quark (void);
250 : : #define TEST_ERROR (test_error_quark ())
251 : :
252 : : typedef struct
253 : : {
254 : : int foo;
255 : : TestErrorCheck *check;
256 : : } TestErrorPrivate;
257 : :
258 : : static void
259 : 2 : test_error_private_init (TestErrorPrivate *priv)
260 : : {
261 : 2 : g_assert_nonnull (priv);
262 : :
263 : 2 : priv->foo = 13;
264 : : /* If that triggers, it's test bug.
265 : : */
266 : 2 : g_assert_nonnull (init_check);
267 : : /* Using global init_check, because error->check is still nil at
268 : : * this point.
269 : : */
270 : 2 : init_check->init_called++;
271 : 2 : }
272 : :
273 : : static void
274 : 1 : test_error_private_copy (const TestErrorPrivate *src_priv,
275 : : TestErrorPrivate *dest_priv)
276 : : {
277 : 1 : g_assert_nonnull (src_priv);
278 : 1 : g_assert_nonnull (dest_priv);
279 : :
280 : 1 : dest_priv->foo = src_priv->foo;
281 : 1 : dest_priv->check = src_priv->check;
282 : :
283 : 1 : g_assert_nonnull (dest_priv->check);
284 : 1 : dest_priv->check->copy_called++;
285 : 1 : }
286 : :
287 : : static void
288 : 2 : test_error_private_clear (TestErrorPrivate *priv)
289 : : {
290 : 2 : g_assert_nonnull (priv->check);
291 : 2 : priv->check->free_called++;
292 : 2 : }
293 : :
294 : 23 : G_DEFINE_EXTENDED_ERROR (TestError, test_error)
295 : :
296 : : static TestErrorPrivate *
297 : 1 : fill_test_error (GError *error, TestErrorCheck *check)
298 : : {
299 : 1 : TestErrorPrivate *test_error = test_error_get_private (error);
300 : :
301 : 1 : g_assert_nonnull (test_error);
302 : 1 : test_error->check = check;
303 : :
304 : 1 : return test_error;
305 : : }
306 : :
307 : : static void
308 : 1 : test_extended (void)
309 : : {
310 : 1 : TestErrorCheck check = { 0, 0, 0 };
311 : : GError *error;
312 : : TestErrorPrivate *test_priv;
313 : : GError *copy_error;
314 : : TestErrorPrivate *copy_test_priv;
315 : :
316 : 1 : init_check = ✓
317 : 1 : error = g_error_new_literal (TEST_ERROR, 0, "foo");
318 : 1 : test_priv = fill_test_error (error, &check);
319 : :
320 : 1 : g_assert_cmpint (check.init_called, ==, 1);
321 : 1 : g_assert_cmpint (check.copy_called, ==, 0);
322 : 1 : g_assert_cmpint (check.free_called, ==, 0);
323 : :
324 : 1 : g_assert_cmpuint (error->domain, ==, TEST_ERROR);
325 : 1 : g_assert_cmpint (test_priv->foo, ==, 13);
326 : :
327 : 1 : copy_error = g_error_copy (error);
328 : 1 : g_assert_cmpint (check.init_called, ==, 2);
329 : 1 : g_assert_cmpint (check.copy_called, ==, 1);
330 : 1 : g_assert_cmpint (check.free_called, ==, 0);
331 : :
332 : 1 : g_assert_cmpuint (error->domain, ==, copy_error->domain);
333 : 1 : g_assert_cmpint (error->code, ==, copy_error->code);
334 : 1 : g_assert_cmpstr (error->message, ==, copy_error->message);
335 : :
336 : 1 : copy_test_priv = test_error_get_private (copy_error);
337 : 1 : g_assert_nonnull (copy_test_priv);
338 : 1 : g_assert_cmpint (test_priv->foo, ==, copy_test_priv->foo);
339 : :
340 : 1 : g_error_free (error);
341 : 1 : g_error_free (copy_error);
342 : :
343 : 1 : g_assert_cmpint (check.init_called, ==, 2);
344 : 1 : g_assert_cmpint (check.copy_called, ==, 1);
345 : 1 : g_assert_cmpint (check.free_called, ==, 2);
346 : 1 : }
347 : :
348 : : static void
349 : 1 : test_extended_duplicate (void)
350 : : {
351 : 1 : g_test_summary ("Test that registering a duplicate extended error domain doesn’t work");
352 : :
353 : 1 : if (!g_test_subprocess ())
354 : : {
355 : : /* Spawn a subprocess and expect it to fail. */
356 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
357 : 1 : g_test_trap_assert_failed ();
358 : 1 : g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*");
359 : : }
360 : : else
361 : : {
362 : : GQuark q;
363 : : guint i;
364 : :
365 : 0 : for (i = 0; i < 2; i++)
366 : : {
367 : 0 : q = g_error_domain_register_static ("TestError",
368 : : sizeof (TestErrorPrivate),
369 : : g_error_with_test_error_private_init,
370 : : g_error_with_test_error_private_copy,
371 : : g_error_with_test_error_private_clear);
372 : 0 : g_assert_cmpstr (g_quark_to_string (q), ==, "TestError");
373 : : }
374 : : }
375 : 1 : }
376 : :
377 : : typedef struct
378 : : {
379 : : int dummy;
380 : : } TestErrorNonStaticPrivate;
381 : :
382 : 1 : static void test_error_non_static_private_init (GError *error) {}
383 : 0 : static void test_error_non_static_private_copy (const GError *src_error, GError *dest_error) {}
384 : 1 : static void test_error_non_static_private_clear (GError *error) {}
385 : :
386 : : static void
387 : 1 : test_extended_non_static (void)
388 : : {
389 : 1 : gchar *domain_name = g_strdup ("TestErrorNonStatic");
390 : : GQuark q;
391 : 1 : GError *error = NULL;
392 : :
393 : 1 : g_test_summary ("Test registering an extended error domain with a non-static name");
394 : :
395 : 1 : q = g_error_domain_register (domain_name,
396 : : sizeof (TestErrorNonStaticPrivate),
397 : : test_error_non_static_private_init,
398 : : test_error_non_static_private_copy,
399 : : test_error_non_static_private_clear);
400 : 1 : g_free (domain_name);
401 : :
402 : 1 : error = g_error_new (q, 0, "Test error: %s", "hello");
403 : 1 : g_assert_true (g_error_matches (error, q, 0));
404 : 1 : g_assert_cmpstr (g_quark_to_string (q), ==, "TestErrorNonStatic");
405 : 1 : g_error_free (error);
406 : 1 : }
407 : :
408 : : int
409 : 1 : main (int argc, char *argv[])
410 : : {
411 : 1 : g_test_init (&argc, &argv, NULL);
412 : :
413 : 1 : g_test_add_func ("/error/overwrite", test_overwrite);
414 : 1 : g_test_add_func ("/error/prefix", test_prefix);
415 : 1 : g_test_add_func ("/error/prefix-literal", test_prefix_literal);
416 : 1 : g_test_add_func ("/error/literal", test_literal);
417 : 1 : g_test_add_func ("/error/copy", test_copy);
418 : 1 : g_test_add_func ("/error/matches", test_matches);
419 : 1 : g_test_add_func ("/error/clear", test_clear);
420 : 1 : g_test_add_func ("/error/new-valist/invalid", test_new_valist_invalid);
421 : 1 : g_test_add_func ("/error/extended", test_extended);
422 : 1 : g_test_add_func ("/error/extended/duplicate", test_extended_duplicate);
423 : 1 : g_test_add_func ("/error/extended/non-static", test_extended_non_static);
424 : :
425 : 1 : return g_test_run ();
426 : : }
|