Blame gio/tests/actions.c

Packit ae235b
#include <gio/gio.h>
Packit ae235b
#include <stdlib.h>
Packit ae235b
#include <string.h>
Packit ae235b
Packit ae235b
#include "gdbus-sessionbus.h"
Packit ae235b
Packit ae235b
typedef struct
Packit ae235b
{
Packit ae235b
  GVariant *params;
Packit ae235b
  gboolean did_run;
Packit ae235b
} Activation;
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate (GAction  *action,
Packit ae235b
          GVariant *parameter,
Packit ae235b
          gpointer  user_data)
Packit ae235b
{
Packit ae235b
  Activation *activation = user_data;
Packit ae235b
Packit ae235b
  if (parameter)
Packit ae235b
    activation->params = g_variant_ref (parameter);
Packit ae235b
  else
Packit ae235b
    activation->params = NULL;
Packit ae235b
  activation->did_run = TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_basic (void)
Packit ae235b
{
Packit ae235b
  Activation a = { 0, };
Packit ae235b
  GSimpleAction *action;
Packit ae235b
  gchar *name;
Packit ae235b
  GVariantType *parameter_type;
Packit ae235b
  gboolean enabled;
Packit ae235b
  GVariantType *state_type;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  action = g_simple_action_new ("foo", NULL);
Packit ae235b
  g_assert (g_action_get_enabled (G_ACTION (action)));
Packit ae235b
  g_assert (g_action_get_parameter_type (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state_type (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state (G_ACTION (action)) == NULL);
Packit ae235b
  g_object_get (action,
Packit ae235b
                "name", &name,
Packit ae235b
                "parameter-type", &parameter_type,
Packit ae235b
                "enabled", &enabled,
Packit ae235b
                "state-type", &state_type,
Packit ae235b
                "state", &state,
Packit ae235b
                 NULL);
Packit ae235b
  g_assert_cmpstr (name, ==, "foo");
Packit ae235b
  g_assert (parameter_type == NULL);
Packit ae235b
  g_assert (enabled);
Packit ae235b
  g_assert (state_type == NULL);
Packit ae235b
  g_assert (state == NULL);
Packit ae235b
  g_free (name);
Packit ae235b
Packit ae235b
  g_signal_connect (action, "activate", G_CALLBACK (activate), &a);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
  g_action_activate (G_ACTION (action), NULL);
Packit ae235b
  g_assert (a.did_run);
Packit ae235b
  a.did_run = FALSE;
Packit ae235b
Packit ae235b
  g_simple_action_set_enabled (action, FALSE);
Packit ae235b
  g_action_activate (G_ACTION (action), NULL);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
Packit ae235b
  if (g_test_undefined ())
Packit ae235b
    {
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*assertion*g_variant_is_of_type*failed*");
Packit ae235b
      g_action_activate (G_ACTION (action), g_variant_new_string ("xxx"));
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_object_unref (action);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
Packit ae235b
  action = g_simple_action_new ("foo", G_VARIANT_TYPE_STRING);
Packit ae235b
  g_assert (g_action_get_enabled (G_ACTION (action)));
Packit ae235b
  g_assert (g_variant_type_equal (g_action_get_parameter_type (G_ACTION (action)), G_VARIANT_TYPE_STRING));
Packit ae235b
  g_assert (g_action_get_state_type (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state (G_ACTION (action)) == NULL);
Packit ae235b
Packit ae235b
  g_signal_connect (action, "activate", G_CALLBACK (activate), &a);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
  g_action_activate (G_ACTION (action), g_variant_new_string ("Hello world"));
Packit ae235b
  g_assert (a.did_run);
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (a.params, NULL), ==, "Hello world");
Packit ae235b
  g_variant_unref (a.params);
Packit ae235b
  a.did_run = FALSE;
Packit ae235b
Packit ae235b
  if (g_test_undefined ())
Packit ae235b
    {
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*assertion*!= NULL*failed*");
Packit ae235b
      g_action_activate (G_ACTION (action), NULL);
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_object_unref (action);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_name (void)
Packit ae235b
{
Packit ae235b
  g_assert (!g_action_name_is_valid (""));
Packit ae235b
  g_assert (!g_action_name_is_valid ("("));
Packit ae235b
  g_assert (!g_action_name_is_valid ("%abc"));
Packit ae235b
  g_assert (!g_action_name_is_valid ("$x1"));
Packit ae235b
  g_assert (g_action_name_is_valid ("abc.def"));
Packit ae235b
  g_assert (g_action_name_is_valid ("ABC-DEF"));
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
strv_has_string (gchar       **haystack,
Packit ae235b
                 const gchar  *needle)
Packit ae235b
{
Packit ae235b
  guint n;
Packit ae235b
Packit ae235b
  for (n = 0; haystack != NULL && haystack[n] != NULL; n++)
Packit ae235b
    {
Packit ae235b
      if (g_strcmp0 (haystack[n], needle) == 0)
Packit ae235b
        return TRUE;
Packit ae235b
    }
Packit ae235b
  return FALSE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
strv_strv_cmp (gchar **a, gchar **b)
Packit ae235b
{
Packit ae235b
  guint n;
Packit ae235b
Packit ae235b
  for (n = 0; a[n] != NULL; n++)
Packit ae235b
    {
Packit ae235b
       if (!strv_has_string (b, a[n]))
Packit ae235b
         return FALSE;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  for (n = 0; b[n] != NULL; n++)
Packit ae235b
    {
Packit ae235b
       if (!strv_has_string (a, b[n]))
Packit ae235b
         return FALSE;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
strv_set_equal (gchar **strv, ...)
Packit ae235b
{
Packit ae235b
  gint count;
Packit ae235b
  va_list list;
Packit ae235b
  const gchar *str;
Packit ae235b
  gboolean res;
Packit ae235b
Packit ae235b
  res = TRUE;
Packit ae235b
  count = 0;
Packit ae235b
  va_start (list, strv);
Packit ae235b
  while (1)
Packit ae235b
    {
Packit ae235b
      str = va_arg (list, const gchar *);
Packit ae235b
      if (str == NULL)
Packit ae235b
        break;
Packit ae235b
      if (!strv_has_string (strv, str))
Packit ae235b
        {
Packit ae235b
          res = FALSE;
Packit ae235b
          break;
Packit ae235b
        }
Packit ae235b
      count++;
Packit ae235b
    }
Packit ae235b
  va_end (list);
Packit ae235b
Packit ae235b
  if (res)
Packit ae235b
    res = g_strv_length ((gchar**)strv) == count;
Packit ae235b
Packit ae235b
  return res;
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_simple_group (void)
Packit ae235b
{
Packit ae235b
  GSimpleActionGroup *group;
Packit ae235b
  Activation a = { 0, };
Packit ae235b
  GSimpleAction *simple;
Packit ae235b
  GAction *action;
Packit ae235b
  gchar **actions;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  simple = g_simple_action_new ("foo", NULL);
Packit ae235b
  g_signal_connect (simple, "activate", G_CALLBACK (activate), &a);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
  g_action_activate (G_ACTION (simple), NULL);
Packit ae235b
  g_assert (a.did_run);
Packit ae235b
  a.did_run = FALSE;
Packit ae235b
Packit ae235b
  group = g_simple_action_group_new ();
Packit ae235b
  g_simple_action_group_insert (group, G_ACTION (simple));
Packit ae235b
  g_object_unref (simple);
Packit ae235b
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "foo", NULL);
Packit ae235b
  g_assert (a.did_run);
Packit ae235b
Packit ae235b
  simple = g_simple_action_new_stateful ("bar", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi"));
Packit ae235b
  g_simple_action_group_insert (group, G_ACTION (simple));
Packit ae235b
  g_object_unref (simple);
Packit ae235b
Packit ae235b
  g_assert (g_action_group_has_action (G_ACTION_GROUP (group), "foo"));
Packit ae235b
  g_assert (g_action_group_has_action (G_ACTION_GROUP (group), "bar"));
Packit ae235b
  g_assert (!g_action_group_has_action (G_ACTION_GROUP (group), "baz"));
Packit ae235b
  actions = g_action_group_list_actions (G_ACTION_GROUP (group));
Packit ae235b
  g_assert_cmpint (g_strv_length (actions), ==, 2);
Packit ae235b
  g_assert (strv_set_equal (actions, "foo", "bar", NULL));
Packit ae235b
  g_strfreev (actions);
Packit ae235b
  g_assert (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "foo"));
Packit ae235b
  g_assert (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar"));
Packit ae235b
  g_assert (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "foo") == NULL);
Packit ae235b
  g_assert (g_variant_type_equal (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING));
Packit ae235b
  g_assert (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "foo") == NULL);
Packit ae235b
  g_assert (g_variant_type_equal (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING));
Packit ae235b
  g_assert (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "foo") == NULL);
Packit ae235b
  g_assert (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "bar") == NULL);
Packit ae235b
  g_assert (g_action_group_get_action_state (G_ACTION_GROUP (group), "foo") == NULL);
Packit ae235b
  state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar");
Packit ae235b
  g_assert (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING));
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "bar", g_variant_new_string ("boo"));
Packit ae235b
  state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar");
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "boo");
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  action = g_simple_action_group_lookup (group, "bar");
Packit ae235b
  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
Packit ae235b
  g_assert (!g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar"));
Packit ae235b
Packit ae235b
  g_simple_action_group_remove (group, "bar");
Packit ae235b
  action = g_simple_action_group_lookup (group, "foo");
Packit ae235b
  g_assert_cmpstr (g_action_get_name (action), ==, "foo");
Packit ae235b
  action = g_simple_action_group_lookup (group, "bar");
Packit ae235b
  g_assert (action == NULL);
Packit ae235b
Packit ae235b
  simple = g_simple_action_new ("foo", NULL);
Packit ae235b
  g_simple_action_group_insert (group, G_ACTION (simple));
Packit ae235b
  g_object_unref (simple);
Packit ae235b
Packit ae235b
  a.did_run = FALSE;
Packit ae235b
  g_object_unref (group);
Packit ae235b
  g_assert (!a.did_run);
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_END_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_stateful (void)
Packit ae235b
{
Packit ae235b
  GSimpleAction *action;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi"));
Packit ae235b
  g_assert (g_action_get_enabled (G_ACTION (action)));
Packit ae235b
  g_assert (g_action_get_parameter_type (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL);
Packit ae235b
  g_assert (g_variant_type_equal (g_action_get_state_type (G_ACTION (action)),
Packit ae235b
                                  G_VARIANT_TYPE_STRING));
Packit ae235b
  state = g_action_get_state (G_ACTION (action));
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  if (g_test_undefined ())
Packit ae235b
    {
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*assertion*g_variant_is_of_type*failed*");
Packit ae235b
      g_simple_action_set_state (action, g_variant_new_int32 (123));
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_simple_action_set_state (action, g_variant_new_string ("hello"));
Packit ae235b
  state = g_action_get_state (G_ACTION (action));
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hello");
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  action = g_simple_action_new ("foo", NULL);
Packit ae235b
Packit ae235b
  if (g_test_undefined ())
Packit ae235b
    {
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*assertion*!= NULL*failed*");
Packit ae235b
      g_simple_action_set_state (action, g_variant_new_int32 (123));
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_object_unref (action);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_default_activate (void)
Packit ae235b
{
Packit ae235b
  GSimpleAction *action;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  /* Test changing state via activation with parameter */
Packit ae235b
  action = g_simple_action_new_stateful ("foo", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi"));
Packit ae235b
  g_action_activate (G_ACTION (action), g_variant_new_string ("bye"));
Packit ae235b
  state = g_action_get_state (G_ACTION (action));
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "bye");
Packit ae235b
  g_variant_unref (state);
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* Test toggling a boolean action via activation with no parameter */
Packit ae235b
  action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_boolean (FALSE));
Packit ae235b
  g_action_activate (G_ACTION (action), NULL);
Packit ae235b
  state = g_action_get_state (G_ACTION (action));
Packit ae235b
  g_assert (g_variant_get_boolean (state));
Packit ae235b
  g_variant_unref (state);
Packit ae235b
  /* and back again */
Packit ae235b
  g_action_activate (G_ACTION (action), NULL);
Packit ae235b
  state = g_action_get_state (G_ACTION (action));
Packit ae235b
  g_assert (!g_variant_get_boolean (state));
Packit ae235b
  g_variant_unref (state);
Packit ae235b
  g_object_unref (action);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean foo_activated = FALSE;
Packit ae235b
static gboolean bar_activated = FALSE;
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate_foo (GSimpleAction *simple,
Packit ae235b
              GVariant      *parameter,
Packit ae235b
              gpointer       user_data)
Packit ae235b
{
Packit ae235b
  g_assert (user_data == GINT_TO_POINTER (123));
Packit ae235b
  g_assert (parameter == NULL);
Packit ae235b
  foo_activated = TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate_bar (GSimpleAction *simple,
Packit ae235b
              GVariant      *parameter,
Packit ae235b
              gpointer       user_data)
Packit ae235b
{
Packit ae235b
  g_assert (user_data == GINT_TO_POINTER (123));
Packit ae235b
  g_assert_cmpstr (g_variant_get_string (parameter, NULL), ==, "param");
Packit ae235b
  bar_activated = TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
change_volume_state (GSimpleAction *action,
Packit ae235b
                     GVariant      *value,
Packit ae235b
                     gpointer       user_data)
Packit ae235b
{
Packit ae235b
  gint requested;
Packit ae235b
Packit ae235b
  requested = g_variant_get_int32 (value);
Packit ae235b
Packit ae235b
  /* Volume only goes from 0 to 10 */
Packit ae235b
  if (0 <= requested && requested <= 10)
Packit ae235b
    g_simple_action_set_state (action, value);
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_entries (void)
Packit ae235b
{
Packit ae235b
  const GActionEntry entries[] = {
Packit ae235b
    { "foo",    activate_foo                                     },
Packit ae235b
    { "bar",    activate_bar, "s"                                },
Packit ae235b
    { "toggle", NULL,         NULL, "false"                      },
Packit ae235b
    { "volume", NULL,         NULL, "0",     change_volume_state }
Packit ae235b
  };
Packit ae235b
  GSimpleActionGroup *actions;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  actions = g_simple_action_group_new ();
Packit ae235b
  g_simple_action_group_add_entries (actions, entries,
Packit ae235b
                                     G_N_ELEMENTS (entries),
Packit ae235b
                                     GINT_TO_POINTER (123));
Packit ae235b
Packit ae235b
  g_assert (!foo_activated);
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (actions), "foo", NULL);
Packit ae235b
  g_assert (foo_activated);
Packit ae235b
  foo_activated = FALSE;
Packit ae235b
Packit ae235b
  g_assert (!bar_activated);
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (actions), "bar",
Packit ae235b
                                  g_variant_new_string ("param"));
Packit ae235b
  g_assert (bar_activated);
Packit ae235b
  g_assert (!foo_activated);
Packit ae235b
Packit ae235b
  if (g_test_undefined ())
Packit ae235b
    {
Packit ae235b
      const GActionEntry bad_type = {
Packit ae235b
        "bad-type", NULL, "ss"
Packit ae235b
      };
Packit ae235b
      const GActionEntry bad_state = {
Packit ae235b
        "bad-state", NULL, NULL, "flse"
Packit ae235b
      };
Packit ae235b
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*not a valid GVariant type string*");
Packit ae235b
      g_simple_action_group_add_entries (actions, &bad_type, 1, NULL);
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
Packit ae235b
      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
Packit ae235b
                             "*could not parse*");
Packit ae235b
      g_simple_action_group_add_entries (actions, &bad_state, 1, NULL);
Packit ae235b
      g_test_assert_expected_messages ();
Packit ae235b
    }
Packit ae235b
Packit ae235b
  state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
Packit ae235b
  g_assert_cmpint (g_variant_get_int32 (state), ==, 0);
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  /* should change */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume",
Packit ae235b
                                      g_variant_new_int32 (7));
Packit ae235b
  state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
Packit ae235b
  g_assert_cmpint (g_variant_get_int32 (state), ==, 7);
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  /* should not change */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume",
Packit ae235b
                                      g_variant_new_int32 (11));
Packit ae235b
  state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
Packit ae235b
  g_assert_cmpint (g_variant_get_int32 (state), ==, 7);
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  g_object_unref (actions);
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_END_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_parse_detailed (void)
Packit ae235b
{
Packit ae235b
  struct {
Packit ae235b
    const gchar *detailed;
Packit ae235b
    const gchar *expected_name;
Packit ae235b
    const gchar *expected_target;
Packit ae235b
    const gchar *expected_error;
Packit ae235b
    const gchar *detailed_roundtrip;
Packit ae235b
  } testcases[] = {
Packit ae235b
    { "abc",              "abc",    NULL,       NULL,             "abc" },
Packit ae235b
    { " abc",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { " abc",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "abc:",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { ":abc",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "abc(",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "abc)",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "(abc",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { ")abc",             NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "abc::xyz",         "abc",    "'xyz'",    NULL,             "abc::xyz" },
Packit ae235b
    { "abc('xyz')",       "abc",    "'xyz'",    NULL,             "abc::xyz" },
Packit ae235b
    { "abc(42)",          "abc",    "42",       NULL,             "abc(42)" },
Packit ae235b
    { "abc(int32 42)",    "abc",    "42",       NULL,             "abc(42)" },
Packit ae235b
    { "abc(@i 42)",       "abc",    "42",       NULL,             "abc(42)" },
Packit ae235b
    { "abc (42)",         NULL,     NULL,       "invalid format", NULL },
Packit ae235b
    { "abc(42abc)",       NULL,     NULL,       "invalid character in number", NULL },
Packit ae235b
    { "abc(42, 4)",       "abc",    "(42, 4)",  "expected end of input", NULL },
Packit ae235b
    { "abc(42,)",         "abc",    "(42,)",    "expected end of input", NULL }
Packit ae235b
  };
Packit ae235b
  gint i;
Packit ae235b
Packit ae235b
  for (i = 0; i < G_N_ELEMENTS (testcases); i++)
Packit ae235b
    {
Packit ae235b
      GError *error = NULL;
Packit ae235b
      GVariant *target;
Packit ae235b
      gboolean success;
Packit ae235b
      gchar *name;
Packit ae235b
Packit ae235b
      success = g_action_parse_detailed_name (testcases[i].detailed, &name, &target, &error);
Packit ae235b
      g_assert (success == (error == NULL));
Packit ae235b
      if (success && testcases[i].expected_error)
Packit ae235b
        g_error ("Unexpected success on '%s'.  Expected error containing '%s'",
Packit ae235b
                 testcases[i].detailed, testcases[i].expected_error);
Packit ae235b
Packit ae235b
      if (!success && !testcases[i].expected_error)
Packit ae235b
        g_error ("Unexpected failure on '%s': %s", testcases[i].detailed, error->message);
Packit ae235b
Packit ae235b
      if (!success)
Packit ae235b
        {
Packit ae235b
          if (!strstr (error->message, testcases[i].expected_error))
Packit ae235b
            g_error ("Failure message '%s' for string '%s' did not contained expected substring '%s'",
Packit ae235b
                     error->message, testcases[i].detailed, testcases[i].expected_error);
Packit ae235b
Packit ae235b
          g_error_free (error);
Packit ae235b
          continue;
Packit ae235b
        }
Packit ae235b
Packit ae235b
      g_assert_cmpstr (name, ==, testcases[i].expected_name);
Packit ae235b
      g_assert ((target == NULL) == (testcases[i].expected_target == NULL));
Packit ae235b
Packit ae235b
      if (success)
Packit ae235b
        {
Packit ae235b
          gchar *detailed;
Packit ae235b
Packit ae235b
          detailed = g_action_print_detailed_name (name, target);
Packit ae235b
          g_assert_cmpstr (detailed, ==, testcases[i].detailed_roundtrip);
Packit ae235b
          g_free (detailed);
Packit ae235b
        }
Packit ae235b
Packit ae235b
      if (target)
Packit ae235b
        {
Packit ae235b
          GVariant *expected;
Packit ae235b
Packit ae235b
          expected = g_variant_parse (NULL, testcases[i].expected_target, NULL, NULL, NULL);
Packit ae235b
          g_assert (expected);
Packit ae235b
Packit ae235b
          g_assert (g_variant_equal (expected, target));
Packit ae235b
          g_variant_unref (expected);
Packit ae235b
          g_variant_unref (target);
Packit ae235b
        }
Packit ae235b
Packit ae235b
      g_free (name);
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
GHashTable *activation_counts;
Packit ae235b
Packit ae235b
static void
Packit ae235b
count_activation (const gchar *action)
Packit ae235b
{
Packit ae235b
  gint count;
Packit ae235b
Packit ae235b
  if (activation_counts == NULL)
Packit ae235b
    activation_counts = g_hash_table_new (g_str_hash, g_str_equal);
Packit ae235b
  count = GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action));
Packit ae235b
  count++;
Packit ae235b
  g_hash_table_insert (activation_counts, (gpointer)action, GINT_TO_POINTER (count));
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint
Packit ae235b
activation_count (const gchar *action)
Packit ae235b
{
Packit ae235b
  if (activation_counts == NULL)
Packit ae235b
    return 0;
Packit ae235b
Packit ae235b
  return GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action));
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data)
Packit ae235b
{
Packit ae235b
  count_activation (g_action_get_name (G_ACTION (action)));
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer user_data)
Packit ae235b
{
Packit ae235b
  GVariant *old_state, *new_state;
Packit ae235b
Packit ae235b
  count_activation (g_action_get_name (G_ACTION (action)));
Packit ae235b
Packit ae235b
  old_state = g_action_get_state (G_ACTION (action));
Packit ae235b
  new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state));
Packit ae235b
  g_simple_action_set_state (action, new_state);
Packit ae235b
  g_variant_unref (old_state);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data)
Packit ae235b
{
Packit ae235b
  GVariant *new_state;
Packit ae235b
Packit ae235b
  count_activation (g_action_get_name (G_ACTION (action)));
Packit ae235b
Packit ae235b
  new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
Packit ae235b
  g_simple_action_set_state (action, new_state);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
compare_action_groups (GActionGroup *a, GActionGroup *b)
Packit ae235b
{
Packit ae235b
  gchar **alist;
Packit ae235b
  gchar **blist;
Packit ae235b
  gint i;
Packit ae235b
  gboolean equal;
Packit ae235b
  gboolean ares, bres;
Packit ae235b
  gboolean aenabled, benabled;
Packit ae235b
  const GVariantType *aparameter_type, *bparameter_type;
Packit ae235b
  const GVariantType *astate_type, *bstate_type;
Packit ae235b
  GVariant *astate_hint, *bstate_hint;
Packit ae235b
  GVariant *astate, *bstate;
Packit ae235b
Packit ae235b
  alist = g_action_group_list_actions (a);
Packit ae235b
  blist = g_action_group_list_actions (b);
Packit ae235b
  equal = strv_strv_cmp (alist, blist);
Packit ae235b
Packit ae235b
  for (i = 0; equal && alist[i]; i++)
Packit ae235b
    {
Packit ae235b
      ares = g_action_group_query_action (a, alist[i], &aenabled, &aparameter_type, &astate_type, &astate_hint, &astate);
Packit ae235b
      bres = g_action_group_query_action (b, alist[i], &benabled, &bparameter_type, &bstate_type, &bstate_hint, &bstate);
Packit ae235b
Packit ae235b
      if (ares && bres)
Packit ae235b
        {
Packit ae235b
          equal = equal && (aenabled == benabled);
Packit ae235b
          equal = equal && ((!aparameter_type && !bparameter_type) || g_variant_type_equal (aparameter_type, bparameter_type));
Packit ae235b
          equal = equal && ((!astate_type && !bstate_type) || g_variant_type_equal (astate_type, bstate_type));
Packit ae235b
          equal = equal && ((!astate_hint && !bstate_hint) || g_variant_equal (astate_hint, bstate_hint));
Packit ae235b
          equal = equal && ((!astate && !bstate) || g_variant_equal (astate, bstate));
Packit ae235b
Packit ae235b
          if (astate_hint)
Packit ae235b
            g_variant_unref (astate_hint);
Packit ae235b
          if (bstate_hint)
Packit ae235b
            g_variant_unref (bstate_hint);
Packit ae235b
          if (astate)
Packit ae235b
            g_variant_unref (astate);
Packit ae235b
          if (bstate)
Packit ae235b
            g_variant_unref (bstate);
Packit ae235b
        }
Packit ae235b
      else
Packit ae235b
        equal = FALSE;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_strfreev (alist);
Packit ae235b
  g_strfreev (blist);
Packit ae235b
Packit ae235b
  return equal;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
stop_loop (gpointer data)
Packit ae235b
{
Packit ae235b
  GMainLoop *loop = data;
Packit ae235b
Packit ae235b
  g_main_loop_quit (loop);
Packit ae235b
Packit ae235b
  return G_SOURCE_REMOVE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static GActionEntry exported_entries[] = {
Packit ae235b
  { "undo",  activate_action, NULL, NULL,      NULL },
Packit ae235b
  { "redo",  activate_action, NULL, NULL,      NULL },
Packit ae235b
  { "cut",   activate_action, NULL, NULL,      NULL },
Packit ae235b
  { "copy",  activate_action, NULL, NULL,      NULL },
Packit ae235b
  { "paste", activate_action, NULL, NULL,      NULL },
Packit ae235b
  { "bold",  activate_toggle, NULL, "true",    NULL },
Packit ae235b
  { "lang",  activate_radio,  "s",  "'latin'", NULL },
Packit ae235b
};
Packit ae235b
Packit ae235b
static void
Packit ae235b
list_cb (GObject      *source,
Packit ae235b
         GAsyncResult *res,
Packit ae235b
         gpointer      user_data)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus = G_DBUS_CONNECTION (source);
Packit ae235b
  GMainLoop *loop = user_data;
Packit ae235b
  GError *error = NULL;
Packit ae235b
  GVariant *v;
Packit ae235b
  gchar **actions;
Packit ae235b
Packit ae235b
  v = g_dbus_connection_call_finish (bus, res, &error);
Packit ae235b
  g_assert (v);
Packit ae235b
  g_variant_get (v, "(^a&s)", &actions);
Packit ae235b
  g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries));
Packit ae235b
  g_free (actions);
Packit ae235b
  g_variant_unref (v);
Packit ae235b
  g_main_loop_quit (loop);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
call_list (gpointer user_data)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus;
Packit ae235b
Packit ae235b
  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
Packit ae235b
  g_dbus_connection_call (bus,
Packit ae235b
                          g_dbus_connection_get_unique_name (bus),
Packit ae235b
                          "/",
Packit ae235b
                          "org.gtk.Actions",
Packit ae235b
                          "List",
Packit ae235b
                          NULL,
Packit ae235b
                          NULL,
Packit ae235b
                          0,
Packit ae235b
                          G_MAXINT,
Packit ae235b
                          NULL,
Packit ae235b
                          list_cb,
Packit ae235b
                          user_data);
Packit ae235b
  g_object_unref (bus);
Packit ae235b
Packit ae235b
  return G_SOURCE_REMOVE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
describe_cb (GObject      *source,
Packit ae235b
             GAsyncResult *res,
Packit ae235b
             gpointer      user_data)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus = G_DBUS_CONNECTION (source);
Packit ae235b
  GMainLoop *loop = user_data;
Packit ae235b
  GError *error = NULL;
Packit ae235b
  GVariant *v;
Packit ae235b
  gboolean enabled;
Packit ae235b
  gchar *param;
Packit ae235b
  GVariantIter *iter;
Packit ae235b
Packit ae235b
  v = g_dbus_connection_call_finish (bus, res, &error);
Packit ae235b
  g_assert (v);
Packit ae235b
  /* FIXME: there's an extra level of tuplelization in here */
Packit ae235b
  g_variant_get (v, "((bgav))", &enabled, &param, &iter);
Packit ae235b
  g_assert (enabled == TRUE);
Packit ae235b
  g_assert_cmpstr (param, ==, "");
Packit ae235b
  g_assert_cmpint (g_variant_iter_n_children (iter), ==, 0);
Packit ae235b
  g_free (param);
Packit ae235b
  g_variant_iter_free (iter);
Packit ae235b
  g_variant_unref (v);
Packit ae235b
Packit ae235b
  g_main_loop_quit (loop);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
call_describe (gpointer user_data)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus;
Packit ae235b
Packit ae235b
  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
Packit ae235b
  g_dbus_connection_call (bus,
Packit ae235b
                          g_dbus_connection_get_unique_name (bus),
Packit ae235b
                          "/",
Packit ae235b
                          "org.gtk.Actions",
Packit ae235b
                          "Describe",
Packit ae235b
                          g_variant_new ("(s)", "copy"),
Packit ae235b
                          NULL,
Packit ae235b
                          0,
Packit ae235b
                          G_MAXINT,
Packit ae235b
                          NULL,
Packit ae235b
                          describe_cb,
Packit ae235b
                          user_data);
Packit ae235b
  g_object_unref (bus);
Packit ae235b
Packit ae235b
  return G_SOURCE_REMOVE;
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_dbus_export (void)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus;
Packit ae235b
  GSimpleActionGroup *group;
Packit ae235b
  GDBusActionGroup *proxy;
Packit ae235b
  GSimpleAction *action;
Packit ae235b
  GMainLoop *loop;
Packit ae235b
  GError *error = NULL;
Packit ae235b
  GVariant *v;
Packit ae235b
  guint id;
Packit ae235b
  gchar **actions;
Packit ae235b
Packit ae235b
  loop = g_main_loop_new (NULL, FALSE);
Packit ae235b
Packit ae235b
  session_bus_up ();
Packit ae235b
  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
Packit ae235b
Packit ae235b
  group = g_simple_action_group_new ();
Packit ae235b
  g_simple_action_group_add_entries (group,
Packit ae235b
                                     exported_entries,
Packit ae235b
                                     G_N_ELEMENTS (exported_entries),
Packit ae235b
                                     NULL);
Packit ae235b
Packit ae235b
  id = g_dbus_connection_export_action_group (bus, "/", G_ACTION_GROUP (group), &error);
Packit ae235b
  g_assert_no_error (error);
Packit ae235b
Packit ae235b
  proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/");
Packit ae235b
Packit ae235b
  actions = g_action_group_list_actions (G_ACTION_GROUP (proxy));
Packit ae235b
  g_assert_cmpint (g_strv_length (actions), ==, 0);
Packit ae235b
  g_strfreev (actions);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  actions = g_action_group_list_actions (G_ACTION_GROUP (proxy));
Packit ae235b
  g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries));
Packit ae235b
  g_strfreev (actions);
Packit ae235b
Packit ae235b
  /* check that calling "List" works too */
Packit ae235b
  g_idle_add (call_list, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  /* check that calling "Describe" works */
Packit ae235b
  g_idle_add (call_describe, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  /* test that the initial transfer works */
Packit ae235b
  g_assert (G_IS_DBUS_ACTION_GROUP (proxy));
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  /* test that various changes get propagated from group to proxy */
Packit ae235b
  action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE));
Packit ae235b
  g_simple_action_group_insert (group, G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "cut"));
Packit ae235b
  g_simple_action_set_enabled (action, FALSE);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "bold"));
Packit ae235b
  g_simple_action_set_state (action, g_variant_new_boolean (FALSE));
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  g_simple_action_group_remove (group, "italic");
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  /* test that activations and state changes propagate the other way */
Packit ae235b
Packit ae235b
  g_assert_cmpint (activation_count ("copy"), ==, 0);
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (proxy), "copy", NULL);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert_cmpint (activation_count ("copy"), ==, 1);
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
Packit ae235b
  g_assert_cmpint (activation_count ("bold"), ==, 0);
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (proxy), "bold", NULL);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert_cmpint (activation_count ("bold"), ==, 1);
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
  v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold");
Packit ae235b
  g_assert (g_variant_get_boolean (v));
Packit ae235b
  g_variant_unref (v);
Packit ae235b
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (proxy), "bold", g_variant_new_boolean (FALSE));
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_assert_cmpint (activation_count ("bold"), ==, 1);
Packit ae235b
  g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
Packit ae235b
  v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold");
Packit ae235b
  g_assert (!g_variant_get_boolean (v));
Packit ae235b
  g_variant_unref (v);
Packit ae235b
Packit ae235b
  g_dbus_connection_unexport_action_group (bus, id);
Packit ae235b
Packit ae235b
  g_object_unref (proxy);
Packit ae235b
  g_object_unref (group);
Packit ae235b
  g_main_loop_unref (loop);
Packit ae235b
  g_object_unref (bus);
Packit ae235b
Packit ae235b
  session_bus_down ();
Packit ae235b
}
Packit ae235b
Packit ae235b
static gpointer
Packit ae235b
do_export (gpointer data)
Packit ae235b
{
Packit ae235b
  GActionGroup *group = data;
Packit ae235b
  GMainContext *ctx;
Packit ae235b
  gint i;
Packit ae235b
  GError *error = NULL;
Packit ae235b
  guint id;
Packit ae235b
  GDBusConnection *bus;
Packit ae235b
  GAction *action;
Packit ae235b
  gchar *path;
Packit ae235b
Packit ae235b
  ctx = g_main_context_new ();
Packit ae235b
Packit ae235b
  g_main_context_push_thread_default (ctx);
Packit ae235b
Packit ae235b
  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
Packit ae235b
  path = g_strdup_printf("/%p", data);
Packit ae235b
Packit ae235b
  for (i = 0; i < 100000; i++)
Packit ae235b
    {
Packit ae235b
      id = g_dbus_connection_export_action_group (bus, path, G_ACTION_GROUP (group), &error);
Packit ae235b
      g_assert_no_error (error);
Packit ae235b
Packit ae235b
      action = g_simple_action_group_lookup (G_SIMPLE_ACTION_GROUP (group), "a");
Packit ae235b
      g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
Packit ae235b
                                   !g_action_get_enabled (action));
Packit ae235b
Packit ae235b
      g_dbus_connection_unexport_action_group (bus, id);
Packit ae235b
Packit ae235b
      while (g_main_context_iteration (ctx, FALSE));
Packit ae235b
    }
Packit ae235b
Packit ae235b
  g_free (path);
Packit ae235b
  g_object_unref (bus);
Packit ae235b
Packit ae235b
  g_main_context_pop_thread_default (ctx);
Packit ae235b
Packit ae235b
  g_main_context_unref (ctx);
Packit ae235b
Packit ae235b
  return NULL;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_dbus_threaded (void)
Packit ae235b
{
Packit ae235b
  GSimpleActionGroup *group[10];
Packit ae235b
  GThread *export[10];
Packit ae235b
  static GActionEntry entries[] = {
Packit ae235b
    { "a",  activate_action, NULL, NULL, NULL },
Packit ae235b
    { "b",  activate_action, NULL, NULL, NULL },
Packit ae235b
  };
Packit ae235b
  gint i;
Packit ae235b
Packit ae235b
  session_bus_up ();
Packit ae235b
Packit ae235b
  for (i = 0; i < 10; i++)
Packit ae235b
    {
Packit ae235b
      group[i] = g_simple_action_group_new ();
Packit ae235b
      g_simple_action_group_add_entries (group[i], entries, G_N_ELEMENTS (entries), NULL);
Packit ae235b
      export[i] = g_thread_new ("export", do_export, group[i]);
Packit ae235b
    }
Packit ae235b
Packit ae235b
  for (i = 0; i < 10; i++)
Packit ae235b
    g_thread_join (export[i]);
Packit ae235b
Packit ae235b
  for (i = 0; i < 10; i++)
Packit ae235b
    g_object_unref (group[i]);
Packit ae235b
Packit ae235b
  session_bus_down ();
Packit ae235b
}
Packit ae235b
Packit ae235b
G_GNUC_END_IGNORE_DEPRECATIONS
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_bug679509 (void)
Packit ae235b
{
Packit ae235b
  GDBusConnection *bus;
Packit ae235b
  GDBusActionGroup *proxy;
Packit ae235b
  GMainLoop *loop;
Packit ae235b
Packit ae235b
  loop = g_main_loop_new (NULL, FALSE);
Packit ae235b
Packit ae235b
  session_bus_up ();
Packit ae235b
  bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
Packit ae235b
Packit ae235b
  proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/");
Packit ae235b
  g_strfreev (g_action_group_list_actions (G_ACTION_GROUP (proxy)));
Packit ae235b
  g_object_unref (proxy);
Packit ae235b
Packit ae235b
  g_timeout_add (100, stop_loop, loop);
Packit ae235b
  g_main_loop_run (loop);
Packit ae235b
Packit ae235b
  g_main_loop_unref (loop);
Packit ae235b
  g_object_unref (bus);
Packit ae235b
Packit ae235b
  session_bus_down ();
Packit ae235b
}
Packit ae235b
Packit ae235b
static gchar *state_change_log;
Packit ae235b
Packit ae235b
static void
Packit ae235b
state_changed (GActionGroup *group,
Packit ae235b
               const gchar  *action_name,
Packit ae235b
               GVariant     *value,
Packit ae235b
               gpointer      user_data)
Packit ae235b
{
Packit ae235b
  GString *string;
Packit ae235b
Packit ae235b
  g_assert (!state_change_log);
Packit ae235b
Packit ae235b
  string = g_string_new (action_name);
Packit ae235b
  g_string_append_c (string, ':');
Packit ae235b
  g_variant_print_string (value, string, TRUE);
Packit ae235b
  state_change_log = g_string_free (string, FALSE);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
verify_changed (const gchar *log_entry)
Packit ae235b
{
Packit ae235b
  g_assert_cmpstr (state_change_log, ==, log_entry);
Packit ae235b
  g_clear_pointer (&state_change_log, g_free);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
ensure_state (GSimpleActionGroup *group,
Packit ae235b
              const gchar        *action_name,
Packit ae235b
              const gchar        *expected)
Packit ae235b
{
Packit ae235b
  GVariant *value;
Packit ae235b
  gchar *printed;
Packit ae235b
Packit ae235b
  value = g_action_group_get_action_state (G_ACTION_GROUP (group), action_name);
Packit ae235b
  printed = g_variant_print (value, TRUE);
Packit ae235b
  g_variant_unref (value);
Packit ae235b
Packit ae235b
  g_assert_cmpstr (printed, ==, expected);
Packit ae235b
  g_free (printed);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_property_actions (void)
Packit ae235b
{
Packit ae235b
  GSimpleActionGroup *group;
Packit ae235b
  GPropertyAction *action;
Packit ae235b
  GSocketClient *client;
Packit ae235b
  GApplication *app;
Packit ae235b
  gchar *name;
Packit ae235b
  GVariantType *ptype, *stype;
Packit ae235b
  gboolean enabled;
Packit ae235b
  GVariant *state;
Packit ae235b
Packit ae235b
  group = g_simple_action_group_new ();
Packit ae235b
  g_signal_connect (group, "action-state-changed", G_CALLBACK (state_changed), NULL);
Packit ae235b
Packit ae235b
  client = g_socket_client_new ();
Packit ae235b
  app = g_application_new ("org.gtk.test", 0);
Packit ae235b
Packit ae235b
  /* string... */
Packit ae235b
  action = g_property_action_new ("app-id", app, "application-id");
Packit ae235b
  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* uint... */
Packit ae235b
  action = g_property_action_new ("keepalive", app, "inactivity-timeout");
Packit ae235b
  g_object_get (action, "name", &name, "parameter-type", &ptype, "enabled", &enabled, "state-type", &stype, "state", &state, NULL);
Packit ae235b
  g_assert_cmpstr (name, ==, "keepalive");
Packit ae235b
  g_assert (enabled);
Packit ae235b
  g_free (name);
Packit ae235b
  g_variant_unref (state);
Packit ae235b
Packit ae235b
  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* bool... */
Packit ae235b
  action = g_property_action_new ("tls", client, "tls");
Packit ae235b
  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* inverted */
Packit ae235b
  action = g_object_new (G_TYPE_PROPERTY_ACTION,
Packit ae235b
                         "name", "disable-proxy",
Packit ae235b
                         "object", client,
Packit ae235b
                         "property-name", "enable-proxy",
Packit ae235b
                         "invert-boolean", TRUE,
Packit ae235b
                         NULL);
Packit ae235b
  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* enum... */
Packit ae235b
  action = g_property_action_new ("type", client, "type");
Packit ae235b
  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  /* the objects should be held alive by the actions... */
Packit ae235b
  g_object_unref (client);
Packit ae235b
  g_object_unref (app);
Packit ae235b
Packit ae235b
  ensure_state (group, "app-id", "'org.gtk.test'");
Packit ae235b
  ensure_state (group, "keepalive", "uint32 0");
Packit ae235b
  ensure_state (group, "tls", "false");
Packit ae235b
  ensure_state (group, "disable-proxy", "false");
Packit ae235b
  ensure_state (group, "type", "'stream'");
Packit ae235b
Packit ae235b
  verify_changed (NULL);
Packit ae235b
Packit ae235b
  /* some string tests... */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test2"));
Packit ae235b
  verify_changed ("app-id:'org.gtk.test2'");
Packit ae235b
  g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test2");
Packit ae235b
  ensure_state (group, "app-id", "'org.gtk.test2'");
Packit ae235b
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test3"));
Packit ae235b
  verify_changed ("app-id:'org.gtk.test3'");
Packit ae235b
  g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test3");
Packit ae235b
  ensure_state (group, "app-id", "'org.gtk.test3'");
Packit ae235b
Packit ae235b
  g_application_set_application_id (app, "org.gtk.test");
Packit ae235b
  verify_changed ("app-id:'org.gtk.test'");
Packit ae235b
  ensure_state (group, "app-id", "'org.gtk.test'");
Packit ae235b
Packit ae235b
  /* uint tests */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 1234));
Packit ae235b
  verify_changed ("keepalive:uint32 1234");
Packit ae235b
  g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 1234);
Packit ae235b
  ensure_state (group, "keepalive", "uint32 1234");
Packit ae235b
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 5678));
Packit ae235b
  verify_changed ("keepalive:uint32 5678");
Packit ae235b
  g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 5678);
Packit ae235b
  ensure_state (group, "keepalive", "uint32 5678");
Packit ae235b
Packit ae235b
  g_application_set_inactivity_timeout (app, 0);
Packit ae235b
  verify_changed ("keepalive:uint32 0");
Packit ae235b
  ensure_state (group, "keepalive", "uint32 0");
Packit ae235b
Packit ae235b
  /* bool tests */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "tls", g_variant_new ("b", TRUE));
