Blame gobject/tests/param.c

Packit ae235b
#define GLIB_DISABLE_DEPRECATION_WARNINGS
Packit ae235b
#include <glib-object.h>
Packit ae235b
#include <stdlib.h>
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_value (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *p, *p2;
Packit ae235b
  GParamSpec *pp;
Packit ae235b
  GValue value = G_VALUE_INIT;
Packit ae235b
Packit ae235b
  g_value_init (&value, G_TYPE_PARAM);
Packit ae235b
  g_assert (G_VALUE_HOLDS_PARAM (&value));
Packit ae235b
Packit ae235b
  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
Packit ae235b
  g_value_take_param (&value, p);
Packit ae235b
  p2 = g_value_get_param (&value);
Packit ae235b
  g_assert (p2 == p);
Packit ae235b
Packit ae235b
  pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE);
Packit ae235b
  g_value_set_param (&value, pp);
Packit ae235b
Packit ae235b
  p2 = g_value_dup_param (&value);
Packit ae235b
  g_assert (p2 == pp); /* param specs use ref/unref for copy/free */
Packit ae235b
  g_param_spec_unref (p2);
Packit ae235b
Packit ae235b
  g_value_unset (&value);
Packit ae235b
  g_param_spec_unref (pp);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint destroy_count;
Packit ae235b
Packit ae235b
static void
Packit ae235b
my_destroy (gpointer data)
Packit ae235b
{
Packit ae235b
  destroy_count++;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_qdata (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *p;
Packit ae235b
  gchar *bla;
Packit ae235b
  GQuark q;
Packit ae235b
Packit ae235b
  q = g_quark_from_string ("bla");
Packit ae235b
Packit ae235b
  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
  g_param_spec_set_qdata (p, q, "bla");
Packit ae235b
  bla = g_param_spec_get_qdata (p, q);
Packit ae235b
  g_assert_cmpstr (bla, ==, "bla");
Packit ae235b
Packit ae235b
  g_assert_cmpint (destroy_count, ==, 0);
Packit ae235b
  g_param_spec_set_qdata_full (p, q, "bla", my_destroy);
Packit ae235b
  g_param_spec_set_qdata_full (p, q, "blabla", my_destroy);
Packit ae235b
  g_assert_cmpint (destroy_count, ==, 1);
Packit ae235b
  g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla");
Packit ae235b
  g_assert_cmpint (destroy_count, ==, 1);
Packit ae235b
  g_assert (g_param_spec_get_qdata (p, q) == NULL);
Packit ae235b
Packit ae235b
  g_param_spec_ref_sink (p);
Packit ae235b
Packit ae235b
  g_param_spec_unref (p);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_validate (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *p;
Packit ae235b
  GValue value = G_VALUE_INIT;
Packit ae235b
Packit ae235b
  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
Packit ae235b
  g_value_init (&value, G_TYPE_INT);
Packit ae235b
  g_value_set_int (&value, 100);
Packit ae235b
  g_assert (!g_param_value_defaults (p, &value));
Packit ae235b
  g_assert (g_param_value_validate (p, &value));
Packit ae235b
  g_assert_cmpint (g_value_get_int (&value), ==, 20);
Packit ae235b
Packit ae235b
  g_param_value_set_default (p, &value);
Packit ae235b
  g_assert (g_param_value_defaults (p, &value));
Packit ae235b
  g_assert_cmpint (g_value_get_int (&value), ==, 10);
Packit ae235b
Packit ae235b
  g_param_spec_unref (p);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_strings (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *p;
Packit ae235b
Packit ae235b
  /* test canonicalization */
Packit ae235b
  p = g_param_spec_int ("my_int:bla", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
Packit ae235b
  g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int-bla");
Packit ae235b
  g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int");
Packit ae235b
  g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb");
Packit ae235b
Packit ae235b
  g_param_spec_unref (p);
Packit ae235b
Packit ae235b
  /* test nick defaults to name */
Packit ae235b
  p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
Packit ae235b
  g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
Packit ae235b
  g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int");
Packit ae235b
  g_assert (g_param_spec_get_blurb (p) == NULL);
Packit ae235b
Packit ae235b
  g_param_spec_unref (p);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_convert (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *p;
Packit ae235b
  GValue v1 = G_VALUE_INIT;
Packit ae235b
  GValue v2 = G_VALUE_INIT;
Packit ae235b
Packit ae235b
  p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
  g_value_init (&v1, G_TYPE_UINT);
Packit ae235b
  g_value_set_uint (&v1, 43);
Packit ae235b
Packit ae235b
  g_value_init (&v2, G_TYPE_INT);
Packit ae235b
  g_value_set_int (&v2, -4);
Packit ae235b
Packit ae235b
  g_assert (!g_param_value_convert (p, &v1, &v2, TRUE));
Packit ae235b
  g_assert_cmpint (g_value_get_int (&v2), ==, -4);
Packit ae235b
Packit ae235b
  g_assert (g_param_value_convert (p, &v1, &v2, FALSE));
Packit ae235b
  g_assert_cmpint (g_value_get_int (&v2), ==, 20);
Packit ae235b
Packit ae235b
  g_param_spec_unref (p);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_value_transform (void)
Packit ae235b
{
Packit ae235b
  GValue src = G_VALUE_INIT;
Packit ae235b
  GValue dest = G_VALUE_INIT;
Packit ae235b
Packit ae235b
#define CHECK_INT_CONVERSION(type, getter, value)                       \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_INT, type));             \
Packit ae235b
  g_value_init (&src, G_TYPE_INT);                                      \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_int (&src, value);                                        \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpint (g_value_get_##getter (&dest), ==, value);            \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  /* Keep a check for an integer in the range of 0-127 so we're
Packit ae235b
   * still testing g_value_get_char().  See
Packit ae235b
   * https://bugzilla.gnome.org/show_bug.cgi?id=659870
Packit ae235b
   * for why it is broken.
Packit ae235b
   */
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124)
Packit ae235b
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_UINT_CONVERSION(type, getter, value)                      \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_UINT, type));            \
Packit ae235b
  g_value_init (&src, G_TYPE_UINT);                                     \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_uint (&src, value);                                       \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpuint (g_value_get_##getter (&dest), ==, value);           \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_LONG, long, 12345678)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_INT64, int64, 12345678)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_LONG_CONVERSION(type, getter, value)                      \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_LONG, type));            \
Packit ae235b
  g_value_init (&src, G_TYPE_LONG);                                     \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_long (&src, value);                                       \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpint (g_value_get_##getter (&dest), ==, value);            \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_ULONG_CONVERSION(type, getter, value)                     \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_ULONG, type));           \
Packit ae235b
  g_value_init (&src, G_TYPE_ULONG);                                    \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_ulong (&src, value);                                      \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpuint (g_value_get_##getter (&dest), ==, value);           \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_INT64_CONVERSION(type, getter, value)                     \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_INT64, type));           \
Packit ae235b
  g_value_init (&src, G_TYPE_INT64);                                    \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_int64 (&src, value);                                      \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpint (g_value_get_##getter (&dest), ==, value);            \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_UINT64_CONVERSION(type, getter, value)                    \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_UINT64, type));          \
Packit ae235b
  g_value_init (&src, G_TYPE_UINT64);                                   \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_uint64 (&src, value);                                     \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpuint (g_value_get_##getter (&dest), ==, value);           \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_FLOAT_CONVERSION(type, getter, value)                    \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_FLOAT, type));          \
Packit ae235b
  g_value_init (&src, G_TYPE_FLOAT);                                   \
Packit ae235b
  g_value_init (&dest, type);                                          \
Packit ae235b
  g_value_set_float (&src, value);                                     \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                          \
Packit ae235b
  g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value);         \
Packit ae235b
  g_value_unset (&src;;                                                \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_DOUBLE_CONVERSION(type, getter, value)                    \
Packit ae235b
  g_assert (g_value_type_transformable (G_TYPE_DOUBLE, type));          \
Packit ae235b
  g_value_init (&src, G_TYPE_DOUBLE);                                   \
Packit ae235b
  g_value_init (&dest, type);                                           \
Packit ae235b
  g_value_set_double (&src, value);                                     \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value);          \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 0)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 255)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, 12345)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 0)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, float, 12345678)
Packit ae235b
  CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_BOOLEAN_CONVERSION(type, setter, value)                   \
Packit ae235b
  g_assert (g_value_type_transformable (type, G_TYPE_BOOLEAN));         \
Packit ae235b
  g_value_init (&src, type);                                            \
Packit ae235b
  g_value_init (&dest, G_TYPE_BOOLEAN);                                 \
Packit ae235b
  g_value_set_##setter (&src, value);                                   \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE);              \
Packit ae235b
  g_value_set_##setter (&src, 0);                                       \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE);             \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
Packit ae235b
#define CHECK_STRING_CONVERSION(int_type, setter, int_value)            \
Packit ae235b
  g_assert (g_value_type_transformable (int_type, G_TYPE_STRING));      \
Packit ae235b
  g_value_init (&src, int_type);                                        \
Packit ae235b
  g_value_init (&dest, G_TYPE_STRING);                                  \
Packit ae235b
  g_value_set_##setter (&src, int_value);                               \
Packit ae235b
  g_assert (g_value_transform (&src, &dest));                           \
Packit ae235b
  g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value);         \
Packit ae235b
  g_value_unset (&src;;                                                 \
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000)
Packit ae235b
  CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567)
Packit ae235b
Packit ae235b
  g_assert (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR));
Packit ae235b
  g_value_init (&src, G_TYPE_STRING);
Packit ae235b
  g_value_init (&dest, G_TYPE_CHAR);
Packit ae235b
  g_value_set_static_string (&src, "bla");
Packit ae235b
  g_value_set_schar (&dest, 'c');
Packit ae235b
  g_assert (!g_value_transform (&src, &dest));
Packit ae235b
  g_assert_cmpint (g_value_get_schar (&dest), ==, 'c');
Packit ae235b
  g_value_unset (&src;;
Packit ae235b
  g_value_unset (&dest);
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
/* We create some dummy objects with a simple relationship:
Packit ae235b
 *
Packit ae235b
 *           GObject
Packit ae235b
 *          /       \
Packit ae235b
 * TestObjectA     TestObjectC
Packit ae235b
 *      |
Packit ae235b
 * TestObjectB
Packit ae235b
 *
Packit ae235b
 * ie: TestObjectB is a subclass of TestObjectA and TestObjectC is
Packit ae235b
 * related to neither.
Packit ae235b
 */
Packit ae235b
Packit ae235b
static GType test_object_a_get_type (void);
Packit ae235b
typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
Packit ae235b
G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
Packit ae235b
static void test_object_a_class_init (TestObjectAClass *class) { }
Packit ae235b
static void test_object_a_init (TestObjectA *a) { }
Packit ae235b
Packit ae235b
static GType test_object_b_get_type (void);
Packit ae235b
typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
Packit ae235b
G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ())
Packit ae235b
static void test_object_b_class_init (TestObjectBClass *class) { }
Packit ae235b
static void test_object_b_init (TestObjectB *b) { }
Packit ae235b
Packit ae235b
static GType test_object_c_get_type (void);
Packit ae235b
typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass;
Packit ae235b
G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT)
Packit ae235b
static void test_object_c_class_init (TestObjectCClass *class) { }
Packit ae235b
static void test_object_c_init (TestObjectC *c) { }
Packit ae235b
Packit ae235b
/* We create an interface and programmatically populate it with
Packit ae235b
 * properties of each of the above type, with various flag combinations.
Packit ae235b
 *
Packit ae235b
 * Properties are named like "type-perm" where type is 'a', 'b' or 'c'
Packit ae235b
 * and perm is a series of characters, indicating the permissions:
Packit ae235b
 *
Packit ae235b
 *   - 'r': readable
Packit ae235b
 *   - 'w': writable
Packit ae235b
 *   - 'c': construct
Packit ae235b
 *   - 'C': construct-only
Packit ae235b
 *
Packit ae235b
 * It doesn't make sense to have a property that is neither readable nor
Packit ae235b
 * writable.  It is also not valid to have construct or construct-only
Packit ae235b
 * on read-only params.  Finally, it is invalid to have both construct
Packit ae235b
 * and construct-only specified, so we do not consider those cases.
Packit ae235b
 * That gives us 7 possible permissions:
Packit ae235b
 *
Packit ae235b
 *     'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC'
Packit ae235b
 *
Packit ae235b
 * And 9 impossible ones:
Packit ae235b
 *
Packit ae235b
 *     '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC'
Packit ae235b
 *
Packit ae235b
 * For a total of 16 combinations.
Packit ae235b
 *
Packit ae235b
 * That gives a total of 48 (16 * 3) possible flag/type combinations, of
Packit ae235b
 * which 27 (9 * 3) are impossible to install.
Packit ae235b
 *
Packit ae235b
 * That gives 21 (7 * 3) properties that will be installed.
Packit ae235b
 */
