1 | #include <stdlib.h> |
2 | |
3 | #include <gtk/gtk.h> |
4 | |
5 | static GType |
6 | string_type (void) |
7 | { |
8 | return G_TYPE_STRING; |
9 | } |
10 | |
11 | static 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 | |
59 | static GdkContentFormats * |
60 | create_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 | |
82 | static void |
83 | test_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 | |
108 | static void |
109 | test_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 | |
141 | static void |
142 | append_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 | |
151 | static char * |
152 | fuzzy_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 | |
183 | static void |
184 | test_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 | |
204 | static void |
205 | test_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 | |
221 | int |
222 | main (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 | |