tests/closure: Use correct prototype for signal callback
[platform/upstream/glib.git] / gobject / tests / param.c
index 0e6b208..0215dc0 100644 (file)
@@ -457,6 +457,7 @@ static void test_object_c_init (TestObjectC *c) { }
  * That gives 21 (7 * 3) properties that will be installed.
  */
 typedef GTypeInterface TestInterfaceInterface;
+static GType test_interface_get_type (void);
 //typedef struct _TestInterface TestInterface;
 G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
 static void
@@ -478,16 +479,18 @@ test_interface_default_init (TestInterfaceInterface *iface)
 
         if (perms[j] == NULL)
           {
+            if (!g_test_undefined ())
+              continue;
+
             /* we think that this is impossible.  make sure. */
-            if (g_test_trap_fork (G_TIME_SPAN_SECOND, G_TEST_TRAP_SILENCE_STDERR))
-              {
-                GParamSpec *pspec;
+            pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
 
-                pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
-                g_object_interface_install_property (iface, pspec);
-                exit (0);
-              }
-            //g_test_trap_assert_failed (); XXX g_object_interface_install_property has no checks
+            g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                                   "*assertion*pspec->flags*failed*");
+            g_object_interface_install_property (iface, pspec);
+            g_test_assert_expected_messages ();
+
+            g_param_spec_unref (pspec);
             continue;
           }
 