Packit ae235b
typedef GTypeInterface TestInterfaceInterface;
Packit ae235b
static GType test_interface_get_type (void);
Packit ae235b
//typedef struct _TestInterface TestInterface;
Packit ae235b
G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
Packit ae235b
static void
Packit ae235b
test_interface_default_init (TestInterfaceInterface *iface)
Packit ae235b
{
Packit ae235b
  const gchar *names[] = { "a", "b", "c" };
Packit ae235b
  const gchar *perms[] = { NULL, "r",  "w",  "rw",
Packit ae235b
                           NULL, NULL, "wc", "rwc",
Packit ae235b
                           NULL, NULL, "wC", "rwC",
Packit ae235b
                           NULL, NULL, NULL, NULL };
Packit ae235b
  const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () };
Packit ae235b
  guint i, j;
Packit ae235b
Packit ae235b
  for (i = 0; i < G_N_ELEMENTS (types); i++)
Packit ae235b
    for (j = 0; j < G_N_ELEMENTS (perms); j++)
Packit ae235b
      {
Packit ae235b
        gchar prop_name[10];
Packit ae235b
        GParamSpec *pspec;
Packit ae235b
Packit ae235b
        if (perms[j] == NULL)
Packit ae235b
          {
Packit ae235b
            if (!g_test_undefined ())
Packit ae235b
              continue;
Packit ae235b
Packit ae235b
            /* we think that this is impossible.  make sure. */
Packit ae235b
            pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
Packit ae235b
Packit ae235b
            g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                                   "*assertion*pspec->flags*failed*");
Packit ae235b
            g_object_interface_install_property (iface, pspec);
Packit ae235b
            g_test_assert_expected_messages ();
Packit ae235b
Packit ae235b
            g_param_spec_unref (pspec);
Packit ae235b
            continue;
Packit ae235b
          }
