|
1 /* GObject - GLib Type, Object, Parameter and Signal Library |
|
2 * Copyright (C) 2001, 2003 Red Hat, Inc. |
|
3 * Portions copyright (c) 2006-2009 Nokia Corporation. All rights reserved. |
|
4 * This library is free software; you can redistribute it and/or |
|
5 * modify it under the terms of the GNU Lesser General Public |
|
6 * License as published by the Free Software Foundation; either |
|
7 * version 2 of the License, or (at your option) any later version. |
|
8 * |
|
9 * This library is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 * Lesser General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU Lesser General |
|
15 * Public License along with this library; if not, write to the |
|
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
|
17 * Boston, MA 02111-1307, USA. |
|
18 */ |
|
19 |
|
20 #undef G_LOG_DOMAIN |
|
21 #define G_LOG_DOMAIN "TestIfaceInit" |
|
22 |
|
23 #undef G_DISABLE_ASSERT |
|
24 #undef G_DISABLE_CHECKS |
|
25 #undef G_DISABLE_CAST_CHECKS |
|
26 |
|
27 #include <glib-object.h> |
|
28 |
|
29 #include "testcommon.h" |
|
30 #ifdef __SYMBIAN32__ |
|
31 #include "mrt2_glib2_test.h" |
|
32 #endif //__SYMBIAN32__ |
|
33 |
|
34 /* What this test tests is the ability to add interfaces dynamically; in |
|
35 * particular adding interfaces to a class while that class is being |
|
36 * initialized. |
|
37 * |
|
38 * The test defines 5 interfaces: |
|
39 * |
|
40 * - TestIface1 is added before the class is initialized |
|
41 * - TestIface2 is added in base_object_base_init() |
|
42 * - TestIface3 is added in test_iface1_base_init() |
|
43 * - TestIface4 is added in test_object_class_init() |
|
44 * - TestIface5 is added in test_object_test_iface1_init() |
|
45 * - TestIface6 is added after the class is initialized |
|
46 */ |
|
47 |
|
48 /* All 6 interfaces actually share the same class structure, though |
|
49 * we use separate typedefs |
|
50 */ |
|
51 typedef struct _TestIfaceClass TestIfaceClass; |
|
52 |
|
53 struct _TestIfaceClass |
|
54 { |
|
55 GTypeInterface base_iface; |
|
56 guint val; |
|
57 guint base_val; |
|
58 guint default_val; |
|
59 }; |
|
60 |
|
61 #define TEST_TYPE_IFACE1 (test_iface1_get_type ()) |
|
62 #define TEST_IFACE1_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE1, TestIface1Class)) |
|
63 typedef struct _TestIface1 TestIface1; |
|
64 typedef struct _TestIfaceClass TestIface1Class; |
|
65 |
|
66 static void test_iface1_base_init (TestIface1Class *iface); |
|
67 static void test_iface1_default_init (TestIface1Class *iface, gpointer class_data); |
|
68 |
|
69 static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init, test_iface1_default_init) |
|
70 |
|
71 #define TEST_TYPE_IFACE2 (test_iface2_get_type ()) |
|
72 #define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) |
|
73 typedef struct _TestIface2 TestIface2; |
|
74 typedef struct _TestIfaceClass TestIface2Class; |
|
75 |
|
76 static void test_iface2_base_init (TestIface2Class *iface); |
|
77 |
|
78 static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init, NULL) |
|
79 |
|
80 #define TEST_TYPE_IFACE3 (test_iface3_get_type ()) |
|
81 #define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) |
|
82 typedef struct _TestIface3 TestIface3; |
|
83 typedef struct _TestIfaceClass TestIface3Class; |
|
84 |
|
85 static void test_iface3_base_init (TestIface3Class *iface); |
|
86 |
|
87 static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init, NULL) |
|
88 |
|
89 #define TEST_TYPE_IFACE4 (test_iface4_get_type ()) |
|
90 #define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) |
|
91 typedef struct _TestIface4 TestIface4; |
|
92 typedef struct _TestIfaceClass TestIface4Class; |
|
93 |
|
94 static void test_iface4_base_init (TestIface4Class *iface); |
|
95 |
|
96 static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init, NULL) |
|
97 |
|
98 #define TEST_TYPE_IFACE5 (test_iface5_get_type ()) |
|
99 #define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) |
|
100 typedef struct _TestIface5 TestIface5; |
|
101 typedef struct _TestIfaceClass TestIface5Class; |
|
102 |
|
103 static void test_iface5_base_init (TestIface5Class *iface); |
|
104 |
|
105 static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init, NULL) |
|
106 |
|
107 #define TEST_TYPE_IFACE6 (test_iface6_get_type ()) |
|
108 #define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) |
|
109 typedef struct _TestIface6 TestIface6; |
|
110 typedef struct _TestIfaceClass TestIface6Class; |
|
111 |
|
112 static void test_iface6_base_init (TestIface6Class *iface); |
|
113 |
|
114 static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init, NULL) |
|
115 |
|
116 /* |
|
117 * BaseObject, a parent class for TestObject |
|
118 */ |
|
119 #define BASE_TYPE_OBJECT (base_object_get_type ()) |
|
120 typedef struct _BaseObject BaseObject; |
|
121 typedef struct _BaseObjectClass BaseObjectClass; |
|
122 |
|
123 struct _BaseObject |
|
124 { |
|
125 GObject parent_instance; |
|
126 }; |
|
127 struct _BaseObjectClass |
|
128 { |
|
129 GObjectClass parent_class; |
|
130 }; |
|
131 |
|
132 /* |
|
133 * TestObject, a parent class for TestObject |
|
134 */ |
|
135 #define TEST_TYPE_OBJECT (test_object_get_type ()) |
|
136 typedef struct _TestObject TestObject; |
|
137 typedef struct _TestObjectClass TestObjectClass; |
|
138 |
|
139 struct _TestObject |
|
140 { |
|
141 BaseObject parent_instance; |
|
142 }; |
|
143 struct _TestObjectClass |
|
144 { |
|
145 BaseObjectClass parent_class; |
|
146 }; |
|
147 |
|
148 #define TEST_CALLED_ONCE() G_STMT_START { \ |
|
149 static gboolean called = 0; \ |
|
150 g_assert (!called); \ |
|
151 called = TRUE; \ |
|
152 } G_STMT_END |
|
153 |
|
154 #define CHECK_IFACE_TWICE(iface) G_STMT_START { \ |
|
155 static guint n_calls = 0; \ |
|
156 n_calls++; \ |
|
157 g_assert (n_calls <= 2); \ |
|
158 g_assert (G_TYPE_IS_INTERFACE (((GTypeInterface*) iface)->g_type)); \ |
|
159 if (n_calls == 1) \ |
|
160 g_assert (((GTypeInterface*) iface)->g_instance_type == 0); \ |
|
161 else \ |
|
162 g_assert (G_TYPE_IS_OBJECT (((GTypeInterface*) iface)->g_instance_type)); \ |
|
163 } G_STMT_END |
|
164 |
|
165 #define ADD_IFACE(n) G_STMT_START { \ |
|
166 static GInterfaceInfo iface_info = { \ |
|
167 (GInterfaceInitFunc)test_object_test_iface##n##_init, \ |
|
168 NULL, NULL }; \ |
|
169 \ |
|
170 g_type_add_interface_static (TEST_TYPE_OBJECT, \ |
|
171 test_iface##n##_get_type (), \ |
|
172 &iface_info); \ |
|
173 \ |
|
174 } G_STMT_END |
|
175 |
|
176 static gboolean base1, base2, base3, base4, base5, base6; |
|
177 static gboolean iface1, iface2, iface3, iface4, iface5, iface6; |
|
178 |
|
179 static void test_object_test_iface1_init (TestIface1Class *iface); |
|
180 static void test_object_test_iface2_init (TestIface1Class *iface); |
|
181 static void test_object_test_iface3_init (TestIface3Class *iface); |
|
182 static void test_object_test_iface4_init (TestIface4Class *iface); |
|
183 static void test_object_test_iface5_init (TestIface5Class *iface); |
|
184 static void test_object_test_iface6_init (TestIface6Class *iface); |
|
185 |
|
186 static GType test_object_get_type (void); |
|
187 |
|
188 static void |
|
189 test_object_test_iface1_init (TestIface1Class *iface) |
|
190 { |
|
191 TEST_CALLED_ONCE(); |
|
192 |
|
193 g_assert (iface->default_val == 0x111111); |
|
194 |
|
195 iface->val = 0x10001; |
|
196 |
|
197 ADD_IFACE(5); |
|
198 |
|
199 iface1 = TRUE; |
|
200 } |
|
201 |
|
202 static void |
|
203 test_object_test_iface2_init (TestIface2Class *iface) |
|
204 { |
|
205 TEST_CALLED_ONCE(); |
|
206 |
|
207 iface->val = 0x20002; |
|
208 |
|
209 iface2 = TRUE; |
|
210 } |
|
211 |
|
212 static void |
|
213 test_object_test_iface3_init (TestIface3Class *iface) |
|
214 { |
|
215 TEST_CALLED_ONCE(); |
|
216 |
|
217 iface->val = 0x30003; |
|
218 |
|
219 iface3 = TRUE; |
|
220 } |
|
221 |
|
222 static void |
|
223 test_object_test_iface4_init (TestIface4Class *iface) |
|
224 { |
|
225 TEST_CALLED_ONCE(); |
|
226 |
|
227 iface->val = 0x40004; |
|
228 |
|
229 iface4 = TRUE; |
|
230 } |
|
231 |
|
232 static void |
|
233 test_object_test_iface5_init (TestIface5Class *iface) |
|
234 { |
|
235 TEST_CALLED_ONCE(); |
|
236 |
|
237 iface->val = 0x50005; |
|
238 |
|
239 iface5 = TRUE; |
|
240 } |
|
241 |
|
242 static void |
|
243 test_object_test_iface6_init (TestIface6Class *iface) |
|
244 { |
|
245 TEST_CALLED_ONCE(); |
|
246 |
|
247 iface->val = 0x60006; |
|
248 |
|
249 iface6 = TRUE; |
|
250 } |
|
251 |
|
252 static void |
|
253 test_iface1_default_init (TestIface1Class *iface, |
|
254 gpointer class_data) |
|
255 { |
|
256 TEST_CALLED_ONCE(); |
|
257 g_assert (iface->base_iface.g_type == TEST_TYPE_IFACE1); |
|
258 g_assert (iface->base_iface.g_instance_type == 0); |
|
259 g_assert (iface->base_val == 0x110011); |
|
260 g_assert (iface->val == 0); |
|
261 g_assert (iface->default_val == 0); |
|
262 iface->default_val = 0x111111; |
|
263 } |
|
264 |
|
265 static void |
|
266 test_iface1_base_init (TestIface1Class *iface) |
|
267 { |
|
268 static guint n_calls = 0; |
|
269 n_calls++; |
|
270 g_assert (n_calls <= 2); |
|
271 |
|
272 if (n_calls == 1) |
|
273 { |
|
274 iface->base_val = 0x110011; |
|
275 g_assert (iface->default_val == 0); |
|
276 } |
|
277 else |
|
278 { |
|
279 g_assert (iface->base_val == 0x110011); |
|
280 g_assert (iface->default_val == 0x111111); |
|
281 } |
|
282 |
|
283 if (n_calls == 1) |
|
284 ADD_IFACE(3); |
|
285 |
|
286 base1 = TRUE; |
|
287 } |
|
288 |
|
289 static void |
|
290 test_iface2_base_init (TestIface2Class *iface) |
|
291 { |
|
292 CHECK_IFACE_TWICE (iface); |
|
293 |
|
294 iface->base_val = 0x220022; |
|
295 |
|
296 base2 = TRUE; |
|
297 } |
|
298 |
|
299 static void |
|
300 test_iface3_base_init (TestIface3Class *iface) |
|
301 { |
|
302 CHECK_IFACE_TWICE (iface); |
|
303 |
|
304 iface->base_val = 0x330033; |
|
305 |
|
306 base3 = TRUE; |
|
307 } |
|
308 |
|
309 static void |
|
310 test_iface4_base_init (TestIface4Class *iface) |
|
311 { |
|
312 CHECK_IFACE_TWICE (iface); |
|
313 |
|
314 iface->base_val = 0x440044; |
|
315 |
|
316 base4 = TRUE; |
|
317 } |
|
318 |
|
319 static void |
|
320 test_iface5_base_init (TestIface5Class *iface) |
|
321 { |
|
322 CHECK_IFACE_TWICE (iface); |
|
323 |
|
324 iface->base_val = 0x550055; |
|
325 |
|
326 base5 = TRUE; |
|
327 } |
|
328 |
|
329 static void |
|
330 test_iface6_base_init (TestIface6Class *iface) |
|
331 { |
|
332 CHECK_IFACE_TWICE (iface); |
|
333 |
|
334 iface->base_val = 0x660066; |
|
335 |
|
336 base6 = TRUE; |
|
337 } |
|
338 |
|
339 static void |
|
340 base_object_base_init (BaseObjectClass *class) |
|
341 { |
|
342 static int n_called = 0; |
|
343 n_called++; |
|
344 |
|
345 /* The second time this is called is for TestObject */ |
|
346 if (n_called == 2) |
|
347 { |
|
348 ADD_IFACE(2); |
|
349 |
|
350 /* No interface base init functions should have been called yet |
|
351 */ |
|
352 g_assert (!base1 && !base2 && !base3 && !base4 && !base5 && !base6); |
|
353 g_assert (!iface1 && !iface2 && !iface3 && !iface4 && !iface5 && !iface6); |
|
354 } |
|
355 } |
|
356 |
|
357 static void |
|
358 test_object_class_init (TestObjectClass *class) |
|
359 { |
|
360 ADD_IFACE(4); |
|
361 |
|
362 /* At this point, the base init functions for all interfaces that have |
|
363 * been added should be called, but no interface init functions. |
|
364 */ |
|
365 g_assert (base1 && base2 && base3 && base4 && !base5 && !base6); |
|
366 g_assert (!iface1 && !iface2 && !iface3 && !iface4 && !iface5 && !iface6); |
|
367 } |
|
368 |
|
369 static DEFINE_TYPE(BaseObject, base_object, |
|
370 NULL, base_object_base_init, NULL, |
|
371 G_TYPE_OBJECT) |
|
372 static DEFINE_TYPE(TestObject, test_object, |
|
373 test_object_class_init, NULL, NULL, |
|
374 BASE_TYPE_OBJECT) |
|
375 |
|
376 int |
|
377 main (int argc, |
|
378 char *argv[]) |
|
379 { |
|
380 TestObject *object; |
|
381 TestObjectClass *object_class; |
|
382 TestIfaceClass *iface; |
|
383 #ifdef __SYMBIAN32__ |
|
384 g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); |
|
385 g_set_print_handler(mrtPrintHandler); |
|
386 #endif /*__SYMBIAN32__*/ |
|
387 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | |
|
388 G_LOG_LEVEL_WARNING | |
|
389 G_LOG_LEVEL_CRITICAL); |
|
390 g_type_init (); |
|
391 |
|
392 /* We force the interfaces to be registered in a different order |
|
393 * than we add them, so our logic doesn't always deal with interfaces |
|
394 * added at the end. |
|
395 */ |
|
396 (void)TEST_TYPE_IFACE4; |
|
397 (void)TEST_TYPE_IFACE2; |
|
398 (void)TEST_TYPE_IFACE6; |
|
399 (void)TEST_TYPE_IFACE5; |
|
400 (void)TEST_TYPE_IFACE3; |
|
401 (void)TEST_TYPE_IFACE1; |
|
402 |
|
403 ADD_IFACE(1); |
|
404 |
|
405 object_class = g_type_class_ref (TEST_TYPE_OBJECT); |
|
406 |
|
407 ADD_IFACE(6); |
|
408 |
|
409 /* All base and interface init functions should have been called |
|
410 */ |
|
411 g_assert (base1 && base2 && base3 && base4 && base5 && base6); |
|
412 g_assert (iface1 && iface2 && iface3 && iface4 && iface5 && iface6); |
|
413 |
|
414 object = g_object_new (TEST_TYPE_OBJECT, NULL); |
|
415 |
|
416 iface = TEST_IFACE1_GET_CLASS (object); |
|
417 g_assert (iface && iface->val == 0x10001 && iface->base_val == 0x110011); |
|
418 iface = TEST_IFACE3_GET_CLASS (object); |
|
419 g_assert (iface && iface->val == 0x30003 && iface->base_val == 0x330033); |
|
420 iface = TEST_IFACE4_GET_CLASS (object); |
|
421 g_assert (iface && iface->val == 0x40004 && iface->base_val == 0x440044); |
|
422 iface = TEST_IFACE5_GET_CLASS (object); |
|
423 g_assert (iface && iface->val == 0x50005 && iface->base_val == 0x550055); |
|
424 iface = TEST_IFACE6_GET_CLASS (object); |
|
425 g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); |
|
426 #ifdef __SYMBIAN32__ |
|
427 testResultXml("ifaceinit"); |
|
428 #endif /*__SYMBIAN32__*/ |
|
429 return 0; |
|
430 } |