1#include <stdlib.h>
2#include <gstdio.h>
3#include <glib-object.h>
4
5typedef struct _TestObject {
6 GObject parent_instance;
7 gint foo;
8 gboolean bar;
9 gchar *baz;
10 gchar *quux;
11} TestObject;
12
13typedef struct _TestObjectClass {
14 GObjectClass parent_class;
15} TestObjectClass;
16
17enum { PROP_0, PROP_FOO, PROP_BAR, PROP_BAZ, PROP_QUUX, N_PROPERTIES };
18
19static GParamSpec *properties[N_PROPERTIES] = { NULL, };
20
21static GType test_object_get_type (void);
22G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
23
24static void
25test_object_set_foo (TestObject *obj,
26 gint foo)
27{
28 if (obj->foo != foo)
29 {
30 obj->foo = foo;
31
32 g_assert (properties[PROP_FOO] != NULL);
33 g_object_notify_by_pspec (G_OBJECT (obj), pspec: properties[PROP_FOO]);
34 }
35}
36
37static void
38test_object_set_bar (TestObject *obj,
39 gboolean bar)
40{
41 bar = !!bar;
42
43 if (obj->bar != bar)
44 {
45 obj->bar = bar;
46
47 g_assert (properties[PROP_BAR] != NULL);
48 g_object_notify_by_pspec (G_OBJECT (obj), pspec: properties[PROP_BAR]);
49 }
50}
51
52static void
53test_object_set_baz (TestObject *obj,
54 const gchar *baz)
55{
56 if (g_strcmp0 (str1: obj->baz, str2: baz) != 0)
57 {
58 g_free (mem: obj->baz);
59 obj->baz = g_strdup (str: baz);
60
61 g_assert (properties[PROP_BAZ] != NULL);
62 g_object_notify_by_pspec (G_OBJECT (obj), pspec: properties[PROP_BAZ]);
63 }
64}
65
66static void
67test_object_set_quux (TestObject *obj,
68 const gchar *quux)
69{
70 if (g_strcmp0 (str1: obj->quux, str2: quux) != 0)
71 {
72 g_free (mem: obj->quux);
73 obj->quux = g_strdup (str: quux);
74
75 g_assert (properties[PROP_QUUX] != NULL);
76 g_object_notify_by_pspec (G_OBJECT (obj), pspec: properties[PROP_QUUX]);
77 }
78}
79
80static void
81test_object_finalize (GObject *gobject)
82{
83 TestObject *self = (TestObject *) gobject;
84
85 g_free (mem: self->baz);
86 g_free (mem: self->quux);
87
88 /* When the ref_count of an object is zero it is still
89 * possible to notify the property, but it should do
90 * nothing and silently quit (bug #705570)
91 */
92 g_object_notify (object: gobject, property_name: "foo");
93 g_object_notify_by_pspec (object: gobject, pspec: properties[PROP_BAR]);
94
95 G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
96}
97
98static void
99test_object_set_property (GObject *gobject,
100 guint prop_id,
101 const GValue *value,
102 GParamSpec *pspec)
103{
104 TestObject *tobj = (TestObject *) gobject;
105
106 g_assert_cmpint (prop_id, !=, 0);
107 g_assert_cmpint (prop_id, !=, N_PROPERTIES);
108 g_assert (pspec == properties[prop_id]);
109
110 switch (prop_id)
111 {
112 case PROP_FOO:
113 test_object_set_foo (obj: tobj, foo: g_value_get_int (value));
114 break;
115
116 case PROP_BAR:
117 test_object_set_bar (obj: tobj, bar: g_value_get_boolean (value));
118 break;
119
120 case PROP_BAZ:
121 test_object_set_baz (obj: tobj, baz: g_value_get_string (value));
122 break;
123
124 case PROP_QUUX:
125 test_object_set_quux (obj: tobj, quux: g_value_get_string (value));
126 break;
127
128 default:
129 g_assert_not_reached ();
130 }
131}
132
133static void
134test_object_get_property (GObject *gobject,
135 guint prop_id,
136 GValue *value,
137 GParamSpec *pspec)
138{
139 TestObject *tobj = (TestObject *) gobject;
140
141 g_assert_cmpint (prop_id, !=, 0);
142 g_assert_cmpint (prop_id, !=, N_PROPERTIES);
143 g_assert (pspec == properties[prop_id]);
144
145 switch (prop_id)
146 {
147 case PROP_FOO:
148 g_value_set_int (value, v_int: tobj->foo);
149 break;
150
151 case PROP_BAR:
152 g_value_set_boolean (value, v_boolean: tobj->bar);
153 break;
154
155 case PROP_BAZ:
156 g_value_set_string (value, v_string: tobj->baz);
157 break;
158
159 case PROP_QUUX:
160 g_value_set_string (value, v_string: tobj->quux);
161 break;
162
163 default:
164 g_assert_not_reached ();
165 }
166}
167
168static void
169test_object_class_init (TestObjectClass *klass)
170{
171 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
172
173 properties[PROP_FOO] = g_param_spec_int (name: "foo", nick: "Foo", blurb: "Foo",
174 minimum: -1, G_MAXINT,
175 default_value: 0,
176 flags: G_PARAM_READWRITE);
177 properties[PROP_BAR] = g_param_spec_boolean (name: "bar", nick: "Bar", blurb: "Bar",
178 FALSE,
179 flags: G_PARAM_READWRITE);
180 properties[PROP_BAZ] = g_param_spec_string (name: "baz", nick: "Baz", blurb: "Baz",
181 NULL,
182 flags: G_PARAM_READWRITE);
183 properties[PROP_QUUX] = g_param_spec_string (name: "quux", nick: "quux", blurb: "quux",
184 NULL,
185 flags: G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
186
187 gobject_class->set_property = test_object_set_property;
188 gobject_class->get_property = test_object_get_property;
189 gobject_class->finalize = test_object_finalize;
190
191 g_object_class_install_properties (oclass: gobject_class, n_pspecs: N_PROPERTIES, pspecs: properties);
192}
193
194static void
195test_object_init (TestObject *self)
196{
197 self->foo = 42;
198 self->bar = TRUE;
199 self->baz = g_strdup (str: "Hello");
200 self->quux = NULL;
201}
202
203static void
204properties_install (void)
205{
206 TestObject *obj = g_object_new (object_type: test_object_get_type (), NULL);
207 GParamSpec *pspec;
208
209 g_assert (properties[PROP_FOO] != NULL);
210
211 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), property_name: "foo");
212 g_assert (properties[PROP_FOO] == pspec);
213
214 g_object_unref (object: obj);
215}
216
217typedef struct {
218 const gchar *name;
219 GParamSpec *pspec;
220 gboolean fired;
221} TestNotifyClosure;
222
223static void
224on_notify (GObject *gobject,
225 GParamSpec *pspec,
226 TestNotifyClosure *closure)
227{
228 g_assert (closure->pspec == pspec);
229 g_assert_cmpstr (closure->name, ==, pspec->name);
230 closure->fired = TRUE;
231}
232
233static void
234properties_notify (void)
235{
236 TestObject *obj = g_object_new (object_type: test_object_get_type (), NULL);
237 TestNotifyClosure closure;
238
239 g_assert (properties[PROP_FOO] != NULL);
240 g_assert (properties[PROP_QUUX] != NULL);
241 g_signal_connect (obj, "notify", G_CALLBACK (on_notify), &closure);
242
243 closure.name = "foo";
244 closure.pspec = properties[PROP_FOO];
245
246 closure.fired = FALSE;
247 g_object_set (object: obj, first_property_name: "foo", 47, NULL);
248 g_assert (closure.fired);
249
250 closure.name = "baz";
251 closure.pspec = properties[PROP_BAZ];
252
253 closure.fired = FALSE;
254 g_object_set (object: obj, first_property_name: "baz", "something new", NULL);
255 g_assert (closure.fired);
256
257 /* baz lacks explicit notify, so we will see this twice */
258 closure.fired = FALSE;
259 g_object_set (object: obj, first_property_name: "baz", "something new", NULL);
260 g_assert (closure.fired);
261
262 /* quux on the other hand, ... */
263 closure.name = "quux";
264 closure.pspec = properties[PROP_QUUX];
265
266 closure.fired = FALSE;
267 g_object_set (object: obj, first_property_name: "quux", "something new", NULL);
268 g_assert (closure.fired);
269
270 /* no change; no notify */
271 closure.fired = FALSE;
272 g_object_set (object: obj, first_property_name: "quux", "something new", NULL);
273 g_assert (!closure.fired);
274
275
276 g_object_unref (object: obj);
277}
278
279typedef struct {
280 GParamSpec *pspec[3];
281 gint pos;
282} Notifys;
283
284static void
285on_notify2 (GObject *gobject,
286 GParamSpec *pspec,
287 Notifys *n)
288{
289 g_assert (n->pspec[n->pos] == pspec);
290 n->pos++;
291}
292
293static void
294properties_notify_queue (void)
295{
296 TestObject *obj = g_object_new (object_type: test_object_get_type (), NULL);
297 Notifys n;
298
299 g_assert (properties[PROP_FOO] != NULL);
300
301 n.pspec[0] = properties[PROP_BAZ];
302 n.pspec[1] = properties[PROP_BAR];
303 n.pspec[2] = properties[PROP_FOO];
304 n.pos = 0;
305
306 g_signal_connect (obj, "notify", G_CALLBACK (on_notify2), &n);
307
308 g_object_freeze_notify (G_OBJECT (obj));
309 g_object_set (object: obj, first_property_name: "foo", 47, NULL);
310 g_object_set (object: obj, first_property_name: "bar", TRUE, "foo", 42, "baz", "abc", NULL);
311 g_object_thaw_notify (G_OBJECT (obj));
312 g_assert (n.pos == 3);
313
314 g_object_unref (object: obj);
315}
316
317static void
318properties_construct (void)
319{
320 TestObject *obj;
321 gint val;
322 gboolean b;
323 gchar *s;
324
325 g_test_bug (bug_uri_snippet: "630357");
326
327 /* more than 16 args triggers a realloc in g_object_new_valist() */
328 obj = g_object_new (object_type: test_object_get_type (),
329 first_property_name: "foo", 1,
330 "foo", 2,
331 "foo", 3,
332 "foo", 4,
333 "foo", 5,
334 "bar", FALSE,
335 "foo", 6,
336 "foo", 7,
337 "foo", 8,
338 "foo", 9,
339 "foo", 10,
340 "baz", "boo",
341 "foo", 11,
342 "foo", 12,
343 "foo", 13,
344 "foo", 14,
345 "foo", 15,
346 "foo", 16,
347 "foo", 17,
348 "foo", 18,
349 NULL);
350
351 g_object_get (object: obj, first_property_name: "foo", &val, NULL);
352 g_assert (val == 18);
353 g_object_get (object: obj, first_property_name: "bar", &b, NULL);
354 g_assert (!b);
355 g_object_get (object: obj, first_property_name: "baz", &s, NULL);
356 g_assert_cmpstr (s, ==, "boo");
357 g_free (mem: s);
358
359 g_object_unref (object: obj);
360}
361
362static void
363properties_testv_with_no_properties (void)
364{
365 TestObject *test_obj;
366 const char *prop_names[4] = { "foo", "bar", "baz", "quux" };
367 GValue values_out[4] = { G_VALUE_INIT };
368 guint i;
369
370 /* Test newv_with_properties && getv */
371 test_obj = (TestObject *) g_object_new_with_properties (
372 object_type: test_object_get_type (), n_properties: 0, NULL, NULL);
373 g_object_getv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_out);
374
375 /* It should have init values */
376 g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 42);
377 g_assert_true (g_value_get_boolean (&values_out[1]));
378 g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "Hello");
379 g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, NULL);
380
381 for (i = 0; i < 4; i++)
382 g_value_unset (value: &values_out[i]);
383 g_object_unref (object: test_obj);
384}
385
386static void
387properties_testv_with_valid_properties (void)
388{
389 TestObject *test_obj;
390 const char *prop_names[4] = { "foo", "bar", "baz", "quux" };
391
392 GValue values_in[4] = { G_VALUE_INIT };
393 GValue values_out[4] = { G_VALUE_INIT };
394 guint i;
395
396 g_value_init (value: &(values_in[0]), G_TYPE_INT);
397 g_value_set_int (value: &(values_in[0]), v_int: 100);
398
399 g_value_init (value: &(values_in[1]), G_TYPE_BOOLEAN);
400 g_value_set_boolean (value: &(values_in[1]), TRUE);
401
402 g_value_init (value: &(values_in[2]), G_TYPE_STRING);
403 g_value_set_string (value: &(values_in[2]), v_string: "pigs");
404
405 g_value_init (value: &(values_in[3]), G_TYPE_STRING);
406 g_value_set_string (value: &(values_in[3]), v_string: "fly");
407
408 /* Test newv_with_properties && getv */
409 test_obj = (TestObject *) g_object_new_with_properties (
410 object_type: test_object_get_type (), n_properties: 4, names: prop_names, values: values_in);
411 g_object_getv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_out);
412
413 g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 100);
414 g_assert_true (g_value_get_boolean (&values_out[1]));
415 g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "pigs");
416 g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, "fly");
417
418 for (i = 0; i < G_N_ELEMENTS (values_out); i++)
419 g_value_unset (value: &values_out[i]);
420
421 /* Test newv2 && getv */
422 g_value_set_string (value: &(values_in[2]), v_string: "Elmo knows");
423 g_value_set_string (value: &(values_in[3]), v_string: "where you live");
424 g_object_setv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_in);
425
426 g_object_getv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_out);
427
428 g_assert_cmpint (g_value_get_int (&values_out[0]), ==, 100);
429 g_assert_true (g_value_get_boolean (&values_out[1]));
430
431 g_assert_cmpstr (g_value_get_string (&values_out[2]), ==, "Elmo knows");
432 g_assert_cmpstr (g_value_get_string (&values_out[3]), ==, "where you live");
433
434 for (i = 0; i < G_N_ELEMENTS (values_in); i++)
435 g_value_unset (value: &values_in[i]);
436 for (i = 0; i < G_N_ELEMENTS (values_out); i++)
437 g_value_unset (value: &values_out[i]);
438
439 g_object_unref (object: test_obj);
440}
441
442static void
443properties_testv_with_invalid_property_type (void)
444{
445 if (g_test_subprocess ())
446 {
447 TestObject *test_obj;
448 const char *invalid_prop_names[1] = { "foo" };
449 GValue values_in[1] = { G_VALUE_INIT };
450
451 g_value_init (value: &(values_in[0]), G_TYPE_STRING);
452 g_value_set_string (value: &(values_in[0]), v_string: "fly");
453
454 test_obj = (TestObject *) g_object_new_with_properties (
455 object_type: test_object_get_type (), n_properties: 1, names: invalid_prop_names, values: values_in);
456 /* should give a warning */
457
458 g_object_unref (object: test_obj);
459 }
460 g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0);
461 g_test_trap_assert_failed ();
462 g_test_trap_assert_stderr ("*WARNING*foo*gint*gchararray*");
463}
464
465
466static void
467properties_testv_with_invalid_property_names (void)
468{
469 if (g_test_subprocess ())
470 {
471 TestObject *test_obj;
472 const char *invalid_prop_names[4] = { "foo", "boo", "moo", "poo" };
473 GValue values_in[4] = { G_VALUE_INIT };
474
475 g_value_init (value: &(values_in[0]), G_TYPE_INT);
476 g_value_set_int (value: &(values_in[0]), v_int: 100);
477
478 g_value_init (value: &(values_in[1]), G_TYPE_BOOLEAN);
479 g_value_set_boolean (value: &(values_in[1]), TRUE);
480
481 g_value_init (value: &(values_in[2]), G_TYPE_STRING);
482 g_value_set_string (value: &(values_in[2]), v_string: "pigs");
483
484 g_value_init (value: &(values_in[3]), G_TYPE_STRING);
485 g_value_set_string (value: &(values_in[3]), v_string: "fly");
486
487 test_obj = (TestObject *) g_object_new_with_properties (
488 object_type: test_object_get_type (), n_properties: 4, names: invalid_prop_names, values: values_in);
489 /* This call should give 3 Critical warnings. Actually, a critical warning
490 * shouldn't make g_object_new_with_properties to fail when a bad named
491 * property is given, because, it will just ignore that property. However,
492 * for test purposes, it is considered that the test doesn't pass.
493 */
494
495 g_object_unref (object: test_obj);
496 }
497
498 g_test_trap_subprocess (NULL, usec_timeout: 0, test_flags: 0);
499 g_test_trap_assert_failed ();
500 g_test_trap_assert_stderr ("*CRITICAL*g_object_new_is_valid_property*boo*");
501}
502
503static void
504properties_testv_getv (void)
505{
506 TestObject *test_obj;
507 const char *prop_names[4] = { "foo", "bar", "baz", "quux" };
508 GValue values_out_initialized[4] = { G_VALUE_INIT };
509 GValue values_out_uninitialized[4] = { G_VALUE_INIT };
510 guint i;
511
512 g_value_init (value: &(values_out_initialized[0]), G_TYPE_INT);
513 g_value_init (value: &(values_out_initialized[1]), G_TYPE_BOOLEAN);
514 g_value_init (value: &(values_out_initialized[2]), G_TYPE_STRING);
515 g_value_init (value: &(values_out_initialized[3]), G_TYPE_STRING);
516
517 test_obj = (TestObject *) g_object_new_with_properties (
518 object_type: test_object_get_type (), n_properties: 0, NULL, NULL);
519
520 /* Test g_object_getv for an initialized values array */
521 g_object_getv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_out_initialized);
522 /* It should have init values */
523 g_assert_cmpint (g_value_get_int (&values_out_initialized[0]), ==, 42);
524 g_assert_true (g_value_get_boolean (&values_out_initialized[1]));
525 g_assert_cmpstr (g_value_get_string (&values_out_initialized[2]), ==, "Hello");
526 g_assert_cmpstr (g_value_get_string (&values_out_initialized[3]), ==, NULL);
527
528 /* Test g_object_getv for an uninitialized values array */
529 g_object_getv (G_OBJECT (test_obj), n_properties: 4, names: prop_names, values: values_out_uninitialized);
530 /* It should have init values */
531 g_assert_cmpint (g_value_get_int (&values_out_uninitialized[0]), ==, 42);
532 g_assert_true (g_value_get_boolean (&values_out_uninitialized[1]));
533 g_assert_cmpstr (g_value_get_string (&values_out_uninitialized[2]), ==, "Hello");
534 g_assert_cmpstr (g_value_get_string (&values_out_uninitialized[3]), ==, NULL);
535
536 for (i = 0; i < 4; i++)
537 {
538 g_value_unset (value: &values_out_initialized[i]);
539 g_value_unset (value: &values_out_uninitialized[i]);
540 }
541 g_object_unref (object: test_obj);
542}
543
544static void
545properties_get_property (void)
546{
547 TestObject *test_obj;
548 struct {
549 const char *name;
550 GType gtype;
551 GValue value;
552 } test_props[] = {
553 { "foo", G_TYPE_INT, G_VALUE_INIT },
554 { "bar", G_TYPE_INVALID, G_VALUE_INIT },
555 { "bar", G_TYPE_STRING, G_VALUE_INIT },
556 };
557 gsize i;
558
559 g_test_summary (summary: "g_object_get_property() accepts uninitialized, "
560 "initialized, and transformable values");
561
562 for (i = 0; i < G_N_ELEMENTS (test_props); i++)
563 {
564 if (test_props[i].gtype != G_TYPE_INVALID)
565 g_value_init (value: &(test_props[i].value), g_type: test_props[i].gtype);
566 }
567
568 test_obj = (TestObject *) g_object_new_with_properties (object_type: test_object_get_type (), n_properties: 0, NULL, NULL);
569
570 g_test_message (format: "Test g_object_get_property with an initialized value");
571 g_object_get_property (G_OBJECT (test_obj), property_name: test_props[0].name, value: &(test_props[0].value));
572 g_assert_cmpint (g_value_get_int (&(test_props[0].value)), ==, 42);
573
574 g_test_message (format: "Test g_object_get_property with an uninitialized value");
575 g_object_get_property (G_OBJECT (test_obj), property_name: test_props[1].name, value: &(test_props[1].value));
576 g_assert_true (g_value_get_boolean (&(test_props[1].value)));
577
578 g_test_message (format: "Test g_object_get_property with a transformable value");
579 g_object_get_property (G_OBJECT (test_obj), property_name: test_props[2].name, value: &(test_props[2].value));
580 g_assert_true (G_VALUE_HOLDS_STRING (&(test_props[2].value)));
581 g_assert_cmpstr (g_value_get_string (&(test_props[2].value)), ==, "TRUE");
582
583 for (i = 0; i < G_N_ELEMENTS (test_props); i++)
584 g_value_unset (value: &(test_props[i].value));
585
586 g_object_unref (object: test_obj);
587}
588
589static void
590properties_testv_notify_queue (void)
591{
592 TestObject *test_obj;
593 const char *prop_names[3] = { "foo", "bar", "baz" };
594 GValue values_in[3] = { G_VALUE_INIT };
595 Notifys n;
596 guint i;
597
598 g_value_init (value: &(values_in[0]), G_TYPE_INT);
599 g_value_set_int (value: &(values_in[0]), v_int: 100);
600
601 g_value_init (value: &(values_in[1]), G_TYPE_BOOLEAN);
602 g_value_set_boolean (value: &(values_in[1]), TRUE);
603
604 g_value_init (value: &(values_in[2]), G_TYPE_STRING);
605 g_value_set_string (value: &(values_in[2]), v_string: "");
606
607 /* Test newv_with_properties && getv */
608 test_obj = (TestObject *) g_object_new_with_properties (
609 object_type: test_object_get_type (), n_properties: 0, NULL, NULL);
610
611 g_assert_nonnull (properties[PROP_FOO]);
612
613 n.pspec[0] = properties[PROP_BAZ];
614 n.pspec[1] = properties[PROP_BAR];
615 n.pspec[2] = properties[PROP_FOO];
616 n.pos = 0;
617
618 g_signal_connect (test_obj, "notify", G_CALLBACK (on_notify2), &n);
619
620 g_object_freeze_notify (G_OBJECT (test_obj));
621 {
622 g_object_setv (G_OBJECT (test_obj), n_properties: 3, names: prop_names, values: values_in);
623
624 /* Set "foo" to 70 */
625 g_value_set_int (value: &(values_in[0]), v_int: 100);
626 g_object_setv (G_OBJECT (test_obj), n_properties: 1, names: prop_names, values: values_in);
627 }
628 g_object_thaw_notify (G_OBJECT (test_obj));
629 g_assert_cmpint (n.pos, ==, 3);
630
631 for (i = 0; i < 3; i++)
632 g_value_unset (value: &values_in[i]);
633 g_object_unref (object: test_obj);
634}
635
636int
637main (int argc, char *argv[])
638{
639 g_test_init (argc: &argc, argv: &argv, NULL);
640
641 g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/");
642
643 g_test_add_func (testpath: "/properties/install", test_func: properties_install);
644 g_test_add_func (testpath: "/properties/notify", test_func: properties_notify);
645 g_test_add_func (testpath: "/properties/notify-queue", test_func: properties_notify_queue);
646 g_test_add_func (testpath: "/properties/construct", test_func: properties_construct);
647 g_test_add_func (testpath: "/properties/get-property", test_func: properties_get_property);
648
649 g_test_add_func (testpath: "/properties/testv_with_no_properties",
650 test_func: properties_testv_with_no_properties);
651 g_test_add_func (testpath: "/properties/testv_with_valid_properties",
652 test_func: properties_testv_with_valid_properties);
653 g_test_add_func (testpath: "/properties/testv_with_invalid_property_type",
654 test_func: properties_testv_with_invalid_property_type);
655 g_test_add_func (testpath: "/properties/testv_with_invalid_property_names",
656 test_func: properties_testv_with_invalid_property_names);
657 g_test_add_func (testpath: "/properties/testv_getv", test_func: properties_testv_getv);
658 g_test_add_func (testpath: "/properties/testv_notify_queue",
659 test_func: properties_testv_notify_queue);
660
661 return g_test_run ();
662}
663

source code of gtk/subprojects/glib/gobject/tests/properties.c