Packit ae235b
Packit ae235b
        /* install the property */
Packit ae235b
        g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
Packit ae235b
        pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[i], j);
Packit ae235b
        g_object_interface_install_property (iface, pspec);
Packit ae235b
      }
Packit ae235b
}
Packit ae235b
Packit ae235b
/* We now have 21 properties.  Each property may be correctly
Packit ae235b
 * implemented with the following types:
Packit ae235b
 *
Packit ae235b
 *   Properties         Valid Types       Reason
Packit ae235b
 *
Packit ae235b
 *   a-r                a, b              Read only can provide subclasses
Packit ae235b
 *   a-w, wc, wC        a, GObject        Write only can accept superclasses
Packit ae235b
 *   a-rw, rwc, rwC     a                 Read-write must be exactly equal
Packit ae235b
 *
Packit ae235b
 *   b-r                b                 (as above)
Packit ae235b
 *   b-w, wc, wC        b, a, GObject
Packit ae235b
 *   b-rw, rwc, rwC     b
Packit ae235b
 *
Packit ae235b
 *   c-r                c                 (as above)
Packit ae235b
 *   c-wo, wc, wC       c, GObject
Packit ae235b
 *   c-rw, rwc, rwC     c
Packit ae235b
 *
Packit ae235b
 * We can express this in a 48-by-4 table where each row represents an
Packit ae235b
 * installed property and each column represents a type.  The value in
Packit ae235b
 * the table represents if it is valid to subclass the row's property
Packit ae235b
 * with the type of the column:
Packit ae235b
 *
Packit ae235b
 *   - 0:   invalid because the interface property doesn't exist (invalid flags)
Packit ae235b
 *   - 'v': valid
Packit ae235b
 *   - '=': invalid because of the type not being exactly equal
Packit ae235b
 *   - '<': invalid because of the type not being a subclass
Packit ae235b
 *   - '>': invalid because of the type not being a superclass
Packit ae235b
 *
Packit ae235b
 * We organise the table by interface property type ('a', 'b', 'c') then
Packit ae235b
 * by interface property flags.
Packit ae235b
 */