Packit ae235b
  verify_changed ("tls:true");
Packit ae235b
  g_assert (g_socket_client_get_tls (client));
Packit ae235b
  ensure_state (group, "tls", "true");
Packit ae235b
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "disable-proxy", g_variant_new ("b", TRUE));
Packit ae235b
  verify_changed ("disable-proxy:true");
Packit ae235b
  ensure_state (group, "disable-proxy", "true");
Packit ae235b
  g_assert (!g_socket_client_get_enable_proxy (client));
Packit ae235b
Packit ae235b
  /* test toggle true->false */
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL);
Packit ae235b
  verify_changed ("tls:false");
Packit ae235b
  g_assert (!g_socket_client_get_tls (client));
Packit ae235b
  ensure_state (group, "tls", "false");
Packit ae235b
Packit ae235b
  /* and now back false->true */
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL);
Packit ae235b
  verify_changed ("tls:true");
Packit ae235b
  g_assert (g_socket_client_get_tls (client));
Packit ae235b
  ensure_state (group, "tls", "true");
Packit ae235b
Packit ae235b
  g_socket_client_set_tls (client, FALSE);
Packit ae235b
  verify_changed ("tls:false");
Packit ae235b
  ensure_state (group, "tls", "false");
Packit ae235b
Packit ae235b
  /* now do the same for the inverted action */
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL);
Packit ae235b
  verify_changed ("disable-proxy:false");
