glib/tsrc/BC/tests/gobject/ifaceproperties.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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.
       
     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 "TestIfaceProperties"
       
    22 
       
    23 #undef G_DISABLE_ASSERT
       
    24 #undef G_DISABLE_CHECKS
       
    25 #undef G_DISABLE_CAST_CHECKS
       
    26 
       
    27 #include <string.h>
       
    28 
       
    29 #include <glib-object.h>
       
    30 #include <gobject_global.h>
       
    31 
       
    32 #include "testcommon.h"
       
    33 #ifdef SYMBIAN
       
    34 #include "mrt2_glib2_test.h"
       
    35 #endif /*SYMBIAN*/
       
    36 
       
    37 
       
    38 
       
    39 /* This test tests interface properties, implementing interface
       
    40  * properties and #GParamSpecOverride.
       
    41  *
       
    42  * Four properties are tested:
       
    43  *
       
    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
       
    48  */
       
    49    
       
    50 static GType base_object_get_type ();
       
    51 static GType derived_object_get_type ();
       
    52 
       
    53 enum {
       
    54   BASE_PROP_0,
       
    55   BASE_PROP1,
       
    56   BASE_PROP2,
       
    57   BASE_PROP3,
       
    58   BASE_PROP4
       
    59 };
       
    60 
       
    61 enum {
       
    62   DERIVED_PROP_0,
       
    63   DERIVED_PROP3,
       
    64   DERIVED_PROP4
       
    65 };
       
    66 
       
    67 
       
    68 /*
       
    69  * BaseObject, a parent class for DerivedObject
       
    70  */
       
    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;
       
    75 
       
    76 struct _BaseObject
       
    77 {
       
    78   GObject parent_instance;
       
    79 
       
    80   gint val1;
       
    81   gint val2;
       
    82   gint val3;
       
    83   gint val4;
       
    84 };
       
    85 struct _BaseObjectClass
       
    86 {
       
    87   GObjectClass parent_class;
       
    88 };
       
    89 
       
    90 GObjectClass *base_parent_class;
       
    91 
       
    92 /*
       
    93  * DerivedObject, the child class of DerivedObject
       
    94  */
       
    95 #define DERIVED_TYPE_OBJECT          (derived_object_get_type ())
       
    96 typedef struct _DerivedObject        DerivedObject;
       
    97 typedef struct _DerivedObjectClass   DerivedObjectClass;
       
    98 
       
    99 struct _DerivedObject
       
   100 {
       
   101   BaseObject parent_instance;
       
   102 };
       
   103 struct _DerivedObjectClass
       
   104 {
       
   105   BaseObjectClass parent_class;
       
   106 };
       
   107 
       
   108 /*
       
   109  * The interface
       
   110  */
       
   111 typedef struct _TestIfaceClass TestIfaceClass;
       
   112 
       
   113 struct _TestIfaceClass
       
   114 {
       
   115   GTypeInterface base_iface;
       
   116 };
       
   117 
       
   118 #define TEST_TYPE_IFACE (test_iface_get_type ())
       
   119 
       
   120 /* The paramspecs installed on our interface
       
   121  */
       
   122 static GParamSpec *iface_spec1, *iface_spec2, *iface_spec3;
       
   123 
       
   124 /* The paramspecs inherited by our derived object
       
   125  */
       
   126 static GParamSpec *inherited_spec1, *inherited_spec2, *inherited_spec3, *inherited_spec4;
       
   127 
       
   128 static void
       
   129 test_iface_default_init (TestIfaceClass *iface_vtable)
       
   130 {
       
   131   inherited_spec1 = iface_spec1 = g_param_spec_int ("prop1",
       
   132 						    "Prop1",
       
   133 						    "Property 1",
       
   134 						    G_MININT, /* min */
       
   135 						    0xFFFF,  /* max */
       
   136 						    42,       /* default */
       
   137 						    G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
       
   138   g_object_interface_install_property (iface_vtable, iface_spec1);
       
   139 
       
   140   iface_spec2 = g_param_spec_int ("prop2",
       
   141 				  "Prop2",
       
   142 				  "Property 2",
       
   143 				  G_MININT, /* min */
       
   144 				  G_MAXINT, /* max */
       
   145 				  0,	       /* default */
       
   146 				  G_PARAM_WRITABLE);
       
   147   g_object_interface_install_property (iface_vtable, iface_spec2);
       
   148     
       
   149   inherited_spec3 = iface_spec3 = g_param_spec_int ("prop3",
       
   150 						    "Prop3",
       
   151 						    "Property 3",
       
   152 						    G_MININT, /* min */
       
   153 						    G_MAXINT, /* max */
       
   154 						    0,	       /* default */
       
   155 						    G_PARAM_READWRITE);
       
   156   g_object_interface_install_property (iface_vtable, iface_spec3);
       
   157 }
       
   158 
       
   159 static DEFINE_IFACE (TestIface, test_iface, NULL, test_iface_default_init)
       
   160 
       
   161 
       
   162 static GObject*
       
   163 base_object_constructor  (GType                  type,
       
   164 			  guint                  n_construct_properties,
       
   165 			  GObjectConstructParam *construct_properties)
       
   166 {
       
   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
       
   169    */
       
   170   GValue value1 = { 0, };
       
   171   GValue value2 = { 0, };
       
   172   GParamSpec *pspec;
       
   173 
       
   174   g_assert (n_construct_properties == 1);
       
   175 
       
   176   pspec = construct_properties->pspec;
       
   177 
       
   178   /* Check we got the param spec we expected
       
   179    */
       
   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);
       
   184 
       
   185   /* Test redirection of the nick and blurb to the redirect target
       
   186    */
       
   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);
       
   189 
       
   190   /* Test forwarding of the various GParamSpec methods to the redirect target
       
   191    */
       
   192   g_value_init (&value1, G_TYPE_INT);
       
   193   g_value_init (&value2, G_TYPE_INT);
       
   194   
       
   195   g_param_value_set_default (pspec, &value1);
       
   196   g_assert (g_value_get_int (&value1) == 42);
       
   197 
       
   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));
       
   203   
       
   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);
       
   209   
       
   210   g_value_unset (&value1);
       
   211   g_value_unset (&value2);
       
   212 
       
   213   return base_parent_class->constructor (type,
       
   214 					 n_construct_properties,
       
   215 					 construct_properties);
       
   216 }
       
   217 
       
   218 static void
       
   219 base_object_set_property (GObject      *object,
       
   220 			  guint         prop_id,
       
   221 			  const GValue *value,
       
   222 			  GParamSpec   *pspec)
       
   223 {
       
   224   BaseObject *base_object = BASE_OBJECT (object);
       
   225   
       
   226   switch (prop_id)
       
   227     {
       
   228     case BASE_PROP1:
       
   229       g_assert (pspec == inherited_spec1);
       
   230       base_object->val1 = g_value_get_int (value);
       
   231       break;
       
   232     case BASE_PROP2:
       
   233       g_assert (pspec == inherited_spec2);
       
   234       base_object->val2 = g_value_get_int (value);
       
   235       break;
       
   236     case BASE_PROP3:
       
   237       g_assert_not_reached ();
       
   238       break;
       
   239     case BASE_PROP4:
       
   240       g_assert_not_reached ();
       
   241       break;
       
   242     default:
       
   243       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   244       break;
       
   245     }
       
   246 }
       
   247 
       
   248 static void
       
   249 base_object_get_property (GObject                *object,
       
   250 			  guint                   prop_id,
       
   251 			  GValue                 *value,
       
   252 			  GParamSpec             *pspec)
       
   253 {
       
   254   BaseObject *base_object = BASE_OBJECT (object);
       
   255 
       
   256   switch (prop_id)
       
   257     {
       
   258     case BASE_PROP1:
       
   259       g_assert (pspec == inherited_spec1);
       
   260       g_value_set_int (value, base_object->val1);
       
   261       break;
       
   262     case BASE_PROP2:
       
   263       g_assert (pspec == inherited_spec2);
       
   264       g_value_set_int (value, base_object->val2);
       
   265       break;
       
   266     case BASE_PROP3:
       
   267       g_assert_not_reached ();
       
   268       break;
       
   269     case BASE_PROP4:
       
   270       g_assert_not_reached ();
       
   271       break;
       
   272     default:
       
   273       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   274       break;
       
   275     }
       
   276 }
       
   277 
       
   278 static void
       
   279 base_object_notify (GObject    *object,
       
   280 		    GParamSpec *pspec)
       
   281 {
       
   282   /* The property passed to notify is the redirect target, not the
       
   283    * GParamSpecOverride
       
   284    */
       
   285   g_assert (pspec == inherited_spec1 ||
       
   286 	    pspec == inherited_spec2 ||
       
   287 	    pspec == inherited_spec3 ||
       
   288 	    pspec == inherited_spec4);
       
   289 }
       
   290 
       
   291 static void
       
   292 base_object_class_init (BaseObjectClass *class)
       
   293 {
       
   294   GObjectClass *object_class = G_OBJECT_CLASS (class);
       
   295 
       
   296   base_parent_class= g_type_class_peek_parent (class);
       
   297 
       
   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;
       
   302 
       
   303   g_object_class_override_property (object_class, BASE_PROP1, "prop1");
       
   304 
       
   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
       
   308    */
       
   309   inherited_spec2 = g_param_spec_int ("prop2",
       
   310 				      "Prop2",
       
   311 				      "Property 2",
       
   312 				      G_MININT, /* min */
       
   313 				      G_MAXINT, /* max */
       
   314 				      0,	       /* default */
       
   315 				      G_PARAM_READWRITE);
       
   316   g_object_class_install_property (object_class, BASE_PROP2, inherited_spec2);
       
   317 
       
   318   g_object_class_override_property (object_class, BASE_PROP3, "prop3");
       
   319   
       
   320   inherited_spec4 = g_param_spec_int ("prop4",
       
   321 				      "Prop4",
       
   322 				      "Property 4",
       
   323 				      G_MININT, /* min */
       
   324 				      G_MAXINT, /* max */
       
   325 				      0,	       /* default */
       
   326 				      G_PARAM_READWRITE);
       
   327   g_object_class_install_property (object_class, BASE_PROP4, inherited_spec4);
       
   328 }
       
   329 
       
   330 static void
       
   331 base_object_init (BaseObject *base_object)
       
   332 {
       
   333   base_object->val1 = 42;
       
   334 }
       
   335 
       
   336 static DEFINE_TYPE_FULL (BaseObject, base_object,
       
   337 			 base_object_class_init, NULL, base_object_init,
       
   338 			 G_TYPE_OBJECT,
       
   339 			 INTERFACE (NULL, TEST_TYPE_IFACE))
       
   340 
       
   341 static void
       
   342 derived_object_set_property (GObject      *object,
       
   343 			     guint         prop_id,
       
   344 			     const GValue *value,
       
   345 			     GParamSpec   *pspec)
       
   346 {
       
   347   BaseObject *base_object = BASE_OBJECT (object);
       
   348 
       
   349   switch (prop_id)
       
   350     {
       
   351     case DERIVED_PROP3:
       
   352       g_assert (pspec == inherited_spec3);
       
   353       base_object->val3 = g_value_get_int (value);
       
   354       break;
       
   355     case DERIVED_PROP4:
       
   356       g_assert (pspec == inherited_spec4);
       
   357       base_object->val4 = g_value_get_int (value);
       
   358       break;
       
   359     default:
       
   360       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   361       break;
       
   362     }
       
   363 }
       
   364 
       
   365 static void
       
   366 derived_object_get_property (GObject                *object,
       
   367 			     guint                   prop_id,
       
   368 			     GValue                 *value,
       
   369 			     GParamSpec             *pspec)
       
   370 {
       
   371   BaseObject *base_object = BASE_OBJECT (object);
       
   372 
       
   373   switch (prop_id)
       
   374     {
       
   375     case DERIVED_PROP3:
       
   376       g_assert (pspec == inherited_spec3);
       
   377       g_value_set_int (value, base_object->val3);
       
   378       break;
       
   379     case DERIVED_PROP4:
       
   380       g_assert (pspec == inherited_spec4);
       
   381       g_value_set_int (value, base_object->val4);
       
   382       break;
       
   383     default:
       
   384       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   385       break;
       
   386     }
       
   387 }
       
   388 
       
   389 static void
       
   390 derived_object_class_init (DerivedObjectClass *class)
       
   391 {
       
   392   GObjectClass *object_class = G_OBJECT_CLASS (class);
       
   393 
       
   394   object_class->set_property = derived_object_set_property;
       
   395   object_class->get_property = derived_object_get_property;
       
   396 
       
   397   /* Overriding a property that is itself overridding an interface property */
       
   398   g_object_class_override_property (object_class, DERIVED_PROP3, "prop3");
       
   399 
       
   400   /* Overriding a property not from an interface */
       
   401   g_object_class_override_property (object_class, DERIVED_PROP4, "prop4");
       
   402 }
       
   403 
       
   404 static DEFINE_TYPE (DerivedObject, derived_object,
       
   405 		    derived_object_class_init, NULL, NULL,
       
   406 		    BASE_TYPE_OBJECT)
       
   407 
       
   408 /* Helper function for testing ...list_properties()
       
   409  */
       
   410 static void
       
   411 assert_in_properties (GParamSpec  *param_spec,
       
   412 		      GParamSpec **properties,
       
   413 		      gint         n_properties)
       
   414 {
       
   415   gint i;
       
   416   gboolean found = FALSE;
       
   417 
       
   418   for (i = 0; i < n_properties; i++)
       
   419     {
       
   420       if (properties[i] == param_spec)
       
   421 	found = TRUE;
       
   422     }
       
   423 
       
   424   g_assert (found);
       
   425 }
       
   426 
       
   427 int
       
   428 main (gint   argc,
       
   429       gchar *argv[])
       
   430 {
       
   431 
       
   432   BaseObject *object;
       
   433   GObjectClass *object_class;
       
   434   TestIfaceClass *iface_vtable;
       
   435   GParamSpec **properties;
       
   436   gint n_properties;
       
   437   gint val1, val2, val3, val4;
       
   438   
       
   439   #ifdef SYMBIAN
       
   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);
       
   442   #endif /*SYMBIAN*/
       
   443 	
       
   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);
       
   447   g_type_init ();
       
   448 
       
   449   object = g_object_new (DERIVED_TYPE_OBJECT, NULL);
       
   450 
       
   451   /* Test setting and getting the properties
       
   452    */
       
   453   g_object_set (object,
       
   454 		"prop1", 0x0101,
       
   455 		"prop2", 0x0202,
       
   456 		"prop3", 0x0303,
       
   457 		"prop4", 0x0404,
       
   458 		NULL);
       
   459   g_object_get (object,
       
   460 		"prop1", &val1,
       
   461 		"prop2", &val2,
       
   462 		"prop3", &val3,
       
   463 		"prop4", &val4,
       
   464 		NULL);
       
   465 
       
   466   g_assert (val1 == 0x0101);
       
   467   g_assert (val2 == 0x0202);
       
   468   g_assert (val3 == 0x0303);
       
   469   g_assert (val4 == 0x0404);
       
   470 
       
   471   /* Test that the right spec is passed on explicit notifications
       
   472    */
       
   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));
       
   479 
       
   480   /* Test g_object_class_find_property() for overridden properties
       
   481    */
       
   482   object_class = G_OBJECT_GET_CLASS (object);
       
   483 
       
   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);
       
   488 
       
   489   /* Test g_object_class_list_properties() for overridden properties
       
   490    */
       
   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);
       
   497   g_free (properties);
       
   498 
       
   499   /* Test g_object_interface_find_property()
       
   500    */
       
   501   iface_vtable = g_type_default_interface_peek (TEST_TYPE_IFACE);
       
   502 
       
   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);
       
   506 
       
   507   /* Test g_object_interface_list_properties()
       
   508    */
       
   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);
       
   514   g_free (properties);
       
   515 
       
   516   g_object_unref (object);
       
   517   
       
   518   #ifdef SYMBIAN
       
   519    testResultXml("ifaceproperties");
       
   520   #endif /*SYMBIAN*/
       
   521 	
       
   522 
       
   523 
       
   524   return 0;
       
   525 }