Packit ae235b
Packit ae235b
static gint valid_impl_types[48][4] = {
Packit ae235b
                    /* a    b    c    GObject */
Packit ae235b
    /* 'a-' */       { 0, },
Packit ae235b
    /* 'a-r' */      { 'v', 'v', '<', '<' },
Packit ae235b
    /* 'a-w' */      { 'v', '>', '>', 'v' },
Packit ae235b
    /* 'a-rw' */     { 'v', '=', '=', '=' },
Packit ae235b
    /* 'a-c */       { 0, },
Packit ae235b
    /* 'a-rc' */     { 0, },
Packit ae235b
    /* 'a-wc' */     { 'v', '>', '>', 'v' },
Packit ae235b
    /* 'a-rwc' */    { 'v', '=', '=', '=' },
Packit ae235b
    /* 'a-C */       { 0, },
Packit ae235b
    /* 'a-rC' */     { 0, },
Packit ae235b
    /* 'a-wC' */     { 'v', '>', '>', 'v' },
Packit ae235b
    /* 'a-rwC' */    { 'v', '=', '=', '=' },
Packit ae235b
    /* 'a-cC */      { 0, },
Packit ae235b
    /* 'a-rcC' */    { 0, },
Packit ae235b
    /* 'a-wcC' */    { 0, },
Packit ae235b
    /* 'a-rwcC' */   { 0, },
Packit ae235b
Packit ae235b
    /* 'b-' */       { 0, },
Packit ae235b
    /* 'b-r' */      { '<', 'v', '<', '<' },
Packit ae235b
    /* 'b-w' */      { 'v', 'v', '>', 'v' },
Packit ae235b
    /* 'b-rw' */     { '=', 'v', '=', '=' },
Packit ae235b
    /* 'b-c */       { 0, },
Packit ae235b
    /* 'b-rc' */     { 0, },
Packit ae235b
    /* 'b-wc' */     { 'v', 'v', '>', 'v' },
Packit ae235b
    /* 'b-rwc' */    { '=', 'v', '=', '=' },
Packit ae235b
    /* 'b-C */       { 0, },
Packit ae235b
    /* 'b-rC' */     { 0, },
Packit ae235b
    /* 'b-wC' */     { 'v', 'v', '>', 'v' },
Packit ae235b
    /* 'b-rwC' */    { '=', 'v', '=', '=' },
Packit ae235b
    /* 'b-cC */      { 0, },
Packit ae235b
    /* 'b-rcC' */    { 0, },
Packit ae235b
    /* 'b-wcC' */    { 0, },
Packit ae235b
    /* 'b-rwcC' */   { 0, },
Packit ae235b
Packit ae235b
    /* 'c-' */       { 0, },
Packit ae235b
    /* 'c-r' */      { '<', '<', 'v', '<' },
Packit ae235b
    /* 'c-w' */      { '>', '>', 'v', 'v' },
Packit ae235b
    /* 'c-rw' */     { '=', '=', 'v', '=' },
Packit ae235b
    /* 'c-c */       { 0, },
Packit ae235b
    /* 'c-rc' */     { 0, },
Packit ae235b
    /* 'c-wc' */     { '>', '>', 'v', 'v' },
Packit ae235b
    /* 'c-rwc' */    { '=', '=', 'v', '=' },
Packit ae235b
    /* 'c-C */       { 0, },
Packit ae235b
    /* 'c-rC' */     { 0, },
Packit ae235b
    /* 'c-wC' */     { '>', '>', 'v', 'v' },
Packit ae235b
    /* 'c-rwC' */    { '=', '=', 'v', '=' },
Packit ae235b
    /* 'c-cC */      { 0, },
Packit ae235b
    /* 'c-rcC' */    { 0, },
Packit ae235b
    /* 'c-wcC' */    { 0, },
Packit ae235b
    /* 'c-rwcC' */   { 0, }
Packit ae235b
};
Packit ae235b
Packit ae235b
/* We also try to change the flags.  We must ensure that all
Packit ae235b
 * implementations provide all functionality promised by the interface.
Packit ae235b
 * We must therefore never remove readability or writability (but we can
Packit ae235b
 * add them).  Construct-only is a restrictions that applies to
Packit ae235b
 * writability, so we can never add it unless writability was never
Packit ae235b
 * present in the first place, in which case "writable at construct
Packit ae235b
 * only" is still better than "not writable".
Packit ae235b
 *
Packit ae235b
 * The 'construct' flag is of interest only to the implementation.  It
Packit ae235b
 * may be changed at any time.
Packit ae235b
 *
Packit ae235b
 *   Properties         Valid Access      Reason
Packit ae235b
 *
Packit ae235b
 *   *-r                r, rw, rwc, rwC   Must keep readable, but can restrict newly-added writable
Packit ae235b
 *   *-w                w, rw, rwc        Must keep writable unrestricted
Packit ae235b
 *   *-rw               rw, rwc           Must not add any restrictions
Packit ae235b
 *   *-rwc              rw, rwc           Must not add any restrictions
Packit ae235b
 *   *-rwC              rw, rwc, rwC      Can remove 'construct-only' restriction
Packit ae235b
 *   *-wc               rwc, rw, w, wc    Can add readability
Packit ae235b
 *   *-wC               rwC, rw, w, wC    Can add readability or remove 'construct only' restriction
Packit ae235b
 *                        rwc, wc
Packit ae235b
 *
Packit ae235b
 * We can represent this with a 16-by-16 table.  The rows represent the
Packit ae235b
 * flags of the property on the interface.  The columns is the flags to
Packit ae235b
 * try to use when overriding the property.  The cell contents are:
Packit ae235b
 *
Packit ae235b
 *   - 0:   invalid because the interface property doesn't exist (invalid flags)
Packit ae235b
 *   - 'v': valid
Packit ae235b
 *   - 'i': invalid because the implementation flags are invalid
Packit ae235b
 *   - 'f': invalid because of the removal of functionality
Packit ae235b
 *   - 'r': invalid because of the addition of restrictions (ie: construct-only)
Packit ae235b
 *
Packit ae235b
 * We also ensure that removal of functionality is reported before
Packit ae235b
 * addition of restrictions, since this is a more basic problem.
Packit ae235b
 */
