~ubuntu-branches/ubuntu/quantal/ibus/quantal

« back to all changes in this revision

Viewing changes to src/tests/ibus-inputcontext.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry Warsaw
  • Date: 2011-08-11 17:00:57 UTC
  • mfrom: (6.2.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110811170057-6dmbfs4s3cchzl7x
Tags: 1.3.99.20110419-1ubuntu1
* Merge with Debian unstable.  Remaining Ubuntu changes:
  - Indicator support:
    + Add 05_appindicator.patch: Use an indicator rather than a notification
      icon.
    + debian/control: Recommend python-appindicator.
  - debian/control: Install im-switch instead of im-config by default.
  - debian/README.source: Removed, it was outdated and no longer correct
  - debian/patches/01_ubuntu_desktop: Fix "Desktop entry needs the
    X-Ubuntu-Gettext-Domain key"  (LP: #457632)
  - debian/patches/02_title_update.patch: Rename "IBus Preferences" to
    "Keyboard Input Methods"
  - debian/patches/06_locale_parser.patch: Cherry-picked from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 
2
/* vim:set et sts=4: */
 
3
/* ibus - The Input Bus
 
4
 * Copyright (C) 2011 Google, Inc.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the
 
18
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
19
 * Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <string.h>
 
23
#include "ibus.h"
 
24
 
 
25
static IBusBus *bus;
 
26
static void
 
27
call_next_async_function (IBusInputContext *context);
 
28
 
 
29
static gboolean
 
30
fatal_handler(const gchar *log_domain,
 
31
              GLogLevelFlags log_level,
 
32
              const gchar *message,
 
33
              gpointer user_data)
 
34
{
 
35
    if (!g_strcmp0 (message, "org.freedesktop.IBus.InputContext.GetEngine: GDBus.Error:org.freedesktop.DBus.Error.Failed: Input context does not have engine."))
 
36
        return FALSE; /* do not call abort. */
 
37
    return TRUE;
 
38
}
 
39
 
 
40
static gchar *
 
41
get_last_engine_id (const GList *engines)
 
42
{
 
43
    const char *result = NULL;
 
44
    for (; engines; engines = g_list_next (engines)) {
 
45
        IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data);
 
46
        g_assert (engine_desc);
 
47
        result = ibus_engine_desc_get_name (engine_desc);
 
48
    }
 
49
    return g_strdup (result);
 
50
}
 
51
 
 
52
static void
 
53
call_basic_ipcs (IBusInputContext *context)
 
