Update contrib.
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2001, 2003 Red Hat, Inc.
3 * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). 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.
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.
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.
21 #define G_LOG_DOMAIN "TestIfaceProperties"
23 #undef G_DISABLE_ASSERT
24 #undef G_DISABLE_CHECKS
25 #undef G_DISABLE_CAST_CHECKS
29 #include <glib-object.h>
30 #include <gobject_global.h>
32 #include "testcommon.h"
34 #include "mrt2_glib2_test.h"
39 /* This test tests interface properties, implementing interface
40 * properties and #GParamSpecOverride.
42 * Four properties are tested:
44 * prop1: Defined in TestIface, Implemented in BaseObject with a GParamSpecOverride
45 * prop2: Defined in TestIface, Implemented in BaseObject with a new property
46 * prop3: Defined in TestIface, Implemented in BaseObject, Overridden in DerivedObject
47 * prop4: Defined in BaseObject, Overridden in DerivedObject
50 static GType base_object_get_type ();
51 static GType derived_object_get_type ();
69 * BaseObject, a parent class for DerivedObject
71 #define BASE_TYPE_OBJECT (base_object_get_type ())
72 #define BASE_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BASE_TYPE_OBJECT, BaseObject))
73 typedef struct _BaseObject BaseObject;
74 typedef struct _BaseObjectClass BaseObjectClass;
78 GObject parent_instance;
85 struct _BaseObjectClass
87 GObjectClass parent_class;
90 GObjectClass *base_parent_class;
93 * DerivedObject, the child class of DerivedObject
95 #define DERIVED_TYPE_OBJECT (derived_object_get_type ())
96 typedef struct _DerivedObject DerivedObject;
97 typedef struct _DerivedObjectClass DerivedObjectClass;
101 BaseObject parent_instance;
103 struct _DerivedObjectClass
105 BaseObjectClass parent_class;
111 typedef struct _TestIfaceClass TestIfaceClass;
113 struct _TestIfaceClass
115 GTypeInterface base_iface;
118 #define TEST_TYPE_IFACE (test_iface_get_type ())
120 /* The paramspecs installed on our interface
122 static GParamSpec *iface_spec1, *iface_spec2, *iface_spec3;
124 /* The paramspecs inherited by our derived object
126 static GParamSpec *inherited_spec1, *inherited_spec2, *inherited_spec3, *inherited_spec4;
129 test_iface_default_init (TestIfaceClass *iface_vtable)
131 inherited_spec1 = iface_spec1 = g_param_spec_int ("prop1",
137 G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
138 g_object_interface_install_property (iface_vtable, iface_spec1);
140 iface_spec2 = g_param_spec_int ("prop2",
147 g_object_interface_install_property (iface_vtable, iface_spec2);
149 inherited_spec3 = iface_spec3 = g_param_spec_int ("prop3",
156 g_object_interface_install_property (iface_vtable, iface_spec3);
159 static DEFINE_IFACE (TestIface, test_iface, NULL, test_iface_default_init)
163 base_object_constructor (GType type,
164 guint n_construct_properties,
165 GObjectConstructParam *construct_properties)
167 /* The constructor is the one place where a GParamSpecOverride is visible
168 * to the outside world, so we do a bunch of checks here
170 GValue value1 = { 0, };
171 GValue value2 = { 0, };
174 g_assert (n_construct_properties == 1);
176 pspec = construct_properties->pspec;
178 /* Check we got the param spec we expected
180 g_assert (G_IS_PARAM_SPEC_OVERRIDE (pspec));
181 g_assert (pspec->param_id == BASE_PROP1);
182 g_assert (strcmp (g_param_spec_get_name (pspec), "prop1") == 0);
183 g_assert (g_param_spec_get_redirect_target (pspec) == iface_spec1);
185 /* Test redirection of the nick and blurb to the redirect target
187 g_assert (strcmp (g_param_spec_get_nick (pspec), "Prop1") == 0);
188 g_assert (strcmp (g_param_spec_get_blurb (pspec), "Property 1") == 0);
190 /* Test forwarding of the various GParamSpec methods to the redirect target
192 g_value_init (&value1, G_TYPE_INT);
193 g_value_init (&value2, G_TYPE_INT);
195 g_param_value_set_default (pspec, &value1);
196 g_assert (g_value_get_int (&value1) == 42);
198 g_value_reset (&value1);
199 g_value_set_int (&value1, 0x10000);
200 g_assert (g_param_value_validate (pspec, &value1));
201 g_assert (g_value_get_int (&value1) == 0xFFFF);
202 g_assert (!g_param_value_validate (pspec, &value1));
204 g_value_reset (&value1);
205 g_value_set_int (&value1, 1);
206 g_value_set_int (&value2, 2);
207 g_assert (g_param_values_cmp (pspec, &value1, &value2) < 0);
208 g_assert (g_param_values_cmp (pspec, &value2, &value1) > 0);
210 g_value_unset (&value1);
211 g_value_unset (&value2);
213 return base_parent_class->constructor (type,
214 n_construct_properties,
215 construct_properties);
219 base_object_set_property (GObject *object,
224 BaseObject *base_object = BASE_OBJECT (object);
229 g_assert (pspec == inherited_spec1);
230 base_object->val1 = g_value_get_int (value);
233 g_assert (pspec == inherited_spec2);
234 base_object->val2 = g_value_get_int (value);
237 g_assert_not_reached ();
240 g_assert_not_reached ();
243 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
249 base_object_get_property (GObject *object,
254 BaseObject *base_object = BASE_OBJECT (object);
259 g_assert (pspec == inherited_spec1);
260 g_value_set_int (value, base_object->val1);
263 g_assert (pspec == inherited_spec2);
264 g_value_set_int (value, base_object->val2);
267 g_assert_not_reached ();
270 g_assert_not_reached ();
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
279 base_object_notify (GObject *object,
282 /* The property passed to notify is the redirect target, not the
285 g_assert (pspec == inherited_spec1 ||
286 pspec == inherited_spec2 ||
287 pspec == inherited_spec3 ||
288 pspec == inherited_spec4);
292 base_object_class_init (BaseObjectClass *class)
294 GObjectClass *object_class = G_OBJECT_CLASS (class);
296 base_parent_class= g_type_class_peek_parent (class);
298 object_class->constructor = base_object_constructor;
299 object_class->set_property = base_object_set_property;
300 object_class->get_property = base_object_get_property;
301 object_class->notify = base_object_notify;
303 g_object_class_override_property (object_class, BASE_PROP1, "prop1");
305 /* We override this one using a real property, not GParamSpecOverride
306 * We change the flags from READONLY to READWRITE to show that we
307 * can make the flags less restrictive
309 inherited_spec2 = g_param_spec_int ("prop2",
316 g_object_class_install_property (object_class, BASE_PROP2, inherited_spec2);
318 g_object_class_override_property (object_class, BASE_PROP3, "prop3");
320 inherited_spec4 = g_param_spec_int ("prop4",
327 g_object_class_install_property (object_class, BASE_PROP4, inherited_spec4);
331 base_object_init (BaseObject *base_object)
333 base_object->val1 = 42;
336 static DEFINE_TYPE_FULL (BaseObject, base_object,
337 base_object_class_init, NULL, base_object_init,
339 INTERFACE (NULL, TEST_TYPE_IFACE))
342 derived_object_set_property (GObject *object,
347 BaseObject *base_object = BASE_OBJECT (object);
352 g_assert (pspec == inherited_spec3);
353 base_object->val3 = g_value_get_int (value);
356 g_assert (pspec == inherited_spec4);
357 base_object->val4 = g_value_get_int (value);
360 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
366 derived_object_get_property (GObject *object,
371 BaseObject *base_object = BASE_OBJECT (object);
376 g_assert (pspec == inherited_spec3);
377 g_value_set_int (value, base_object->val3);
380 g_assert (pspec == inherited_spec4);
381 g_value_set_int (value, base_object->val4);
384 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
390 derived_object_class_init (DerivedObjectClass *class)
392 GObjectClass *object_class = G_OBJECT_CLASS (class);
394 object_class->set_property = derived_object_set_property;
395 object_class->get_property = derived_object_get_property;
397 /* Overriding a property that is itself overridding an interface property */
398 g_object_class_override_property (object_class, DERIVED_PROP3, "prop3");
400 /* Overriding a property not from an interface */
401 g_object_class_override_property (object_class, DERIVED_PROP4, "prop4");
404 static DEFINE_TYPE (DerivedObject, derived_object,
405 derived_object_class_init, NULL, NULL,
408 /* Helper function for testing ...list_properties()
411 assert_in_properties (GParamSpec *param_spec,
412 GParamSpec **properties,
416 gboolean found = FALSE;
418 for (i = 0; i < n_properties; i++)
420 if (properties[i] == param_spec)
433 GObjectClass *object_class;
434 TestIfaceClass *iface_vtable;
435 GParamSpec **properties;
437 gint val1, val2, val3, val4;
440 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);
441 g_set_print_handler(mrtPrintHandler);
444 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
445 G_LOG_LEVEL_WARNING |
446 G_LOG_LEVEL_CRITICAL);
449 object = g_object_new (DERIVED_TYPE_OBJECT, NULL);
451 /* Test setting and getting the properties
453 g_object_set (object,
459 g_object_get (object,
466 g_assert (val1 == 0x0101);
467 g_assert (val2 == 0x0202);
468 g_assert (val3 == 0x0303);
469 g_assert (val4 == 0x0404);
471 /* Test that the right spec is passed on explicit notifications
473 g_object_freeze_notify (G_OBJECT (object));
474 g_object_notify (G_OBJECT (object), "prop1");
475 g_object_notify (G_OBJECT (object), "prop2");
476 g_object_notify (G_OBJECT (object), "prop3");
477 g_object_notify (G_OBJECT (object), "prop4");
478 g_object_thaw_notify (G_OBJECT (object));
480 /* Test g_object_class_find_property() for overridden properties
482 object_class = G_OBJECT_GET_CLASS (object);
484 g_assert (g_object_class_find_property (object_class, "prop1") == inherited_spec1);
485 g_assert (g_object_class_find_property (object_class, "prop2") == inherited_spec2);
486 g_assert (g_object_class_find_property (object_class, "prop3") == inherited_spec3);
487 g_assert (g_object_class_find_property (object_class, "prop4") == inherited_spec4);
489 /* Test g_object_class_list_properties() for overridden properties
491 properties = g_object_class_list_properties (object_class,(guint *) &n_properties);
492 g_assert (n_properties == 4);
493 assert_in_properties (inherited_spec1, properties, n_properties);
494 assert_in_properties (inherited_spec2, properties, n_properties);
495 assert_in_properties (inherited_spec3, properties, n_properties);
496 assert_in_properties (inherited_spec4, properties, n_properties);
499 /* Test g_object_interface_find_property()
501 iface_vtable = g_type_default_interface_peek (TEST_TYPE_IFACE);
503 g_assert (g_object_interface_find_property (iface_vtable, "prop1") == iface_spec1);
504 g_assert (g_object_interface_find_property (iface_vtable, "prop2") == iface_spec2);
505 g_assert (g_object_interface_find_property (iface_vtable, "prop3") == iface_spec3);
507 /* Test g_object_interface_list_properties()
509 properties = g_object_interface_list_properties (iface_vtable, (guint *)&n_properties);
510 g_assert (n_properties == 3);
511 assert_in_properties (iface_spec1, properties, n_properties);
512 assert_in_properties (iface_spec2, properties, n_properties);
513 assert_in_properties (iface_spec3, properties, n_properties);
516 g_object_unref (object);
519 testResultXml("ifaceproperties");