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