Blame src/tests/ibus-inputcontext.c

Packit Service 1d8f1c
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
Packit Service 1d8f1c
/* vim:set et sts=4: */
Packit Service 1d8f1c
/* ibus - The Input Bus
Packit Service 1d8f1c
 * Copyright (C) 2011 Google, Inc.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
 * modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
 * License as published by the Free Software Foundation; either
Packit Service 1d8f1c
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
 * Lesser General Public License for more details.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
 * License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
 * USA
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
Packit Service 1d8f1c
#include <string.h>
Packit Service 1d8f1c
#include "ibus.h"
Packit Service 1d8f1c
Packit Service 1d8f1c
static IBusBus *bus;
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
call_next_async_function (IBusInputContext *context);
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
fatal_handler(const gchar *log_domain,
Packit Service 1d8f1c
              GLogLevelFlags log_level,
Packit Service 1d8f1c
              const gchar *message,
Packit Service 1d8f1c
              gpointer user_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (!g_strcmp0 (message, "org.freedesktop.IBus.InputContext.GetEngine: GDBus.Error:org.freedesktop.DBus.Error.Failed: Input context does not have engine."))
Packit Service 1d8f1c
        return FALSE; /* do not call abort. */
Packit Service 1d8f1c
    return TRUE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
get_last_engine_id (const GList *engines)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    const char *result = NULL;
Packit Service 1d8f1c
    for (; engines; engines = g_list_next (engines)) {
Packit Service 1d8f1c
        IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data);
Packit Service 1d8f1c
        g_assert (engine_desc);
Packit Service 1d8f1c
        result = ibus_engine_desc_get_name (engine_desc);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    return g_strdup (result);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
call_basic_ipcs (IBusInputContext *context)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_input_context_set_cursor_location (context, 0, 0, 1, 1);
Packit Service 1d8f1c
    ibus_input_context_set_capabilities (context, IBUS_CAP_FOCUS);
Packit Service 1d8f1c
    ibus_input_context_property_activate (context, "dummy.prop.name", PROP_STATE_CHECKED);
Packit Service 1d8f1c
    ibus_input_context_reset (context);
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* When enable() is called, ibus-daemon may start a global (or preloaded,
Packit Service 1d8f1c
     * or default) engine in an asynchrnous manner and return immediately.
Packit Service 1d8f1c
     * Therefore, it is not guaranteed that ibus_input_context_is_enabled()
Packit Service 1d8f1c
     * returns TRUE. */
Packit Service 1d8f1c
Packit Service 1d8f1c
    ibus_input_context_focus_in (context);
Packit Service 1d8f1c
} 
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
test_input_context (void)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GList *engines;
Packit Service 1d8f1c
    gchar *active_engine_name = NULL;
Packit Service 1d8f1c
    IBusInputContext *context;
Packit Service 1d8f1c
    IBusEngineDesc *engine_desc;
Packit Service 1d8f1c
    gchar *current_ic;
Packit Service 1d8f1c
Packit Service 1d8f1c
    context = ibus_bus_create_input_context (bus, "test");
Packit Service 1d8f1c
    call_basic_ipcs (context);
Packit Service 1d8f1c
Packit Service 1d8f1c
    engines = ibus_bus_list_active_engines (bus);