Packit ae235b
static gint valid_impl_flags[16][16] = {
Packit ae235b
                 /* ''   r    w    rw   c    rc   wc   rwc  C    rC   wC   rwC  cC   rcC  wcC  rwcC */
Packit ae235b
    /* '*-' */    { 0, },
Packit ae235b
    /* '*-r' */   { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-w' */   { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-rw' */  { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-c */    { 0, },
Packit ae235b
    /* '*-rc' */  { 0, },
Packit ae235b
    /* '*-wc' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-C */    { 0, },
Packit ae235b
    /* '*-rC' */  { 0, },
Packit ae235b
    /* '*-wC' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
Packit ae235b
    /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
Packit ae235b
};
Packit ae235b
Packit ae235b
static guint change_this_flag;
Packit ae235b
static guint change_this_type;
Packit ae235b
static guint use_this_flag;
Packit ae235b
static guint use_this_type;
Packit ae235b
Packit ae235b
typedef GObjectClass TestImplementationClass;
Packit ae235b
typedef GObject TestImplementation;
Packit ae235b
Packit ae235b
static void test_implementation_init (TestImplementation *impl) { }
Packit ae235b
static void test_implementation_iface_init (TestInterfaceInterface *iface) { }
Packit ae235b
Packit ae235b
static GType test_implementation_get_type (void);
Packit ae235b
G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT,
Packit ae235b
                         G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init))
Packit ae235b
Packit ae235b
static void test_implementation_class_init (TestImplementationClass *class)
Packit ae235b
{
Packit ae235b
  const gchar *names[] = { "a", "b", "c" };
Packit ae235b
  const gchar *perms[] = { NULL, "r",  "w",  "rw",
Packit ae235b
                           NULL, NULL, "wc", "rwc",
Packit ae235b
                           NULL, NULL, "wC", "rwC",
Packit ae235b
                           NULL, NULL, NULL, NULL };
Packit ae235b
  const GType types[] = { test_object_a_get_type (), test_object_b_get_type (),
Packit ae235b
                          test_object_c_get_type (), G_TYPE_OBJECT };
Packit ae235b
  gchar prop_name[10];
Packit ae235b
  GParamSpec *pspec;
Packit ae235b
  guint i, j;
Packit ae235b
Packit ae235b
  class->get_property = GINT_TO_POINTER (1);
Packit ae235b
  class->set_property = GINT_TO_POINTER (1);
Packit ae235b
Packit ae235b
  /* Install all of the non-modified properties or else GObject will
Packit ae235b
   * complain about non-implemented properties.
Packit ae235b
   */
Packit ae235b
  for (i = 0; i < 3; i++)
Packit ae235b
    for (j = 0; j < G_N_ELEMENTS (perms); j++)
Packit ae235b
      {
Packit ae235b
        if (i == change_this_type && j == change_this_flag)
Packit ae235b
          continue;
Packit ae235b
Packit ae235b
        if (perms[j] != NULL)
Packit ae235b
          {
Packit ae235b
            /* override the property without making changes */
Packit ae235b
            g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
Packit ae235b
            g_object_class_override_property (class, 1, prop_name);
Packit ae235b
          }
Packit ae235b
      }
Packit ae235b
Packit ae235b
  /* Now try installing our modified property */
Packit ae235b
  if (perms[change_this_flag] == NULL)
Packit ae235b
    g_error ("Interface property does not exist");
Packit ae235b
Packit ae235b
  g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]);
Packit ae235b
  pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag);
