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 : priv->foo = 13;
262 : : /* If that triggers, it's test bug.
263 : : */
264 : 2 : g_assert_nonnull (init_check);
265 : : /* Using global init_check, because error->check is still nil at
266 : : * this point.
267 : : */
268 : 2 : init_check->init_called++;
269 : 2 : }
270 : :
271 : : static void
272 : 1 : test_error_private_copy (const TestErrorPrivate *src_priv,
273 : : TestErrorPrivate *dest_priv)
274 : : {
275 : 1 : dest_priv->foo = src_priv->foo;
276 : 1 : dest_priv->check = src_priv->check;
277 : :
278 : 1 : dest_priv->check->copy_called++;
279 : 1 : }
280 : :
281 : : static void
282 : 2 : test_error_private_clear (TestErrorPrivate *priv)
283 : : {
284 : 2 : priv->check->free_called++;
285 : 2 : }
286 : :
287 [ + + + + : 23 : G_DEFINE_EXTENDED_ERROR (TestError, test_error)
+ + ]
288 : :
289 : : static TestErrorPrivate *
290 : 1 : fill_test_error (GError *error, TestErrorCheck *check)
291 : : {
292 : 1 : TestErrorPrivate *test_error = test_error_get_private (error);
293 : :
294 : 1 : test_error->check = check;
295 : :
296 : 1 : return test_error;
297 : : }
298 : :
299 : : static void
300 : 1 : test_extended (void)
301 : : {
302 : 1 : TestErrorCheck check = { 0, 0, 0 };
303 : : GError *error;
304 : : TestErrorPrivate *test_priv;
305 : : GError *copy_error;
306 : : TestErrorPrivate *copy_test_priv;
307 : :
308 : 1 : init_check = ✓
309 : 1 : error = g_error_new_literal (TEST_ERROR, 0, "foo");
310 : 1 : test_priv = fill_test_error (error, &check);
311 : :
312 : 1 : g_assert_cmpint (check.init_called, ==, 1);
313 : 1 : g_assert_cmpint (check.copy_called, ==, 0);
314 : 1 : g_assert_cmpint (check.free_called, ==, 0);
315 : :
316 : 1 : g_assert_cmpuint (error->domain, ==, TEST_ERROR);
317 : 1 : g_assert_cmpint (test_priv->foo, ==, 13);
318 : :
319 : 1 : copy_error = g_error_copy (error);
320 : 1 : g_assert_cmpint (check.init_called, ==, 2);
321 : 1 : g_assert_cmpint (check.copy_called, ==, 1);
322 : 1 : g_assert_cmpint (check.free_called, ==, 0);
323 : :
324 : 1 : g_assert_cmpuint (error->domain, ==, copy_error->domain);
325 : 1 : g_assert_cmpint (error->code, ==, copy_error->code);
326 : 1 : g_assert_cmpstr (error->message, ==, copy_error->message);
327 : :
328 : 1 : copy_test_priv = test_error_get_private (copy_error);
329 : 1 : g_assert_cmpint (test_priv->foo, ==, copy_test_priv->foo);
330 : :
331 : 1 : g_error_free (error);
332 : 1 : g_error_free (copy_error);
333 : :
334 : 1 : g_assert_cmpint (check.init_called, ==, 2);
335 : 1 : g_assert_cmpint (check.copy_called, ==, 1);
336 : 1 : g_assert_cmpint (check.free_called, ==, 2);
337 : 1 : }
338 : :
339 : : static void
340 : 1 : test_extended_duplicate (void)
341 : : {
342 : 1 : g_test_summary ("Test that registering a duplicate extended error domain doesn’t work");
343 : :
344 [ + - ]: 1 : if (!g_test_subprocess ())
345 : : {
346 : : /* Spawn a subprocess and expect it to fail. */
347 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
348 : 1 : g_test_trap_assert_failed ();
349 : 1 : g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*");
350 : : }
351 : : else
352 : : {
353 : : GQuark q;
354 : : guint i;
355 : :
356 [ # # ]: 0 : for (i = 0; i < 2; i++)
357 : : {
358 : 0 : q = g_error_domain_register_static ("TestError",
359 : : sizeof (TestErrorPrivate),
360 : : g_error_with_test_error_private_init,
361 : : g_error_with_test_error_private_copy,
362 : : g_error_with_test_error_private_clear);
363 : 0 : g_assert_cmpstr (g_quark_to_string (q), ==, "TestError");
364 : : }
365 : : }
366 : 1 : }
367 : :
368 : : typedef struct
369 : : {
370 : : int dummy;
371 : : } TestErrorNonStaticPrivate;
372 : :
373 : 1 : static void test_error_non_static_private_init (GError *error) {}
374 : 0 : static void test_error_non_static_private_copy (const GError *src_error, GError *dest_error) {}
375 : 1 : static void test_error_non_static_private_clear (GError *error) {}
376 : :
377 : : static void
378 : 1 : test_extended_non_static (void)
379 : : {
380 : 1 : gchar *domain_name = g_strdup ("TestErrorNonStatic");
381 : : GQuark q;
382 : 1 : GError *error = NULL;
383 : :
384 : 1 : g_test_summary ("Test registering an extended error domain with a non-static name");
385 : :
386 : 1 : q = g_error_domain_register (domain_name,
387 : : sizeof (TestErrorNonStaticPrivate),
388 : : test_error_non_static_private_init,
389 : : test_error_non_static_private_copy,
390 : : test_error_non_static_private_clear);
391 : 1 : g_free (domain_name);
392 : :
393 : 1 : error = g_error_new (q, 0, "Test error: %s", "hello");
394 : 1 : g_assert_true (g_error_matches (error, q, 0));
395 : 1 : g_assert_cmpstr (g_quark_to_string (q), ==, "TestErrorNonStatic");
396 : 1 : g_error_free (error);
397 : 1 : }
398 : :
399 : : int
400 : 1 : main (int argc, char *argv[])
401 : : {
402 : 1 : g_test_init (&argc, &argv, NULL);
403 : :
404 : 1 : g_test_add_func ("/error/overwrite", test_overwrite);
405 : 1 : g_test_add_func ("/error/prefix", test_prefix);
406 : 1 : g_test_add_func ("/error/prefix-literal", test_prefix_literal);
407 : 1 : g_test_add_func ("/error/literal", test_literal);
408 : 1 : g_test_add_func ("/error/copy", test_copy);
409 : 1 : g_test_add_func ("/error/matches", test_matches);
410 : 1 : g_test_add_func ("/error/clear", test_clear);
411 : 1 : g_test_add_func ("/error/new-valist/invalid", test_new_valist_invalid);
412 : 1 : g_test_add_func ("/error/extended", test_extended);
413 : 1 : g_test_add_func ("/error/extended/duplicate", test_extended_duplicate);
414 : 1 : g_test_add_func ("/error/extended/non-static", test_extended_non_static);
415 : :
416 : 1 : return g_test_run ();
417 : : }
|