Packit ae235b
  g_assert (g_socket_client_get_enable_proxy (client));
Packit ae235b
  ensure_state (group, "disable-proxy", "false");
Packit ae235b
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL);
Packit ae235b
  verify_changed ("disable-proxy:true");
Packit ae235b
  g_assert (!g_socket_client_get_enable_proxy (client));
Packit ae235b
  ensure_state (group, "disable-proxy", "true");
Packit ae235b
Packit ae235b
  g_socket_client_set_enable_proxy (client, TRUE);
Packit ae235b
  verify_changed ("disable-proxy:false");
Packit ae235b
  ensure_state (group, "disable-proxy", "false");
Packit ae235b
Packit ae235b
  /* enum tests */
Packit ae235b
  g_action_group_change_action_state (G_ACTION_GROUP (group), "type", g_variant_new ("s", "datagram"));
Packit ae235b
  verify_changed ("type:'datagram'");
Packit ae235b
  g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
Packit ae235b
  ensure_state (group, "type", "'datagram'");
Packit ae235b
Packit ae235b
  g_action_group_activate_action (G_ACTION_GROUP (group), "type", g_variant_new ("s", "stream"));
Packit ae235b
  verify_changed ("type:'stream'");
Packit ae235b
  g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
Packit ae235b
  ensure_state (group, "type", "'stream'");