54
{
 
55
    ibus_input_context_set_cursor_location (context, 0, 0, 1, 1);
 
56
    ibus_input_context_set_capabilities (context, IBUS_CAP_FOCUS);
 
57
    ibus_input_context_property_activate (context, "dummy.prop.name", PROP_STATE_CHECKED);
 
58
    ibus_input_context_reset (context);
 
59
    ibus_input_context_disable (context);
 
60
    /* g_assert (ibus_input_context_is_enabled (context) == FALSE); */ /* see below. */
 
61
    ibus_input_context_enable (context);
 
62
    /* g_assert (ibus_input_context_is_enabled (context) == TRUE); */ /* see below. */
 
63
 
 
64
    /* When enable() is called, ibus-daemon may start a global (or preloaded,
 
65
     * or default) engine in an asynchrnous manner and return immediately.
 
66
     * Therefore, it is not guaranteed that ibus_input_context_is_enabled()
 
67
     * returns TRUE. */
 
68
 
 
69
    ibus_input_context_focus_in (context);
 
70
 
71
 
 
72
static void
 
73
test_input_context (void)
 
74
{
 
75
    GList *engines;
 
76
    gchar *active_engine_name = NULL;
 
77
    IBusInputContext *context;
 
78
    IBusEngineDesc *engine_desc;
 
79
    gchar *current_ic;
 
80
 
 
81
    context = ibus_bus_create_input_context (bus, "test");
 
82
    call_basic_ipcs (context);
 
83
 
 
84
    engines = ibus_bus_list_active_engines (bus);
 
85
    if (engines != NULL) {
 
86
        active_engine_name = get_last_engine_id (engines);
 
87
    } else {
 
88
        active_engine_name = g_strdup ("dummy-engine-name");
 
89
    }
 
90
    g_assert (active_engine_name);
 
91
    g_debug ("Use '%s' for testing.", active_engine_name);
 
92
 
 
93
    ibus_input_context_set_engine (context, active_engine_name);
 
94
    current_ic = ibus_bus_current_input_context (bus);
 
95
    g_assert (!strcmp (current_ic, g_dbus_proxy_get_object_path ((GDBusProxy *)context)));
 
96
 
 
97
    g_test_log_set_fatal_handler (fatal_handler, NULL);
 
98
    engine_desc = ibus_input_context_get_engine (context);
 
99
    if (engine_desc) {
 
100
        /* FIXME race condition between ibus_input_context_set_engine and _get_engine.
 
101
         * ibus_input_context_get_engine is not guaranteed to return non-NULL
 
102
         * (even if we use synchronous set_engine()) because ibus-daemon sets a context
 
103
         * engine in an asynchronous manner. See _context_request_engine_cb in
 
104
         * ibusimpl.c which handles context_signals[REQUEST_ENGINE] signal. */
 
105
        g_assert (!strcmp (active_engine_name, ibus_engine_desc_get_name(engine_desc)));
 
106
        g_object_unref (engine_desc);
 
107
        engine_desc = NULL;
 
108
    }
 
109
    ibus_input_context_process_key_event (context, 0, 0, 0);
 
110
 
 
111
    /* An engine is set. Try to call basic IPCs again. */
 
112
    call_basic_ipcs (context);
 
113
 
 
114
    g_free (current_ic);
 
115
    g_object_unref (context);
 
116
 
 
117
    g_free (active_engine_name);
 
118
    g_list_foreach (engines, (GFunc) g_object_unref, NULL);
 
119
    g_list_free (engines);
 
120
}
 
121
 
 
122
static void
 
123
finish_is_enabled_async (GObject *source_object,
 
124
                         GAsyncResult *res,
 
125
                         gpointer user_data)
 
126
{
 
127
    IBusInputContext *context = IBUS_INPUT_CONTEXT (source_object);
 
128
    GError *error = NULL;
 
129
    gboolean retval = FALSE;
 
130
    gboolean result = ibus_input_context_is_enabled_async_finish (context,
 
131
                                                                  res,
 
132
                                                                  &retval,
 
133
                                                                  &error);
 
134
    g_assert (result);
 
135
    g_assert (retval);
 
136
    g_debug ("ibus_context_is_enabled_async_finish: OK");
 
137
    call_next_async_function (context);
 
138
}
 
139
 
 
140
static void
 
141
start_is_enabled_async (IBusInputContext *context)
 
142
{
 
143
    ibus_input_context_is_enabled_async (context,
 
144
                                         -1, /* timeout */
 
145
                                         NULL, /* cancellable */
 
146
                                         finish_is_enabled_async,
 
147
                                         NULL); /* user_data */
 
148
}
 
149
 
 
150
static void
 
151
finish_get_engine_async (GObject *source_object,
 
152
                         GAsyncResult *res,
 
153
                         gpointer user_data)
 
154
{
 
155
    IBusInputContext *context = IBUS_INPUT_CONTEXT (source_object);
 
156
    GError *error = NULL;
 
157
    IBusEngineDesc *desc = ibus_input_context_get_engine_async_finish (context,
 
158
                                                                       res,
 
159
                                                                       &error);
 
160
    if (desc) {
 
161
        g_object_unref (desc);
 
162
    }
 
163
    g_debug ("ibus_context_get_engine_async_finish: OK");
 
164
    call_next_async_function (context);
 
165
}
 
166
 
 
167
static void
 
168
start_get_engine_async (IBusInputContext *context)
 
169
{
 
170
    ibus_input_context_get_engine_async (context,
 
171
                                         -1, /* timeout */
 
172
                                         NULL, /* cancellable */
 
173
                                         finish_get_engine_async,
 
174
                                         NULL); /* user_data */
 
175
}
 
176
 
 
177
static void
 
178
finish_process_key_event_async (GObject *source_object,
 
179
                         GAsyncResult *res,
 
180
                         gpointer user_data)
 
181
{
 
182
    IBusInputContext *context = IBUS_INPUT_CONTEXT (source_object);
 
183
    GError *error = NULL;
 
184
    gboolean processed = FALSE;
 
185
    gboolean result = ibus_input_context_process_key_event_async_finish (context,
 
186
                                                                         res,
 
187
                                                                         &processed,
 
188
                                                                         &error);
 
189
    g_assert (result);
 
190
    g_debug ("ibus_context_process_key_event_async_finish: OK");
 
191
    call_next_async_function (context);
 
192
}
 
193
 
 
194
static void
 
195
start_process_key_event_async (IBusInputContext *context)
 
196
{
 
197
    ibus_input_context_process_key_event_async (context,
 
198
                                                0, 0, 0,
 
199
                                                -1, /* timeout */
 
200
                                                NULL, /* cancellable */
 
201
                                                finish_process_key_event_async,
 
202
                                                NULL); /* user_data */
 
203
}
 
204
 
 
205
static gboolean
 
206
test_async_apis_finish (gpointer user_data)
 
207
{
 
208
    ibus_quit ();
 
209
    return FALSE;
 
210
}
 
211
 
 
212
static void
 
213
test_async_apis (void)
 
214
{
 
215
    g_debug ("start");
 
216
    IBusInputContext *context;
 
217
    context = ibus_bus_create_input_context (bus, "test");
 
218
    call_basic_ipcs (context);
 
219
 
 
220
    call_next_async_function (context);
 
221
    ibus_main ();
 
222
}
 
223
 
 
224
static void
 
225
call_next_async_function (IBusInputContext *context)
 
226
{
 
227
    static void (*async_functions[])(IBusInputContext *) = {
 
228
        start_is_enabled_async,
 
229
        start_get_engine_async,
 
230
        start_process_key_event_async,
 
231
    };
 
232
    static guint index = 0;
 
233
 
 
234
    // Use g_timeout_add to make sure test_async_apis finishes even if async_functions is empty.
 
235
    if (index >= G_N_ELEMENTS (async_functions))
 
236
        g_timeout_add (1, test_async_apis_finish, NULL);
 
237
    else
 
238
        (*async_functions[index++])(context);
 
239
}
 
240
 
 
241
gint
 
242
main (gint    argc,
 
243
      gchar **argv)
 
244
{
 
245
    gint result;
 
246
    g_type_init ();
 
247
    g_test_init (&argc, &argv, NULL);
 
248
    ibus_init ();
 
249
    bus = ibus_bus_new ();
 
250
 
 
251
    g_test_add_func ("/ibus/input_context", test_input_context);
 
252
    g_test_add_func ("/ibus/input_context_async_with_callback", test_async_apis);
 
253
 
 
254
    result = g_test_run ();
 
255
    g_object_unref (bus);
 
256
 
 
257
    return result;
 
258
}