gtestutils: Fix a typo in a documentation comment
[glib.git] / gobject / tests / properties.c
blobf9923170734e8e49d2999ec0ac1a493e431039da
1 #include <stdlib.h>
2 #include <gstdio.h>
3 #include <glib-object.h>
5 typedef struct _TestObject {
6 GObject parent_instance;
7 gint foo;
8 gboolean bar;
9 gchar *baz;
10 gchar *quux;
11 } TestObject;
13 typedef struct _TestObjectClass {
14 GObjectClass parent_class;
15 } TestObjectClass;
17 enum { PROP_0, PROP_FOO, PROP_BAR, PROP_BAZ, PROP_QUUX, N_PROPERTIES };
19 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
21 static GType test_object_get_type (void);
22 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
24 static void
25 test_object_set_foo (TestObject *obj,
26 gint foo)
28 if (obj->foo != foo)
30 obj->foo = foo;
32 g_assert (properties[PROP_FOO] != NULL);
33 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_FOO]);
37 static void
38 test_object_set_bar (TestObject *obj,
39 gboolean bar)
41 bar = !!bar;
43 if (obj->bar != bar)
45 obj->bar = bar;
47 g_assert (properties[PROP_BAR] != NULL);
48 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAR]);
52 static void
53 test_object_set_baz (TestObject *obj,
54 const gchar *baz)
56 if (g_strcmp0 (obj->baz, baz) != 0)
58 g_free (obj->baz);
59 obj->baz = g_strdup (baz);
61 g_assert (properties[PROP_BAZ] != NULL);
62 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAZ]);
66 static void
67 test_object_set_quux (TestObject *obj,
68 const gchar *quux)
70 if (g_strcmp0 (obj->quux, quux) != 0)
72 g_free (obj->quux);
73 obj->quux = g_strdup (quux);
75 g_assert (properties[PROP_QUUX] != NULL);
76 g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_QUUX]);
80 static void
81 test_object_finalize (GObject *gobject)
83 g_free (((TestObject *) gobject)->baz);
85 /* When the ref_count of an object is zero it is still
86 * possible to notify the property, but it should do
87 * nothing and silenty quit (bug #705570)
89 g_object_notify (gobject, "foo");
90 g_object_notify_by_pspec (gobject, properties[PROP_BAR]);
92 G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
95 static void
96 test_object_set_property (GObject *gobject,
97 guint prop_id,
98 const GValue *value,
99 GParamSpec *pspec)
101 TestObject *tobj = (TestObject *) gobject;
103 g_assert_cmpint (prop_id, !=, 0);
104 g_assert_cmpint (prop_id, !=, N_PROPERTIES);
105 g_assert (pspec == properties[prop_id]);
107 switch (prop_id)
109 case PROP_FOO:
110 test_object_set_foo (tobj, g_value_get_int (value));
111 break;
113 case PROP_BAR:
114 test_object_set_bar (tobj, g_value_get_boolean (value));
115 break;
117 case PROP_BAZ:
118 test_object_set_baz (tobj, g_value_get_string (value));
119 break;
121 case PROP_QUUX:
122 test_object_set_quux (tobj, g_value_get_string (value));
123 break;
125 default:
126 g_assert_not_reached ();
130 static void
131 test_object_get_property (GObject *gobject,
132 guint prop_id,
133 GValue *value,
134 GParamSpec *pspec)
136 TestObject *tobj = (TestObject *) gobject;
138 g_assert_cmpint (prop_id, !=, 0);
139 g_assert_cmpint (prop_id, !=, N_PROPERTIES);
140 g_assert (pspec == properties[prop_id]);
142 switch (prop_id)
144 case PROP_FOO:
145 g_value_set_int (value, tobj->foo);
146 break;
148 case PROP_BAR:
149 g_value_set_boolean (value, tobj->bar);
150 break;
152 case PROP_BAZ:
153 g_value_set_string (value, tobj->baz);
154 break;
156 case PROP_QUUX:
157 g_value_set_string (value, tobj->quux);
158 break;
160 default:
161 g_assert_not_reached ();
165 static void
166 test_object_class_init (TestObjectClass *klass)
168 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
170 properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "Foo",
171 -1, G_MAXINT,
173 G_PARAM_READWRITE);
174 properties[PROP_BAR] = g_param_spec_boolean ("bar", "Bar", "Bar",
175 FALSE,
176 G_PARAM_READWRITE);
177 properties[PROP_BAZ] = g_param_spec_string ("baz", "Baz", "Baz",
178 NULL,
179 G_PARAM_READWRITE);
180 properties[PROP_QUUX] = g_param_spec_string ("quux", "quux", "quux",
181 NULL,
182 G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
184 gobject_class->set_property = test_object_set_property;
185 gobject_class->get_property = test_object_get_property;
186 gobject_class->finalize = test_object_finalize;
188 g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
191 static void
192 test_object_init (TestObject *self)
194 self->foo = 42;
195 self->bar = TRUE;
196 self->baz = g_strdup ("Hello");
197 self->quux = NULL;
200 static void
201 properties_install (void)
203 TestObject *obj = g_object_new (test_object_get_type (), NULL);
204 GParamSpec *pspec;
206 g_assert (properties[PROP_FOO] != NULL);
208 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), "foo");
209 g_assert (properties[PROP_FOO] == pspec);
211 g_object_unref (obj);
214 typedef struct {
215 const gchar *name;
216 GParamSpec *pspec;
217 gboolean fired;
218 } TestNotifyClosure;
220 static void
221 on_notify (GObject *gobject,
222 GParamSpec *pspec,
223 TestNotifyClosure *clos)
225 g_assert (clos->pspec == pspec);
226 g_assert_cmpstr (clos->name, ==, pspec->name);
227 clos->fired = TRUE;
230 static void
231 properties_notify (void)
233 TestObject *obj = g_object_new (test_object_get_type (), NULL);
234 TestNotifyClosure clos;
236 g_assert (properties[PROP_FOO] != NULL);
237 g_assert (properties[PROP_QUUX] != NULL);
238 g_signal_connect (obj, "notify", G_CALLBACK (on_notify), &clos);
240 clos.name = "foo";
241 clos.pspec = properties[PROP_FOO];
243 clos.fired = FALSE;
244 g_object_set (obj, "foo", 47, NULL);
245 g_assert (clos.fired);
247 clos.name = "baz";
248 clos.pspec = properties[PROP_BAZ];
250 clos.fired = FALSE;
251 g_object_set (obj, "baz", "something new", NULL);
252 g_assert (clos.fired);
254 /* baz lacks explicit notify, so we will see this twice */
255 clos.fired = FALSE;
256 g_object_set (obj, "baz", "something new", NULL);
257 g_assert (clos.fired);
259 /* quux on the other hand, ... */
260 clos.name = "quux";
261 clos.pspec = properties[PROP_QUUX];
263 clos.fired = FALSE;
264 g_object_set (obj, "quux", "something new", NULL);
265 g_assert (clos.fired);
267 /* no change; no notify */
268 clos.fired = FALSE;
269 g_object_set (obj, "quux", "something new", NULL);
270 g_assert (!clos.fired);
273 g_object_unref (obj);
276 typedef struct {
277 GParamSpec *pspec[3];
278 gint pos;
279 } Notifys;
281 static void
282 on_notify2 (GObject *gobject,
283 GParamSpec *pspec,
284 Notifys *n)
286 g_assert (n->pspec[n->pos] == pspec);
287 n->pos++;
290 static void
291 properties_notify_queue (void)
293 TestObject *obj = g_object_new (test_object_get_type (), NULL);
294 Notifys n;
296 g_assert (properties[PROP_FOO] != NULL);
298 n.pspec[0] = properties[PROP_BAZ];
299 n.pspec[1] = properties[PROP_BAR];
300 n.pspec[2] = properties[PROP_FOO];
301 n.pos = 0;
303 g_signal_connect (obj, "notify", G_CALLBACK (on_notify2), &n);
305 g_object_freeze_notify (G_OBJECT (obj));
306 g_object_set (obj, "foo", 47, NULL);
307 g_object_set (obj, "bar", TRUE, "foo", 42, "baz", "abc", NULL);
308 g_object_thaw_notify (G_OBJECT (obj));
309 g_assert (n.pos == 3);
311 g_object_unref (obj);
314 static void
315 properties_construct (void)
317 TestObject *obj;
318 gint val;
319 gboolean b;
320 gchar *s;
322 g_test_bug ("630357");
324 /* more than 16 args triggers a realloc in g_object_new_valist() */
325 obj = g_object_new (test_object_get_type (),
326 "foo", 1,
327 "foo", 2,
328 "foo", 3,
329 "foo", 4,
330 "foo", 5,
331 "bar", FALSE,
332 "foo", 6,
333 "foo", 7,
334 "foo", 8,
335 "foo", 9,
336 "foo", 10,
337 "baz", "boo",
338 "foo", 11,
339 "foo", 12,
340 "foo", 13,
341 "foo", 14,
342 "foo", 15,
343 "foo", 16,
344 "foo", 17,
345 "foo", 18,
346 NULL);
348 g_object_get (obj, "foo", &val, NULL);
349 g_assert (val == 18);
350 g_object_get (obj, "bar", &b, NULL);
351 g_assert (!b);
352 g_object_get (obj, "baz", &s, NULL);
353 g_assert_cmpstr (s, ==, "boo");
354 g_free (s);
356 g_object_unref (obj);
360 main (int argc, char *argv[])
362 g_test_init (&argc, &argv, NULL);
364 g_test_bug_base ("http://bugzilla.gnome.org/");
366 g_test_add_func ("/properties/install", properties_install);
367 g_test_add_func ("/properties/notify", properties_notify);
368 g_test_add_func ("/properties/notify-queue", properties_notify_queue);
369 g_test_add_func ("/properties/construct", properties_construct);
371 return g_test_run ();