mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-15 05:46:15 +01:00
73f445b099
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
1242 lines
41 KiB
C
1242 lines
41 KiB
C
/*
|
|
* Copyright © 2010, 2011, 2013, 2014 Codethink Limited
|
|
* Copyright © 2010, 2011, 2012, 2013, 2015 Red Hat, Inc.
|
|
* Copyright © 2012 Pavel Vasin
|
|
* Copyright © 2022 Endless OS Foundation, LLC
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General
|
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors: Ryan Lortie <desrt@desrt.ca>
|
|
*/
|
|
|
|
#include <gio/gio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "gdbus-sessionbus.h"
|
|
|
|
typedef struct
|
|
{
|
|
GVariant *params;
|
|
gboolean did_run;
|
|
} Activation;
|
|
|
|
static void
|
|
activate (GAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
Activation *activation = user_data;
|
|
|
|
if (parameter)
|
|
activation->params = g_variant_ref (parameter);
|
|
else
|
|
activation->params = NULL;
|
|
activation->did_run = TRUE;
|
|
}
|
|
|
|
static void
|
|
test_basic (void)
|
|
{
|
|
Activation a = { 0, };
|
|
GSimpleAction *action;
|
|
gchar *name;
|
|
GVariantType *parameter_type;
|
|
gboolean enabled;
|
|
GVariantType *state_type;
|
|
GVariant *state;
|
|
|
|
action = g_simple_action_new ("foo", NULL);
|
|
g_assert_true (g_action_get_enabled (G_ACTION (action)));
|
|
g_assert_null (g_action_get_parameter_type (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state_type (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state_hint (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state (G_ACTION (action)));
|
|
g_object_get (action,
|
|
"name", &name,
|
|
"parameter-type", ¶meter_type,
|
|
"enabled", &enabled,
|
|
"state-type", &state_type,
|
|
"state", &state,
|
|
NULL);
|
|
g_assert_cmpstr (name, ==, "foo");
|
|
g_assert_null (parameter_type);
|
|
g_assert_true (enabled);
|
|
g_assert_null (state_type);
|
|
g_assert_null (state);
|
|
g_free (name);
|
|
|
|
g_signal_connect (action, "activate", G_CALLBACK (activate), &a);
|
|
g_assert_false (a.did_run);
|
|
g_action_activate (G_ACTION (action), NULL);
|
|
g_assert_true (a.did_run);
|
|
a.did_run = FALSE;
|
|
|
|
g_simple_action_set_enabled (action, FALSE);
|
|
g_action_activate (G_ACTION (action), NULL);
|
|
g_assert_false (a.did_run);
|
|
|
|
if (g_test_undefined ())
|
|
{
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*assertion*g_variant_is_of_type*failed*");
|
|
g_action_activate (G_ACTION (action), g_variant_new_string ("xxx"));
|
|
g_test_assert_expected_messages ();
|
|
}
|
|
|
|
g_object_unref (action);
|
|
g_assert_false (a.did_run);
|
|
|
|
action = g_simple_action_new ("foo", G_VARIANT_TYPE_STRING);
|
|
g_assert_true (g_action_get_enabled (G_ACTION (action)));
|
|
g_assert_true (g_variant_type_equal (g_action_get_parameter_type (G_ACTION (action)), G_VARIANT_TYPE_STRING));
|
|
g_assert_null (g_action_get_state_type (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state_hint (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state (G_ACTION (action)));
|
|
|
|
g_signal_connect (action, "activate", G_CALLBACK (activate), &a);
|
|
g_assert_false (a.did_run);
|
|
g_action_activate (G_ACTION (action), g_variant_new_string ("Hello world"));
|
|
g_assert_true (a.did_run);
|
|
g_assert_cmpstr (g_variant_get_string (a.params, NULL), ==, "Hello world");
|
|
g_variant_unref (a.params);
|
|
a.did_run = FALSE;
|
|
|
|
if (g_test_undefined ())
|
|
{
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*assertion*!= NULL*failed*");
|
|
g_action_activate (G_ACTION (action), NULL);
|
|
g_test_assert_expected_messages ();
|
|
}
|
|
|
|
g_object_unref (action);
|
|
g_assert_false (a.did_run);
|
|
}
|
|
|
|
static void
|
|
test_name (void)
|
|
{
|
|
g_assert_false (g_action_name_is_valid (""));
|
|
g_assert_false (g_action_name_is_valid ("("));
|
|
g_assert_false (g_action_name_is_valid ("%abc"));
|
|
g_assert_false (g_action_name_is_valid ("$x1"));
|
|
g_assert_true (g_action_name_is_valid ("abc.def"));
|
|
g_assert_true (g_action_name_is_valid ("ABC-DEF"));
|
|
}
|
|
|
|
static gboolean
|
|
strv_strv_cmp (const gchar * const *a,
|
|
const gchar * const *b)
|
|
{
|
|
guint n;
|
|
|
|
for (n = 0; a[n] != NULL; n++)
|
|
{
|
|
if (!g_strv_contains (b, a[n]))
|
|
return FALSE;
|
|
}
|
|
|
|
for (n = 0; b[n] != NULL; n++)
|
|
{
|
|
if (!g_strv_contains (a, b[n]))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
strv_set_equal (const gchar * const *strv, ...)
|
|
{
|
|
guint count;
|
|
va_list list;
|
|
const gchar *str;
|
|
gboolean res;
|
|
|
|
res = TRUE;
|
|
count = 0;
|
|
va_start (list, strv);
|
|
while (1)
|
|
{
|
|
str = va_arg (list, const gchar *);
|
|
if (str == NULL)
|
|
break;
|
|
if (!g_strv_contains (strv, str))
|
|
{
|
|
res = FALSE;
|
|
break;
|
|
}
|
|
count++;
|
|
}
|
|
va_end (list);
|
|
|
|
if (res)
|
|
res = g_strv_length ((gchar**)strv) == count;
|
|
|
|
return res;
|
|
}
|
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
test_simple_group (void)
|
|
{
|
|
GSimpleActionGroup *group;
|
|
Activation a = { 0, };
|
|
GSimpleAction *simple;
|
|
GAction *action;
|
|
gchar **actions;
|
|
GVariant *state;
|
|
|
|
simple = g_simple_action_new ("foo", NULL);
|
|
g_signal_connect (simple, "activate", G_CALLBACK (activate), &a);
|
|
g_assert_false (a.did_run);
|
|
g_action_activate (G_ACTION (simple), NULL);
|
|
g_assert_true (a.did_run);
|
|
a.did_run = FALSE;
|
|
|
|
group = g_simple_action_group_new ();
|
|
g_simple_action_group_insert (group, G_ACTION (simple));
|
|
g_object_unref (simple);
|
|
|
|
g_assert_false (a.did_run);
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "foo", NULL);
|
|
g_assert_true (a.did_run);
|
|
|
|
simple = g_simple_action_new_stateful ("bar", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi"));
|
|
g_simple_action_group_insert (group, G_ACTION (simple));
|
|
g_object_unref (simple);
|
|
|
|
g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "foo"));
|
|
g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "bar"));
|
|
g_assert_false (g_action_group_has_action (G_ACTION_GROUP (group), "baz"));
|
|
actions = g_action_group_list_actions (G_ACTION_GROUP (group));
|
|
g_assert_cmpint (g_strv_length (actions), ==, 2);
|
|
g_assert_true (strv_set_equal ((const gchar * const *) actions, "foo", "bar", NULL));
|
|
g_strfreev (actions);
|
|
g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "foo"));
|
|
g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar"));
|
|
g_assert_null (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "foo"));
|
|
g_assert_true (g_variant_type_equal (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING));
|
|
g_assert_null (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "foo"));
|
|
g_assert_true (g_variant_type_equal (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING));
|
|
g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "foo"));
|
|
g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "bar"));
|
|
g_assert_null (g_action_group_get_action_state (G_ACTION_GROUP (group), "foo"));
|
|
state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar");
|
|
g_assert_true (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING));
|
|
g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
|
|
g_variant_unref (state);
|
|
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "bar", g_variant_new_string ("boo"));
|
|
state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar");
|
|
g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "boo");
|
|
g_variant_unref (state);
|
|
|
|
action = g_simple_action_group_lookup (group, "bar");
|
|
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
|
g_assert_false (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar"));
|
|
|
|
g_simple_action_group_remove (group, "bar");
|
|
action = g_simple_action_group_lookup (group, "foo");
|
|
g_assert_cmpstr (g_action_get_name (action), ==, "foo");
|
|
action = g_simple_action_group_lookup (group, "bar");
|
|
g_assert_null (action);
|
|
|
|
simple = g_simple_action_new ("foo", NULL);
|
|
g_simple_action_group_insert (group, G_ACTION (simple));
|
|
g_object_unref (simple);
|
|
|
|
a.did_run = FALSE;
|
|
g_object_unref (group);
|
|
g_assert_false (a.did_run);
|
|
}
|
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
test_stateful (void)
|
|
{
|
|
GSimpleAction *action;
|
|
GVariant *state;
|
|
|
|
action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi"));
|
|
g_assert_true (g_action_get_enabled (G_ACTION (action)));
|
|
g_assert_null (g_action_get_parameter_type (G_ACTION (action)));
|
|
g_assert_null (g_action_get_state_hint (G_ACTION (action)));
|
|
g_assert_true (g_variant_type_equal (g_action_get_state_type (G_ACTION (action)),
|
|
G_VARIANT_TYPE_STRING));
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
|
|
g_variant_unref (state);
|
|
|
|
if (g_test_undefined ())
|
|
{
|
|
GVariant *new_state = g_variant_ref_sink (g_variant_new_int32 (123));
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*assertion*g_variant_is_of_type*failed*");
|
|
g_simple_action_set_state (action, new_state);
|
|
g_test_assert_expected_messages ();
|
|
g_variant_unref (new_state);
|
|
}
|
|
|
|
g_simple_action_set_state (action, g_variant_new_string ("hello"));
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hello");
|
|
g_variant_unref (state);
|
|
|
|
g_object_unref (action);
|
|
|
|
action = g_simple_action_new ("foo", NULL);
|
|
|
|
if (g_test_undefined ())
|
|
{
|
|
GVariant *new_state = g_variant_ref_sink (g_variant_new_int32 (123));
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*assertion*!= NULL*failed*");
|
|
g_simple_action_set_state (action, new_state);
|
|
g_test_assert_expected_messages ();
|
|
g_variant_unref (new_state);
|
|
}
|
|
|
|
g_object_unref (action);
|
|
}
|
|
|
|
static void
|
|
test_default_activate (void)
|
|
{
|
|
GSimpleAction *action;
|
|
GVariant *state;
|
|
|
|
/* Test changing state via activation with parameter */
|
|
action = g_simple_action_new_stateful ("foo", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi"));
|
|
g_action_activate (G_ACTION (action), g_variant_new_string ("bye"));
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "bye");
|
|
g_variant_unref (state);
|
|
g_object_unref (action);
|
|
|
|
/* Test toggling a boolean action via activation with no parameter */
|
|
action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_boolean (FALSE));
|
|
g_action_activate (G_ACTION (action), NULL);
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_assert_true (g_variant_get_boolean (state));
|
|
g_variant_unref (state);
|
|
/* and back again */
|
|
g_action_activate (G_ACTION (action), NULL);
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_assert_false (g_variant_get_boolean (state));
|
|
g_variant_unref (state);
|
|
g_object_unref (action);
|
|
}
|
|
|
|
static gboolean foo_activated = FALSE;
|
|
static gboolean bar_activated = FALSE;
|
|
|
|
static void
|
|
activate_foo (GSimpleAction *simple,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
g_assert_true (user_data == GINT_TO_POINTER (123));
|
|
g_assert_null (parameter);
|
|
foo_activated = TRUE;
|
|
}
|
|
|
|
static void
|
|
activate_bar (GSimpleAction *simple,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
g_assert_true (user_data == GINT_TO_POINTER (123));
|
|
g_assert_cmpstr (g_variant_get_string (parameter, NULL), ==, "param");
|
|
bar_activated = TRUE;
|
|
}
|
|
|
|
static void
|
|
change_volume_state (GSimpleAction *action,
|
|
GVariant *value,
|
|
gpointer user_data)
|
|
{
|
|
gint requested;
|
|
|
|
requested = g_variant_get_int32 (value);
|
|
|
|
/* Volume only goes from 0 to 10 */
|
|
if (0 <= requested && requested <= 10)
|
|
g_simple_action_set_state (action, value);
|
|
}
|
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
test_entries (void)
|
|
{
|
|
const GActionEntry entries[] = {
|
|
{ "foo", activate_foo, NULL, NULL, NULL, { 0 } },
|
|
{ "bar", activate_bar, "s", NULL, NULL, { 0 } },
|
|
{ "toggle", NULL, NULL, "false", NULL, { 0 } },
|
|
{ "volume", NULL, NULL, "0", change_volume_state, { 0 } },
|
|
};
|
|
GSimpleActionGroup *actions;
|
|
GVariant *state;
|
|
|
|
actions = g_simple_action_group_new ();
|
|
g_simple_action_group_add_entries (actions, entries,
|
|
G_N_ELEMENTS (entries),
|
|
GINT_TO_POINTER (123));
|
|
|
|
g_assert_false (foo_activated);
|
|
g_action_group_activate_action (G_ACTION_GROUP (actions), "foo", NULL);
|
|
g_assert_true (foo_activated);
|
|
foo_activated = FALSE;
|
|
|
|
g_assert_false (bar_activated);
|
|
g_action_group_activate_action (G_ACTION_GROUP (actions), "bar",
|
|
g_variant_new_string ("param"));
|
|
g_assert_true (bar_activated);
|
|
g_assert_false (foo_activated);
|
|
|
|
if (g_test_undefined ())
|
|
{
|
|
const GActionEntry bad_type = {
|
|
"bad-type", NULL, "ss", NULL, NULL, { 0 }
|
|
};
|
|
const GActionEntry bad_state = {
|
|
"bad-state", NULL, NULL, "flse", NULL, { 0 }
|
|
};
|
|
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*not a valid GVariant type string*");
|
|
g_simple_action_group_add_entries (actions, &bad_type, 1, NULL);
|
|
g_test_assert_expected_messages ();
|
|
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
"*could not parse*");
|
|
g_simple_action_group_add_entries (actions, &bad_state, 1, NULL);
|
|
g_test_assert_expected_messages ();
|
|
}
|
|
|
|
state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
|
|
g_assert_cmpint (g_variant_get_int32 (state), ==, 0);
|
|
g_variant_unref (state);
|
|
|
|
/* should change */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume",
|
|
g_variant_new_int32 (7));
|
|
state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
|
|
g_assert_cmpint (g_variant_get_int32 (state), ==, 7);
|
|
g_variant_unref (state);
|
|
|
|
/* should not change */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (actions), "volume",
|
|
g_variant_new_int32 (11));
|
|
state = g_action_group_get_action_state (G_ACTION_GROUP (actions), "volume");
|
|
g_assert_cmpint (g_variant_get_int32 (state), ==, 7);
|
|
g_variant_unref (state);
|
|
|
|
g_object_unref (actions);
|
|
}
|
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
test_parse_detailed (void)
|
|
{
|
|
struct {
|
|
const gchar *detailed;
|
|
const gchar *expected_name;
|
|
const gchar *expected_target;
|
|
const gchar *expected_error;
|
|
const gchar *detailed_roundtrip;
|
|
} testcases[] = {
|
|
{ "abc", "abc", NULL, NULL, "abc" },
|
|
{ " abc", NULL, NULL, "invalid format", NULL },
|
|
{ " abc", NULL, NULL, "invalid format", NULL },
|
|
{ "abc:", NULL, NULL, "invalid format", NULL },
|
|
{ ":abc", NULL, NULL, "invalid format", NULL },
|
|
{ "abc(", NULL, NULL, "invalid format", NULL },
|
|
{ "abc)", NULL, NULL, "invalid format", NULL },
|
|
{ "(abc", NULL, NULL, "invalid format", NULL },
|
|
{ ")abc", NULL, NULL, "invalid format", NULL },
|
|
{ "abc::xyz", "abc", "'xyz'", NULL, "abc::xyz" },
|
|
{ "abc('xyz')", "abc", "'xyz'", NULL, "abc::xyz" },
|
|
{ "abc(42)", "abc", "42", NULL, "abc(42)" },
|
|
{ "abc(int32 42)", "abc", "42", NULL, "abc(42)" },
|
|
{ "abc(@i 42)", "abc", "42", NULL, "abc(42)" },
|
|
{ "abc (42)", NULL, NULL, "invalid format", NULL },
|
|
{ "abc(42abc)", NULL, NULL, "invalid character in number", NULL },
|
|
{ "abc(42, 4)", "abc", "(42, 4)", "expected end of input", NULL },
|
|
{ "abc(42,)", "abc", "(42,)", "expected end of input", NULL }
|
|
};
|
|
gsize i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (testcases); i++)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *target;
|
|
gboolean success;
|
|
gchar *name;
|
|
|
|
success = g_action_parse_detailed_name (testcases[i].detailed, &name, &target, &error);
|
|
g_assert_true (success == (error == NULL));
|
|
if (success && testcases[i].expected_error)
|
|
g_error ("Unexpected success on '%s'. Expected error containing '%s'",
|
|
testcases[i].detailed, testcases[i].expected_error);
|
|
|
|
if (!success && !testcases[i].expected_error)
|
|
g_error ("Unexpected failure on '%s': %s", testcases[i].detailed, error->message);
|
|
|
|
if (!success)
|
|
{
|
|
if (!strstr (error->message, testcases[i].expected_error))
|
|
g_error ("Failure message '%s' for string '%s' did not contained expected substring '%s'",
|
|
error->message, testcases[i].detailed, testcases[i].expected_error);
|
|
|
|
g_error_free (error);
|
|
continue;
|
|
}
|
|
|
|
g_assert_cmpstr (name, ==, testcases[i].expected_name);
|
|
g_assert_true ((target == NULL) == (testcases[i].expected_target == NULL));
|
|
|
|
if (success)
|
|
{
|
|
gchar *detailed;
|
|
|
|
detailed = g_action_print_detailed_name (name, target);
|
|
g_assert_cmpstr (detailed, ==, testcases[i].detailed_roundtrip);
|
|
g_free (detailed);
|
|
}
|
|
|
|
if (target)
|
|
{
|
|
GVariant *expected;
|
|
|
|
expected = g_variant_parse (NULL, testcases[i].expected_target, NULL, NULL, NULL);
|
|
g_assert_true (expected);
|
|
|
|
g_assert_cmpvariant (expected, target);
|
|
g_variant_unref (expected);
|
|
g_variant_unref (target);
|
|
}
|
|
|
|
g_free (name);
|
|
}
|
|
}
|
|
|
|
GHashTable *activation_counts;
|
|
|
|
static void
|
|
count_activation (const gchar *action)
|
|
{
|
|
gint count;
|
|
|
|
if (activation_counts == NULL)
|
|
activation_counts = g_hash_table_new (g_str_hash, g_str_equal);
|
|
count = GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action));
|
|
count++;
|
|
g_hash_table_insert (activation_counts, (gpointer)action, GINT_TO_POINTER (count));
|
|
|
|
g_main_context_wakeup (NULL);
|
|
}
|
|
|
|
static gint
|
|
activation_count (const gchar *action)
|
|
{
|
|
if (activation_counts == NULL)
|
|
return 0;
|
|
|
|
return GPOINTER_TO_INT (g_hash_table_lookup (activation_counts, action));
|
|
}
|
|
|
|
static void
|
|
activate_action (GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
|
{
|
|
count_activation (g_action_get_name (G_ACTION (action)));
|
|
}
|
|
|
|
static void
|
|
activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
|
{
|
|
GVariant *old_state, *new_state;
|
|
|
|
count_activation (g_action_get_name (G_ACTION (action)));
|
|
|
|
old_state = g_action_get_state (G_ACTION (action));
|
|
new_state = g_variant_new_boolean (!g_variant_get_boolean (old_state));
|
|
g_simple_action_set_state (action, new_state);
|
|
g_variant_unref (old_state);
|
|
}
|
|
|
|
static void
|
|
activate_radio (GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
|
{
|
|
GVariant *new_state;
|
|
|
|
count_activation (g_action_get_name (G_ACTION (action)));
|
|
|
|
new_state = g_variant_new_string (g_variant_get_string (parameter, NULL));
|
|
g_simple_action_set_state (action, new_state);
|
|
}
|
|
|
|
static gboolean
|
|
compare_action_groups (GActionGroup *a, GActionGroup *b)
|
|
{
|
|
gchar **alist;
|
|
gchar **blist;
|
|
gint i;
|
|
gboolean equal;
|
|
gboolean ares, bres;
|
|
gboolean aenabled, benabled;
|
|
const GVariantType *aparameter_type, *bparameter_type;
|
|
const GVariantType *astate_type, *bstate_type;
|
|
GVariant *astate_hint, *bstate_hint;
|
|
GVariant *astate, *bstate;
|
|
|
|
alist = g_action_group_list_actions (a);
|
|
blist = g_action_group_list_actions (b);
|
|
equal = strv_strv_cmp ((const gchar * const *) alist, (const gchar * const *) blist);
|
|
|
|
for (i = 0; equal && alist[i]; i++)
|
|
{
|
|
ares = g_action_group_query_action (a, alist[i], &aenabled, &aparameter_type, &astate_type, &astate_hint, &astate);
|
|
bres = g_action_group_query_action (b, alist[i], &benabled, &bparameter_type, &bstate_type, &bstate_hint, &bstate);
|
|
|
|
if (ares && bres)
|
|
{
|
|
equal = equal && (aenabled == benabled);
|
|
equal = equal && ((!aparameter_type && !bparameter_type) || g_variant_type_equal (aparameter_type, bparameter_type));
|
|
equal = equal && ((!astate_type && !bstate_type) || g_variant_type_equal (astate_type, bstate_type));
|
|
equal = equal && ((!astate_hint && !bstate_hint) || g_variant_equal (astate_hint, bstate_hint));
|
|
equal = equal && ((!astate && !bstate) || g_variant_equal (astate, bstate));
|
|
|
|
if (astate_hint)
|
|
g_variant_unref (astate_hint);
|
|
if (bstate_hint)
|
|
g_variant_unref (bstate_hint);
|
|
if (astate)
|
|
g_variant_unref (astate);
|
|
if (bstate)
|
|
g_variant_unref (bstate);
|
|
}
|
|
else
|
|
equal = FALSE;
|
|
}
|
|
|
|
g_strfreev (alist);
|
|
g_strfreev (blist);
|
|
|
|
return equal;
|
|
}
|
|
|
|
static gboolean
|
|
timeout_cb (gpointer user_data)
|
|
{
|
|
gboolean *timed_out = user_data;
|
|
|
|
g_assert_false (*timed_out);
|
|
*timed_out = TRUE;
|
|
g_main_context_wakeup (NULL);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
static GActionEntry exported_entries[] = {
|
|
{ "undo", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "redo", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "cut", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "copy", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "paste", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "bold", activate_toggle, NULL, "true", NULL, { 0 } },
|
|
{ "lang", activate_radio, "s", "'latin'", NULL, { 0 } },
|
|
};
|
|
|
|
static void
|
|
async_result_cb (GObject *source,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
GAsyncResult **result_out = user_data;
|
|
|
|
g_assert_null (*result_out);
|
|
*result_out = g_object_ref (res);
|
|
|
|
g_main_context_wakeup (NULL);
|
|
}
|
|
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
action_added_removed_cb (GActionGroup *action_group,
|
|
char *action_name,
|
|
gpointer user_data)
|
|
{
|
|
guint *counter = user_data;
|
|
|
|
*counter = *counter + 1;
|
|
g_main_context_wakeup (NULL);
|
|
}
|
|
|
|
static void
|
|
action_enabled_changed_cb (GActionGroup *action_group,
|
|
char *action_name,
|
|
gboolean enabled,
|
|
gpointer user_data)
|
|
{
|
|
guint *counter = user_data;
|
|
|
|
*counter = *counter + 1;
|
|
g_main_context_wakeup (NULL);
|
|
}
|
|
|
|
static void
|
|
action_state_changed_cb (GActionGroup *action_group,
|
|
char *action_name,
|
|
GVariant *value,
|
|
gpointer user_data)
|
|
{
|
|
guint *counter = user_data;
|
|
|
|
*counter = *counter + 1;
|
|
g_main_context_wakeup (NULL);
|
|
}
|
|
|
|
static void
|
|
test_dbus_export (void)
|
|
{
|
|
GDBusConnection *bus;
|
|
GSimpleActionGroup *group;
|
|
GDBusActionGroup *proxy;
|
|
GSimpleAction *action;
|
|
GError *error = NULL;
|
|
GVariant *v;
|
|
guint id;
|
|
gchar **actions;
|
|
guint n_actions_added = 0, n_actions_enabled_changed = 0, n_actions_removed = 0, n_actions_state_changed = 0;
|
|
gulong added_signal_id, enabled_changed_signal_id, removed_signal_id, state_changed_signal_id;
|
|
gboolean enabled;
|
|
gchar *param;
|
|
GVariantIter *iter;
|
|
GAsyncResult *async_result = NULL;
|
|
|
|
session_bus_up ();
|
|
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
|
|
group = g_simple_action_group_new ();
|
|
g_simple_action_group_add_entries (group,
|
|
exported_entries,
|
|
G_N_ELEMENTS (exported_entries),
|
|
NULL);
|
|
|
|
id = g_dbus_connection_export_action_group (bus, "/", G_ACTION_GROUP (group), &error);
|
|
g_assert_no_error (error);
|
|
|
|
proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/");
|
|
added_signal_id = g_signal_connect (proxy, "action-added", G_CALLBACK (action_added_removed_cb), &n_actions_added);
|
|
enabled_changed_signal_id = g_signal_connect (proxy, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), &n_actions_enabled_changed);
|
|
removed_signal_id = g_signal_connect (proxy, "action-removed", G_CALLBACK (action_added_removed_cb), &n_actions_removed);
|
|
state_changed_signal_id = g_signal_connect (proxy, "action-state-changed", G_CALLBACK (action_state_changed_cb), &n_actions_state_changed);
|
|
|
|
actions = g_action_group_list_actions (G_ACTION_GROUP (proxy));
|
|
g_assert_cmpint (g_strv_length (actions), ==, 0);
|
|
g_strfreev (actions);
|
|
|
|
/* Actions are queried from the bus asynchronously after the first
|
|
* list_actions() call. Wait for the expected signals then check again. */
|
|
while (n_actions_added < G_N_ELEMENTS (exported_entries))
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
actions = g_action_group_list_actions (G_ACTION_GROUP (proxy));
|
|
g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries));
|
|
g_strfreev (actions);
|
|
|
|
/* check that calling "List" works too */
|
|
g_dbus_connection_call (bus,
|
|
g_dbus_connection_get_unique_name (bus),
|
|
"/",
|
|
"org.gtk.Actions",
|
|
"List",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
G_MAXINT,
|
|
NULL,
|
|
async_result_cb,
|
|
&async_result);
|
|
|
|
while (async_result == NULL)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
v = g_dbus_connection_call_finish (bus, async_result, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_nonnull (v);
|
|
g_variant_get (v, "(^a&s)", &actions);
|
|
g_assert_cmpuint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries));
|
|
g_free (actions);
|
|
g_variant_unref (v);
|
|
g_clear_object (&async_result);
|
|
|
|
/* check that calling "Describe" works */
|
|
g_dbus_connection_call (bus,
|
|
g_dbus_connection_get_unique_name (bus),
|
|
"/",
|
|
"org.gtk.Actions",
|
|
"Describe",
|
|
g_variant_new ("(s)", "copy"),
|
|
NULL,
|
|
0,
|
|
G_MAXINT,
|
|
NULL,
|
|
async_result_cb,
|
|
&async_result);
|
|
|
|
while (async_result == NULL)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
v = g_dbus_connection_call_finish (bus, async_result, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_nonnull (v);
|
|
/* FIXME: there's an extra level of tuplelization in here */
|
|
g_variant_get (v, "((bgav))", &enabled, ¶m, &iter);
|
|
g_assert_true (enabled);
|
|
g_assert_cmpstr (param, ==, "");
|
|
g_assert_cmpint (g_variant_iter_n_children (iter), ==, 0);
|
|
g_free (param);
|
|
g_variant_iter_free (iter);
|
|
g_variant_unref (v);
|
|
g_clear_object (&async_result);
|
|
|
|
/* test that the initial transfer works */
|
|
g_assert_true (G_IS_DBUS_ACTION_GROUP (proxy));
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
/* test that various changes get propagated from group to proxy */
|
|
n_actions_added = 0;
|
|
action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE));
|
|
g_simple_action_group_insert (group, G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
while (n_actions_added == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "cut"));
|
|
g_simple_action_set_enabled (action, FALSE);
|
|
|
|
while (n_actions_enabled_changed == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "bold"));
|
|
g_simple_action_set_state (action, g_variant_new_boolean (FALSE));
|
|
|
|
while (n_actions_state_changed == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
g_simple_action_group_remove (group, "italic");
|
|
|
|
while (n_actions_removed == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
/* test that activations and state changes propagate the other way */
|
|
n_actions_state_changed = 0;
|
|
g_assert_cmpint (activation_count ("copy"), ==, 0);
|
|
g_action_group_activate_action (G_ACTION_GROUP (proxy), "copy", NULL);
|
|
|
|
while (activation_count ("copy") == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_cmpint (activation_count ("copy"), ==, 1);
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
|
|
n_actions_state_changed = 0;
|
|
g_assert_cmpint (activation_count ("bold"), ==, 0);
|
|
g_action_group_activate_action (G_ACTION_GROUP (proxy), "bold", NULL);
|
|
|
|
while (n_actions_state_changed == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_cmpint (activation_count ("bold"), ==, 1);
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold");
|
|
g_assert_true (g_variant_get_boolean (v));
|
|
g_variant_unref (v);
|
|
|
|
n_actions_state_changed = 0;
|
|
g_action_group_change_action_state (G_ACTION_GROUP (proxy), "bold", g_variant_new_boolean (FALSE));
|
|
|
|
while (n_actions_state_changed == 0)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_assert_cmpint (activation_count ("bold"), ==, 1);
|
|
g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy)));
|
|
v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold");
|
|
g_assert_false (g_variant_get_boolean (v));
|
|
g_variant_unref (v);
|
|
|
|
g_dbus_connection_unexport_action_group (bus, id);
|
|
|
|
g_signal_handler_disconnect (proxy, added_signal_id);
|
|
g_signal_handler_disconnect (proxy, enabled_changed_signal_id);
|
|
g_signal_handler_disconnect (proxy, removed_signal_id);
|
|
g_signal_handler_disconnect (proxy, state_changed_signal_id);
|
|
g_object_unref (proxy);
|
|
g_object_unref (group);
|
|
g_object_unref (bus);
|
|
|
|
session_bus_down ();
|
|
}
|
|
|
|
static gpointer
|
|
do_export (gpointer data)
|
|
{
|
|
GActionGroup *group = data;
|
|
GMainContext *ctx;
|
|
gint i;
|
|
GError *error = NULL;
|
|
guint id;
|
|
GDBusConnection *bus;
|
|
GAction *action;
|
|
gchar *path;
|
|
|
|
ctx = g_main_context_new ();
|
|
|
|
g_main_context_push_thread_default (ctx);
|
|
|
|
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
path = g_strdup_printf("/%p", data);
|
|
|
|
for (i = 0; i < 10000; i++)
|
|
{
|
|
id = g_dbus_connection_export_action_group (bus, path, G_ACTION_GROUP (group), &error);
|
|
g_assert_no_error (error);
|
|
|
|
action = g_simple_action_group_lookup (G_SIMPLE_ACTION_GROUP (group), "a");
|
|
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
|
!g_action_get_enabled (action));
|
|
|
|
g_dbus_connection_unexport_action_group (bus, id);
|
|
|
|
while (g_main_context_iteration (ctx, FALSE));
|
|
}
|
|
|
|
g_free (path);
|
|
g_object_unref (bus);
|
|
|
|
g_main_context_pop_thread_default (ctx);
|
|
|
|
g_main_context_unref (ctx);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
test_dbus_threaded (void)
|
|
{
|
|
GSimpleActionGroup *group[10];
|
|
GThread *export[10];
|
|
static GActionEntry entries[] = {
|
|
{ "a", activate_action, NULL, NULL, NULL, { 0 } },
|
|
{ "b", activate_action, NULL, NULL, NULL, { 0 } },
|
|
};
|
|
gint i;
|
|
|
|
session_bus_up ();
|
|
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
group[i] = g_simple_action_group_new ();
|
|
g_simple_action_group_add_entries (group[i], entries, G_N_ELEMENTS (entries), NULL);
|
|
export[i] = g_thread_new ("export", do_export, group[i]);
|
|
}
|
|
|
|
for (i = 0; i < 10; i++)
|
|
g_thread_join (export[i]);
|
|
|
|
for (i = 0; i < 10; i++)
|
|
g_object_unref (group[i]);
|
|
|
|
session_bus_down ();
|
|
}
|
|
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
|
|
static void
|
|
test_bug679509 (void)
|
|
{
|
|
GDBusConnection *bus;
|
|
GDBusActionGroup *proxy;
|
|
gboolean timed_out = FALSE;
|
|
|
|
session_bus_up ();
|
|
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
|
|
proxy = g_dbus_action_group_get (bus, g_dbus_connection_get_unique_name (bus), "/");
|
|
g_strfreev (g_action_group_list_actions (G_ACTION_GROUP (proxy)));
|
|
g_object_unref (proxy);
|
|
|
|
g_timeout_add (100, timeout_cb, &timed_out);
|
|
while (!timed_out)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
g_object_unref (bus);
|
|
|
|
session_bus_down ();
|
|
}
|
|
|
|
static gchar *state_change_log;
|
|
|
|
static void
|
|
state_changed (GActionGroup *group,
|
|
const gchar *action_name,
|
|
GVariant *value,
|
|
gpointer user_data)
|
|
{
|
|
GString *string;
|
|
|
|
g_assert_false (state_change_log);
|
|
|
|
string = g_string_new (action_name);
|
|
g_string_append_c (string, ':');
|
|
g_variant_print_string (value, string, TRUE);
|
|
state_change_log = g_string_free (string, FALSE);
|
|
}
|
|
|
|
static void
|
|
verify_changed (const gchar *log_entry)
|
|
{
|
|
g_assert_cmpstr (state_change_log, ==, log_entry);
|
|
g_clear_pointer (&state_change_log, g_free);
|
|
}
|
|
|
|
static void
|
|
ensure_state (GSimpleActionGroup *group,
|
|
const gchar *action_name,
|
|
const gchar *expected)
|
|
{
|
|
GVariant *value;
|
|
gchar *printed;
|
|
|
|
value = g_action_group_get_action_state (G_ACTION_GROUP (group), action_name);
|
|
printed = g_variant_print (value, TRUE);
|
|
g_variant_unref (value);
|
|
|
|
g_assert_cmpstr (printed, ==, expected);
|
|
g_free (printed);
|
|
}
|
|
|
|
static void
|
|
test_property_actions (void)
|
|
{
|
|
GSimpleActionGroup *group;
|
|
GPropertyAction *action;
|
|
GSocketClient *client;
|
|
GApplication *app;
|
|
gchar *name;
|
|
GVariantType *ptype, *stype;
|
|
gboolean enabled;
|
|
GVariant *state;
|
|
|
|
group = g_simple_action_group_new ();
|
|
g_signal_connect (group, "action-state-changed", G_CALLBACK (state_changed), NULL);
|
|
|
|
client = g_socket_client_new ();
|
|
app = g_application_new ("org.gtk.test", 0);
|
|
|
|
/* string... */
|
|
action = g_property_action_new ("app-id", app, "application-id");
|
|
g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
/* uint... */
|
|
action = g_property_action_new ("keepalive", app, "inactivity-timeout");
|
|
g_object_get (action, "name", &name, "parameter-type", &ptype, "enabled", &enabled, "state-type", &stype, "state", &state, NULL);
|
|
g_assert_cmpstr (name, ==, "keepalive");
|
|
g_assert_true (enabled);
|
|
g_free (name);
|
|
g_variant_type_free (ptype);
|
|
g_variant_type_free (stype);
|
|
g_variant_unref (state);
|
|
|
|
g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
/* bool... */
|
|
action = g_property_action_new ("tls", client, "tls");
|
|
g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
/* inverted */
|
|
action = g_object_new (G_TYPE_PROPERTY_ACTION,
|
|
"name", "disable-proxy",
|
|
"object", client,
|
|
"property-name", "enable-proxy",
|
|
"invert-boolean", TRUE,
|
|
NULL);
|
|
g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
/* enum... */
|
|
action = g_property_action_new ("type", client, "type");
|
|
g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action));
|
|
g_object_unref (action);
|
|
|
|
/* the objects should be held alive by the actions... */
|
|
g_object_unref (client);
|
|
g_object_unref (app);
|
|
|
|
ensure_state (group, "app-id", "'org.gtk.test'");
|
|
ensure_state (group, "keepalive", "uint32 0");
|
|
ensure_state (group, "tls", "false");
|
|
ensure_state (group, "disable-proxy", "false");
|
|
ensure_state (group, "type", "'stream'");
|
|
|
|
verify_changed (NULL);
|
|
|
|
/* some string tests... */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test2"));
|
|
verify_changed ("app-id:'org.gtk.test2'");
|
|
g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test2");
|
|
ensure_state (group, "app-id", "'org.gtk.test2'");
|
|
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "app-id", g_variant_new ("s", "org.gtk.test3"));
|
|
verify_changed ("app-id:'org.gtk.test3'");
|
|
g_assert_cmpstr (g_application_get_application_id (app), ==, "org.gtk.test3");
|
|
ensure_state (group, "app-id", "'org.gtk.test3'");
|
|
|
|
g_application_set_application_id (app, "org.gtk.test");
|
|
verify_changed ("app-id:'org.gtk.test'");
|
|
ensure_state (group, "app-id", "'org.gtk.test'");
|
|
|
|
/* uint tests */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 1234));
|
|
verify_changed ("keepalive:uint32 1234");
|
|
g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 1234);
|
|
ensure_state (group, "keepalive", "uint32 1234");
|
|
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "keepalive", g_variant_new ("u", 5678));
|
|
verify_changed ("keepalive:uint32 5678");
|
|
g_assert_cmpuint (g_application_get_inactivity_timeout (app), ==, 5678);
|
|
ensure_state (group, "keepalive", "uint32 5678");
|
|
|
|
g_application_set_inactivity_timeout (app, 0);
|
|
verify_changed ("keepalive:uint32 0");
|
|
ensure_state (group, "keepalive", "uint32 0");
|
|
|
|
/* bool tests */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "tls", g_variant_new ("b", TRUE));
|
|
verify_changed ("tls:true");
|
|
g_assert_true (g_socket_client_get_tls (client));
|
|
ensure_state (group, "tls", "true");
|
|
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "disable-proxy", g_variant_new ("b", TRUE));
|
|
verify_changed ("disable-proxy:true");
|
|
ensure_state (group, "disable-proxy", "true");
|
|
g_assert_false (g_socket_client_get_enable_proxy (client));
|
|
|
|
/* test toggle true->false */
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL);
|
|
verify_changed ("tls:false");
|
|
g_assert_false (g_socket_client_get_tls (client));
|
|
ensure_state (group, "tls", "false");
|
|
|
|
/* and now back false->true */
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL);
|
|
verify_changed ("tls:true");
|
|
g_assert_true (g_socket_client_get_tls (client));
|
|
ensure_state (group, "tls", "true");
|
|
|
|
g_socket_client_set_tls (client, FALSE);
|
|
verify_changed ("tls:false");
|
|
ensure_state (group, "tls", "false");
|
|
|
|
/* now do the same for the inverted action */
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL);
|
|
verify_changed ("disable-proxy:false");
|
|
g_assert_true (g_socket_client_get_enable_proxy (client));
|
|
ensure_state (group, "disable-proxy", "false");
|
|
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL);
|
|
verify_changed ("disable-proxy:true");
|
|
g_assert_false (g_socket_client_get_enable_proxy (client));
|
|
ensure_state (group, "disable-proxy", "true");
|
|
|
|
g_socket_client_set_enable_proxy (client, TRUE);
|
|
verify_changed ("disable-proxy:false");
|
|
ensure_state (group, "disable-proxy", "false");
|
|
|
|
/* enum tests */
|
|
g_action_group_change_action_state (G_ACTION_GROUP (group), "type", g_variant_new ("s", "datagram"));
|
|
verify_changed ("type:'datagram'");
|
|
g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
|
|
ensure_state (group, "type", "'datagram'");
|
|
|
|
g_action_group_activate_action (G_ACTION_GROUP (group), "type", g_variant_new ("s", "stream"));
|
|
verify_changed ("type:'stream'");
|
|
g_assert_cmpint (g_socket_client_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
|
|
ensure_state (group, "type", "'stream'");
|
|
|
|
g_socket_client_set_socket_type (client, G_SOCKET_TYPE_SEQPACKET);
|
|
verify_changed ("type:'seqpacket'");
|
|
ensure_state (group, "type", "'seqpacket'");
|
|
|
|
/* Check some error cases... */
|
|
g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*non-existent*");
|
|
action = g_property_action_new ("foo", app, "xyz");
|
|
g_test_assert_expected_messages ();
|
|
g_object_unref (action);
|
|
|
|
g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*writable*");
|
|
action = g_property_action_new ("foo", app, "is-registered");
|
|
g_test_assert_expected_messages ();
|
|
g_object_unref (action);
|
|
|
|
g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_CRITICAL, "*type 'GSocketAddress'*");
|
|
action = g_property_action_new ("foo", client, "local-address");
|
|
g_test_assert_expected_messages ();
|
|
g_object_unref (action);
|
|
|
|
g_object_unref (group);
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
g_test_add_func ("/actions/basic", test_basic);
|
|
g_test_add_func ("/actions/name", test_name);
|
|
g_test_add_func ("/actions/simplegroup", test_simple_group);
|
|
g_test_add_func ("/actions/stateful", test_stateful);
|
|
g_test_add_func ("/actions/default-activate", test_default_activate);
|
|
g_test_add_func ("/actions/entries", test_entries);
|
|
g_test_add_func ("/actions/parse-detailed", test_parse_detailed);
|
|
g_test_add_func ("/actions/dbus/export", test_dbus_export);
|
|
g_test_add_func ("/actions/dbus/threaded", test_dbus_threaded);
|
|
g_test_add_func ("/actions/dbus/bug679509", test_bug679509);
|
|
g_test_add_func ("/actions/property", test_property_actions);
|
|
|
|
return g_test_run ();
|
|
}
|