Packit ae235b
  g_object_class_install_property (class, 1, pspec);
Packit ae235b
}
Packit ae235b
Packit ae235b
typedef struct {
Packit ae235b
  gint change_this_flag;
Packit ae235b
  gint change_this_type;
Packit ae235b
  gint use_this_flag;
Packit ae235b
  gint use_this_type;
Packit ae235b
} TestParamImplementData;
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_implement_child (gconstpointer user_data)
Packit ae235b
{
Packit ae235b
  TestParamImplementData *data = (gpointer) user_data;
Packit ae235b
Packit ae235b
  /* GObject oddity: GObjectClass must be initialised before we can
Packit ae235b
   * initialise a GTypeInterface.
Packit ae235b
   */
Packit ae235b
  g_type_class_ref (G_TYPE_OBJECT);
Packit ae235b
Packit ae235b
  /* Bring up the interface first. */
Packit ae235b
  g_type_default_interface_ref (test_interface_get_type ());
Packit ae235b
Packit ae235b
  /* Copy the flags into the global vars so
Packit ae235b
   * test_implementation_class_init() will see them.
Packit ae235b
   */
Packit ae235b
  change_this_flag = data->change_this_flag;
Packit ae235b
  change_this_type = data->change_this_type;
Packit ae235b
  use_this_flag = data->use_this_flag;
Packit ae235b
  use_this_type = data->use_this_type;
Packit ae235b
Packit ae235b
  g_type_class_ref (test_implementation_get_type ());
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_implement (void)
Packit ae235b
{
Packit ae235b
  gchar *test_path;
Packit ae235b
Packit ae235b
  for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
Packit ae235b
    for (change_this_type = 0; change_this_type < 3; change_this_type++)
Packit ae235b
      for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
Packit ae235b
        for (use_this_type = 0; use_this_type < 4; use_this_type++)
Packit ae235b
          {
Packit ae235b
            if (!g_test_undefined ())
Packit ae235b
              {
Packit ae235b
                /* only test the valid (defined) cases, e.g. under valgrind */
Packit ae235b
                if (valid_impl_flags[change_this_flag][use_this_flag] != 'v')
Packit ae235b
                  continue;
Packit ae235b
Packit ae235b
                if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v')
Packit ae235b
                  continue;
Packit ae235b
              }
Packit ae235b
Packit ae235b
            test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
Packit ae235b
                                         change_this_flag, change_this_type,
Packit ae235b
                                         use_this_flag, use_this_type);
Packit ae235b
            g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, 0);
Packit ae235b
            g_free (test_path);
Packit ae235b
Packit ae235b
            /* We want to ensure that any flags mismatch problems are reported first. */
Packit ae235b
            switch (valid_impl_flags[change_this_flag][use_this_flag])
Packit ae235b
              {
Packit ae235b
              case 0:
Packit ae235b
                /* make sure the other table agrees */
Packit ae235b
                g_assert (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] == 0);
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*Interface property does not exist*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case 'i':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*g_object_class_install_property*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case 'f':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*remove functionality*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case 'r':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*introduce additional restrictions*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case 'v':
Packit ae235b
                break;
Packit ae235b
              }
