More GValue conversion tests
[platform/upstream/glib.git] / gobject / tests / properties.c
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 } TestObject;
11
12 typedef struct _TestObjectClass {
13   GObjectClass parent_class;
14 } TestObjectClass;
15
16 enum { PROP_0, PROP_FOO, PROP_BAR, PROP_BAZ, N_PROPERTIES };
17
18 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
19
20 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
21
22 static void
23 test_object_set_foo (TestObject *obj,
24                      gint        foo)
25 {
26   if (obj->foo != foo)
27     {
28       obj->foo = foo;
29
30       g_assert (properties[PROP_FOO] != NULL);
31       g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_FOO]);
32     }
33 }
34
35 static void
36 test_object_set_bar (TestObject *obj,
37                      gboolean    bar)
38 {
39   bar = !!bar;
40
41   if (obj->bar != bar)
42     {
43       obj->bar = bar;
44
45       g_assert (properties[PROP_BAR] != NULL);
46       g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAR]);
47     }
48 }
49
50 static void
51 test_object_set_baz (TestObject  *obj,
52                      const gchar *baz)
53 {
54   if (g_strcmp0 (obj->baz, baz) != 0)
55     {
56       g_free (obj->baz);
57       obj->baz = g_strdup (baz);
58
59       g_assert (properties[PROP_BAZ] != NULL);
60       g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_BAZ]);
61     }
62 }
63
64 static void
65 test_object_finalize (GObject *gobject)
66 {
67   g_free (((TestObject *) gobject)->baz);
68
69   G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
70 }
71
72 static void
73 test_object_set_property (GObject *gobject,
74                           guint prop_id,
75                           const GValue *value,
76                           GParamSpec *pspec)
77 {
78   TestObject *tobj = (TestObject *) gobject;
79
80   g_assert_cmpint (prop_id, !=, 0);
81   g_assert_cmpint (prop_id, !=, N_PROPERTIES);
82   g_assert (pspec == properties[prop_id]);
83
84   switch (prop_id)
85     {
86     case PROP_FOO:
87       test_object_set_foo (tobj, g_value_get_int (value));
88       break;
89
90     case PROP_BAR:
91       test_object_set_bar (tobj, g_value_get_boolean (value));
92       break;
93
94     case PROP_BAZ:
95       test_object_set_baz (tobj, g_value_get_string (value));
96       break;
97
98     default:
99       g_assert_not_reached ();
100     }
101 }
102
103 static void
104 test_object_get_property (GObject *gobject,
105                           guint prop_id,
106                           GValue *value,
107                           GParamSpec *pspec)
108 {
109   TestObject *tobj = (TestObject *) gobject;
110
111   g_assert_cmpint (prop_id, !=, 0);
112   g_assert_cmpint (prop_id, !=, N_PROPERTIES);
113   g_assert (pspec == properties[prop_id]);
114
115   switch (prop_id)
116     {
117     case PROP_FOO:
118       g_value_set_int (value, tobj->foo);
119       break;
120
121     case PROP_BAR:
122       g_value_set_boolean (value, tobj->bar);
123       break;
124
125     case PROP_BAZ:
126       g_value_set_string (value, tobj->baz);
127       break;
128
129     default:
130       g_assert_not_reached ();
131     }
132 }
133
134 static void
135 test_object_class_init (TestObjectClass *klass)
136 {
137   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
138
139   properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "Foo",
140                                            -1, G_MAXINT,
141                                            0,
142                                            G_PARAM_READWRITE);
143   properties[PROP_BAR] = g_param_spec_boolean ("bar", "Bar", "Bar",
144                                                FALSE,
145                                                G_PARAM_READWRITE);
146   properties[PROP_BAZ] = g_param_spec_string ("baz", "Baz", "Baz",
147                                               NULL,
148                                               G_PARAM_READWRITE);
149
150   gobject_class->set_property = test_object_set_property;
151   gobject_class->get_property = test_object_get_property;
152   gobject_class->finalize = test_object_finalize;
153
154   g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
155 }
156
157 static void
158 test_object_init (TestObject *self)
159 {
160   self->foo = 42;
161   self->bar = TRUE;
162   self->baz = g_strdup ("Hello");
163 }
164
165 static void
166 properties_install (void)
167 {
168   TestObject *obj = g_object_new (test_object_get_type (), NULL);
169   GParamSpec *pspec;
170
171   g_assert (properties[PROP_FOO] != NULL);
172
173   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), "foo");
174   g_assert (properties[PROP_FOO] == pspec);
175
176   g_object_unref (obj);
177 }
178
179 typedef struct {
180   const gchar *name;
181   GParamSpec *pspec;
182 } TestNotifyClosure;
183
184 static void
185 on_notify (GObject           *gobject,
186            GParamSpec        *pspec,
187            TestNotifyClosure *clos)
188 {
189   g_assert (clos->pspec == pspec);
190   g_assert_cmpstr (clos->name, ==, pspec->name);
191 }
192
193 static void
194 properties_notify (void)
195 {
196   TestObject *obj = g_object_new (test_object_get_type (), NULL);
197   TestNotifyClosure clos;
198
199   g_assert (properties[PROP_FOO] != NULL);
200
201   clos.name = "foo";
202   clos.pspec = properties[PROP_FOO];
203
204   g_signal_connect (obj, "notify", G_CALLBACK (on_notify), &clos);
205   g_object_set (obj, "foo", 47, NULL);
206
207   g_object_unref (obj);
208 }
209
210 static void
211 properties_construct (void)
212 {
213   TestObject *obj;
214   gint val;
215
216   g_test_bug ("630357");
217
218   /* more than 16 args triggers a realloc in g_object_new_valist() */
219   obj = g_object_new (test_object_get_type (),
220                       "foo", 1,
221                       "foo", 2,
222                       "foo", 3,
223                       "foo", 4,
224                       "foo", 5,
225                       "foo", 6,
226                       "foo", 7,
227                       "foo", 8,
228                       "foo", 9,
229                       "foo", 10,
230                       "foo", 11,
231                       "foo", 12,
232                       "foo", 13,
233                       "foo", 14,
234                       "foo", 15,
235                       "foo", 16,
236                       "foo", 17,
237                       "foo", 18,
238                       NULL);
239
240   g_object_get (obj, "foo", &val, NULL);
241   g_assert (val == 18);
242
243   g_object_unref (obj);
244 }
245
246 int
247 main (int argc, char *argv[])
248 {
249   g_type_init ();
250   g_test_init (&argc, &argv, NULL);
251
252   g_test_bug_base ("http://bugzilla.gnome.org/");
253
254   g_test_add_func ("/properties/install", properties_install);
255   g_test_add_func ("/properties/notify", properties_notify);
256   g_test_add_func ("/properties/construct", properties_construct);
257
258   return g_test_run ();
259 }