1#include <stdlib.h>
2
3#include <gtk/gtk.h>
4
5static GType
6string_type (void)
7{
8 return G_TYPE_STRING;
9}
10
11static struct {
12 GType (* type_func) (void);
13 const char *mime_type;
14} possible_types[] = {
15 /* GTypes go here */
16 { string_type, NULL },
17 { gdk_file_list_get_type, NULL },
18 { gdk_rgba_get_type, NULL },
19 { gdk_texture_get_type, NULL },
20 /* mime types go here */
21 { NULL, "text/plain" },
22 { NULL, "text/plain;charset=utf-8" },
23 { NULL, "image/png" },
24 { NULL, "image/jpeg" },
25 { NULL, "application/x-color" },
26};
27
28#define assert_printf(...) G_STMT_START{ \
29 char *_s = g_strdup_printf (__VA_ARGS__); \
30 g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, _s); \
31 g_free (_s); \
32}G_STMT_END
33
34#define assert_formats_subset(a, b) G_STMT_START{ \
35 const GType *_gtypes; \
36 const char * const *_mime_types; \
37 gsize _i, _n; \
38\
39 _gtypes = gdk_content_formats_get_gtypes (a, &_n); \
40 for (_i = 0; _i < _n; _i++) \
41 { \
42 if (!gdk_content_formats_contain_gtype (b, _gtypes[_i])) \
43 assert_printf (#a " ⊆ " #b ": does not contain GType %s", g_type_name (_gtypes[_i])); \
44 } \
45\
46 _mime_types = gdk_content_formats_get_mime_types (a, &_n); \
47 for (_i = 0; _i < _n; _i++) \
48 { \
49 if (!gdk_content_formats_contain_mime_type (b, _mime_types[_i])) \
50 assert_printf (#a " ⊆ " #b ": does not contain mime type %s", _mime_types[_i]); \
51 } \
52}G_STMT_END
53
54#define assert_formats_equal(a, b) G_STMT_START{\
55 assert_formats_subset(a, b); \
56 assert_formats_subset(b, a); \
57}G_STMT_END
58
59static GdkContentFormats *
60create_random_content_formats (void)
61{
62 GdkContentFormatsBuilder *builder;
63 gsize i, n;
64
65 n = g_test_rand_int_range (begin: 0, G_N_ELEMENTS (possible_types));
66 builder = gdk_content_formats_builder_new ();
67
68 for (i = 0; i < n; i++)
69 {
70 gsize j = g_random_int_range (begin: 0, G_N_ELEMENTS (possible_types));
71 if (possible_types[j].type_func)
72 gdk_content_formats_builder_add_gtype (builder, type: possible_types[j].type_func ());
73 else if (possible_types[j].mime_type)
74 gdk_content_formats_builder_add_mime_type (builder, mime_type: possible_types[j].mime_type);
75 else
76 g_assert_not_reached ();
77 }
78
79 return gdk_content_formats_builder_free_to_formats (builder);
80}
81
82static void
83test_print_and_parse (void)
84{
85 GdkContentFormats *before, *parsed;
86 char *string_before, *string_parsed;
87 gsize i;
88
89 for (i = 0; i < 100; i++)
90 {
91 before = create_random_content_formats ();
92 string_before = gdk_content_formats_to_string (formats: before);
93
94 parsed = gdk_content_formats_parse (string: string_before);
95 g_assert (parsed);
96 assert_formats_equal (before, parsed);
97
98 string_parsed = gdk_content_formats_to_string (formats: parsed);
99 g_assert_cmpstr (string_before, ==, string_parsed);
100
101 g_free (mem: string_parsed);
102 g_free (mem: string_before);
103 gdk_content_formats_unref (formats: parsed);
104 gdk_content_formats_unref (formats: before);
105 }
106}
107
108static void
109test_union (void)
110{
111 GdkContentFormatsBuilder *builder;
112 GdkContentFormats *a, *b, *ab, *ab2;
113 gsize i;
114
115 for (i = 0; i < 100; i++)
116 {
117 a = create_random_content_formats ();
118 b = create_random_content_formats ();
119
120 ab = gdk_content_formats_union (first: gdk_content_formats_ref (formats: a), second: b);
121 assert_formats_subset (a, ab);
122 assert_formats_subset (b, ab);
123
124 ab2 = gdk_content_formats_union (first: gdk_content_formats_ref (formats: a), second: ab);
125 assert_formats_equal (ab, ab2);
126 gdk_content_formats_unref (formats: ab2);
127
128 builder = gdk_content_formats_builder_new ();
129 gdk_content_formats_builder_add_formats (builder, formats: a);
130 gdk_content_formats_builder_add_formats (builder, formats: b);
131 ab2 = gdk_content_formats_builder_free_to_formats (builder);
132 assert_formats_equal (ab, ab2);
133 gdk_content_formats_unref (formats: ab2);
134
135 gdk_content_formats_unref (formats: ab);
136 gdk_content_formats_unref (formats: a);
137 gdk_content_formats_unref (formats: b);
138 }
139}
140
141static void
142append_separator (GString *string)
143{
144 static const char *separators = "\t\n\f\r ";
145
146 do {
147 g_string_append_c (string, separators[g_test_rand_int_range (0, strlen (separators))]);
148 } while (g_test_rand_bit ());
149}
150
151static char *
152fuzzy_print (GdkContentFormats *formats)
153{
154 GString *string;
155 const GType *types;
156 const char * const *mime_types;
157 gsize i, n;
158
159 string = g_string_new (init: "");
160
161 types = gdk_content_formats_get_gtypes (formats, n_gtypes: &n);
162 for (i = 0; i < n; i++)
163 {
164 if (string->len || g_test_rand_bit ())
165 append_separator (string);
166 g_string_append (string, val: g_type_name (type: types[i]));
167 }
168
169 mime_types = gdk_content_formats_get_mime_types (formats, n_mime_types: &n);
170 for (i = 0; i < n; i++)
171 {
172 if (string->len || g_test_rand_bit ())
173 append_separator (string);
174 g_string_append (string, val: mime_types[i]);
175 }
176
177 if (g_test_rand_bit ())
178 append_separator (string);
179
180 return g_string_free (string, FALSE);
181}
182
183static void
184test_parse (void)
185{
186 gsize i;
187
188 for (i = 0; i < 100; i++)
189 {
190 GdkContentFormats *formats, *parsed;
191 char *fuzzy;
192
193 formats = create_random_content_formats ();
194 fuzzy = fuzzy_print (formats);
195 parsed = gdk_content_formats_parse (string: fuzzy);
196 assert_formats_equal (formats, parsed);
197
198 g_free (mem: fuzzy);
199 gdk_content_formats_unref (formats: parsed);
200 gdk_content_formats_unref (formats);
201 }
202}
203
204static void
205test_parse_fail (void)
206{
207 static const char *failures[] = {
208 "GtkNonexistingType",
209 "text/plain TypeAfterMime",
210 "notamimetype",
211 "image/png stillnotamimetype",
212 };
213 gsize i;
214
215 for (i = 0; i < G_N_ELEMENTS (failures); i++)
216 {
217 g_assert_null (gdk_content_formats_parse (failures[i]));
218 }
219}
220
221int
222main (int argc, char *argv[])
223{
224 gsize i;
225
226 (g_test_init) (argc: &argc, argv: &argv, NULL);
227
228 gtk_init ();
229
230 /* Ensure all the types we care about to exist */
231 for (i = 0; i < G_N_ELEMENTS(possible_types); i++)
232 {
233 if (possible_types[i].type_func)
234 g_type_ensure (type: possible_types[i].type_func ());
235 }
236
237 g_test_add_func (testpath: "/contentformats/parse", test_func: test_parse);
238 g_test_add_func (testpath: "/contentformats/parse_fail", test_func: test_parse_fail);
239 g_test_add_func (testpath: "/contentformats/print_and_parse", test_func: test_print_and_parse);
240 g_test_add_func (testpath: "/contentformats/union", test_func: test_union);
241
242 return g_test_run ();
243}
244

source code of gtk/testsuite/gdk/contentformats.c