Packit ae235b
Packit ae235b
            /* Next, we check if there should have been a type error. */
Packit ae235b
            switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type])
Packit ae235b
              {
Packit ae235b
              case 0:
Packit ae235b
                /* this should have been caught above */
Packit ae235b
                g_assert_not_reached ();
Packit ae235b
Packit ae235b
              case '=':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*exactly equal*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case '<':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*equal to or more restrictive*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case '>':
Packit ae235b
                g_test_trap_assert_failed ();
Packit ae235b
                g_test_trap_assert_stderr ("*equal to or less restrictive*");
Packit ae235b
                continue;
Packit ae235b
Packit ae235b
              case 'v':
Packit ae235b
                break;
Packit ae235b
              }
Packit ae235b
Packit ae235b
            g_test_trap_assert_passed ();
Packit ae235b
          }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_param_default (void)
Packit ae235b
{
Packit ae235b
  GParamSpec *param;
Packit ae235b
  const GValue *def;
Packit ae235b
Packit ae235b
  param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
Packit ae235b
  def = g_param_spec_get_default_value (param);
Packit ae235b
Packit ae235b
  g_assert (G_VALUE_HOLDS (def, G_TYPE_INT));
Packit ae235b
  g_assert_cmpint (g_value_get_int (def), ==, 10);
Packit ae235b
Packit ae235b
  g_param_spec_unref (param);
Packit ae235b
}
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int argc, char *argv[])
Packit ae235b
{
Packit ae235b
  TestParamImplementData data, *test_data;
Packit ae235b
  gchar *test_path;
Packit ae235b
Packit ae235b
  g_test_init (&argc, &argv, NULL);
Packit ae235b
Packit ae235b
  g_test_add_func ("/param/value", test_param_value);
Packit ae235b
  g_test_add_func ("/param/strings", test_param_strings);
Packit ae235b
  g_test_add_func ("/param/qdata", test_param_qdata);
Packit ae235b
  g_test_add_func ("/param/validate", test_param_validate);
Packit ae235b
  g_test_add_func ("/param/convert", test_param_convert);
Packit ae235b
Packit ae235b
  if (g_test_slow ())
Packit ae235b
    g_test_add_func ("/param/implement", test_param_implement);
Packit ae235b
Packit ae235b
  for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
Packit ae235b
    for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)
Packit ae235b
      for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++)
Packit ae235b
        for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++)
Packit ae235b
          {
Packit ae235b
            test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
Packit ae235b
                                         data.change_this_flag, data.change_this_type,
Packit ae235b
                                         data.use_this_flag, data.use_this_type);
Packit ae235b
            test_data = g_memdup (&data, sizeof (TestParamImplementData));
Packit ae235b
            g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
Packit ae235b
            g_free (test_path);
Packit ae235b
          }
Packit ae235b
Packit ae235b
  g_test_add_func ("/value/transform", test_value_transform);
Packit ae235b
  g_test_add_func ("/param/default", test_param_default);
Packit ae235b
Packit ae235b
  return g_test_run ();
Packit ae235b
}