Packit Service 1d8f1c
    if (engines != NULL) {
Packit Service 1d8f1c
        active_engine_name = get_last_engine_id (engines);
Packit Service 1d8f1c
    } else {
Packit Service 1d8f1c
        active_engine_name = g_strdup ("dummy");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_assert (active_engine_name);
Packit Service 1d8f1c
    g_debug ("Use '%s' for testing.", active_engine_name);
Packit Service 1d8f1c
Packit Service 1d8f1c
    ibus_input_context_set_engine (context, active_engine_name);
Packit Service 1d8f1c
    current_ic = ibus_bus_current_input_context (bus);
Packit Service 1d8f1c
    g_assert (!strcmp (current_ic, g_dbus_proxy_get_object_path ((GDBusProxy *)context)));
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_test_log_set_fatal_handler (fatal_handler, NULL);
Packit Service 1d8f1c
    engine_desc = ibus_input_context_get_engine (context);
Packit Service 1d8f1c
    if (engine_desc) {
Packit Service 1d8f1c
        /* FIXME race condition between ibus_input_context_set_engine and _get_engine.
Packit Service 1d8f1c
         * ibus_input_context_get_engine is not guaranteed to return non-NULL
Packit Service 1d8f1c
         * (even if we use synchronous set_engine()) because ibus-daemon sets a context
Packit Service 1d8f1c
         * engine in an asynchronous manner. See _context_request_engine_cb in
Packit Service 1d8f1c
         * ibusimpl.c which handles context_signals[REQUEST_ENGINE] signal. */
Packit Service 1d8f1c
        g_assert (!strcmp (active_engine_name, ibus_engine_desc_get_name(engine_desc)));
Packit Service 1d8f1c
        g_object_unref (engine_desc);
Packit Service 1d8f1c
        engine_desc = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    ibus_input_context_process_key_event (context, 0, 0, 0);
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* An engine is set. Try to call basic IPCs again. */
Packit Service 1d8f1c
    call_basic_ipcs (context);
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_free (current_ic);
Packit Service 1d8f1c
    g_object_unref (context);
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_free (active_engine_name);
Packit Service 1d8f1c
    g_list_foreach (engines, (GFunc) g_object_unref, NULL);
Packit Service 1d8f1c
    g_list_free (engines);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
finish_get_engine_async (GObject *source_object,
Packit Service 1d8f1c
                         GAsyncResult *res,
Packit Service 1d8f1c
                         gpointer user_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusInputContext *context = IBUS_INPUT_CONTEXT (source_object);
Packit Service 1d8f1c
    GError *error = NULL;
Packit Service 1d8f1c
    IBusEngineDesc *desc = ibus_input_context_get_engine_async_finish (context,
Packit Service 1d8f1c
                                                                       res,
Packit Service 1d8f1c
                                                                       &error);
Packit Service 1d8f1c
    if (desc) {
Packit Service 1d8f1c
        g_object_unref (desc);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_debug ("ibus_context_get_engine_async_finish: OK");
Packit Service 1d8f1c
    call_next_async_function (context);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
start_get_engine_async (IBusInputContext *context)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_input_context_get_engine_async (context,
Packit Service 1d8f1c
                                         -1, /* timeout */
Packit Service 1d8f1c
                                         NULL, /* cancellable */
Packit Service 1d8f1c
                                         finish_get_engine_async,
Packit Service 1d8f1c
                                         NULL); /* user_data */
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
finish_process_key_event_async (GObject *source_object,
Packit Service 1d8f1c
                         GAsyncResult *res,
Packit Service 1d8f1c
                         gpointer user_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusInputContext *context = IBUS_INPUT_CONTEXT (source_object);
Packit Service 1d8f1c
    GError *error = NULL;
Packit Service 1d8f1c
    gboolean result = ibus_input_context_process_key_event_async_finish (context,
Packit Service 1d8f1c
                                                                         res,
Packit Service 1d8f1c
                                                                         &error);
Packit Service 1d8f1c
    g_assert (result || error == NULL);
Packit Service 1d8f1c
    g_debug ("ibus_context_process_key_event_async_finish: OK");
Packit Service 1d8f1c
    call_next_async_function (context);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
start_process_key_event_async (IBusInputContext *context)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_input_context_process_key_event_async (context,
Packit Service 1d8f1c
                                                0, 0, 0,
Packit Service 1d8f1c
                                                -1, /* timeout */
Packit Service 1d8f1c
                                                NULL, /* cancellable */
Packit Service 1d8f1c
                                                finish_process_key_event_async,
Packit Service 1d8f1c
                                                NULL); /* user_data */
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
test_async_apis_finish (gpointer user_data)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    ibus_quit ();
Packit Service 1d8f1c
    return FALSE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
test_async_apis (void)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    g_debug ("start");
Packit Service 1d8f1c
    IBusInputContext *context;
Packit Service 1d8f1c
    context = ibus_bus_create_input_context (bus, "test");
Packit Service 1d8f1c
    call_basic_ipcs (context);
Packit Service 1d8f1c
Packit Service 1d8f1c
    call_next_async_function (context);
Packit Service 1d8f1c
    ibus_main ();
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
call_next_async_function (IBusInputContext *context)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    static void (*async_functions[])(IBusInputContext *) = {
Packit Service 1d8f1c
        start_get_engine_async,
Packit Service 1d8f1c
        start_process_key_event_async,
Packit Service 1d8f1c
    };
Packit Service 1d8f1c
    static guint index = 0;
Packit Service 1d8f1c
Packit Service 1d8f1c
    // Use g_timeout_add to make sure test_async_apis finishes even if async_functions is empty.
Packit Service 1d8f1c
    if (index >= G_N_ELEMENTS (async_functions))
Packit Service 1d8f1c
        g_timeout_add (1, test_async_apis_finish, NULL);
Packit Service 1d8f1c
    else
Packit Service 1d8f1c
        (*async_functions[index++])(context);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
gint
Packit Service 1d8f1c
main (gint    argc,
Packit Service 1d8f1c
      gchar **argv)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    gint result;
Packit Service 1d8f1c
    ibus_init ();
Packit Service 1d8f1c
    g_test_init (&argc, &argv, NULL);
Packit Service 1d8f1c
    bus = ibus_bus_new ();
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_test_add_func ("/ibus/input_context", test_input_context);
Packit Service 1d8f1c
    g_test_add_func ("/ibus/input_context_async_with_callback", test_async_apis);
Packit Service 1d8f1c
Packit Service 1d8f1c
    result = g_test_run ();
Packit Service 1d8f1c
    g_object_unref (bus);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return result;
Packit Service 1d8f1c
}