Merge remote branch 'gvdb/master'
[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 int
211 main (int argc, char *argv[])
212 {
213   g_type_init ();
214   g_test_init (&argc, &argv, NULL);
215
216   g_test_bug_base ("http://bugzilla.gnome.org/");
217
218   g_test_add_func ("/properties/install", properties_install);
219   g_test_add_func ("/properties/notify", properties_notify);
220
221   return g_test_run ();
222 }