1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27 #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
28 #define GLIB_DISABLE_DEPRECATION_WARNINGS
29 #endif
30
31 #include <glib-object.h>
32 #include <stdlib.h>
33
34 static void
35 test_param_spec_char (void)
36 {
37 GParamSpec *pspec;
38 GValue value = G_VALUE_INIT;
39
40 pspec = g_param_spec_char ("char", "nick", "blurb",
41 20, 40, 30, G_PARAM_READWRITE);
42
43 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
44 g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
45 g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
46
47 g_value_init (&value, G_TYPE_CHAR);
48 g_value_set_char (&value, 30);
49
50 g_assert_true (g_param_value_defaults (pspec, &value));
51
52 g_value_set_char (&value, 0);
53 g_assert_false (g_param_value_is_valid (pspec, &value));
54 g_assert_true (g_param_value_validate (pspec, &value));
55 g_assert_cmpint (g_value_get_char (&value), ==, 20);
56
57 g_value_set_char (&value, 20);
58 g_assert_true (g_param_value_is_valid (pspec, &value));
59 g_assert_false (g_param_value_validate (pspec, &value));
60 g_assert_cmpint (g_value_get_char (&value), ==, 20);
61
62 g_value_set_char (&value, 40);
63 g_assert_true (g_param_value_is_valid (pspec, &value));
64 g_assert_false (g_param_value_validate (pspec, &value));
65 g_assert_cmpint (g_value_get_char (&value), ==, 40);
66
67 g_value_set_char (&value, 60);
68 g_assert_false (g_param_value_is_valid (pspec, &value));
69 g_assert_true (g_param_value_validate (pspec, &value));
70 g_assert_cmpint (g_value_get_char (&value), ==, 40);
71
72 g_value_set_schar (&value, 0);
73 g_assert_false (g_param_value_is_valid (pspec, &value));
74 g_assert_true (g_param_value_validate (pspec, &value));
75 g_assert_cmpint (g_value_get_schar (&value), ==, 20);
76
77 g_value_set_schar (&value, 20);
78 g_assert_true (g_param_value_is_valid (pspec, &value));
79 g_assert_false (g_param_value_validate (pspec, &value));
80 g_assert_cmpint (g_value_get_schar (&value), ==, 20);
81
82 g_value_set_schar (&value, 40);
83 g_assert_true (g_param_value_is_valid (pspec, &value));
84 g_assert_false (g_param_value_validate (pspec, &value));
85 g_assert_cmpint (g_value_get_schar (&value), ==, 40);
86
87 g_value_set_schar (&value, 60);
88 g_assert_false (g_param_value_is_valid (pspec, &value));
89 g_assert_true (g_param_value_validate (pspec, &value));
90 g_assert_cmpint (g_value_get_schar (&value), ==, 40);
91
92 g_param_spec_unref (pspec);
93 }
94
95 static void
96 test_param_spec_uchar (void)
97 {
98 GParamSpec *pspec;
99 GValue value = G_VALUE_INIT;
100
101 pspec = g_param_spec_uchar ("char", NULL, NULL,
102 20, 40, 30, G_PARAM_READWRITE);
103
104 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
105
106 g_value_init (&value, G_TYPE_UCHAR);
107
108 g_value_set_uchar (&value, 0);
109 g_assert_false (g_param_value_is_valid (pspec, &value));
110 g_assert_true (g_param_value_validate (pspec, &value));
111 g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
112
113 g_value_set_uchar (&value, 20);
114 g_assert_true (g_param_value_is_valid (pspec, &value));
115 g_assert_false (g_param_value_validate (pspec, &value));
116 g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
117
118 g_param_spec_unref (pspec);
119 }
120
121 static void
122 test_param_spec_int (void)
123 {
124 GParamSpec *pspec;
125 GValue value = G_VALUE_INIT;
126
127 pspec = g_param_spec_int ("int", NULL, NULL,
128 20, 40, 30, G_PARAM_READWRITE);
129
130 g_param_value_set_default (pspec, &value);
131 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT);
132 g_assert_cmpint (g_value_get_int (&value), ==, 30);
133 g_assert_true (g_param_value_defaults (pspec, &value));
134
135 g_value_set_int (&value, 0);
136 g_assert_false (g_param_value_is_valid (pspec, &value));
137 g_assert_true (g_param_value_validate (pspec, &value));
138 g_assert_cmpint (g_value_get_int (&value), ==, 20);
139
140 g_param_spec_unref (pspec);
141 }
142
143 static void
144 test_param_spec_uint (void)
145 {
146 GParamSpec *pspec;
147 GValue value = G_VALUE_INIT;
148
149 pspec = g_param_spec_uint ("uint", NULL, NULL,
150 20, 40, 30, G_PARAM_READWRITE);
151
152 g_param_value_set_default (pspec, &value);
153 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT);
154 g_assert_cmpint (g_value_get_uint (&value), ==, 30);
155 g_assert_true (g_param_value_defaults (pspec, &value));
156
157 g_value_set_uint (&value, 0);
158 g_assert_false (g_param_value_is_valid (pspec, &value));
159 g_assert_true (g_param_value_validate (pspec, &value));
160 g_assert_cmpint (g_value_get_uint (&value), ==, 20);
161
162 g_param_spec_unref (pspec);
163 }
164
165 static void
166 test_param_spec_long (void)
167 {
168 GParamSpec *pspec;
169 GValue value = G_VALUE_INIT;
170
171 pspec = g_param_spec_long ("long", NULL, NULL,
172 20, 40, 30, G_PARAM_READWRITE);
173
174 g_param_value_set_default (pspec, &value);
175 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_LONG);
176 g_assert_cmpint (g_value_get_long (&value), ==, 30);
177 g_assert_true (g_param_value_defaults (pspec, &value));
178
179 g_value_set_long (&value, 0);
180 g_assert_false (g_param_value_is_valid (pspec, &value));
181 g_assert_true (g_param_value_validate (pspec, &value));
182 g_assert_cmpint (g_value_get_long (&value), ==, 20);
183
184 g_param_spec_unref (pspec);
185 }
186
187 static void
188 test_param_spec_ulong (void)
189 {
190 GParamSpec *pspec;
191 GValue value = G_VALUE_INIT;
192
193 pspec = g_param_spec_ulong ("ulong", NULL, NULL,
194 20, 40, 30, G_PARAM_READWRITE);
195
196 g_param_value_set_default (pspec, &value);
197 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_ULONG);
198 g_assert_cmpint (g_value_get_ulong (&value), ==, 30);
199 g_assert_true (g_param_value_defaults (pspec, &value));
200
201 g_value_set_ulong (&value, 0);
202 g_assert_false (g_param_value_is_valid (pspec, &value));
203 g_assert_true (g_param_value_validate (pspec, &value));
204 g_assert_cmpint (g_value_get_ulong (&value), ==, 20);
205
206 g_param_spec_unref (pspec);
207 }
208
209 static void
210 test_param_spec_int64 (void)
211 {
212 GParamSpec *pspec;
213 GValue value = G_VALUE_INIT;
214
215 pspec = g_param_spec_int64 ("int64", NULL, NULL,
216 20, 40, 30, G_PARAM_READWRITE);
217
218 g_param_value_set_default (pspec, &value);
219 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT64);
220 g_assert_cmpint (g_value_get_int64 (&value), ==, 30);
221 g_assert_true (g_param_value_defaults (pspec, &value));
222
223 g_value_set_int64 (&value, 0);
224 g_assert_false (g_param_value_is_valid (pspec, &value));
225 g_assert_true (g_param_value_validate (pspec, &value));
226 g_assert_cmpint (g_value_get_int64 (&value), ==, 20);
227
228 g_param_spec_unref (pspec);
229 }
230
231 static void
232 test_param_spec_uint64 (void)
233 {
234 GParamSpec *pspec;
235 GValue value = G_VALUE_INIT;
236
237 pspec = g_param_spec_uint64 ("uint64", NULL, NULL,
238 20, 40, 30, G_PARAM_READWRITE);
239
240 g_param_value_set_default (pspec, &value);
241 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT64);
242 g_assert_cmpint (g_value_get_uint64 (&value), ==, 30);
243 g_assert_true (g_param_value_defaults (pspec, &value));
244
245 g_value_set_uint64 (&value, 0);
246 g_assert_false (g_param_value_is_valid (pspec, &value));
247 g_assert_true (g_param_value_validate (pspec, &value));
248 g_assert_cmpint (g_value_get_uint64 (&value), ==, 20);
249
250 g_param_spec_unref (pspec);
251 }
252
253 static void
254 test_param_spec_float (void)
255 {
256 GParamSpec *pspec;
257 GValue value = G_VALUE_INIT;
258
259 pspec = g_param_spec_float ("float", NULL, NULL,
260 20.0, 40.0, 30.0, G_PARAM_READWRITE);
261
262 g_param_value_set_default (pspec, &value);
263 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_FLOAT);
264 g_assert_cmpfloat (g_value_get_float (&value), ==, 30.0);
265 g_assert_true (g_param_value_defaults (pspec, &value));
266
267 g_value_set_float (&value, 0.0);
268 g_assert_false (g_param_value_is_valid (pspec, &value));
269 g_assert_true (g_param_value_validate (pspec, &value));
270 g_assert_cmpint (g_value_get_float (&value), ==, 20.0);
271
272 g_param_spec_unref (pspec);
273 }
274
275 static void
276 test_param_spec_double (void)
277 {
278 GParamSpec *pspec;
279 GValue value = G_VALUE_INIT;
280
281 pspec = g_param_spec_double ("double", NULL, NULL,
282 20.0, 40.0, 30.0, G_PARAM_READWRITE);
283
284 g_param_value_set_default (pspec, &value);
285 g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_DOUBLE);
286 g_assert_cmpfloat (g_value_get_double (&value), ==, 30.0);
287 g_assert_true (g_param_value_defaults (pspec, &value));
288
289 g_value_set_double (&value, 0.0);
290 g_assert_false (g_param_value_is_valid (pspec, &value));
291 g_assert_true (g_param_value_validate (pspec, &value));
292 g_assert_cmpint (g_value_get_double (&value), ==, 20.0);
293
294 g_param_spec_unref (pspec);
295 }
296
297 static void
298 test_param_spec_unichar (void)
299 {
300 GParamSpec *pspec;
301 GValue value = G_VALUE_INIT;
302
303 pspec = g_param_spec_unichar ("unichar", NULL, NULL,
304 0x1F4A9, G_PARAM_READWRITE);
305
306 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "unichar");
307
308 g_value_init (&value, G_TYPE_UINT);
309
310 /* Unicode codepoints can’t be 0x110000 or above, as that’s not representable
311 * in UTF-16. */
312 g_value_set_uint (&value, 0x110000);
313 g_assert_false (g_param_value_is_valid (pspec, &value));
314 g_assert_true (g_param_value_validate (pspec, &value));
315 g_assert_cmpint (g_value_get_uint (&value), ==, 0);
316
317 g_value_set_uint (&value, 0x20);
318 g_assert_true (g_param_value_is_valid (pspec, &value));
319 g_assert_false (g_param_value_validate (pspec, &value));
320 g_assert_cmpint (g_value_get_uint (&value), ==, 0x20);
321
322 g_param_spec_unref (pspec);
323 }
324
325 static void
326 test_param_spec_param (void)
327 {
328 GParamSpec *wrapped_pspec_uint;
329 GParamSpec *pspec;
330 GValue value = G_VALUE_INIT;
331
332 wrapped_pspec_uint = g_param_spec_uint ("uint", NULL, NULL,
333 0, G_MAXUINT, 5, G_PARAM_READWRITE);
334
335 pspec = g_param_spec_param ("param", NULL, NULL,
336 G_TYPE_PARAM_UINT, G_PARAM_READWRITE);
337
338 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
339
340 g_value_init (&value, G_TYPE_PARAM_UINT);
341
342 g_value_set_param (&value, wrapped_pspec_uint);
343 g_assert_true (g_param_value_is_valid (pspec, &value));
344 g_assert_false (g_param_value_validate (pspec, &value));
345 g_assert_true (g_value_get_param (&value) == wrapped_pspec_uint);
346
347 g_value_unset (&value);
348 g_param_spec_unref (pspec);
349 g_param_spec_unref (wrapped_pspec_uint);
350 }
351
352 static void
353 test_param_spec_null_param (void)
354 {
355 GParamSpec *pspec;
356 GValue value = G_VALUE_INIT;
357
358 pspec = g_param_spec_param ("param", NULL, NULL,
359 G_TYPE_PARAM_POINTER, G_PARAM_READWRITE);
360
361 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
362
363 g_value_init (&value, G_TYPE_PARAM_POINTER);
364 g_assert_false (g_param_value_is_valid (pspec, &value));
365 g_assert_false (g_param_value_validate (pspec, &value));
366
367 g_value_unset (&value);
368 g_param_spec_unref (pspec);
369 }
370
371 static void
372 test_param_spec_string (void)
373 {
374 GParamSpec *pspec;
375 GValue value = G_VALUE_INIT;
376
377 pspec = g_param_spec_string ("string", "nick", "blurb",
378 NULL, G_PARAM_READWRITE);
379 g_value_init (&value, G_TYPE_STRING);
380
381 g_value_set_string (&value, "foobar");
382 g_assert_true (g_param_value_is_valid (pspec, &value));
383 g_assert_false (g_param_value_validate (pspec, &value));
384
385 g_value_set_string (&value, "");
386 g_assert_true (g_param_value_is_valid (pspec, &value));
387 g_assert_false (g_param_value_validate (pspec, &value));
388 g_assert_nonnull (g_value_get_string (&value));
389
390 /* test ensure_non_null */
391
392 G_PARAM_SPEC_STRING (pspec)->ensure_non_null = TRUE;
393
394 g_value_set_string (&value, NULL);
395 g_assert_false (g_param_value_is_valid (pspec, &value));
396 g_assert_true (g_param_value_validate (pspec, &value));
397 g_assert_nonnull (g_value_get_string (&value));
398
399 G_PARAM_SPEC_STRING (pspec)->ensure_non_null = FALSE;
400
401 /* test null_fold_if_empty */
402
403 G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = TRUE;
404
405 g_value_set_string (&value, "");
406 g_assert_false (g_param_value_is_valid (pspec, &value));
407 g_assert_true (g_param_value_validate (pspec, &value));
408 g_assert_null (g_value_get_string (&value));
409
410 g_value_set_static_string (&value, "");
411 g_assert_false (g_param_value_is_valid (pspec, &value));
412 g_assert_true (g_param_value_validate (pspec, &value));
413 g_assert_null (g_value_get_string (&value));
414
415 G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = FALSE;
416
417 /* test cset_first */
418
419 G_PARAM_SPEC_STRING (pspec)->cset_first = g_strdup ("abc");
420 G_PARAM_SPEC_STRING (pspec)->substitutor = '-';
421
422 g_value_set_string (&value, "ABC");
423 g_assert_false (g_param_value_is_valid (pspec, &value));
424 g_assert_true (g_param_value_validate (pspec, &value));
425 g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
426
427 g_value_set_static_string (&value, "ABC");
428 g_assert_false (g_param_value_is_valid (pspec, &value));
429 g_assert_true (g_param_value_validate (pspec, &value));
430 g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
431
432 /* test cset_nth */
433
434 G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc");
435
436 g_value_set_string (&value, "aBC");
437 g_assert_false (g_param_value_is_valid (pspec, &value));
438 g_assert_true (g_param_value_validate (pspec, &value));
439 g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
440
441 g_value_set_static_string (&value, "aBC");
442 g_assert_false (g_param_value_is_valid (pspec, &value));
443 g_assert_true (g_param_value_validate (pspec, &value));
444 g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
445
446 g_value_unset (&value);
447 g_param_spec_unref (pspec);
448 }
449
450 static void
451 test_param_spec_override (void)
452 {
453 GParamSpec *ospec, *pspec;
454 GValue value = G_VALUE_INIT;
455
456 ospec = g_param_spec_char ("char", "nick", "blurb",
457 20, 40, 30, G_PARAM_READWRITE);
458
459 pspec = g_param_spec_override ("override", ospec);
460
461 g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "override");
462 g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
463 g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
464
465 g_value_init (&value, G_TYPE_CHAR);
466 g_value_set_char (&value, 30);
467
468 g_assert_true (g_param_value_defaults (pspec, &value));
469
470 g_value_set_char (&value, 0);
471 g_assert_false (g_param_value_is_valid (pspec, &value));
472 g_assert_true (g_param_value_validate (pspec, &value));
473 g_assert_cmpint (g_value_get_char (&value), ==, 20);
474
475 g_value_set_char (&value, 20);
476 g_assert_true (g_param_value_is_valid (pspec, &value));
477 g_assert_false (g_param_value_validate (pspec, &value));
478 g_assert_cmpint (g_value_get_char (&value), ==, 20);
479
480 g_value_set_char (&value, 40);
481 g_assert_true (g_param_value_is_valid (pspec, &value));
482 g_assert_false (g_param_value_validate (pspec, &value));
483 g_assert_cmpint (g_value_get_char (&value), ==, 40);
484
485 g_value_set_char (&value, 60);
486 g_assert_false (g_param_value_is_valid (pspec, &value));
487 g_assert_true (g_param_value_validate (pspec, &value));
488 g_assert_cmpint (g_value_get_char (&value), ==, 40);
489
490 g_param_spec_unref (pspec);
491 g_param_spec_unref (ospec);
492 }
493
494 static void
495 test_param_spec_gtype (void)
496 {
497 GParamSpec *pspec;
498 GValue value = G_VALUE_INIT;
499
500 pspec = g_param_spec_gtype ("gtype", "nick", "blurb",
501 G_TYPE_PARAM, G_PARAM_READWRITE);
502
503 g_value_init (&value, G_TYPE_GTYPE);
504 g_value_set_gtype (&value, G_TYPE_PARAM);
505
506 g_assert_true (g_param_value_defaults (pspec, &value));
507
508 g_value_set_gtype (&value, G_TYPE_INT);
509 g_assert_false (g_param_value_is_valid (pspec, &value));
510 g_assert_true (g_param_value_validate (pspec, &value));
511 g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM);
512
513 g_value_set_gtype (&value, G_TYPE_PARAM_INT);
514 g_assert_true (g_param_value_is_valid (pspec, &value));
515 g_assert_false (g_param_value_validate (pspec, &value));
516 g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM_INT);
517
518 g_param_spec_unref (pspec);
519 }
520
521 static void
522 test_param_spec_variant (void)
523 {
524 GParamSpec *pspec;
525 GValue value = G_VALUE_INIT;
526 GValue value2 = G_VALUE_INIT;
527 GValue value3 = G_VALUE_INIT;
528 GValue value4 = G_VALUE_INIT;
529 GValue value5 = G_VALUE_INIT;
530
531 pspec = g_param_spec_variant ("variant", "nick", "blurb",
532 G_VARIANT_TYPE ("i"),
533 g_variant_new_int32 (42),
534 G_PARAM_READWRITE);
535
536 g_value_init (&value, G_TYPE_VARIANT);
537 g_value_set_variant (&value, g_variant_new_int32 (42));
538
539 g_value_init (&value2, G_TYPE_VARIANT);
540 g_value_set_variant (&value2, g_variant_new_int32 (43));
541
542 g_value_init (&value3, G_TYPE_VARIANT);
543 g_value_set_variant (&value3, g_variant_new_int16 (42));
544
545 g_value_init (&value4, G_TYPE_VARIANT);
546 g_value_set_variant (&value4, g_variant_new_parsed ("[@u 15, @u 10]"));
547
548 g_value_init (&value5, G_TYPE_VARIANT);
549 g_value_set_variant (&value5, NULL);
550
551 g_assert_true (g_param_value_defaults (pspec, &value));
552 g_assert_false (g_param_value_defaults (pspec, &value2));
553 g_assert_false (g_param_value_defaults (pspec, &value3));
554 g_assert_false (g_param_value_defaults (pspec, &value4));
555 g_assert_false (g_param_value_defaults (pspec, &value5));
556
557 g_assert_true (g_param_value_is_valid (pspec, &value));
558 g_assert_false (g_param_value_validate (pspec, &value));
559
560 g_value_reset (&value);
561 g_value_set_variant (&value, g_variant_new_uint32 (41));
562 g_assert_false (g_param_value_is_valid (pspec, &value));
563 g_assert_true (g_param_value_validate (pspec, &value));
564 g_assert_true (g_param_value_is_valid (pspec, &value));
565 g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42);
566 g_value_unset (&value);
567
568 g_value_unset (&value5);
569 g_value_unset (&value4);
570 g_value_unset (&value3);
571 g_value_unset (&value2);
572
573 g_param_spec_unref (pspec);
574 }
575
576 /* Test g_param_values_cmp() for #GParamSpecVariant. */
577 static void
578 test_param_spec_variant_cmp (void)
579 {
580 const struct
581 {
582 const GVariantType *pspec_type;
583 const gchar *v1;
584 enum
585 {
586 LESS_THAN = -1,
587 EQUAL = 0,
588 GREATER_THAN = 1,
589 NOT_EQUAL,
590 } expected_result;
591 const gchar *v2;
592 }
593 vectors[] =
594 {
595 { G_VARIANT_TYPE ("i"), "@i 1", LESS_THAN, "@i 2" },
596 { G_VARIANT_TYPE ("i"), "@i 2", EQUAL, "@i 2" },
597 { G_VARIANT_TYPE ("i"), "@i 3", GREATER_THAN, "@i 2" },
598 { G_VARIANT_TYPE ("i"), NULL, LESS_THAN, "@i 2" },
599 { G_VARIANT_TYPE ("i"), NULL, EQUAL, NULL },
600 { G_VARIANT_TYPE ("i"), "@i 1", GREATER_THAN, NULL },
601 { G_VARIANT_TYPE ("i"), "@u 1", LESS_THAN, "@u 2" },
602 { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@u 2" },
603 { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@as ['there']" },
604 { G_VARIANT_TYPE ("i"), "@as ['hi']", EQUAL, "@as ['hi']" },
605 };
606 gsize i;
607
608 for (i = 0; i < G_N_ELEMENTS (vectors); i++)
609 {
610 GParamSpec *pspec;
611 GValue v1 = G_VALUE_INIT;
612 GValue v2 = G_VALUE_INIT;
613 gint cmp;
614
615 pspec = g_param_spec_variant ("variant", "nick", "blurb",
616 vectors[i].pspec_type,
617 NULL,
618 G_PARAM_READWRITE);
619
620 g_value_init (&v1, G_TYPE_VARIANT);
621 g_value_set_variant (&v1,
622 (vectors[i].v1 != NULL) ?
623 g_variant_new_parsed (vectors[i].v1) : NULL);
624
625 g_value_init (&v2, G_TYPE_VARIANT);
626 g_value_set_variant (&v2,
627 (vectors[i].v2 != NULL) ?
628 g_variant_new_parsed (vectors[i].v2) : NULL);
629
630 cmp = g_param_values_cmp (pspec, &v1, &v2);
631
632 switch (vectors[i].expected_result)
633 {
634 case LESS_THAN:
635 case EQUAL:
636 case GREATER_THAN:
637 g_assert_cmpint (cmp, ==, vectors[i].expected_result);
638 break;
639 case NOT_EQUAL:
640 g_assert_cmpint (cmp, !=, 0);
641 break;
642 default:
643 g_assert_not_reached ();
644 }
645
646 g_value_unset (&v2);
647 g_value_unset (&v1);
648 g_param_spec_unref (pspec);
649 }
650 }
651
652 static void
653 test_param_value (void)
654 {
655 GParamSpec *p, *p2;
656 GParamSpec *pp;
657 GValue value = G_VALUE_INIT;
658
659 g_value_init (&value, G_TYPE_PARAM);
660 g_assert_true (G_VALUE_HOLDS_PARAM (&value));
661
662 p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
663
664 g_value_take_param (&value, p);
665 p2 = g_value_get_param (&value);
666 g_assert_true (p2 == p);
667
668 pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE);
669 g_value_set_param (&value, pp);
670
671 p2 = g_value_dup_param (&value);
672 g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */
673 g_param_spec_unref (p2);
674
675 g_value_unset (&value);
676 g_param_spec_unref (pp);
677 }
678
679 static gint destroy_count;
680
681 static void
682 my_destroy (gpointer data)
683 {
684 destroy_count++;
685 }
686
687 static void
688 test_param_qdata (void)
689 {
690 GParamSpec *p;
691 gchar *bla;
692 GQuark q;
693
694 q = g_quark_from_string ("bla");
695
696 p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
697 g_param_spec_set_qdata (p, q, "bla");
698 bla = g_param_spec_get_qdata (p, q);
699 g_assert_cmpstr (bla, ==, "bla");
700
701 g_assert_cmpint (destroy_count, ==, 0);
702 g_param_spec_set_qdata_full (p, q, "bla", my_destroy);
703 g_param_spec_set_qdata_full (p, q, "blabla", my_destroy);
704 g_assert_cmpint (destroy_count, ==, 1);
705 g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla");
706 g_assert_cmpint (destroy_count, ==, 1);
707 g_assert_null (g_param_spec_get_qdata (p, q));
708
709 g_param_spec_ref_sink (p);
710
711 g_param_spec_unref (p);
712 }
713
714 static void
715 test_param_validate (void)
716 {
717 GParamSpec *p;
718 GValue value = G_VALUE_INIT;
719
720 p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
721
722 g_value_init (&value, G_TYPE_INT);
723 g_value_set_int (&value, 100);
724 g_assert_false (g_param_value_defaults (p, &value));
725 g_assert_true (g_param_value_validate (p, &value));
726 g_assert_cmpint (g_value_get_int (&value), ==, 20);
727
728 g_param_value_set_default (p, &value);
729 g_assert_true (g_param_value_defaults (p, &value));
730 g_assert_cmpint (g_value_get_int (&value), ==, 10);
731
732 g_param_spec_unref (p);
733 }
734
735 static void
736 test_param_strings (void)
737 {
738 GParamSpec *p;
739
740 /* test canonicalization */
741 p = g_param_spec_int ("my_int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
742
743 g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
744 g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int");
745 g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb");
746
747 g_param_spec_unref (p);
748
749 /* test nick defaults to name */
750 p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE);
751
752 g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
753 g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int");
754 g_assert_null (g_param_spec_get_blurb (p));
755
756 g_param_spec_unref (p);
757 }
758
759 static void
760 test_param_invalid_name (gconstpointer test_data)
761 {
762 const gchar *invalid_name = test_data;
763
764 g_test_summary ("Test that properties cannot be created with invalid names");
765
766 if (g_test_subprocess ())
767 {
768 GParamSpec *p;
769 p = g_param_spec_int (invalid_name, "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
770 g_param_spec_unref (p);
771 return;
772 }
773
774 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
775 g_test_trap_assert_failed ();
776 g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*");
777 }
778
779 static void
780 test_param_convert (void)
781 {
782 GParamSpec *p;
783 GValue v1 = G_VALUE_INIT;
784 GValue v2 = G_VALUE_INIT;
785
786 p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
787 g_value_init (&v1, G_TYPE_UINT);
788 g_value_set_uint (&v1, 43);
789
790 g_value_init (&v2, G_TYPE_INT);
791 g_value_set_int (&v2, -4);
792
793 g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE));
794 g_assert_cmpint (g_value_get_int (&v2), ==, -4);
795
796 g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE));
797 g_assert_cmpint (g_value_get_int (&v2), ==, 20);
798
799 g_param_spec_unref (p);
800 }
801
802 static void
803 test_value_transform (void)
804 {
805 GValue src = G_VALUE_INIT;
806 GValue dest = G_VALUE_INIT;
807
808 #define CHECK_INT_CONVERSION(type, getter, value) \
809 g_assert_true (g_value_type_transformable (G_TYPE_INT, type)); \
810 g_value_init (&src, G_TYPE_INT); \
811 g_value_init (&dest, type); \
812 g_value_set_int (&src, value); \
813 g_assert_true (g_value_transform (&src, &dest)); \
814 g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
815 g_value_unset (&src); \
816 g_value_unset (&dest);
817
818 /* Keep a check for an integer in the range of 0-127 so we're
819 * still testing g_value_get_char(). See
820 * https://bugzilla.gnome.org/show_bug.cgi?id=659870
821 * for why it is broken.
822 */
823 CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124)
824
825 CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124)
826 CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124)
827 CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
828 CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
829 CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345)
830 CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345)
831 CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0)
832 CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345)
833 CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678)
834 CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
835 CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678)
836 CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
837 CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
838 CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
839
840 #define CHECK_UINT_CONVERSION(type, getter, value) \
841 g_assert_true (g_value_type_transformable (G_TYPE_UINT, type)); \
842 g_value_init (&src, G_TYPE_UINT); \
843 g_value_init (&dest, type); \
844 g_value_set_uint (&src, value); \
845 g_assert_true (g_value_transform (&src, &dest)); \
846 g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
847 g_value_unset (&src); \
848 g_value_unset (&dest);
849
850 CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
851 CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
852 CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
853 CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
854 CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
855 CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
856 CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 0)
857 CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 12345)
858 CHECK_UINT_CONVERSION(G_TYPE_LONG, long, 12345678)
859 CHECK_UINT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
860 CHECK_UINT_CONVERSION(G_TYPE_INT64, int64, 12345678)
861 CHECK_UINT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
862 CHECK_UINT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
863 CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
864
865 #define CHECK_LONG_CONVERSION(type, getter, value) \
866 g_assert_true (g_value_type_transformable (G_TYPE_LONG, type)); \
867 g_value_init (&src, G_TYPE_LONG); \
868 g_value_init (&dest, type); \
869 g_value_set_long (&src, value); \
870 g_assert_true (g_value_transform (&src, &dest)); \
871 g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
872 g_value_unset (&src); \
873 g_value_unset (&dest);
874
875 CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124)
876 CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124)
877 CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
878 CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
879 CHECK_LONG_CONVERSION(G_TYPE_INT, int, -12345)
880 CHECK_LONG_CONVERSION(G_TYPE_INT, int, 12345)
881 CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 0)
882 CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 12345)
883 CHECK_LONG_CONVERSION(G_TYPE_LONG, long, -12345678)
884 CHECK_LONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
885 CHECK_LONG_CONVERSION(G_TYPE_INT64, int64, -12345678)
886 CHECK_LONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
887 CHECK_LONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
888 CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
889
890 #define CHECK_ULONG_CONVERSION(type, getter, value) \
891 g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type)); \
892 g_value_init (&src, G_TYPE_ULONG); \
893 g_value_init (&dest, type); \
894 g_value_set_ulong (&src, value); \
895 g_assert_true (g_value_transform (&src, &dest)); \
896 g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
897 g_value_unset (&src); \
898 g_value_unset (&dest);
899
900 CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
901 CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
902 CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
903 CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
904 CHECK_ULONG_CONVERSION(G_TYPE_INT, int, -12345)
905 CHECK_ULONG_CONVERSION(G_TYPE_INT, int, 12345)
906 CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 0)
907 CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 12345)
908 CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678)
909 CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
910 CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678)
911 CHECK_ULONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
912 CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
913 CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
914
915 #define CHECK_INT64_CONVERSION(type, getter, value) \
916 g_assert_true (g_value_type_transformable (G_TYPE_INT64, type)); \
917 g_value_init (&src, G_TYPE_INT64); \
918 g_value_init (&dest, type); \
919 g_value_set_int64 (&src, value); \
920 g_assert_true (g_value_transform (&src, &dest)); \
921 g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
922 g_value_unset (&src); \
923 g_value_unset (&dest);
924
925 CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124)
926 CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124)
927 CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
928 CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
929 CHECK_INT64_CONVERSION(G_TYPE_INT, int, -12345)
930 CHECK_INT64_CONVERSION(G_TYPE_INT, int, 12345)
931 CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 0)
932 CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 12345)
933 CHECK_INT64_CONVERSION(G_TYPE_LONG, long, -12345678)
934 CHECK_INT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
935 CHECK_INT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
936 CHECK_INT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
937 CHECK_INT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
938 CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
939
940 #define CHECK_UINT64_CONVERSION(type, getter, value) \
941 g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type)); \
942 g_value_init (&src, G_TYPE_UINT64); \
943 g_value_init (&dest, type); \
944 g_value_set_uint64 (&src, value); \
945 g_assert_true (g_value_transform (&src, &dest)); \
946 g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
947 g_value_unset (&src); \
948 g_value_unset (&dest);
949
950 CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124)
951 CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124)
952 CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
953 CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
954 CHECK_UINT64_CONVERSION(G_TYPE_INT, int, -12345)
955 CHECK_UINT64_CONVERSION(G_TYPE_INT, int, 12345)
956 CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 0)
957 CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 12345)
958 CHECK_UINT64_CONVERSION(G_TYPE_LONG, long, -12345678)
959 CHECK_UINT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
960 CHECK_UINT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
961 CHECK_UINT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
962 CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
963 CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
964
965 #define CHECK_FLOAT_CONVERSION(type, getter, value) \
966 g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type)); \
967 g_value_init (&src, G_TYPE_FLOAT); \
968 g_value_init (&dest, type); \
969 g_value_set_float (&src, value); \
970 g_assert_true (g_value_transform (&src, &dest)); \
971 g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \
972 g_value_unset (&src); \
973 g_value_unset (&dest);
974
975 CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124)
976 CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124)
977 CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
978 CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
979 CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, -12345)
980 CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, 12345)
981 CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 0)
982 CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 12345)
983 CHECK_FLOAT_CONVERSION(G_TYPE_LONG, long, -12345678)
984 CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
985 CHECK_FLOAT_CONVERSION(G_TYPE_INT64, int64, -12345678)
986 CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
987 CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
988 CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
989
990 #define CHECK_DOUBLE_CONVERSION(type, getter, value) \
991 g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type)); \
992 g_value_init (&src, G_TYPE_DOUBLE); \
993 g_value_init (&dest, type); \
994 g_value_set_double (&src, value); \
995 g_assert_true (g_value_transform (&src, &dest)); \
996 g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \
997 g_value_unset (&src); \
998 g_value_unset (&dest);
999
1000 CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124)
1001 CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124)
1002 CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 0)
1003 CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 255)
1004 CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, -12345)
1005 CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, 12345)
1006 CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 0)
1007 CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 12345)
1008 CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, long, -12345678)
1009 CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
1010 CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, int64, -12345678)
1011 CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
1012 CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, float, 12345678)
1013 CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
1014
1015 #define CHECK_BOOLEAN_CONVERSION(type, setter, value) \
1016 g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN)); \
1017 g_value_init (&src, type); \
1018 g_value_init (&dest, G_TYPE_BOOLEAN); \
1019 g_value_set_##setter (&src, value); \
1020 g_assert_true (g_value_transform (&src, &dest)); \
1021 g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE); \
1022 g_value_set_##setter (&src, 0); \
1023 g_assert_true (g_value_transform (&src, &dest)); \
1024 g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE); \
1025 g_value_unset (&src); \
1026 g_value_unset (&dest);
1027
1028 CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345)
1029 CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345)
1030 CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678)
1031 CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
1032 CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678)
1033 CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
1034
1035 #define CHECK_STRING_CONVERSION(int_type, setter, int_value) \
1036 g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \
1037 g_value_init (&src, int_type); \
1038 g_value_init (&dest, G_TYPE_STRING); \
1039 g_value_set_##setter (&src, int_value); \
1040 g_assert_true (g_value_transform (&src, &dest)); \
1041 g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value); \
1042 g_value_unset (&src); \
1043 g_value_unset (&dest);
1044
1045 CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345)
1046 CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345)
1047 CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678)
1048 CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
1049 CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678)
1050 CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
1051 CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000)
1052 CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567)
1053
1054 g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR));
1055 g_value_init (&src, G_TYPE_STRING);
1056 g_value_init (&dest, G_TYPE_CHAR);
1057 g_value_set_static_string (&src, "bla");
1058 g_value_set_schar (&dest, 'c');
1059 g_assert_false (g_value_transform (&src, &dest));
1060 g_assert_cmpint (g_value_get_schar (&dest), ==, 'c');
1061 g_value_unset (&src);
1062 g_value_unset (&dest);
1063 }
1064
1065
1066 /* We create some dummy objects with a simple relationship:
1067 *
1068 * GObject
1069 * / \
1070 * TestObjectA TestObjectC
1071 * |
1072 * TestObjectB
1073 *
1074 * ie: TestObjectB is a subclass of TestObjectA and TestObjectC is
1075 * related to neither.
1076 */
1077
1078 static GType test_object_a_get_type (void);
1079 typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
1080 G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
1081 static void test_object_a_class_init (TestObjectAClass *class) { }
1082 static void test_object_a_init (TestObjectA *a) { }
1083
1084 static GType test_object_b_get_type (void);
1085 typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
1086 G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ())
1087 static void test_object_b_class_init (TestObjectBClass *class) { }
1088 static void test_object_b_init (TestObjectB *b) { }
1089
1090 static GType test_object_c_get_type (void);
1091 typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass;
1092 G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT)
1093 static void test_object_c_class_init (TestObjectCClass *class) { }
1094 static void test_object_c_init (TestObjectC *c) { }
1095
1096 /* We create an interface and programmatically populate it with
1097 * properties of each of the above type, with various flag combinations.
1098 *
1099 * Properties are named like "type-perm" where type is 'a', 'b' or 'c'
1100 * and perm is a series of characters, indicating the permissions:
1101 *
1102 * - 'r': readable
1103 * - 'w': writable
1104 * - 'c': construct
1105 * - 'C': construct-only
1106 *
1107 * It doesn't make sense to have a property that is neither readable nor
1108 * writable. It is also not valid to have construct or construct-only
1109 * on read-only params. Finally, it is invalid to have both construct
1110 * and construct-only specified, so we do not consider those cases.
1111 * That gives us 7 possible permissions:
1112 *
1113 * 'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC'
1114 *
1115 * And 9 impossible ones:
1116 *
1117 * '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC'
1118 *
1119 * For a total of 16 combinations.
1120 *
1121 * That gives a total of 48 (16 * 3) possible flag/type combinations, of
1122 * which 27 (9 * 3) are impossible to install.
1123 *
1124 * That gives 21 (7 * 3) properties that will be installed.
1125 */
1126 typedef GTypeInterface TestInterfaceInterface;
1127 static GType test_interface_get_type (void);
1128 //typedef struct _TestInterface TestInterface;
1129 G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
1130 static void
1131 test_interface_default_init (TestInterfaceInterface *iface)
1132 {
1133 const gchar *names[] = { "a", "b", "c" };
1134 const gchar *perms[] = { NULL, "r", "w", "rw",
1135 NULL, NULL, "wc", "rwc",
1136 NULL, NULL, "wC", "rwC",
1137 NULL, NULL, NULL, NULL };
1138 const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () };
1139 guint i, j;
1140
1141 for (i = 0; i < G_N_ELEMENTS (types); i++)
1142 for (j = 0; j < G_N_ELEMENTS (perms); j++)
1143 {
1144 gchar prop_name[10];
1145 GParamSpec *pspec;
1146
1147 if (perms[j] == NULL)
1148 {
1149 if (!g_test_undefined ())
1150 continue;
1151
1152 /* we think that this is impossible. make sure. */
1153 pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
1154
1155 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1156 "*assertion*pspec->flags*failed*");
1157 g_object_interface_install_property (iface, pspec);
1158 g_test_assert_expected_messages ();
1159
1160 g_param_spec_unref (pspec);
1161 continue;
1162 }
1163
1164 /* install the property */
1165 g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
1166 pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[i], j);
1167 g_object_interface_install_property (iface, pspec);
1168 }
1169 }
1170
1171 /* We now have 21 properties. Each property may be correctly
1172 * implemented with the following types:
1173 *
1174 * Properties Valid Types Reason
1175 *
1176 * a-r a, b Read only can provide subclasses
1177 * a-w, wc, wC a, GObject Write only can accept superclasses
1178 * a-rw, rwc, rwC a Read-write must be exactly equal
1179 *
1180 * b-r b (as above)
1181 * b-w, wc, wC b, a, GObject
1182 * b-rw, rwc, rwC b
1183 *
1184 * c-r c (as above)
1185 * c-wo, wc, wC c, GObject
1186 * c-rw, rwc, rwC c
1187 *
1188 * We can express this in a 48-by-4 table where each row represents an
1189 * installed property and each column represents a type. The value in
1190 * the table represents if it is valid to subclass the row's property
1191 * with the type of the column:
1192 *
1193 * - 0: invalid because the interface property doesn't exist (invalid flags)
1194 * - 'v': valid
1195 * - '=': invalid because of the type not being exactly equal
1196 * - '<': invalid because of the type not being a subclass
1197 * - '>': invalid because of the type not being a superclass
1198 *
1199 * We organise the table by interface property type ('a', 'b', 'c') then
1200 * by interface property flags.
1201 */
1202
1203 static gint valid_impl_types[48][4] = {
1204 /* a b c GObject */
1205 /* 'a-' */ { 0, },
1206 /* 'a-r' */ { 'v', 'v', '<', '<' },
1207 /* 'a-w' */ { 'v', '>', '>', 'v' },
1208 /* 'a-rw' */ { 'v', '=', '=', '=' },
1209 /* 'a-c */ { 0, },
1210 /* 'a-rc' */ { 0, },
1211 /* 'a-wc' */ { 'v', '>', '>', 'v' },
1212 /* 'a-rwc' */ { 'v', '=', '=', '=' },
1213 /* 'a-C */ { 0, },
1214 /* 'a-rC' */ { 0, },
1215 /* 'a-wC' */ { 'v', '>', '>', 'v' },
1216 /* 'a-rwC' */ { 'v', '=', '=', '=' },
1217 /* 'a-cC */ { 0, },
1218 /* 'a-rcC' */ { 0, },
1219 /* 'a-wcC' */ { 0, },
1220 /* 'a-rwcC' */ { 0, },
1221
1222 /* 'b-' */ { 0, },
1223 /* 'b-r' */ { '<', 'v', '<', '<' },
1224 /* 'b-w' */ { 'v', 'v', '>', 'v' },
1225 /* 'b-rw' */ { '=', 'v', '=', '=' },
1226 /* 'b-c */ { 0, },
1227 /* 'b-rc' */ { 0, },
1228 /* 'b-wc' */ { 'v', 'v', '>', 'v' },
1229 /* 'b-rwc' */ { '=', 'v', '=', '=' },
1230 /* 'b-C */ { 0, },
1231 /* 'b-rC' */ { 0, },
1232 /* 'b-wC' */ { 'v', 'v', '>', 'v' },
1233 /* 'b-rwC' */ { '=', 'v', '=', '=' },
1234 /* 'b-cC */ { 0, },
1235 /* 'b-rcC' */ { 0, },
1236 /* 'b-wcC' */ { 0, },
1237 /* 'b-rwcC' */ { 0, },
1238
1239 /* 'c-' */ { 0, },
1240 /* 'c-r' */ { '<', '<', 'v', '<' },
1241 /* 'c-w' */ { '>', '>', 'v', 'v' },
1242 /* 'c-rw' */ { '=', '=', 'v', '=' },
1243 /* 'c-c */ { 0, },
1244 /* 'c-rc' */ { 0, },
1245 /* 'c-wc' */ { '>', '>', 'v', 'v' },
1246 /* 'c-rwc' */ { '=', '=', 'v', '=' },
1247 /* 'c-C */ { 0, },
1248 /* 'c-rC' */ { 0, },
1249 /* 'c-wC' */ { '>', '>', 'v', 'v' },
1250 /* 'c-rwC' */ { '=', '=', 'v', '=' },
1251 /* 'c-cC */ { 0, },
1252 /* 'c-rcC' */ { 0, },
1253 /* 'c-wcC' */ { 0, },
1254 /* 'c-rwcC' */ { 0, }
1255 };
1256
1257 /* We also try to change the flags. We must ensure that all
1258 * implementations provide all functionality promised by the interface.
1259 * We must therefore never remove readability or writability (but we can
1260 * add them). Construct-only is a restrictions that applies to
1261 * writability, so we can never add it unless writability was never
1262 * present in the first place, in which case "writable at construct
1263 * only" is still better than "not writable".
1264 *
1265 * The 'construct' flag is of interest only to the implementation. It
1266 * may be changed at any time.
1267 *
1268 * Properties Valid Access Reason
1269 *
1270 * *-r r, rw, rwc, rwC Must keep readable, but can restrict newly-added writable
1271 * *-w w, rw, rwc Must keep writable unrestricted
1272 * *-rw rw, rwc Must not add any restrictions
1273 * *-rwc rw, rwc Must not add any restrictions
1274 * *-rwC rw, rwc, rwC Can remove 'construct-only' restriction
1275 * *-wc rwc, rw, w, wc Can add readability
1276 * *-wC rwC, rw, w, wC Can add readability or remove 'construct only' restriction
1277 * rwc, wc
1278 *
1279 * We can represent this with a 16-by-16 table. The rows represent the
1280 * flags of the property on the interface. The columns is the flags to
1281 * try to use when overriding the property. The cell contents are:
1282 *
1283 * - 0: invalid because the interface property doesn't exist (invalid flags)
1284 * - 'v': valid
1285 * - 'i': invalid because the implementation flags are invalid
1286 * - 'f': invalid because of the removal of functionality
1287 * - 'r': invalid because of the addition of restrictions (ie: construct-only)
1288 *
1289 * We also ensure that removal of functionality is reported before
1290 * addition of restrictions, since this is a more basic problem.
1291 */
1292 static gint valid_impl_flags[16][16] = {
1293 /* '' r w rw c rc wc rwc C rC wC rwC cC rcC wcC rwcC */
1294 /* '*-' */ { 0, },
1295 /* '*-r' */ { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
1296 /* '*-w' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
1297 /* '*-rw' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
1298 /* '*-c */ { 0, },
1299 /* '*-rc' */ { 0, },
1300 /* '*-wc' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
1301 /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
1302 /* '*-C */ { 0, },
1303 /* '*-rC' */ { 0, },
1304 /* '*-wC' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
1305 /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
1306 };
1307
1308 static guint change_this_flag;
1309 static guint change_this_type;
1310 static guint use_this_flag;
1311 static guint use_this_type;
1312
1313 typedef GObjectClass TestImplementationClass;
1314 typedef GObject TestImplementation;
1315
1316 static void test_implementation_init (TestImplementation *impl) { }
1317 static void test_implementation_iface_init (TestInterfaceInterface *iface) { }
1318
1319 static GType test_implementation_get_type (void);
1320 G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT,
1321 G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init))
1322
1323 static void test_implementation_class_init (TestImplementationClass *class)
1324 {
1325 const gchar *names[] = { "a", "b", "c" };
1326 const gchar *perms[] = { NULL, "r", "w", "rw",
1327 NULL, NULL, "wc", "rwc",
1328 NULL, NULL, "wC", "rwC",
1329 NULL, NULL, NULL, NULL };
1330 const GType types[] = { test_object_a_get_type (), test_object_b_get_type (),
1331 test_object_c_get_type (), G_TYPE_OBJECT };
1332 gchar prop_name[10];
1333 GParamSpec *pspec;
1334 guint i, j;
1335
1336 class->get_property = GINT_TO_POINTER (1);
1337 class->set_property = GINT_TO_POINTER (1);
1338
1339 /* Install all of the non-modified properties or else GObject will
1340 * complain about non-implemented properties.
1341 */
1342 for (i = 0; i < 3; i++)
1343 for (j = 0; j < G_N_ELEMENTS (perms); j++)
1344 {
1345 if (i == change_this_type && j == change_this_flag)
1346 continue;
1347
1348 if (perms[j] != NULL)
1349 {
1350 /* override the property without making changes */
1351 g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
1352 g_object_class_override_property (class, 1, prop_name);
1353 }
1354 }
1355
1356 /* Now try installing our modified property */
1357 if (perms[change_this_flag] == NULL)
1358 g_error ("Interface property does not exist");
1359
1360 g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]);
1361 pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag);
1362 g_object_class_install_property (class, 1, pspec);
1363 }
1364
1365 typedef struct {
1366 gint change_this_flag;
1367 gint change_this_type;
1368 gint use_this_flag;
1369 gint use_this_type;
1370 } TestParamImplementData;
1371
1372 static void
1373 test_param_implement_child (gconstpointer user_data)
1374 {
1375 TestParamImplementData *data = (gpointer) user_data;
1376
1377 /* GObject oddity: GObjectClass must be initialised before we can
1378 * initialise a GTypeInterface.
1379 */
1380 g_type_class_ref (G_TYPE_OBJECT);
1381
1382 /* Bring up the interface first. */
1383 g_type_default_interface_ref (test_interface_get_type ());
1384
1385 /* Copy the flags into the global vars so
1386 * test_implementation_class_init() will see them.
1387 */
1388 change_this_flag = data->change_this_flag;
1389 change_this_type = data->change_this_type;
1390 use_this_flag = data->use_this_flag;
1391 use_this_type = data->use_this_type;
1392
1393 g_type_class_ref (test_implementation_get_type ());
1394 }
1395
1396 static void
1397 test_param_implement (void)
1398 {
1399 gchar *test_path;
1400
1401 for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
1402 for (change_this_type = 0; change_this_type < 3; change_this_type++)
1403 for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
1404 for (use_this_type = 0; use_this_type < 4; use_this_type++)
1405 {
1406 if (!g_test_undefined ())
1407 {
1408 /* only test the valid (defined) cases, e.g. under valgrind */
1409 if (valid_impl_flags[change_this_flag][use_this_flag] != 'v')
1410 continue;
1411
1412 if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v')
1413 continue;
1414 }
1415
1416 test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
1417 change_this_flag, change_this_type,
1418 use_this_flag, use_this_type);
1419 g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND,
1420 G_TEST_SUBPROCESS_DEFAULT);
1421 g_free (test_path);
1422
1423 /* We want to ensure that any flags mismatch problems are reported first. */
1424 switch (valid_impl_flags[change_this_flag][use_this_flag])
1425 {
1426 case 0:
1427 /* make sure the other table agrees */
1428 g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0);
1429 g_test_trap_assert_failed ();
1430 g_test_trap_assert_stderr ("*Interface property does not exist*");
1431 continue;
1432
1433 case 'i':
1434 g_test_trap_assert_failed ();
1435 g_test_trap_assert_stderr ("*g_object_class_install_property*");
1436 continue;
1437
1438 case 'f':
1439 g_test_trap_assert_failed ();
1440 g_test_trap_assert_stderr ("*remove functionality*");
1441 continue;
1442
1443 case 'r':
1444 g_test_trap_assert_failed ();
1445 g_test_trap_assert_stderr ("*introduce additional restrictions*");
1446 continue;
1447
1448 case 'v':
1449 break;
1450 }
1451
1452 /* Next, we check if there should have been a type error. */
1453 switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type])
1454 {
1455 case 0:
1456 /* this should have been caught above */
1457 g_assert_not_reached ();
1458
1459 case '=':
1460 g_test_trap_assert_failed ();
1461 g_test_trap_assert_stderr ("*exactly equal*");
1462 continue;
1463
1464 case '<':
1465 g_test_trap_assert_failed ();
1466 g_test_trap_assert_stderr ("*equal to or more restrictive*");
1467 continue;
1468
1469 case '>':
1470 g_test_trap_assert_failed ();
1471 g_test_trap_assert_stderr ("*equal to or less restrictive*");
1472 continue;
1473
1474 case 'v':
1475 break;
1476 }
1477
1478 g_test_trap_assert_passed ();
1479 }
1480 }
1481
1482 static void
1483 test_param_default (void)
1484 {
1485 GParamSpec *param;
1486 const GValue *def;
1487
1488 param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
1489 def = g_param_spec_get_default_value (param);
1490
1491 g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT));
1492 g_assert_cmpint (g_value_get_int (def), ==, 10);
1493
1494 g_param_spec_unref (param);
1495 }
1496
1497 static void
1498 test_param_is_valid_name (void)
1499 {
1500 const gchar *valid_names[] =
1501 {
1502 "property",
1503 "i",
1504 "multiple-segments",
1505 "segment0-SEGMENT1",
1506 "using_underscores",
1507 };
1508 const gchar *invalid_names[] =
1509 {
1510 "",
1511 "7zip",
1512 "my_int:hello",
1513 };
1514 gsize i;
1515
1516 for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
1517 g_assert_true (g_param_spec_is_valid_name (valid_names[i]));
1518
1519 for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
1520 g_assert_false (g_param_spec_is_valid_name (invalid_names[i]));
1521 }
1522
1523 static void
1524 param_int_init (GParamSpec *pspec)
1525 {
1526 GParamSpecInt *ispec = (GParamSpecInt *)pspec;
1527
1528 ispec->minimum = 0x7fffffff;
1529 ispec->maximum = 0x80000000;
1530 ispec->default_value = 0;
1531 }
1532
1533 static void
1534 param_int_set_default (GParamSpec *pspec,
1535 GValue *value)
1536 {
1537 value->data[0].v_int = ((GParamSpecInt *)pspec)->default_value;
1538 }
1539
1540 static gboolean
1541 param_int_validate (GParamSpec *pspec,
1542 GValue *value)
1543 {
1544 GParamSpecInt *ispec = (GParamSpecInt *)pspec;
1545 int oval = value->data[0].v_int;
1546
1547 value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
1548
1549 return value->data[0].v_int != oval;
1550 }
1551
1552 static int
1553 param_int_values_cmp (GParamSpec *pspec,
1554 const GValue *value1,
1555 const GValue *value2)
1556 {
1557 if (value1->data[0].v_int < value2->data[0].v_int)
1558 return -1;
1559 else
1560 return value1->data[0].v_int > value2->data[0].v_int;
1561 }
1562
1563 static GType custom_type;
1564
1565 /* Register a pspec that has a validate vfunc, but not
1566 * value_is_valid, to test the fallback in g_param_value_is_valid
1567 */
1568 static void
1569 register_custom_pspec (void)
1570 {
1571 const GParamSpecTypeInfo pspec_info = {
1572 sizeof (GParamSpecInt), /* instance_size */
1573 16, /* n_preallocs */
1574 param_int_init, /* instance_init */
1575 G_TYPE_INT, /* value_type */
1576 NULL, /* finalize */
1577 param_int_set_default, /* value_set_default */
1578 param_int_validate, /* value_validate */
1579 param_int_values_cmp, /* values_cmp */
1580 };
1581
1582 custom_type = g_param_type_register_static ("GParamInt2", &pspec_info);
1583 }
1584
1585 static GParamSpec *
1586 g_param_spec_custom (const char *name,
1587 int minimum,
1588 int maximum,
1589 int default_value,
1590 GParamFlags flags)
1591 {
1592 GParamSpecInt *ispec;
1593
1594 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1595
1596 ispec = g_param_spec_internal (custom_type, name, NULL, NULL, flags);
1597 if (ispec == NULL)
1598 return NULL;
1599
1600 ispec->minimum = minimum;
1601 ispec->maximum = maximum;
1602 ispec->default_value = default_value;
1603
1604 return G_PARAM_SPEC (ispec);
1605 }
1606
1607 static void
1608 test_param_spec_custom (void)
1609 {
1610 GParamSpec *pspec;
1611 GValue value = G_VALUE_INIT;
1612
1613 register_custom_pspec ();
1614
1615 pspec = g_param_spec_custom ("myint", 10, 30, 20, G_PARAM_READWRITE);
1616
1617 g_value_init (&value, G_TYPE_INT);
1618
1619 g_value_set_int (&value, 40);
1620
1621 g_assert_false (g_param_value_is_valid (pspec, &value));
1622 g_assert_cmpint (g_value_get_int (&value), ==, 40);
1623
1624 g_param_spec_unref (pspec);
1625 }
1626
1627 static void
1628 test_param_spec_pool (void)
1629 {
1630 GParamSpecPool *pool = g_param_spec_pool_new (FALSE);
1631 GParamSpec *pspec = g_param_spec_int ("int", NULL, NULL, -1, 100, -1, G_PARAM_READWRITE);
1632 GParamSpec *check = NULL;
1633
1634 g_param_spec_pool_insert (pool, g_param_spec_ref_sink (pspec), G_TYPE_OBJECT);
1635 check = g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE);
1636 g_assert_true (check->owner_type == G_TYPE_OBJECT);
1637
1638 g_param_spec_pool_remove (pool, pspec);
1639 g_assert_null (g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE));
1640
1641 g_param_spec_pool_free (pool);
1642 }
1643
1644 int
1645 main (int argc, char *argv[])
1646 {
1647 TestParamImplementData data, *test_data;
1648 gchar *test_path;
1649
1650 g_test_init (&argc, &argv, NULL);
1651
1652 g_test_add_func ("/param/value", test_param_value);
1653 g_test_add_func ("/param/strings", test_param_strings);
1654 g_test_add_data_func ("/param/invalid-name/colon", "my_int:hello", test_param_invalid_name);
1655 g_test_add_data_func ("/param/invalid-name/first-char", "7zip", test_param_invalid_name);
1656 g_test_add_data_func ("/param/invalid-name/empty", "", test_param_invalid_name);
1657 g_test_add_func ("/param/qdata", test_param_qdata);
1658 g_test_add_func ("/param/validate", test_param_validate);
1659 g_test_add_func ("/param/convert", test_param_convert);
1660
1661 if (g_test_slow ())
1662 g_test_add_func ("/param/implement", test_param_implement);
1663
1664 for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
1665 for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)
1666 for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++)
1667 for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++)
1668 {
1669 test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
1670 data.change_this_flag, data.change_this_type,
1671 data.use_this_flag, data.use_this_type);
1672 test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
1673 g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
1674 g_free (test_data);
1675 g_free (test_path);
1676 }
1677
1678 g_test_add_func ("/value/transform", test_value_transform);
1679 g_test_add_func ("/param/default", test_param_default);
1680 g_test_add_func ("/param/is-valid-name", test_param_is_valid_name);
1681 g_test_add_func ("/paramspec/char", test_param_spec_char);
1682 g_test_add_func ("/paramspec/uchar", test_param_spec_uchar);
1683 g_test_add_func ("/paramspec/int", test_param_spec_int);
1684 g_test_add_func ("/paramspec/uint", test_param_spec_uint);
1685 g_test_add_func ("/paramspec/long", test_param_spec_long);
1686 g_test_add_func ("/paramspec/ulong", test_param_spec_ulong);
1687 g_test_add_func ("/paramspec/int64", test_param_spec_int64);
1688 g_test_add_func ("/paramspec/uint64", test_param_spec_uint64);
1689 g_test_add_func ("/paramspec/float", test_param_spec_float);
1690 g_test_add_func ("/paramspec/double", test_param_spec_double);
1691 g_test_add_func ("/paramspec/unichar", test_param_spec_unichar);
1692 g_test_add_func ("/paramspec/param", test_param_spec_param);
1693 g_test_add_func ("/paramspec/null-param", test_param_spec_null_param);
1694 g_test_add_func ("/paramspec/string", test_param_spec_string);
1695 g_test_add_func ("/paramspec/override", test_param_spec_override);
1696 g_test_add_func ("/paramspec/gtype", test_param_spec_gtype);
1697 g_test_add_func ("/paramspec/variant", test_param_spec_variant);
1698 g_test_add_func ("/paramspec/variant/cmp", test_param_spec_variant_cmp);
1699 g_test_add_func ("/paramspec/custom", test_param_spec_custom);
1700 g_test_add_func ("/paramspec/pool", test_param_spec_pool);
1701
1702 return g_test_run ();
1703 }