gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / gobject / tests / object.c
1 #include <glib-object.h>
2
3 /* --------------------------------- */
4 /* test_object_constructor_singleton */
5
6 typedef GObject MySingletonObject;
7 typedef GObjectClass MySingletonObjectClass;
8
9 GType my_singleton_object_get_type (void);
10
11 G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT)
12
13 static MySingletonObject *singleton;
14
15 static void
16 my_singleton_object_init (MySingletonObject *obj)
17 {
18 }
19
20 static GObject *
21 my_singleton_object_constructor (GType                  type,
22                                  guint                  n_construct_properties,
23                                  GObjectConstructParam *construct_params)
24 {
25   GObject *object;
26
27   if (singleton)
28     return g_object_ref (singleton);
29
30   object = G_OBJECT_CLASS (my_singleton_object_parent_class)->
31     constructor (type, n_construct_properties, construct_params);
32   singleton = (MySingletonObject *)object;
33
34   return object;
35 }
36
37 static void
38 my_singleton_object_finalize (MySingletonObject *obj)
39 {
40   singleton = NULL;
41
42   G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj);
43 }
44
45 static void
46 my_singleton_object_class_init (MySingletonObjectClass *klass)
47 {
48   GObjectClass *object_class = G_OBJECT_CLASS (klass);
49
50   object_class->constructor = my_singleton_object_constructor;
51   object_class->finalize = my_singleton_object_finalize;
52 }
53
54 static void
55 test_object_constructor_singleton (void)
56 {
57   MySingletonObject *one, *two, *three;
58
59   one = g_object_new (my_singleton_object_get_type (), NULL);
60   g_assert_cmpint (G_OBJECT (one)->ref_count, ==, 1);
61
62   two = g_object_new (my_singleton_object_get_type (), NULL);
63   g_assert (one == two);
64   g_assert_cmpint (G_OBJECT (two)->ref_count, ==, 2);
65
66   three = g_object_new (my_singleton_object_get_type (), NULL);
67   g_assert (one == three);
68   g_assert_cmpint (G_OBJECT (three)->ref_count, ==, 3);
69
70   g_object_add_weak_pointer (G_OBJECT (one), (gpointer *)&one);
71
72   g_object_unref (one);
73   g_assert (one != NULL);
74
75   g_object_unref (three);
76   g_object_unref (two);
77
78   g_assert (one == NULL);
79 }
80
81 /* ----------------------------------- */
82 /* test_object_constructor_infanticide */
83
84 typedef GObject MyInfanticideObject;
85 typedef GObjectClass MyInfanticideObjectClass;
86
87 GType my_infanticide_object_get_type (void);
88
89 G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT)
90
91 static void
92 my_infanticide_object_init (MyInfanticideObject *obj)
93 {
94 }
95
96 static GObject *
97 my_infanticide_object_constructor (GType                  type,
98                                    guint                  n_construct_properties,
99                                    GObjectConstructParam *construct_params)
100 {
101   GObject *object;
102
103   object = G_OBJECT_CLASS (my_infanticide_object_parent_class)->
104     constructor (type, n_construct_properties, construct_params);
105
106   g_object_unref (object);
107
108   return NULL;
109 }
110
111 static void
112 my_infanticide_object_class_init (MyInfanticideObjectClass *klass)
113 {
114   GObjectClass *object_class = G_OBJECT_CLASS (klass);
115
116   object_class->constructor = my_infanticide_object_constructor;
117 }
118
119 static void
120 test_object_constructor_infanticide (void)
121 {
122   GObject *obj;
123   int i;
124
125 #ifndef G_ENABLE_DEBUG
126   g_test_skip ("skip tests that rely on debug-only warnings");
127   return;
128 #endif
129
130   g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576");
131
132   for (i = 0; i < 1000; i++)
133     {
134       g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
135                              "*finalized while still in-construction*");
136       g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
137                              "*Custom constructor*returned NULL*");
138       obj = g_object_new (my_infanticide_object_get_type (), NULL);
139       g_assert_null (obj);
140       g_test_assert_expected_messages ();
141     }
142 }
143
144 /* --------------------------------- */
145
146 int
147 main (int argc, char *argv[])
148 {
149   g_test_init (&argc, &argv, NULL);
150
151   g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton);
152   g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide);
153
154   return g_test_run ();
155 }