1 #include <stdlib.h>
2 #include <gstdio.h>
3 #include <glib-object.h>
4
5 typedef struct _TestObject {
6 GObject parent_instance;
7 gint foo;
8 gboolean bar;
9 gchar *baz;
10 gchar *quux;
11 } TestObject;
12
13 typedef struct _TestObjectClass {
14 GObjectClass parent_class;
15 } TestObjectClass;
16
17 enum { PROP_0, PROP_FOO, PROP_BAR, PROP_BAZ, PROP_QUUX, N_PROPERTIES };
18
19 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
20
21 static GType test_object_get_type (void);
G_DEFINE_TYPE(TestObject,test_object,G_TYPE_OBJECT)22 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
23
24 static void
25 test_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), properties[PROP_FOO]);
34 }
35 }
36
37 static void
test_object_set_bar(TestObject * obj,gboolean bar)38 test_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), properties[PROP_BAR]);
49 }
50 }
51
52 static void
test_object_set_baz(TestObject * obj,const gchar * baz)53 test_object_set_baz (TestObject *obj,
54 const gchar *baz)
55 {
56 if (g_strcmp0 (obj->baz, baz) != 0)
57 {
58 g_free (obj->baz);
59 obj->baz = g_strdup (baz);
60
61 g_assert (properties[PROP_BAZ] != NULL);
62 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAZ]);
63 }
64 }
65
66 static void
test_object_set_quux(TestObject * obj,const gchar * quux)67 test_object_set_quux (TestObject *obj,
68 const gchar *quux)
69 {
70 if (g_strcmp0 (obj->quux, quux) != 0)
71 {
72 g_free (obj->quux);
73 obj->quux = g_strdup (quux);
74
75 g_assert (properties[PROP_QUUX] != NULL);
76 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_QUUX]);
77 }
78 }
79
80 static void
test_object_finalize(GObject * gobject)81 test_object_finalize (GObject *gobject)
82 {
83 TestObject *self = (TestObject *) gobject;
84
85 g_free (self->baz);
86 g_free (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 (gobject, "foo");
93 g_object_notify_by_pspec (gobject, properties[PROP_BAR]);
94
95 G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
96 }
97
98 static void
test_object_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * pspec)99 test_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 (tobj, g_value_get_int (value));
114 break;
115
116 case PROP_BAR:
117 test_object_set_bar (tobj, g_value_get_boolean (value));
118 break;
119
120 case PROP_BAZ:
121 test_object_set_baz (tobj, g_value_get_string (value));
122 break;
123
124 case PROP_QUUX:
125 test_object_set_quux (tobj, g_value_get_string (value));
126 break;
127
128 default:
129 g_assert_not_reached ();
130 }
131 }
132
133 static void
test_object_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * pspec)134 test_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, tobj->foo);
149 break;
150
151 case PROP_BAR:
152 g_value_set_boolean (value, tobj->bar);
153 break;
154
155 case PROP_BAZ:
156 g_value_set_string (value, tobj->baz);
157 break;
158
159 case PROP_QUUX:
160 g_value_set_string (value, tobj->quux);
161 break;
162
163 default:
164 g_assert_not_reached ();
165 }
166 }
167
168 static void
test_object_class_init(TestObjectClass * klass)169 test_object_class_init (TestObjectClass *klass)
170 {
171 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
172
173 properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "Foo",
174 -1, G_MAXINT,
175 0,
176 G_PARAM_READWRITE);
177 properties[PROP_BAR] = g_param_spec_boolean ("bar", "Bar", "Bar",
178 FALSE,
179 G_PARAM_READWRITE);
180 properties[PROP_BAZ] = g_param_spec_string ("baz", "Baz", "Baz",
181 NULL,
182 G_PARAM_READWRITE);
183 properties[PROP_QUUX] = g_param_spec_string ("quux", "quux", "quux",
184 NULL,
185 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 (gobject_class, N_PROPERTIES, properties);
192 }
193
194 static void
test_object_init(TestObject * self)195 test_object_init (TestObject *self)
196 {
197 self->foo = 42;
198 self->bar = TRUE;
199 self->baz = g_strdup ("Hello");
200 self->quux = NULL;
201 }
202
203 static void
properties_install(void)204 properties_install (void)
205 {
206 TestObject *obj = g_object_new (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), "foo");
212 g_assert (properties[PROP_FOO] == pspec);
213
214 g_object_unref (obj);
215 }
216
217 typedef struct {
218 const gchar *name;
219 GParamSpec *pspec;
220 gboolean fired;
221 } TestNotifyClosure;
222
223 static void
on_notify(GObject * gobject,GParamSpec * pspec,TestNotifyClosure * closure)224 on_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
233 static void
properties_notify(void)234 properties_notify (void)
235 {
236 TestObject *obj = g_object_new (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 (obj, "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 (obj, "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 (obj, "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 (obj, "quux", "something new", NULL);
268 g_assert (closure.fired);
269
270 /* no change; no notify */
271 closure.fired = FALSE;
272 g_object_set (obj, "quux", "something new", NULL);
273 g_assert (!closure.fired);
274
275
276 g_object_unref (obj);
277 }
278
279 typedef struct {
280 GParamSpec *pspec[3];
281 gint pos;
282 } Notifys;
283
284 static void
on_notify2(GObject * gobject,GParamSpec * pspec,Notifys * n)285 on_notify2 (GObject *gobject,
286 GParamSpec *pspec,
287 Notifys *n)
288 {
289 g_assert (n->pspec[n->pos] == pspec);
290 n->pos++;
291 }
292
293 static void
properties_notify_queue(void)294 properties_notify_queue (void)
295 {
296 TestObject *obj = g_object_new (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 (obj, "foo", 47, NULL);
310 g_object_set (obj, "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 (obj);
315 }
316
317 static void
properties_construct(void)318 properties_construct (void)
319 {
320 TestObject *obj;
321 gint val;
322 gboolean b;
323 gchar *s;
324
325 g_test_bug ("630357");
326
327 /* more than 16 args triggers a realloc in g_object_new_valist() */
328 obj = g_object_new (test_object_get_type (),
329 "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 (obj, "foo", &val, NULL);
352 g_assert (val == 18);
353 g_object_get (obj, "bar", &b, NULL);
354 g_assert (!b);
355 g_object_get (obj, "baz", &s, NULL);
356 g_assert_cmpstr (s, ==, "boo");
357 g_free (s);
358
359 g_object_unref (obj);
360 }
361
362 static void
properties_testv_with_no_properties(void)363 properties_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 test_object_get_type (), 0, NULL, NULL);
373 g_object_getv (G_OBJECT (test_obj), 4, prop_names, 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 (&values_out[i]);
383 g_object_unref (test_obj);
384 }
385
386 static void
properties_testv_with_valid_properties(void)387 properties_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 (&(values_in[0]), G_TYPE_INT);
397 g_value_set_int (&(values_in[0]), 100);
398
399 g_value_init (&(values_in[1]), G_TYPE_BOOLEAN);
400 g_value_set_boolean (&(values_in[1]), TRUE);
401
402 g_value_init (&(values_in[2]), G_TYPE_STRING);
403 g_value_set_string (&(values_in[2]), "pigs");
404
405 g_value_init (&(values_in[3]), G_TYPE_STRING);
406 g_value_set_string (&(values_in[3]), "fly");
407
408 /* Test newv_with_properties && getv */
409 test_obj = (TestObject *) g_object_new_with_properties (
410 test_object_get_type (), 4, prop_names, values_in);
411 g_object_getv (G_OBJECT (test_obj), 4, prop_names, 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 (&values_out[i]);
420
421 /* Test newv2 && getv */
422 g_value_set_string (&(values_in[2]), "Elmo knows");
423 g_value_set_string (&(values_in[3]), "where you live");
424 g_object_setv (G_OBJECT (test_obj), 4, prop_names, values_in);
425
426 g_object_getv (G_OBJECT (test_obj), 4, prop_names, 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 (&values_in[i]);
436 for (i = 0; i < G_N_ELEMENTS (values_out); i++)
437 g_value_unset (&values_out[i]);
438
439 g_object_unref (test_obj);
440 }
441
442 static void
properties_testv_with_invalid_property_type(void)443 properties_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 (&(values_in[0]), G_TYPE_STRING);
452 g_value_set_string (&(values_in[0]), "fly");
453
454 test_obj = (TestObject *) g_object_new_with_properties (
455 test_object_get_type (), 1, invalid_prop_names, values_in);
456 /* should give a warning */
457
458 g_object_unref (test_obj);
459 }
460 g_test_trap_subprocess (NULL, 0, 0);
461 g_test_trap_assert_failed ();
462 g_test_trap_assert_stderr ("*WARNING*foo*gint*gchararray*");
463 }
464
465
466 static void
properties_testv_with_invalid_property_names(void)467 properties_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 (&(values_in[0]), G_TYPE_INT);
476 g_value_set_int (&(values_in[0]), 100);
477
478 g_value_init (&(values_in[1]), G_TYPE_BOOLEAN);
479 g_value_set_boolean (&(values_in[1]), TRUE);
480
481 g_value_init (&(values_in[2]), G_TYPE_STRING);
482 g_value_set_string (&(values_in[2]), "pigs");
483
484 g_value_init (&(values_in[3]), G_TYPE_STRING);
485 g_value_set_string (&(values_in[3]), "fly");
486
487 test_obj = (TestObject *) g_object_new_with_properties (
488 test_object_get_type (), 4, invalid_prop_names, 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 (test_obj);
496 }
497
498 g_test_trap_subprocess (NULL, 0, 0);
499 g_test_trap_assert_failed ();
500 g_test_trap_assert_stderr ("*CRITICAL*g_object_new_is_valid_property*boo*");
501 }
502
503 static void
properties_testv_getv(void)504 properties_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 (&(values_out_initialized[0]), G_TYPE_INT);
513 g_value_init (&(values_out_initialized[1]), G_TYPE_BOOLEAN);
514 g_value_init (&(values_out_initialized[2]), G_TYPE_STRING);
515 g_value_init (&(values_out_initialized[3]), G_TYPE_STRING);
516
517 test_obj = (TestObject *) g_object_new_with_properties (
518 test_object_get_type (), 0, NULL, NULL);
519
520 /* Test g_object_getv for an initialized values array */
521 g_object_getv (G_OBJECT (test_obj), 4, prop_names, 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), 4, prop_names, 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 (&values_out_initialized[i]);
539 g_value_unset (&values_out_uninitialized[i]);
540 }
541 g_object_unref (test_obj);
542 }
543
544 static void
properties_get_property(void)545 properties_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 ("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 (&(test_props[i].value), test_props[i].gtype);
566 }
567
568 test_obj = (TestObject *) g_object_new_with_properties (test_object_get_type (), 0, NULL, NULL);
569
570 g_test_message ("Test g_object_get_property with an initialized value");
571 g_object_get_property (G_OBJECT (test_obj), test_props[0].name, &(test_props[0].value));
572 g_assert_cmpint (g_value_get_int (&(test_props[0].value)), ==, 42);
573
574 g_test_message ("Test g_object_get_property with an uninitialized value");
575 g_object_get_property (G_OBJECT (test_obj), test_props[1].name, &(test_props[1].value));
576 g_assert_true (g_value_get_boolean (&(test_props[1].value)));
577
578 g_test_message ("Test g_object_get_property with a transformable value");
579 g_object_get_property (G_OBJECT (test_obj), test_props[2].name, &(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 (&(test_props[i].value));
585
586 g_object_unref (test_obj);
587 }
588
589 static void
properties_testv_notify_queue(void)590 properties_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 (&(values_in[0]), G_TYPE_INT);
599 g_value_set_int (&(values_in[0]), 100);
600
601 g_value_init (&(values_in[1]), G_TYPE_BOOLEAN);
602 g_value_set_boolean (&(values_in[1]), TRUE);
603
604 g_value_init (&(values_in[2]), G_TYPE_STRING);
605 g_value_set_string (&(values_in[2]), "");
606
607 /* Test newv_with_properties && getv */
608 test_obj = (TestObject *) g_object_new_with_properties (
609 test_object_get_type (), 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), 3, prop_names, values_in);
623
624 /* Set "foo" to 70 */
625 g_value_set_int (&(values_in[0]), 100);
626 g_object_setv (G_OBJECT (test_obj), 1, prop_names, 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 (&values_in[i]);
633 g_object_unref (test_obj);
634 }
635
636 int
main(int argc,char * argv[])637 main (int argc, char *argv[])
638 {
639 g_test_init (&argc, &argv, NULL);
640
641 g_test_bug_base ("http://bugzilla.gnome.org/");
642
643 g_test_add_func ("/properties/install", properties_install);
644 g_test_add_func ("/properties/notify", properties_notify);
645 g_test_add_func ("/properties/notify-queue", properties_notify_queue);
646 g_test_add_func ("/properties/construct", properties_construct);
647 g_test_add_func ("/properties/get-property", properties_get_property);
648
649 g_test_add_func ("/properties/testv_with_no_properties",
650 properties_testv_with_no_properties);
651 g_test_add_func ("/properties/testv_with_valid_properties",
652 properties_testv_with_valid_properties);
653 g_test_add_func ("/properties/testv_with_invalid_property_type",
654 properties_testv_with_invalid_property_type);
655 g_test_add_func ("/properties/testv_with_invalid_property_names",
656 properties_testv_with_invalid_property_names);
657 g_test_add_func ("/properties/testv_getv", properties_testv_getv);
658 g_test_add_func ("/properties/testv_notify_queue",
659 properties_testv_notify_queue);
660
661 return g_test_run ();
662 }
663