1 #include <glib-object.h>
4 test_fundamentals (void)
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));
30 g_assert (g_type_fundamental_next () == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST));
34 test_type_qdata (void)
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");
44 test_type_query (void)
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);
55 typedef struct _MyObject MyObject;
56 typedef struct _MyObjectClass MyObjectClass;
57 typedef struct _MyObjectClassPrivate MyObjectClassPrivate;
61 GObject parent_instance;
68 GObjectClass parent_class;
71 struct _MyObjectClassPrivate
73 gint secret_class_count;
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)) );
81 my_object_init (MyObject *obj)
87 my_object_class_init (MyObjectClass *klass)
92 test_class_private (void)
96 MyObjectClassPrivate *priv;
98 obj = g_object_new (my_object_get_type (), NULL);
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);
105 g_object_unref (obj);
107 g_assert_cmpint (g_type_qname (my_object_get_type ()), ==, g_quark_from_string ("MyObject"));
117 g_assert (o == NULL);
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);
124 g_assert_cmpint (tmp->ref_count, ==, 2);
126 g_assert_cmpint (tmp->ref_count, ==, 1);
127 g_assert (o == NULL);
129 g_object_unref (tmp);
133 test_clear_function (void)
135 volatile GObject *o = NULL;
138 (g_clear_object) (&o);
139 g_assert (o == NULL);
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);
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);
151 g_object_unref (tmp);
155 test_object_value (void)
159 GValue value = G_VALUE_INIT;
161 g_value_init (&value, G_TYPE_OBJECT);
163 v = g_object_new (G_TYPE_OBJECT, NULL);
164 g_value_take_object (&value, v);
166 v2 = g_value_get_object (&value);
169 v2 = g_value_dup_object (&value);
170 g_assert (v2 == v); /* objects use ref/unref for copy/free */
173 g_value_unset (&value);
177 test_initially_unowned (void)
181 obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
182 g_assert (g_object_is_floating (obj));
183 g_assert_cmpint (obj->ref_count, ==, 1);
185 g_object_ref_sink (obj);
186 g_assert (!g_object_is_floating (obj));
187 g_assert_cmpint (obj->ref_count, ==, 1);
189 g_object_ref_sink (obj);
190 g_assert (!g_object_is_floating (obj));
191 g_assert_cmpint (obj->ref_count, ==, 2);
193 g_object_unref (obj);
194 g_assert_cmpint (obj->ref_count, ==, 1);
196 g_object_force_floating (obj);
197 g_assert (g_object_is_floating (obj));
198 g_assert_cmpint (obj->ref_count, ==, 1);
200 g_object_ref_sink (obj);
201 g_object_unref (obj);
205 test_weak_pointer (void)
211 weak = weak2 = obj = g_object_new (G_TYPE_OBJECT, NULL);
212 g_assert_cmpint (obj->ref_count, ==, 1);
214 g_object_add_weak_pointer (obj, &weak);
215 g_object_add_weak_pointer (obj, &weak2);
216 g_assert_cmpint (obj->ref_count, ==, 1);
217 g_assert (weak == obj);
218 g_assert (weak2 == obj);
220 g_object_remove_weak_pointer (obj, &weak2);
221 g_assert_cmpint (obj->ref_count, ==, 1);
222 g_assert (weak == obj);
223 g_assert (weak2 == obj);
225 g_object_unref (obj);
226 g_assert (weak == NULL);
227 g_assert (weak2 == obj);
230 /* See gobject/tests/threadtests.c for the threaded version */
237 GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
238 GWeakRef weak2 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
239 GWeakRef weak3 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
240 GWeakRef *dynamic_weak = g_new (GWeakRef, 1);
242 /* you can initialize to empty like this... */
243 g_weak_ref_init (&weak2, NULL);
244 g_assert (g_weak_ref_get (&weak2) == NULL);
246 /* ... or via an initializer */
247 g_weak_ref_init (&weak3, NULL);
248 g_assert (g_weak_ref_get (&weak3) == NULL);
250 obj = g_object_new (G_TYPE_OBJECT, NULL);
251 g_assert_cmpint (obj->ref_count, ==, 1);
253 obj2 = g_object_new (G_TYPE_OBJECT, NULL);
254 g_assert_cmpint (obj2->ref_count, ==, 1);
256 /* you can init with an object (even if uninitialized) */
257 g_weak_ref_init (&weak, obj);
258 g_weak_ref_init (dynamic_weak, obj);
259 /* or set to point at an object, if initialized (maybe to 0) */
260 g_weak_ref_set (&weak2, obj);
261 g_weak_ref_set (&weak3, obj);
262 /* none of this affects its refcount */
263 g_assert_cmpint (obj->ref_count, ==, 1);
265 /* getting the value takes a ref */
266 tmp = g_weak_ref_get (&weak);
267 g_assert (tmp == obj);
268 g_assert_cmpint (obj->ref_count, ==, 2);
269 g_object_unref (tmp);
270 g_assert_cmpint (obj->ref_count, ==, 1);
272 tmp = g_weak_ref_get (&weak2);
273 g_assert (tmp == obj);
274 g_assert_cmpint (obj->ref_count, ==, 2);
275 g_object_unref (tmp);
276 g_assert_cmpint (obj->ref_count, ==, 1);
278 tmp = g_weak_ref_get (&weak3);
279 g_assert (tmp == obj);
280 g_assert_cmpint (obj->ref_count, ==, 2);
281 g_object_unref (tmp);
282 g_assert_cmpint (obj->ref_count, ==, 1);
284 tmp = g_weak_ref_get (dynamic_weak);
285 g_assert (tmp == obj);
286 g_assert_cmpint (obj->ref_count, ==, 2);
287 g_object_unref (tmp);
288 g_assert_cmpint (obj->ref_count, ==, 1);
290 /* clearing a weak ref stops tracking */
291 g_weak_ref_clear (&weak);
293 /* setting a weak ref to NULL stops tracking too */
294 g_weak_ref_set (&weak2, NULL);
295 g_assert (g_weak_ref_get (&weak2) == NULL);
296 g_weak_ref_clear (&weak2);
298 /* setting a weak ref to a new object stops tracking the old one */
299 g_weak_ref_set (dynamic_weak, obj2);
300 tmp = g_weak_ref_get (dynamic_weak);
301 g_assert (tmp == obj2);
302 g_assert_cmpint (obj2->ref_count, ==, 2);
303 g_object_unref (tmp);
304 g_assert_cmpint (obj2->ref_count, ==, 1);
306 g_assert_cmpint (obj->ref_count, ==, 1);
308 /* free the object: weak3 is the only one left pointing there */
309 g_object_unref (obj);
310 g_assert (g_weak_ref_get (&weak3) == NULL);
312 /* setting a weak ref to a new object stops tracking the old one */
313 g_weak_ref_set (dynamic_weak, obj2);
314 tmp = g_weak_ref_get (dynamic_weak);
315 g_assert (tmp == obj2);
316 g_assert_cmpint (obj2->ref_count, ==, 2);
317 g_object_unref (tmp);
318 g_assert_cmpint (obj2->ref_count, ==, 1);
320 g_weak_ref_clear (&weak3);
322 /* clear and free dynamic_weak... */
323 g_weak_ref_clear (dynamic_weak);
325 /* ... to prove that doing so stops this from being a use-after-free */
326 g_object_unref (obj2);
327 g_free (dynamic_weak);
331 main (int argc, char **argv)
333 g_test_init (&argc, &argv, NULL);
337 g_test_add_func ("/type/fundamentals", test_fundamentals);
338 g_test_add_func ("/type/qdata", test_type_qdata);
339 g_test_add_func ("/type/query", test_type_query);
340 g_test_add_func ("/type/class-private", test_class_private);
341 g_test_add_func ("/object/clear", test_clear);
342 g_test_add_func ("/object/clear-function", test_clear_function);
343 g_test_add_func ("/object/value", test_object_value);
344 g_test_add_func ("/object/initially-unowned", test_initially_unowned);
345 g_test_add_func ("/object/weak-pointer", test_weak_pointer);
346 g_test_add_func ("/object/weak-ref", test_weak_ref);
348 return g_test_run ();