1 #include <glib-object.h>
2
3 static void
test_fundamentals(void)4 test_fundamentals (void)
5 {
6 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_NONE));
7 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INTERFACE));
8 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_CHAR));
9 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UCHAR));
10 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOOLEAN));
11 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT));
12 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT));
13 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_LONG));
14 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ULONG));
15 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT64));
16 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT64));
17 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ENUM));
18 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLAGS));
19 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLOAT));
20 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_DOUBLE));
21 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_STRING));
22 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_POINTER));
23 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOXED));
24 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_PARAM));
25 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_OBJECT));
26 g_assert (G_TYPE_OBJECT == g_object_get_type ());
27 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_VARIANT));
28 g_assert (G_TYPE_IS_DERIVED (G_TYPE_INITIALLY_UNOWNED));
29
30 g_assert (g_type_fundamental_next () == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST));
31 }
32
33 static void
test_type_qdata(void)34 test_type_qdata (void)
35 {
36 gchar *data;
37
38 g_type_set_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"), "bla");
39 data = g_type_get_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"));
40 g_assert_cmpstr (data, ==, "bla");
41 }
42
43 static void
test_type_query(void)44 test_type_query (void)
45 {
46 GTypeQuery query;
47
48 g_type_query (G_TYPE_ENUM, &query);
49 g_assert_cmpint (query.type, ==, G_TYPE_ENUM);
50 g_assert_cmpstr (query.type_name, ==, "GEnum");
51 g_assert_cmpint (query.class_size, ==, sizeof (GEnumClass));
52 g_assert_cmpint (query.instance_size, ==, 0);
53 }
54
55 typedef struct _MyObject MyObject;
56 typedef struct _MyObjectClass MyObjectClass;
57 typedef struct _MyObjectClassPrivate MyObjectClassPrivate;
58
59 struct _MyObject
60 {
61 GObject parent_instance;
62
63 gint count;
64 };
65
66 struct _MyObjectClass
67 {
68 GObjectClass parent_class;
69 };
70
71 struct _MyObjectClassPrivate
72 {
73 gint secret_class_count;
74 };
75
76 static GType my_object_get_type (void);
77 G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT,
78 g_type_add_class_private (g_define_type_id, sizeof (MyObjectClassPrivate)) );
79
80 static void
my_object_init(MyObject * obj)81 my_object_init (MyObject *obj)
82 {
83 obj->count = 42;
84 }
85
86 static void
my_object_class_init(MyObjectClass * klass)87 my_object_class_init (MyObjectClass *klass)
88 {
89 }
90
91 static void
test_class_private(void)92 test_class_private (void)
93 {
94 GObject *obj;
95 MyObjectClass *class;
96 MyObjectClassPrivate *priv;
97
98 obj = g_object_new (my_object_get_type (), NULL);
99
100 class = g_type_class_ref (my_object_get_type ());
101 priv = G_TYPE_CLASS_GET_PRIVATE (class, my_object_get_type (), MyObjectClassPrivate);
102 priv->secret_class_count = 13;
103 g_type_class_unref (class);
104
105 g_object_unref (obj);
106
107 g_assert_cmpint (g_type_qname (my_object_get_type ()), ==, g_quark_from_string ("MyObject"));
108 }
109
110 static void
test_clear(void)111 test_clear (void)
112 {
113 GObject *o = NULL;
114 GObject *tmp;
115
116 g_clear_object (&o);
117 g_assert (o == NULL);
118
119 tmp = g_object_new (G_TYPE_OBJECT, NULL);
120 g_assert_cmpint (tmp->ref_count, ==, 1);
121 o = g_object_ref (tmp);
122 g_assert (o != NULL);
123
124 g_assert_cmpint (tmp->ref_count, ==, 2);
125 g_clear_object (&o);
126 g_assert_cmpint (tmp->ref_count, ==, 1);
127 g_assert (o == NULL);
128
129 g_object_unref (tmp);
130 }
131
132 static void
test_clear_function(void)133 test_clear_function (void)
134 {
135 GObject *o = NULL;
136 GObject *tmp;
137
138 (g_clear_object) (&o);
139 g_assert (o == NULL);
140
141 tmp = g_object_new (G_TYPE_OBJECT, NULL);
142 g_assert_cmpint (tmp->ref_count, ==, 1);
143 o = g_object_ref (tmp);
144 g_assert (o != NULL);
145
146 g_assert_cmpint (tmp->ref_count, ==, 2);
147 (g_clear_object) (&o);
148 g_assert_cmpint (tmp->ref_count, ==, 1);
149 g_assert (o == NULL);
150
151 g_object_unref (tmp);
152 }
153
154 static void
test_set(void)155 test_set (void)
156 {
157 GObject *o = NULL;
158 GObject *tmp;
159 gpointer tmp_weak = NULL;
160
161 g_assert (!g_set_object (&o, NULL));
162 g_assert (o == NULL);
163
164 tmp = g_object_new (G_TYPE_OBJECT, NULL);
165 tmp_weak = tmp;
166 g_object_add_weak_pointer (tmp, &tmp_weak);
167 g_assert_cmpint (tmp->ref_count, ==, 1);
168
169 g_assert (g_set_object (&o, tmp));
170 g_assert (o == tmp);
171 g_assert_cmpint (tmp->ref_count, ==, 2);
172
173 g_object_unref (tmp);
174 g_assert_cmpint (tmp->ref_count, ==, 1);
175
176 /* Setting it again shouldn’t cause finalisation. */
177 g_assert (!g_set_object (&o, tmp));
178 g_assert (o == tmp);
179 g_assert_cmpint (tmp->ref_count, ==, 1);
180 g_assert_nonnull (tmp_weak);
181
182 g_assert (g_set_object (&o, NULL));
183 g_assert (o == NULL);
184 g_assert_null (tmp_weak);
185 }
186
187 static void
test_set_function(void)188 test_set_function (void)
189 {
190 GObject *o = NULL;
191 GObject *tmp;
192 gpointer tmp_weak = NULL;
193
194 g_assert (!(g_set_object) (&o, NULL));
195 g_assert (o == NULL);
196
197 tmp = g_object_new (G_TYPE_OBJECT, NULL);
198 tmp_weak = tmp;
199 g_object_add_weak_pointer (tmp, &tmp_weak);
200 g_assert_cmpint (tmp->ref_count, ==, 1);
201
202 g_assert ((g_set_object) (&o, tmp));
203 g_assert (o == tmp);
204 g_assert_cmpint (tmp->ref_count, ==, 2);
205
206 g_object_unref (tmp);
207 g_assert_cmpint (tmp->ref_count, ==, 1);
208
209 /* Setting it again shouldn’t cause finalisation. */
210 g_assert (!(g_set_object) (&o, tmp));
211 g_assert (o == tmp);
212 g_assert_cmpint (tmp->ref_count, ==, 1);
213 g_assert_nonnull (tmp_weak);
214
215 g_assert ((g_set_object) (&o, NULL));
216 g_assert (o == NULL);
217 g_assert_null (tmp_weak);
218 }
219
220 static void
toggle_cb(gpointer data,GObject * obj,gboolean is_last)221 toggle_cb (gpointer data, GObject *obj, gboolean is_last)
222 {
223 gboolean *b = data;
224
225 *b = TRUE;
226 }
227
228 static void
test_object_value(void)229 test_object_value (void)
230 {
231 GObject *v;
232 GObject *v2;
233 GValue value = G_VALUE_INIT;
234 gboolean toggled = FALSE;
235
236 g_value_init (&value, G_TYPE_OBJECT);
237
238 v = g_object_new (G_TYPE_OBJECT, NULL);
239 g_object_add_toggle_ref (v, toggle_cb, &toggled);
240
241 g_value_take_object (&value, v);
242
243 v2 = g_value_get_object (&value);
244 g_assert (v2 == v);
245
246 v2 = g_value_dup_object (&value);
247 g_assert (v2 == v); /* objects use ref/unref for copy/free */
248 g_object_unref (v2);
249
250 g_assert (!toggled);
251 g_value_unset (&value);
252 g_assert (toggled);
253
254 /* test the deprecated variant too */
255 g_value_init (&value, G_TYPE_OBJECT);
256 /* get a new reference */
257 g_object_ref (v);
258
259 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
260 g_value_set_object_take_ownership (&value, v);
261 G_GNUC_END_IGNORE_DEPRECATIONS
262
263 toggled = FALSE;
264 g_value_unset (&value);
265 g_assert (toggled);
266
267 g_object_remove_toggle_ref (v, toggle_cb, &toggled);
268 }
269
270 static void
test_initially_unowned(void)271 test_initially_unowned (void)
272 {
273 GObject *obj;
274
275 obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
276 g_assert (g_object_is_floating (obj));
277 g_assert_cmpint (obj->ref_count, ==, 1);
278
279 g_object_ref_sink (obj);
280 g_assert (!g_object_is_floating (obj));
281 g_assert_cmpint (obj->ref_count, ==, 1);
282
283 g_object_ref_sink (obj);
284 g_assert (!g_object_is_floating (obj));
285 g_assert_cmpint (obj->ref_count, ==, 2);
286
287 g_object_unref (obj);
288 g_assert_cmpint (obj->ref_count, ==, 1);
289
290 g_object_force_floating (obj);
291 g_assert (g_object_is_floating (obj));
292 g_assert_cmpint (obj->ref_count, ==, 1);
293
294 g_object_ref_sink (obj);
295 g_object_unref (obj);
296 }
297
298 static void
test_weak_pointer(void)299 test_weak_pointer (void)
300 {
301 GObject *obj;
302 gpointer weak;
303 gpointer weak2;
304
305 weak = weak2 = obj = g_object_new (G_TYPE_OBJECT, NULL);
306 g_assert_cmpint (obj->ref_count, ==, 1);
307
308 g_object_add_weak_pointer (obj, &weak);
309 g_object_add_weak_pointer (obj, &weak2);
310 g_assert_cmpint (obj->ref_count, ==, 1);
311 g_assert (weak == obj);
312 g_assert (weak2 == obj);
313
314 g_object_remove_weak_pointer (obj, &weak2);
315 g_assert_cmpint (obj->ref_count, ==, 1);
316 g_assert (weak == obj);
317 g_assert (weak2 == obj);
318
319 g_object_unref (obj);
320 g_assert (weak == NULL);
321 g_assert (weak2 == obj);
322 }
323
324 static void
test_weak_pointer_clear(void)325 test_weak_pointer_clear (void)
326 {
327 GObject *obj;
328 gpointer weak = NULL;
329
330 g_clear_weak_pointer (&weak);
331 g_assert_null (weak);
332
333 weak = obj = g_object_new (G_TYPE_OBJECT, NULL);
334 g_assert_cmpint (obj->ref_count, ==, 1);
335
336 g_object_add_weak_pointer (obj, &weak);
337 g_assert_cmpint (obj->ref_count, ==, 1);
338 g_assert_true (weak == obj);
339
340 g_clear_weak_pointer (&weak);
341 g_assert_cmpint (obj->ref_count, ==, 1);
342 g_assert_null (weak);
343
344 g_object_unref (obj);
345 }
346
347 static void
test_weak_pointer_clear_function(void)348 test_weak_pointer_clear_function (void)
349 {
350 GObject *obj;
351 gpointer weak = NULL;
352
353 (g_clear_weak_pointer) (&weak);
354 g_assert_null (weak);
355
356 weak = obj = g_object_new (G_TYPE_OBJECT, NULL);
357 g_assert_cmpint (obj->ref_count, ==, 1);
358
359 g_object_add_weak_pointer (obj, &weak);
360 g_assert_cmpint (obj->ref_count, ==, 1);
361 g_assert_true (weak == obj);
362
363 (g_clear_weak_pointer) (&weak);
364 g_assert_cmpint (obj->ref_count, ==, 1);
365 g_assert_null (weak);
366
367 g_object_unref (obj);
368 }
369
370 static void
test_weak_pointer_set(void)371 test_weak_pointer_set (void)
372 {
373 GObject *obj;
374 gpointer weak = NULL;
375
376 g_assert_false (g_set_weak_pointer (&weak, NULL));
377 g_assert_null (weak);
378
379 obj = g_object_new (G_TYPE_OBJECT, NULL);
380 g_assert_cmpint (obj->ref_count, ==, 1);
381
382 g_assert_true (g_set_weak_pointer (&weak, obj));
383 g_assert_cmpint (obj->ref_count, ==, 1);
384 g_assert_true (weak == obj);
385
386 g_assert_true (g_set_weak_pointer (&weak, NULL));
387 g_assert_cmpint (obj->ref_count, ==, 1);
388 g_assert_null (weak);
389
390 g_assert_true (g_set_weak_pointer (&weak, obj));
391 g_assert_cmpint (obj->ref_count, ==, 1);
392 g_assert_true (weak == obj);
393
394 g_object_unref (obj);
395 g_assert_null (weak);
396 }
397
398 static void
test_weak_pointer_set_function(void)399 test_weak_pointer_set_function (void)
400 {
401 GObject *obj;
402 gpointer weak = NULL;
403
404 g_assert_false ((g_set_weak_pointer) (&weak, NULL));
405 g_assert_null (weak);
406
407 obj = g_object_new (G_TYPE_OBJECT, NULL);
408 g_assert_cmpint (obj->ref_count, ==, 1);
409
410 g_assert_true ((g_set_weak_pointer) (&weak, obj));
411 g_assert_cmpint (obj->ref_count, ==, 1);
412 g_assert_true (weak == obj);
413
414 g_assert_true ((g_set_weak_pointer) (&weak, NULL));
415 g_assert_cmpint (obj->ref_count, ==, 1);
416 g_assert_null (weak);
417
418 g_assert_true ((g_set_weak_pointer) (&weak, obj));
419 g_assert_cmpint (obj->ref_count, ==, 1);
420 g_assert_true (weak == obj);
421
422 g_object_unref (obj);
423 g_assert_null (weak);
424 }
425
426 /* See gobject/tests/threadtests.c for the threaded version */
427 static void
test_weak_ref(void)428 test_weak_ref (void)
429 {
430 GObject *obj;
431 GObject *obj2;
432 GObject *tmp;
433 GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
434 GWeakRef weak2 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
435 GWeakRef weak3 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
436 GWeakRef *dynamic_weak = g_new (GWeakRef, 1);
437
438 /* you can initialize to empty like this... */
439 g_weak_ref_init (&weak2, NULL);
440 g_assert (g_weak_ref_get (&weak2) == NULL);
441
442 /* ... or via an initializer */
443 g_weak_ref_init (&weak3, NULL);
444 g_assert (g_weak_ref_get (&weak3) == NULL);
445
446 obj = g_object_new (G_TYPE_OBJECT, NULL);
447 g_assert_cmpint (obj->ref_count, ==, 1);
448
449 obj2 = g_object_new (G_TYPE_OBJECT, NULL);
450 g_assert_cmpint (obj2->ref_count, ==, 1);
451
452 /* you can init with an object (even if uninitialized) */
453 g_weak_ref_init (&weak, obj);
454 g_weak_ref_init (dynamic_weak, obj);
455 /* or set to point at an object, if initialized (maybe to 0) */
456 g_weak_ref_set (&weak2, obj);
457 g_weak_ref_set (&weak3, obj);
458 /* none of this affects its refcount */
459 g_assert_cmpint (obj->ref_count, ==, 1);
460
461 /* getting the value takes a ref */
462 tmp = g_weak_ref_get (&weak);
463 g_assert (tmp == obj);
464 g_assert_cmpint (obj->ref_count, ==, 2);
465 g_object_unref (tmp);
466 g_assert_cmpint (obj->ref_count, ==, 1);
467
468 tmp = g_weak_ref_get (&weak2);
469 g_assert (tmp == obj);
470 g_assert_cmpint (obj->ref_count, ==, 2);
471 g_object_unref (tmp);
472 g_assert_cmpint (obj->ref_count, ==, 1);
473
474 tmp = g_weak_ref_get (&weak3);
475 g_assert (tmp == obj);
476 g_assert_cmpint (obj->ref_count, ==, 2);
477 g_object_unref (tmp);
478 g_assert_cmpint (obj->ref_count, ==, 1);
479
480 tmp = g_weak_ref_get (dynamic_weak);
481 g_assert (tmp == obj);
482 g_assert_cmpint (obj->ref_count, ==, 2);
483 g_object_unref (tmp);
484 g_assert_cmpint (obj->ref_count, ==, 1);
485
486 /* clearing a weak ref stops tracking */
487 g_weak_ref_clear (&weak);
488
489 /* setting a weak ref to NULL stops tracking too */
490 g_weak_ref_set (&weak2, NULL);
491 g_assert (g_weak_ref_get (&weak2) == NULL);
492 g_weak_ref_clear (&weak2);
493
494 /* setting a weak ref to a new object stops tracking the old one */
495 g_weak_ref_set (dynamic_weak, obj2);
496 tmp = g_weak_ref_get (dynamic_weak);
497 g_assert (tmp == obj2);
498 g_assert_cmpint (obj2->ref_count, ==, 2);
499 g_object_unref (tmp);
500 g_assert_cmpint (obj2->ref_count, ==, 1);
501
502 g_assert_cmpint (obj->ref_count, ==, 1);
503
504 /* free the object: weak3 is the only one left pointing there */
505 g_object_unref (obj);
506 g_assert (g_weak_ref_get (&weak3) == NULL);
507
508 /* setting a weak ref to a new object stops tracking the old one */
509 g_weak_ref_set (dynamic_weak, obj2);
510 tmp = g_weak_ref_get (dynamic_weak);
511 g_assert (tmp == obj2);
512 g_assert_cmpint (obj2->ref_count, ==, 2);
513 g_object_unref (tmp);
514 g_assert_cmpint (obj2->ref_count, ==, 1);
515
516 g_weak_ref_clear (&weak3);
517
518 /* clear and free dynamic_weak... */
519 g_weak_ref_clear (dynamic_weak);
520
521 /* ... to prove that doing so stops this from being a use-after-free */
522 g_object_unref (obj2);
523 g_free (dynamic_weak);
524 }
525
526 typedef struct
527 {
528 gboolean should_be_last;
529 gint count;
530 } Count;
531
532 static void
toggle_notify(gpointer data,GObject * obj,gboolean is_last)533 toggle_notify (gpointer data,
534 GObject *obj,
535 gboolean is_last)
536 {
537 Count *c = data;
538
539 g_assert (is_last == c->should_be_last);
540
541 c->count++;
542 }
543
544 static void
test_toggle_ref(void)545 test_toggle_ref (void)
546 {
547 GObject *obj;
548 Count c, c2;
549
550 obj = g_object_new (G_TYPE_OBJECT, NULL);
551
552 g_object_add_toggle_ref (obj, toggle_notify, &c);
553 g_object_add_toggle_ref (obj, toggle_notify, &c2);
554
555 c.should_be_last = c2.should_be_last = TRUE;
556 c.count = c2.count = 0;
557
558 g_object_unref (obj);
559
560 g_assert_cmpint (c.count, ==, 0);
561 g_assert_cmpint (c2.count, ==, 0);
562
563 g_object_ref (obj);
564
565 g_assert_cmpint (c.count, ==, 0);
566 g_assert_cmpint (c2.count, ==, 0);
567
568 g_object_remove_toggle_ref (obj, toggle_notify, &c2);
569
570 g_object_unref (obj);
571
572 g_assert_cmpint (c.count, ==, 1);
573
574 c.should_be_last = FALSE;
575
576 g_object_ref (obj);
577
578 g_assert_cmpint (c.count, ==, 2);
579
580 c.should_be_last = TRUE;
581
582 g_object_unref (obj);
583
584 g_assert_cmpint (c.count, ==, 3);
585
586 g_object_remove_toggle_ref (obj, toggle_notify, &c);
587 }
588
589 static gboolean destroyed;
590 static gint value;
591
592 static void
data_destroy(gpointer data)593 data_destroy (gpointer data)
594 {
595 g_assert_cmpint (GPOINTER_TO_INT (data), ==, value);
596
597 destroyed = TRUE;
598 }
599
600 static void
test_object_qdata(void)601 test_object_qdata (void)
602 {
603 GObject *obj;
604 gpointer v;
605 GQuark quark;
606
607 obj = g_object_new (G_TYPE_OBJECT, NULL);
608
609 value = 1;
610 destroyed = FALSE;
611 g_object_set_data_full (obj, "test", GINT_TO_POINTER (1), data_destroy);
612 v = g_object_get_data (obj, "test");
613 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1);
614 g_object_set_data_full (obj, "test", GINT_TO_POINTER (2), data_destroy);
615 g_assert (destroyed);
616 value = 2;
617 destroyed = FALSE;
618 v = g_object_steal_data (obj, "test");
619 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2);
620 g_assert (!destroyed);
621
622 value = 1;
623 destroyed = FALSE;
624 quark = g_quark_from_string ("test");
625 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (1), data_destroy);
626 v = g_object_get_qdata (obj, quark);
627 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1);
628 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (2), data_destroy);
629 g_assert (destroyed);
630 value = 2;
631 destroyed = FALSE;
632 v = g_object_steal_qdata (obj, quark);
633 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2);
634 g_assert (!destroyed);
635
636 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (3), data_destroy);
637 value = 3;
638 destroyed = FALSE;
639 g_object_unref (obj);
640
641 g_assert (destroyed);
642 }
643
644 typedef struct {
645 const gchar *value;
646 gint refcount;
647 } Value;
648
649 static gpointer
ref_value(gpointer value,gpointer user_data)650 ref_value (gpointer value, gpointer user_data)
651 {
652 Value *v = value;
653 Value **old_value_p = user_data;
654
655 if (old_value_p)
656 *old_value_p = v;
657
658 if (v)
659 v->refcount += 1;
660
661 return value;
662 }
663
664 static void
unref_value(gpointer value)665 unref_value (gpointer value)
666 {
667 Value *v = value;
668
669 v->refcount -= 1;
670 if (v->refcount == 0)
671 g_free (value);
672 }
673
674 static
675 Value *
new_value(const gchar * s)676 new_value (const gchar *s)
677 {
678 Value *v;
679
680 v = g_new (Value, 1);
681 v->value = s;
682 v->refcount = 1;
683
684 return v;
685 }
686
687 static void
test_object_qdata2(void)688 test_object_qdata2 (void)
689 {
690 GObject *obj;
691 Value *v, *v1, *v2, *v3, *old_val;
692 GDestroyNotify old_destroy;
693 gboolean res;
694
695 obj = g_object_new (G_TYPE_OBJECT, NULL);
696
697 v1 = new_value ("bla");
698
699 g_object_set_data_full (obj, "test", v1, unref_value);
700
701 v = g_object_get_data (obj, "test");
702 g_assert_cmpstr (v->value, ==, "bla");
703 g_assert_cmpint (v->refcount, ==, 1);
704
705 v = g_object_dup_data (obj, "test", ref_value, &old_val);
706 g_assert (old_val == v1);
707 g_assert_cmpstr (v->value, ==, "bla");
708 g_assert_cmpint (v->refcount, ==, 2);
709 unref_value (v);
710
711 v = g_object_dup_data (obj, "nono", ref_value, &old_val);
712 g_assert (old_val == NULL);
713 g_assert (v == NULL);
714
715 v2 = new_value ("not");
716
717 res = g_object_replace_data (obj, "test", v1, v2, unref_value, &old_destroy);
718 g_assert (res == TRUE);
719 g_assert (old_destroy == unref_value);
720 g_assert_cmpstr (v1->value, ==, "bla");
721 g_assert_cmpint (v1->refcount, ==, 1);
722
723 v = g_object_get_data (obj, "test");
724 g_assert_cmpstr (v->value, ==, "not");
725 g_assert_cmpint (v->refcount, ==, 1);
726
727 v3 = new_value ("xyz");
728 res = g_object_replace_data (obj, "test", v1, v3, unref_value, &old_destroy);
729 g_assert (res == FALSE);
730 g_assert_cmpstr (v2->value, ==, "not");
731 g_assert_cmpint (v2->refcount, ==, 1);
732
733 unref_value (v1);
734
735 res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy);
736 g_assert (res == FALSE);
737 g_assert_cmpstr (v2->value, ==, "not");
738 g_assert_cmpint (v2->refcount, ==, 1);
739
740 res = g_object_replace_data (obj, "test", v2, NULL, unref_value, &old_destroy);
741 g_assert (res == TRUE);
742 g_assert (old_destroy == unref_value);
743 g_assert_cmpstr (v2->value, ==, "not");
744 g_assert_cmpint (v2->refcount, ==, 1);
745
746 unref_value (v2);
747
748 v = g_object_get_data (obj, "test");
749 g_assert (v == NULL);
750
751 res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy);
752 g_assert (res == TRUE);
753
754 v = g_object_get_data (obj, "test");
755 g_assert (v == v3);
756
757 ref_value (v3, NULL);
758 g_assert_cmpint (v3->refcount, ==, 2);
759 g_object_unref (obj);
760 g_assert_cmpint (v3->refcount, ==, 1);
761 unref_value (v3);
762 }
763
764 int
main(int argc,char ** argv)765 main (int argc, char **argv)
766 {
767 g_test_init (&argc, &argv, NULL);
768
769 g_test_add_func ("/type/fundamentals", test_fundamentals);
770 g_test_add_func ("/type/qdata", test_type_qdata);
771 g_test_add_func ("/type/query", test_type_query);
772 g_test_add_func ("/type/class-private", test_class_private);
773 g_test_add_func ("/object/clear", test_clear);
774 g_test_add_func ("/object/clear-function", test_clear_function);
775 g_test_add_func ("/object/set", test_set);
776 g_test_add_func ("/object/set-function", test_set_function);
777 g_test_add_func ("/object/value", test_object_value);
778 g_test_add_func ("/object/initially-unowned", test_initially_unowned);
779 g_test_add_func ("/object/weak-pointer", test_weak_pointer);
780 g_test_add_func ("/object/weak-pointer/clear", test_weak_pointer_clear);
781 g_test_add_func ("/object/weak-pointer/clear-function", test_weak_pointer_clear_function);
782 g_test_add_func ("/object/weak-pointer/set", test_weak_pointer_set);
783 g_test_add_func ("/object/weak-pointer/set-function", test_weak_pointer_set_function);
784 g_test_add_func ("/object/weak-ref", test_weak_ref);
785 g_test_add_func ("/object/toggle-ref", test_toggle_ref);
786 g_test_add_func ("/object/qdata", test_object_qdata);
787 g_test_add_func ("/object/qdata2", test_object_qdata2);
788
789 return g_test_run ();
790 }
791