Packit ae235b
Packit ae235b
  g_socket_client_set_socket_type (client, G_SOCKET_TYPE_SEQPACKET);
Packit ae235b
  verify_changed ("type:'seqpacket'");
Packit ae235b
  ensure_state (group, "type", "'seqpacket'");
Packit ae235b
Packit ae235b
  /* Check some error cases... */
Packit ae235b
  g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*non-existent*");
Packit ae235b
  action = g_property_action_new ("foo", app, "xyz");
Packit ae235b
  g_test_assert_expected_messages ();
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*writable*");
Packit ae235b
  action = g_property_action_new ("foo", app, "is-registered");
Packit ae235b
  g_test_assert_expected_messages ();
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*type 'GSocketAddress'*");
Packit ae235b
  action = g_property_action_new ("foo", client, "local-address");
Packit ae235b
  g_test_assert_expected_messages ();
Packit ae235b
  g_object_unref (action);
Packit ae235b
Packit ae235b
  g_object_unref (group);
Packit ae235b
}
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int argc, char **argv)
Packit ae235b
{
Packit ae235b
  g_test_init (&argc, &argv, NULL);
Packit ae235b
Packit ae235b
  g_test_add_func ("/actions/basic", test_basic);
Packit ae235b
  g_test_add_func ("/actions/name", test_name);
Packit ae235b
  g_test_add_func ("/actions/simplegroup", test_simple_group);
Packit ae235b
  g_test_add_func ("/actions/stateful", test_stateful);
Packit ae235b
  g_test_add_func ("/actions/default-activate", test_default_activate);
Packit ae235b
  g_test_add_func ("/actions/entries", test_entries);
Packit ae235b
  g_test_add_func ("/actions/parse-detailed", test_parse_detailed);
Packit ae235b
  g_test_add_func ("/actions/dbus/export", test_dbus_export);
Packit ae235b
  g_test_add_func ("/actions/dbus/threaded", test_dbus_threaded);
Packit ae235b
  g_test_add_func ("/actions/dbus/bug679509", test_bug679509);
Packit ae235b
  g_test_add_func ("/actions/property", test_property_actions);
Packit ae235b
Packit ae235b
  return g_test_run ();
Packit ae235b
}