@@ -587,20 +590,24 @@ static gint valid_impl_types[48][4] = {
 /* We also try to change the flags.  We must ensure that all
  * implementations provide all functionality promised by the interface.
  * We must therefore never remove readability or writability (but we can
- * add them).  Construct/construct-only are restrictions that apply to
- * writability, so we can never add them unless writability was never
- * present in the first place, in which case we should be able to add
- * them.
+ * add them).  Construct-only is a restrictions that applies to
+ * writability, so we can never add it unless writability was never
+ * present in the first place, in which case "writable at construct
+ * only" is still better than "not writable".
+ *
+ * The 'construct' flag is of interest only to the implementation.  It
+ * may be changed at any time.
  *
  *   Properties         Valid Access      Reason
  *
  *   *-r                r, rw, rwc, rwC   Must keep readable, but can restrict newly-added writable
- *   *-w                w, rw             Must keep writable unrestricted
- *   *-rw               rw                Must not add any restrictions
- *   *-rwc              rw, rwc           Can remove 'construct' restriction
- *   *-rwC              rw, rwC           Can remove 'construct-only' restriction
- *   *-wc               rwc, rw, w, wc    Can add readability or remove 'construct' restriction
+ *   *-w                w, rw, rwc        Must keep writable unrestricted
+ *   *-rw               rw, rwc           Must not add any restrictions
+ *   *-rwc              rw, rwc           Must not add any restrictions
+ *   *-rwC              rw, rwc, rwC      Can remove 'construct-only' restriction
+ *   *-wc               rwc, rw, w, wc    Can add readability
  *   *-wC               rwC, rw, w, wC    Can add readability or remove 'construct only' restriction
+ *                        rwc, wc
  *
  * We can represent this with a 16-by-16 table.  The rows represent the
  * flags of the property on the interface.  The columns is the flags to
@@ -610,7 +617,7 @@ static gint valid_impl_types[48][4] = {
  *   - 'v': valid
  *   - 'i': invalid because the implementation flags are invalid
  *   - 'f': invalid because of the removal of functionality
- *   - 'r': invalid because of the addition of restrictions
+ *   - 'r': invalid because of the addition of restrictions (ie: construct-only)
  *
  * We also ensure that removal of functionality is reported before
  * addition of restrictions, since this is a more basic problem.
@@ -619,16 +626,16 @@ static gint valid_impl_flags[16][16] = {
                  /* ''   r    w    rw   c    rc   wc   rwc  C    rC   wC   rwC  cC   rcC  wcC  rwcC */
     /* '*-' */    { },
     /* '*-r' */   { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
-    /* '*-w' */   { 'i', 'f', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
-    /* '*-rw' */  { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
+    /* '*-w' */   { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
+    /* '*-rw' */  { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
     /* '*-c */    { },
     /* '*-rc' */  { },
     /* '*-wc' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
     /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
     /* '*-C */    { },
     /* '*-rC' */  { },
-    /* '*-wC' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
-    /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
+    /* '*-wC' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
+    /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
 };
 
 static guint change_this_flag;
@@ -683,17 +690,23 @@ static void test_implementation_class_init (TestImplementationClass *class)
   if (perms[change_this_flag] == NULL)
     g_error ("Interface property does not exist");
 
-  if (!(use_this_flag & (G_PARAM_READABLE | G_PARAM_WRITABLE)))
-    g_error ("g_object_class_install_property should probably fail here...");
-
   g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]);
   pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag);
   g_object_class_install_property (class, 1, pspec);
 }
 
+typedef struct {
+  gint change_this_flag;
+  gint change_this_type;
+  gint use_this_flag;
+  gint use_this_type;
+} TestParamImplementData;
+
 static void
-test_param_implement (void)
+test_param_implement_child (gconstpointer user_data)
 {
+  TestParamImplementData *data = (gpointer) user_data;
+
   /* GObject oddity: GObjectClass must be initialised before we can
    * initialise a GTypeInterface.
    */
@@ -702,17 +715,43 @@ test_param_implement (void)
   /* Bring up the interface first. */
   g_type_default_interface_ref (test_interface_get_type ());
 
+  /* Copy the flags into the global vars so
+   * test_implementation_class_init() will see them.
+   */
+  change_this_flag = data->change_this_flag;
+  change_this_type = data->change_this_type;
+  use_this_flag = data->use_this_flag;
+  use_this_type = data->use_this_type;
+
+  g_type_class_ref (test_implementation_get_type ());
+}
+
+static void
+test_param_implement (void)
+{
+  gchar *test_path;
+
   for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
     for (change_this_type = 0; change_this_type < 3; change_this_type++)
       for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
         for (use_this_type = 0; use_this_type < 4; use_this_type++)
           {
-            if (g_test_trap_fork (G_TIME_SPAN_SECOND, G_TEST_TRAP_SILENCE_STDERR))
+            if (!g_test_undefined ())
               {
-                g_type_class_ref (test_implementation_get_type ());
-                exit (0);
+                /* only test the valid (defined) cases, e.g. under valgrind */
+                if (valid_impl_flags[change_this_flag][use_this_flag] != 'v')
+                  continue;
+
+                if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v')
+                  continue;
               }
 
+            test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
+                                         change_this_flag, change_this_type,
+                                         use_this_flag, use_this_type);
+            g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, 0);
+            g_free (test_path);
+
             /* We want to ensure that any flags mismatch problems are reported first. */
             switch (valid_impl_flags[change_this_flag][use_this_flag])
               {
@@ -772,10 +811,27 @@ test_param_implement (void)
           }
 }
 
+static void
+test_param_default (void)
+{
+  GParamSpec *param;
+  const GValue *def;
+
+  param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+  def = g_param_spec_get_default_value (param);
+
+  g_assert (G_VALUE_HOLDS (def, G_TYPE_INT));
+  g_assert_cmpint (g_value_get_int (def), ==, 10);
+
+  g_param_spec_unref (param);
+}
+
 int
 main (int argc, char *argv[])
 {
-  g_type_init ();
+  TestParamImplementData data, *test_data;
+  gchar *test_path;
+
   g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/param/value", test_param_value);
@@ -783,8 +839,23 @@ main (int argc, char *argv[])
   g_test_add_func ("/param/qdata", test_param_qdata);
   g_test_add_func ("/param/validate", test_param_validate);
   g_test_add_func ("/param/convert", test_param_convert);
+
   g_test_add_func ("/param/implement", test_param_implement);
+  for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
+    for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)
+      for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++)
+        for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++)
+          {
+            test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
+                                         data.change_this_flag, data.change_this_type,
+                                         data.use_this_flag, data.use_this_type);
+            test_data = g_memdup (&data, sizeof (TestParamImplementData));
+            g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
+            g_free (test_path);
+          }
+
   g_test_add_func ("/value/transform", test_value_transform);
+  g_test_add_func ("/param/default", test_param_default);
 
   return g_test_run ();
 }