1 | #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS |
2 | #define GLIB_DISABLE_DEPRECATION_WARNINGS |
3 | #endif |
4 | |
5 | #include <glib-object.h> |
6 | #include <stdlib.h> |
7 | |
8 | static void |
9 | test_param_value (void) |
10 | { |
11 | GParamSpec *p, *p2; |
12 | GParamSpec *pp; |
13 | GValue value = G_VALUE_INIT; |
14 | |
15 | g_value_init (value: &value, G_TYPE_PARAM); |
16 | g_assert_true (G_VALUE_HOLDS_PARAM (&value)); |
17 | |
18 | p = g_param_spec_int (name: "my-int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
19 | |
20 | g_value_take_param (value: &value, param: p); |
21 | p2 = g_value_get_param (value: &value); |
22 | g_assert_true (p2 == p); |
23 | |
24 | pp = g_param_spec_uint (name: "my-uint" , nick: "My UInt" , blurb: "Blurb" , minimum: 0, maximum: 10, default_value: 5, flags: G_PARAM_READWRITE); |
25 | g_value_set_param (value: &value, param: pp); |
26 | |
27 | p2 = g_value_dup_param (value: &value); |
28 | g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */ |
29 | g_param_spec_unref (pspec: p2); |
30 | |
31 | g_value_unset (value: &value); |
32 | g_param_spec_unref (pspec: pp); |
33 | } |
34 | |
35 | static gint destroy_count; |
36 | |
37 | static void |
38 | my_destroy (gpointer data) |
39 | { |
40 | destroy_count++; |
41 | } |
42 | |
43 | static void |
44 | test_param_qdata (void) |
45 | { |
46 | GParamSpec *p; |
47 | gchar *bla; |
48 | GQuark q; |
49 | |
50 | q = g_quark_from_string (string: "bla" ); |
51 | |
52 | p = g_param_spec_int (name: "my-int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
53 | g_param_spec_set_qdata (pspec: p, quark: q, data: "bla" ); |
54 | bla = g_param_spec_get_qdata (pspec: p, quark: q); |
55 | g_assert_cmpstr (bla, ==, "bla" ); |
56 | |
57 | g_assert_cmpint (destroy_count, ==, 0); |
58 | g_param_spec_set_qdata_full (pspec: p, quark: q, data: "bla" , destroy: my_destroy); |
59 | g_param_spec_set_qdata_full (pspec: p, quark: q, data: "blabla" , destroy: my_destroy); |
60 | g_assert_cmpint (destroy_count, ==, 1); |
61 | g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla" ); |
62 | g_assert_cmpint (destroy_count, ==, 1); |
63 | g_assert_null (g_param_spec_get_qdata (p, q)); |
64 | |
65 | g_param_spec_ref_sink (pspec: p); |
66 | |
67 | g_param_spec_unref (pspec: p); |
68 | } |
69 | |
70 | static void |
71 | test_param_validate (void) |
72 | { |
73 | GParamSpec *p; |
74 | GValue value = G_VALUE_INIT; |
75 | |
76 | p = g_param_spec_int (name: "my-int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
77 | |
78 | g_value_init (value: &value, G_TYPE_INT); |
79 | g_value_set_int (value: &value, v_int: 100); |
80 | g_assert_false (g_param_value_defaults (p, &value)); |
81 | g_assert_true (g_param_value_validate (p, &value)); |
82 | g_assert_cmpint (g_value_get_int (&value), ==, 20); |
83 | |
84 | g_param_value_set_default (pspec: p, value: &value); |
85 | g_assert_true (g_param_value_defaults (p, &value)); |
86 | g_assert_cmpint (g_value_get_int (&value), ==, 10); |
87 | |
88 | g_param_spec_unref (pspec: p); |
89 | } |
90 | |
91 | static void |
92 | test_param_strings (void) |
93 | { |
94 | GParamSpec *p; |
95 | |
96 | /* test canonicalization */ |
97 | p = g_param_spec_int (name: "my_int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
98 | |
99 | g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int" ); |
100 | g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int" ); |
101 | g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb" ); |
102 | |
103 | g_param_spec_unref (pspec: p); |
104 | |
105 | /* test nick defaults to name */ |
106 | p = g_param_spec_int (name: "my-int" , NULL, NULL, minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
107 | |
108 | g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int" ); |
109 | g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int" ); |
110 | g_assert_null (g_param_spec_get_blurb (p)); |
111 | |
112 | g_param_spec_unref (pspec: p); |
113 | } |
114 | |
115 | static void |
116 | test_param_invalid_name (gconstpointer test_data) |
117 | { |
118 | const gchar *invalid_name = test_data; |
119 | |
120 | g_test_summary (summary: "Test that properties cannot be created with invalid names" ); |
121 | |
122 | if (g_test_subprocess ()) |
123 | { |
124 | GParamSpec *p; |
125 | p = g_param_spec_int (name: invalid_name, nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
126 | g_param_spec_unref (pspec: p); |
127 | return; |
128 | } |
129 | |
130 | g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0); |
131 | g_test_trap_assert_failed (); |
132 | g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*" ); |
133 | } |
134 | |
135 | static void |
136 | test_param_convert (void) |
137 | { |
138 | GParamSpec *p; |
139 | GValue v1 = G_VALUE_INIT; |
140 | GValue v2 = G_VALUE_INIT; |
141 | |
142 | p = g_param_spec_int (name: "my-int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
143 | g_value_init (value: &v1, G_TYPE_UINT); |
144 | g_value_set_uint (value: &v1, v_uint: 43); |
145 | |
146 | g_value_init (value: &v2, G_TYPE_INT); |
147 | g_value_set_int (value: &v2, v_int: -4); |
148 | |
149 | g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE)); |
150 | g_assert_cmpint (g_value_get_int (&v2), ==, -4); |
151 | |
152 | g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE)); |
153 | g_assert_cmpint (g_value_get_int (&v2), ==, 20); |
154 | |
155 | g_param_spec_unref (pspec: p); |
156 | } |
157 | |
158 | static void |
159 | test_value_transform (void) |
160 | { |
161 | GValue src = G_VALUE_INIT; |
162 | GValue dest = G_VALUE_INIT; |
163 | |
164 | #define CHECK_INT_CONVERSION(type, getter, value) \ |
165 | g_assert_true (g_value_type_transformable (G_TYPE_INT, type)); \ |
166 | g_value_init (&src, G_TYPE_INT); \ |
167 | g_value_init (&dest, type); \ |
168 | g_value_set_int (&src, value); \ |
169 | g_assert_true (g_value_transform (&src, &dest)); \ |
170 | g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ |
171 | g_value_unset (&src); \ |
172 | g_value_unset (&dest); |
173 | |
174 | /* Keep a check for an integer in the range of 0-127 so we're |
175 | * still testing g_value_get_char(). See |
176 | * https://bugzilla.gnome.org/show_bug.cgi?id=659870 |
177 | * for why it is broken. |
178 | */ |
179 | CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124) |
180 | |
181 | CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124) |
182 | CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124) |
183 | CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
184 | CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
185 | CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345) |
186 | CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345) |
187 | CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0) |
188 | CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345) |
189 | CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678) |
190 | CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
191 | CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678) |
192 | CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
193 | CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
194 | CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
195 | |
196 | #define CHECK_UINT_CONVERSION(type, getter, value) \ |
197 | g_assert_true (g_value_type_transformable (G_TYPE_UINT, type)); \ |
198 | g_value_init (&src, G_TYPE_UINT); \ |
199 | g_value_init (&dest, type); \ |
200 | g_value_set_uint (&src, value); \ |
201 | g_assert_true (g_value_transform (&src, &dest)); \ |
202 | g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ |
203 | g_value_unset (&src); \ |
204 | g_value_unset (&dest); |
205 | |
206 | CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124) |
207 | CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124) |
208 | CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
209 | CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
210 | CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345) |
211 | CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345) |
212 | CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 0) |
213 | CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 12345) |
214 | CHECK_UINT_CONVERSION(G_TYPE_LONG, long, 12345678) |
215 | CHECK_UINT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
216 | CHECK_UINT_CONVERSION(G_TYPE_INT64, int64, 12345678) |
217 | CHECK_UINT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
218 | CHECK_UINT_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
219 | CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
220 | |
221 | #define CHECK_LONG_CONVERSION(type, getter, value) \ |
222 | g_assert_true (g_value_type_transformable (G_TYPE_LONG, type)); \ |
223 | g_value_init (&src, G_TYPE_LONG); \ |
224 | g_value_init (&dest, type); \ |
225 | g_value_set_long (&src, value); \ |
226 | g_assert_true (g_value_transform (&src, &dest)); \ |
227 | g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ |
228 | g_value_unset (&src); \ |
229 | g_value_unset (&dest); |
230 | |
231 | CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124) |
232 | CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124) |
233 | CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
234 | CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
235 | CHECK_LONG_CONVERSION(G_TYPE_INT, int, -12345) |
236 | CHECK_LONG_CONVERSION(G_TYPE_INT, int, 12345) |
237 | CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 0) |
238 | CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 12345) |
239 | CHECK_LONG_CONVERSION(G_TYPE_LONG, long, -12345678) |
240 | CHECK_LONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
241 | CHECK_LONG_CONVERSION(G_TYPE_INT64, int64, -12345678) |
242 | CHECK_LONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
243 | CHECK_LONG_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
244 | CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
245 | |
246 | #define CHECK_ULONG_CONVERSION(type, getter, value) \ |
247 | g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type)); \ |
248 | g_value_init (&src, G_TYPE_ULONG); \ |
249 | g_value_init (&dest, type); \ |
250 | g_value_set_ulong (&src, value); \ |
251 | g_assert_true (g_value_transform (&src, &dest)); \ |
252 | g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ |
253 | g_value_unset (&src); \ |
254 | g_value_unset (&dest); |
255 | |
256 | CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124) |
257 | CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124) |
258 | CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
259 | CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
260 | CHECK_ULONG_CONVERSION(G_TYPE_INT, int, -12345) |
261 | CHECK_ULONG_CONVERSION(G_TYPE_INT, int, 12345) |
262 | CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 0) |
263 | CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 12345) |
264 | CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678) |
265 | CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
266 | CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678) |
267 | CHECK_ULONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
268 | CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
269 | CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
270 | |
271 | #define CHECK_INT64_CONVERSION(type, getter, value) \ |
272 | g_assert_true (g_value_type_transformable (G_TYPE_INT64, type)); \ |
273 | g_value_init (&src, G_TYPE_INT64); \ |
274 | g_value_init (&dest, type); \ |
275 | g_value_set_int64 (&src, value); \ |
276 | g_assert_true (g_value_transform (&src, &dest)); \ |
277 | g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ |
278 | g_value_unset (&src); \ |
279 | g_value_unset (&dest); |
280 | |
281 | CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124) |
282 | CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124) |
283 | CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
284 | CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
285 | CHECK_INT64_CONVERSION(G_TYPE_INT, int, -12345) |
286 | CHECK_INT64_CONVERSION(G_TYPE_INT, int, 12345) |
287 | CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 0) |
288 | CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 12345) |
289 | CHECK_INT64_CONVERSION(G_TYPE_LONG, long, -12345678) |
290 | CHECK_INT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
291 | CHECK_INT64_CONVERSION(G_TYPE_INT64, int64, -12345678) |
292 | CHECK_INT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
293 | CHECK_INT64_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
294 | CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
295 | |
296 | #define CHECK_UINT64_CONVERSION(type, getter, value) \ |
297 | g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type)); \ |
298 | g_value_init (&src, G_TYPE_UINT64); \ |
299 | g_value_init (&dest, type); \ |
300 | g_value_set_uint64 (&src, value); \ |
301 | g_assert_true (g_value_transform (&src, &dest)); \ |
302 | g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ |
303 | g_value_unset (&src); \ |
304 | g_value_unset (&dest); |
305 | |
306 | CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124) |
307 | CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124) |
308 | CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
309 | CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
310 | CHECK_UINT64_CONVERSION(G_TYPE_INT, int, -12345) |
311 | CHECK_UINT64_CONVERSION(G_TYPE_INT, int, 12345) |
312 | CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 0) |
313 | CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 12345) |
314 | CHECK_UINT64_CONVERSION(G_TYPE_LONG, long, -12345678) |
315 | CHECK_UINT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
316 | CHECK_UINT64_CONVERSION(G_TYPE_INT64, int64, -12345678) |
317 | CHECK_UINT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
318 | CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
319 | CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
320 | |
321 | #define CHECK_FLOAT_CONVERSION(type, getter, value) \ |
322 | g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type)); \ |
323 | g_value_init (&src, G_TYPE_FLOAT); \ |
324 | g_value_init (&dest, type); \ |
325 | g_value_set_float (&src, value); \ |
326 | g_assert_true (g_value_transform (&src, &dest)); \ |
327 | g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ |
328 | g_value_unset (&src); \ |
329 | g_value_unset (&dest); |
330 | |
331 | CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124) |
332 | CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124) |
333 | CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
334 | CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
335 | CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, -12345) |
336 | CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, 12345) |
337 | CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 0) |
338 | CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 12345) |
339 | CHECK_FLOAT_CONVERSION(G_TYPE_LONG, long, -12345678) |
340 | CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
341 | CHECK_FLOAT_CONVERSION(G_TYPE_INT64, int64, -12345678) |
342 | CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
343 | CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
344 | CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
345 | |
346 | #define CHECK_DOUBLE_CONVERSION(type, getter, value) \ |
347 | g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type)); \ |
348 | g_value_init (&src, G_TYPE_DOUBLE); \ |
349 | g_value_init (&dest, type); \ |
350 | g_value_set_double (&src, value); \ |
351 | g_assert_true (g_value_transform (&src, &dest)); \ |
352 | g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ |
353 | g_value_unset (&src); \ |
354 | g_value_unset (&dest); |
355 | |
356 | CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124) |
357 | CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124) |
358 | CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 0) |
359 | CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 255) |
360 | CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, -12345) |
361 | CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, 12345) |
362 | CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 0) |
363 | CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 12345) |
364 | CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, long, -12345678) |
365 | CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
366 | CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, int64, -12345678) |
367 | CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
368 | CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, float, 12345678) |
369 | CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, double, 12345678) |
370 | |
371 | #define CHECK_BOOLEAN_CONVERSION(type, setter, value) \ |
372 | g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN)); \ |
373 | g_value_init (&src, type); \ |
374 | g_value_init (&dest, G_TYPE_BOOLEAN); \ |
375 | g_value_set_##setter (&src, value); \ |
376 | g_assert_true (g_value_transform (&src, &dest)); \ |
377 | g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE); \ |
378 | g_value_set_##setter (&src, 0); \ |
379 | g_assert_true (g_value_transform (&src, &dest)); \ |
380 | g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE); \ |
381 | g_value_unset (&src); \ |
382 | g_value_unset (&dest); |
383 | |
384 | CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345) |
385 | CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345) |
386 | CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678) |
387 | CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
388 | CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678) |
389 | CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
390 | |
391 | #define CHECK_STRING_CONVERSION(int_type, setter, int_value) \ |
392 | g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \ |
393 | g_value_init (&src, int_type); \ |
394 | g_value_init (&dest, G_TYPE_STRING); \ |
395 | g_value_set_##setter (&src, int_value); \ |
396 | g_assert_true (g_value_transform (&src, &dest)); \ |
397 | g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value); \ |
398 | g_value_unset (&src); \ |
399 | g_value_unset (&dest); |
400 | |
401 | CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345) |
402 | CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345) |
403 | CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678) |
404 | CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678) |
405 | CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678) |
406 | CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678) |
407 | CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000) |
408 | CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567) |
409 | |
410 | g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR)); |
411 | g_value_init (value: &src, G_TYPE_STRING); |
412 | g_value_init (value: &dest, G_TYPE_CHAR); |
413 | g_value_set_static_string (value: &src, v_string: "bla" ); |
414 | g_value_set_schar (value: &dest, v_char: 'c'); |
415 | g_assert_false (g_value_transform (&src, &dest)); |
416 | g_assert_cmpint (g_value_get_schar (&dest), ==, 'c'); |
417 | g_value_unset (value: &src); |
418 | g_value_unset (value: &dest); |
419 | } |
420 | |
421 | |
422 | /* We create some dummy objects with a simple relationship: |
423 | * |
424 | * GObject |
425 | * / \ |
426 | * TestObjectA TestObjectC |
427 | * | |
428 | * TestObjectB |
429 | * |
430 | * ie: TestObjectB is a subclass of TestObjectA and TestObjectC is |
431 | * related to neither. |
432 | */ |
433 | |
434 | static GType test_object_a_get_type (void); |
435 | typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass; |
436 | G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT) |
437 | static void test_object_a_class_init (TestObjectAClass *class) { } |
438 | static void test_object_a_init (TestObjectA *a) { } |
439 | |
440 | static GType test_object_b_get_type (void); |
441 | typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass; |
442 | G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ()) |
443 | static void test_object_b_class_init (TestObjectBClass *class) { } |
444 | static void test_object_b_init (TestObjectB *b) { } |
445 | |
446 | static GType test_object_c_get_type (void); |
447 | typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass; |
448 | G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT) |
449 | static void test_object_c_class_init (TestObjectCClass *class) { } |
450 | static void test_object_c_init (TestObjectC *c) { } |
451 | |
452 | /* We create an interface and programmatically populate it with |
453 | * properties of each of the above type, with various flag combinations. |
454 | * |
455 | * Properties are named like "type-perm" where type is 'a', 'b' or 'c' |
456 | * and perm is a series of characters, indicating the permissions: |
457 | * |
458 | * - 'r': readable |
459 | * - 'w': writable |
460 | * - 'c': construct |
461 | * - 'C': construct-only |
462 | * |
463 | * It doesn't make sense to have a property that is neither readable nor |
464 | * writable. It is also not valid to have construct or construct-only |
465 | * on read-only params. Finally, it is invalid to have both construct |
466 | * and construct-only specified, so we do not consider those cases. |
467 | * That gives us 7 possible permissions: |
468 | * |
469 | * 'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC' |
470 | * |
471 | * And 9 impossible ones: |
472 | * |
473 | * '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC' |
474 | * |
475 | * For a total of 16 combinations. |
476 | * |
477 | * That gives a total of 48 (16 * 3) possible flag/type combinations, of |
478 | * which 27 (9 * 3) are impossible to install. |
479 | * |
480 | * That gives 21 (7 * 3) properties that will be installed. |
481 | */ |
482 | typedef GTypeInterface TestInterfaceInterface; |
483 | static GType test_interface_get_type (void); |
484 | //typedef struct _TestInterface TestInterface; |
485 | G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT) |
486 | static void |
487 | test_interface_default_init (TestInterfaceInterface *iface) |
488 | { |
489 | const gchar *names[] = { "a" , "b" , "c" }; |
490 | const gchar *perms[] = { NULL, "r" , "w" , "rw" , |
491 | NULL, NULL, "wc" , "rwc" , |
492 | NULL, NULL, "wC" , "rwC" , |
493 | NULL, NULL, NULL, NULL }; |
494 | const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () }; |
495 | guint i, j; |
496 | |
497 | for (i = 0; i < G_N_ELEMENTS (types); i++) |
498 | for (j = 0; j < G_N_ELEMENTS (perms); j++) |
499 | { |
500 | gchar prop_name[10]; |
501 | GParamSpec *pspec; |
502 | |
503 | if (perms[j] == NULL) |
504 | { |
505 | if (!g_test_undefined ()) |
506 | continue; |
507 | |
508 | /* we think that this is impossible. make sure. */ |
509 | pspec = g_param_spec_object (name: "xyz" , nick: "xyz" , blurb: "xyz" , object_type: types[i], flags: j); |
510 | |
511 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_CRITICAL, |
512 | pattern: "*assertion*pspec->flags*failed*" ); |
513 | g_object_interface_install_property (g_iface: iface, pspec); |
514 | g_test_assert_expected_messages (); |
515 | |
516 | g_param_spec_unref (pspec); |
517 | continue; |
518 | } |
519 | |
520 | /* install the property */ |
521 | g_snprintf (string: prop_name, n: sizeof prop_name, format: "%s-%s" , names[i], perms[j]); |
522 | pspec = g_param_spec_object (name: prop_name, nick: prop_name, blurb: prop_name, object_type: types[i], flags: j); |
523 | g_object_interface_install_property (g_iface: iface, pspec); |
524 | } |
525 | } |
526 | |
527 | /* We now have 21 properties. Each property may be correctly |
528 | * implemented with the following types: |
529 | * |
530 | * Properties Valid Types Reason |
531 | * |
532 | * a-r a, b Read only can provide subclasses |
533 | * a-w, wc, wC a, GObject Write only can accept superclasses |
534 | * a-rw, rwc, rwC a Read-write must be exactly equal |
535 | * |
536 | * b-r b (as above) |
537 | * b-w, wc, wC b, a, GObject |
538 | * b-rw, rwc, rwC b |
539 | * |
540 | * c-r c (as above) |
541 | * c-wo, wc, wC c, GObject |
542 | * c-rw, rwc, rwC c |
543 | * |
544 | * We can express this in a 48-by-4 table where each row represents an |
545 | * installed property and each column represents a type. The value in |
546 | * the table represents if it is valid to subclass the row's property |
547 | * with the type of the column: |
548 | * |
549 | * - 0: invalid because the interface property doesn't exist (invalid flags) |
550 | * - 'v': valid |
551 | * - '=': invalid because of the type not being exactly equal |
552 | * - '<': invalid because of the type not being a subclass |
553 | * - '>': invalid because of the type not being a superclass |
554 | * |
555 | * We organise the table by interface property type ('a', 'b', 'c') then |
556 | * by interface property flags. |
557 | */ |
558 | |
559 | static gint valid_impl_types[48][4] = { |
560 | /* a b c GObject */ |
561 | /* 'a-' */ { 0, }, |
562 | /* 'a-r' */ { 'v', 'v', '<', '<' }, |
563 | /* 'a-w' */ { 'v', '>', '>', 'v' }, |
564 | /* 'a-rw' */ { 'v', '=', '=', '=' }, |
565 | /* 'a-c */ { 0, }, |
566 | /* 'a-rc' */ { 0, }, |
567 | /* 'a-wc' */ { 'v', '>', '>', 'v' }, |
568 | /* 'a-rwc' */ { 'v', '=', '=', '=' }, |
569 | /* 'a-C */ { 0, }, |
570 | /* 'a-rC' */ { 0, }, |
571 | /* 'a-wC' */ { 'v', '>', '>', 'v' }, |
572 | /* 'a-rwC' */ { 'v', '=', '=', '=' }, |
573 | /* 'a-cC */ { 0, }, |
574 | /* 'a-rcC' */ { 0, }, |
575 | /* 'a-wcC' */ { 0, }, |
576 | /* 'a-rwcC' */ { 0, }, |
577 | |
578 | /* 'b-' */ { 0, }, |
579 | /* 'b-r' */ { '<', 'v', '<', '<' }, |
580 | /* 'b-w' */ { 'v', 'v', '>', 'v' }, |
581 | /* 'b-rw' */ { '=', 'v', '=', '=' }, |
582 | /* 'b-c */ { 0, }, |
583 | /* 'b-rc' */ { 0, }, |
584 | /* 'b-wc' */ { 'v', 'v', '>', 'v' }, |
585 | /* 'b-rwc' */ { '=', 'v', '=', '=' }, |
586 | /* 'b-C */ { 0, }, |
587 | /* 'b-rC' */ { 0, }, |
588 | /* 'b-wC' */ { 'v', 'v', '>', 'v' }, |
589 | /* 'b-rwC' */ { '=', 'v', '=', '=' }, |
590 | /* 'b-cC */ { 0, }, |
591 | /* 'b-rcC' */ { 0, }, |
592 | /* 'b-wcC' */ { 0, }, |
593 | /* 'b-rwcC' */ { 0, }, |
594 | |
595 | /* 'c-' */ { 0, }, |
596 | /* 'c-r' */ { '<', '<', 'v', '<' }, |
597 | /* 'c-w' */ { '>', '>', 'v', 'v' }, |
598 | /* 'c-rw' */ { '=', '=', 'v', '=' }, |
599 | /* 'c-c */ { 0, }, |
600 | /* 'c-rc' */ { 0, }, |
601 | /* 'c-wc' */ { '>', '>', 'v', 'v' }, |
602 | /* 'c-rwc' */ { '=', '=', 'v', '=' }, |
603 | /* 'c-C */ { 0, }, |
604 | /* 'c-rC' */ { 0, }, |
605 | /* 'c-wC' */ { '>', '>', 'v', 'v' }, |
606 | /* 'c-rwC' */ { '=', '=', 'v', '=' }, |
607 | /* 'c-cC */ { 0, }, |
608 | /* 'c-rcC' */ { 0, }, |
609 | /* 'c-wcC' */ { 0, }, |
610 | /* 'c-rwcC' */ { 0, } |
611 | }; |
612 | |
613 | /* We also try to change the flags. We must ensure that all |
614 | * implementations provide all functionality promised by the interface. |
615 | * We must therefore never remove readability or writability (but we can |
616 | * add them). Construct-only is a restrictions that applies to |
617 | * writability, so we can never add it unless writability was never |
618 | * present in the first place, in which case "writable at construct |
619 | * only" is still better than "not writable". |
620 | * |
621 | * The 'construct' flag is of interest only to the implementation. It |
622 | * may be changed at any time. |
623 | * |
624 | * Properties Valid Access Reason |
625 | * |
626 | * *-r r, rw, rwc, rwC Must keep readable, but can restrict newly-added writable |
627 | * *-w w, rw, rwc Must keep writable unrestricted |
628 | * *-rw rw, rwc Must not add any restrictions |
629 | * *-rwc rw, rwc Must not add any restrictions |
630 | * *-rwC rw, rwc, rwC Can remove 'construct-only' restriction |
631 | * *-wc rwc, rw, w, wc Can add readability |
632 | * *-wC rwC, rw, w, wC Can add readability or remove 'construct only' restriction |
633 | * rwc, wc |
634 | * |
635 | * We can represent this with a 16-by-16 table. The rows represent the |
636 | * flags of the property on the interface. The columns is the flags to |
637 | * try to use when overriding the property. The cell contents are: |
638 | * |
639 | * - 0: invalid because the interface property doesn't exist (invalid flags) |
640 | * - 'v': valid |
641 | * - 'i': invalid because the implementation flags are invalid |
642 | * - 'f': invalid because of the removal of functionality |
643 | * - 'r': invalid because of the addition of restrictions (ie: construct-only) |
644 | * |
645 | * We also ensure that removal of functionality is reported before |
646 | * addition of restrictions, since this is a more basic problem. |
647 | */ |
648 | static gint valid_impl_flags[16][16] = { |
649 | /* '' r w rw c rc wc rwc C rC wC rwC cC rcC wcC rwcC */ |
650 | /* '*-' */ { 0, }, |
651 | /* '*-r' */ { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' }, |
652 | /* '*-w' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' }, |
653 | /* '*-rw' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' }, |
654 | /* '*-c */ { 0, }, |
655 | /* '*-rc' */ { 0, }, |
656 | /* '*-wc' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' }, |
657 | /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' }, |
658 | /* '*-C */ { 0, }, |
659 | /* '*-rC' */ { 0, }, |
660 | /* '*-wC' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' }, |
661 | /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' }, |
662 | }; |
663 | |
664 | static guint change_this_flag; |
665 | static guint change_this_type; |
666 | static guint use_this_flag; |
667 | static guint use_this_type; |
668 | |
669 | typedef GObjectClass TestImplementationClass; |
670 | typedef GObject TestImplementation; |
671 | |
672 | static void test_implementation_init (TestImplementation *impl) { } |
673 | static void test_implementation_iface_init (TestInterfaceInterface *iface) { } |
674 | |
675 | static GType test_implementation_get_type (void); |
676 | G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT, |
677 | G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init)) |
678 | |
679 | static void test_implementation_class_init (TestImplementationClass *class) |
680 | { |
681 | const gchar *names[] = { "a" , "b" , "c" }; |
682 | const gchar *perms[] = { NULL, "r" , "w" , "rw" , |
683 | NULL, NULL, "wc" , "rwc" , |
684 | NULL, NULL, "wC" , "rwC" , |
685 | NULL, NULL, NULL, NULL }; |
686 | const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), |
687 | test_object_c_get_type (), G_TYPE_OBJECT }; |
688 | gchar prop_name[10]; |
689 | GParamSpec *pspec; |
690 | guint i, j; |
691 | |
692 | class->get_property = GINT_TO_POINTER (1); |
693 | class->set_property = GINT_TO_POINTER (1); |
694 | |
695 | /* Install all of the non-modified properties or else GObject will |
696 | * complain about non-implemented properties. |
697 | */ |
698 | for (i = 0; i < 3; i++) |
699 | for (j = 0; j < G_N_ELEMENTS (perms); j++) |
700 | { |
701 | if (i == change_this_type && j == change_this_flag) |
702 | continue; |
703 | |
704 | if (perms[j] != NULL) |
705 | { |
706 | /* override the property without making changes */ |
707 | g_snprintf (string: prop_name, n: sizeof prop_name, format: "%s-%s" , names[i], perms[j]); |
708 | g_object_class_override_property (oclass: class, property_id: 1, name: prop_name); |
709 | } |
710 | } |
711 | |
712 | /* Now try installing our modified property */ |
713 | if (perms[change_this_flag] == NULL) |
714 | g_error ("Interface property does not exist" ); |
715 | |
716 | g_snprintf (string: prop_name, n: sizeof prop_name, format: "%s-%s" , names[change_this_type], perms[change_this_flag]); |
717 | pspec = g_param_spec_object (name: prop_name, nick: prop_name, blurb: prop_name, object_type: types[use_this_type], flags: use_this_flag); |
718 | g_object_class_install_property (oclass: class, property_id: 1, pspec); |
719 | } |
720 | |
721 | typedef struct { |
722 | gint change_this_flag; |
723 | gint change_this_type; |
724 | gint use_this_flag; |
725 | gint use_this_type; |
726 | } TestParamImplementData; |
727 | |
728 | static void |
729 | test_param_implement_child (gconstpointer user_data) |
730 | { |
731 | TestParamImplementData *data = (gpointer) user_data; |
732 | |
733 | /* GObject oddity: GObjectClass must be initialised before we can |
734 | * initialise a GTypeInterface. |
735 | */ |
736 | g_type_class_ref (G_TYPE_OBJECT); |
737 | |
738 | /* Bring up the interface first. */ |
739 | g_type_default_interface_ref (g_type: test_interface_get_type ()); |
740 | |
741 | /* Copy the flags into the global vars so |
742 | * test_implementation_class_init() will see them. |
743 | */ |
744 | change_this_flag = data->change_this_flag; |
745 | change_this_type = data->change_this_type; |
746 | use_this_flag = data->use_this_flag; |
747 | use_this_type = data->use_this_type; |
748 | |
749 | g_type_class_ref (type: test_implementation_get_type ()); |
750 | } |
751 | |
752 | static void |
753 | test_param_implement (void) |
754 | { |
755 | gchar *test_path; |
756 | |
757 | for (change_this_flag = 0; change_this_flag < 16; change_this_flag++) |
758 | for (change_this_type = 0; change_this_type < 3; change_this_type++) |
759 | for (use_this_flag = 0; use_this_flag < 16; use_this_flag++) |
760 | for (use_this_type = 0; use_this_type < 4; use_this_type++) |
761 | { |
762 | if (!g_test_undefined ()) |
763 | { |
764 | /* only test the valid (defined) cases, e.g. under valgrind */ |
765 | if (valid_impl_flags[change_this_flag][use_this_flag] != 'v') |
766 | continue; |
767 | |
768 | if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v') |
769 | continue; |
770 | } |
771 | |
772 | test_path = g_strdup_printf (format: "/param/implement/subprocess/%d-%d-%d-%d" , |
773 | change_this_flag, change_this_type, |
774 | use_this_flag, use_this_type); |
775 | g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, test_flags: 0); |
776 | g_free (mem: test_path); |
777 | |
778 | /* We want to ensure that any flags mismatch problems are reported first. */ |
779 | switch (valid_impl_flags[change_this_flag][use_this_flag]) |
780 | { |
781 | case 0: |
782 | /* make sure the other table agrees */ |
783 | g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0); |
784 | g_test_trap_assert_failed (); |
785 | g_test_trap_assert_stderr ("*Interface property does not exist*" ); |
786 | continue; |
787 | |
788 | case 'i': |
789 | g_test_trap_assert_failed (); |
790 | g_test_trap_assert_stderr ("*g_object_class_install_property*" ); |
791 | continue; |
792 | |
793 | case 'f': |
794 | g_test_trap_assert_failed (); |
795 | g_test_trap_assert_stderr ("*remove functionality*" ); |
796 | continue; |
797 | |
798 | case 'r': |
799 | g_test_trap_assert_failed (); |
800 | g_test_trap_assert_stderr ("*introduce additional restrictions*" ); |
801 | continue; |
802 | |
803 | case 'v': |
804 | break; |
805 | } |
806 | |
807 | /* Next, we check if there should have been a type error. */ |
808 | switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type]) |
809 | { |
810 | case 0: |
811 | /* this should have been caught above */ |
812 | g_assert_not_reached (); |
813 | |
814 | case '=': |
815 | g_test_trap_assert_failed (); |
816 | g_test_trap_assert_stderr ("*exactly equal*" ); |
817 | continue; |
818 | |
819 | case '<': |
820 | g_test_trap_assert_failed (); |
821 | g_test_trap_assert_stderr ("*equal to or more restrictive*" ); |
822 | continue; |
823 | |
824 | case '>': |
825 | g_test_trap_assert_failed (); |
826 | g_test_trap_assert_stderr ("*equal to or less restrictive*" ); |
827 | continue; |
828 | |
829 | case 'v': |
830 | break; |
831 | } |
832 | |
833 | g_test_trap_assert_passed (); |
834 | } |
835 | } |
836 | |
837 | static void |
838 | test_param_default (void) |
839 | { |
840 | GParamSpec *param; |
841 | const GValue *def; |
842 | |
843 | param = g_param_spec_int (name: "my-int" , nick: "My Int" , blurb: "Blurb" , minimum: 0, maximum: 20, default_value: 10, flags: G_PARAM_READWRITE); |
844 | def = g_param_spec_get_default_value (pspec: param); |
845 | |
846 | g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT)); |
847 | g_assert_cmpint (g_value_get_int (def), ==, 10); |
848 | |
849 | g_param_spec_unref (pspec: param); |
850 | } |
851 | |
852 | static void |
853 | test_param_is_valid_name (void) |
854 | { |
855 | const gchar *valid_names[] = |
856 | { |
857 | "property" , |
858 | "i" , |
859 | "multiple-segments" , |
860 | "segment0-SEGMENT1" , |
861 | "using_underscores" , |
862 | }; |
863 | const gchar *invalid_names[] = |
864 | { |
865 | "" , |
866 | "7zip" , |
867 | "my_int:hello" , |
868 | }; |
869 | gsize i; |
870 | |
871 | for (i = 0; i < G_N_ELEMENTS (valid_names); i++) |
872 | g_assert_true (g_param_spec_is_valid_name (valid_names[i])); |
873 | |
874 | for (i = 0; i < G_N_ELEMENTS (invalid_names); i++) |
875 | g_assert_false (g_param_spec_is_valid_name (invalid_names[i])); |
876 | } |
877 | |
878 | int |
879 | main (int argc, char *argv[]) |
880 | { |
881 | TestParamImplementData data, *test_data; |
882 | gchar *test_path; |
883 | |
884 | g_test_init (argc: &argc, argv: &argv, NULL); |
885 | |
886 | g_test_add_func (testpath: "/param/value" , test_func: test_param_value); |
887 | g_test_add_func (testpath: "/param/strings" , test_func: test_param_strings); |
888 | g_test_add_data_func (testpath: "/param/invalid-name/colon" , test_data: "my_int:hello" , test_func: test_param_invalid_name); |
889 | g_test_add_data_func (testpath: "/param/invalid-name/first-char" , test_data: "7zip" , test_func: test_param_invalid_name); |
890 | g_test_add_data_func (testpath: "/param/invalid-name/empty" , test_data: "" , test_func: test_param_invalid_name); |
891 | g_test_add_func (testpath: "/param/qdata" , test_func: test_param_qdata); |
892 | g_test_add_func (testpath: "/param/validate" , test_func: test_param_validate); |
893 | g_test_add_func (testpath: "/param/convert" , test_func: test_param_convert); |
894 | |
895 | if (g_test_slow ()) |
896 | g_test_add_func (testpath: "/param/implement" , test_func: test_param_implement); |
897 | |
898 | for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++) |
899 | for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++) |
900 | for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++) |
901 | for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++) |
902 | { |
903 | test_path = g_strdup_printf (format: "/param/implement/subprocess/%d-%d-%d-%d" , |
904 | data.change_this_flag, data.change_this_type, |
905 | data.use_this_flag, data.use_this_type); |
906 | test_data = g_memdup2 (mem: &data, byte_size: sizeof (TestParamImplementData)); |
907 | g_test_add_data_func_full (testpath: test_path, test_data, test_func: test_param_implement_child, data_free_func: g_free); |
908 | g_free (mem: test_path); |
909 | } |
910 | |
911 | g_test_add_func (testpath: "/value/transform" , test_func: test_value_transform); |
912 | g_test_add_func (testpath: "/param/default" , test_func: test_param_default); |
913 | g_test_add_func (testpath: "/param/is-valid-name" , test_func: test_param_is_valid_name); |
914 | |
915 | return g_test_run (); |
916 | } |
917 | |