~michael-sheldon/ubuntu-keyboard/fix-oxide-dismiss-test

« back to all changes in this revision

Viewing changes to tests/preedit-string/main.cpp

  • Committer: Thomas Moenicke
  • Date: 2013-07-19 12:05:07 UTC
  • Revision ID: thomas.moenicke@canonical.com-20130719120507-lzw5oq50xm567x0j
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of Maliit Plugins
 
3
 *
 
4
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
 
5
 *
 
6
 * Contact: Mohammad Anwari <Mohammad.Anwari@nokia.com>
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without modification,
 
9
 * are permitted provided that the following conditions are met:
 
10
 *
 
11
 * Redistributions of source code must retain the above copyright notice, this list
 
12
 * of conditions and the following disclaimer.
 
13
 * Redistributions in binary form must reproduce the above copyright notice, this list
 
14
 * of conditions and the following disclaimer in the documentation and/or other materials
 
15
 * provided with the distribution.
 
16
 * Neither the name of Nokia Corporation nor the names of its contributors may be
 
17
 * used to endorse or promote products derived from this software without specific
 
18
 * prior written permission.
 
19
 *
 
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 
21
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
22
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 
23
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
24
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
25
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
27
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
28
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 *
 
30
 */
 
31
 
 
32
#include "utils.h"
 
33
 
 
34
#include "models/area.h"
 
35
#include "models/key.h"
 
36
#include "models/keyarea.h"
 
37
#include "models/text.h"
 
38
#include "models/layout.h"
 
39
 
 
40
#include "logic/languagefeatures.h"
 
41
#include "logic/layouthelper.h"
 
42
#include "logic/layoutupdater.h"
 
43
#include "logic/eventhandler.h"
 
44
#include "logic/style.h"
 
45
 
 
46
#include "view/setup.h"
 
47
#include "plugin/editor.h"
 
48
#include "plugin/updatenotifier.h"
 
49
#include "inputmethodhostprobe.h"
 
50
#include "wordengineprobe.h"
 
51
 
 
52
#include <maliit/plugins/testsurfacefactory.h>
 
53
#include <maliit/plugins/updateevent.h>
 
54
 
 
55
#include <QtTest>
 
56
#include <QtCore>
 
57
#include <QtGui>
 
58
 
 
59
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
 
60
#include <QtWidgets>
 
61
#endif
 
62
 
 
63
using namespace MaliitKeyboard;
 
64
Q_DECLARE_METATYPE(Logic::LayoutHelper::Orientation)
 
65
Q_DECLARE_METATYPE(QList<QMouseEvent*>)
 
66
 
 
67
namespace {
 
68
const int g_size = 48;
 
69
const int g_divider = 3;
 
70
 
 
71
QPoint keyOriginLookup(const QString &name)
 
72
{
 
73
    static const int distance = g_size / g_divider;
 
74
 
 
75
    if (name == "a") {
 
76
        return QPoint(0, 0);
 
77
    } else if (name == "b") {
 
78
        return QPoint(distance, 0);
 
79
    } else if (name == "c") {
 
80
        return QPoint(0, distance);
 
81
    } else if (name == "d") {
 
82
        return QPoint(distance, distance);
 
83
    } else if (name == "space") {
 
84
        return QPoint(distance * 2, 0);
 
85
    } else if (name == "return") {
 
86
        return QPoint(distance * 2, distance);
 
87
    }
 
88
 
 
89
    return QPoint();
 
90
}
 
91
 
 
92
Key createKey(Key::Action action,
 
93
              const QString &text)
 
94
{
 
95
    static const QSize size(g_size / g_divider, g_size / g_divider);
 
96
 
 
97
    Key result;
 
98
    result.setAction(action);
 
99
    result.setOrigin(keyOriginLookup(text));
 
100
    result.rArea().setSize(size);
 
101
    result.rLabel().setText(text);
 
102
 
 
103
    return result;
 
104
}
 
105
 
 
106
// Populate KeyArea with six keys, a, b, c, d, space and return. Notice how the KeyArea
 
107
// covers the whole widget. Key width and height equals g_size / g_divider.
 
108
// .-----------.
 
109
// | a | b |<s>|
 
110
// |---|---|---|
 
111
// | c | d |<r>|
 
112
// `-----------'
 
113
KeyArea createAbcdArea()
 
114
{
 
115
    KeyArea key_area;
 
116
    Area area;
 
117
    area.setSize(QSize(g_size, g_size));
 
118
    key_area.setArea(area);
 
119
 
 
120
    key_area.rKeys().append(createKey(Key::ActionInsert, "a"));
 
121
    key_area.rKeys().append(createKey(Key::ActionInsert, "b"));
 
122
    key_area.rKeys().append(createKey(Key::ActionInsert, "c"));
 
123
    key_area.rKeys().append(createKey(Key::ActionInsert, "d"));
 
124
    key_area.rKeys().append(createKey(Key::ActionSpace,  "space"));
 
125
    key_area.rKeys().append(createKey(Key::ActionReturn, "return"));
 
126
 
 
127
    return key_area;
 
128
}
 
129
 
 
130
int lookup(const QString &name)
 
131
{
 
132
    if (name == "a") {
 
133
        return 0;
 
134
    } else if (name == "b") {
 
135
        return 1;
 
136
    } else if (name == "c") {
 
137
        return 2;
 
138
    } else if (name == "d") {
 
139
        return 3;
 
140
    } else if (name == "space") {
 
141
        return 4;
 
142
    } else if (name == "return") {
 
143
        return 5;
 
144
    }
 
145
 
 
146
    return -1;
 
147
}
 
148
 
 
149
bool operator==(const Maliit::PreeditTextFormat &a, const Maliit::PreeditTextFormat &b) {
 
150
    return ((a.start == b.start) and (a.length == b.length) and (a.preeditFace == b.preeditFace));
 
151
}
 
152
 
 
153
MImUpdateEvent *createUpdateEvent(const QString &surrounding_text,
 
154
                                  int cursor_position)
 
155
{
 
156
    const char *const cur_pos("cursorPosition");
 
157
    QStringList properties_changed(cur_pos);
 
158
    QMap<QString, QVariant> update;
 
159
 
 
160
    update.insert(cur_pos, cursor_position);
 
161
    update.insert("surroundingText", surrounding_text);
 
162
 
 
163
    return new MImUpdateEvent(update, properties_changed);
 
164
}
 
165
 
 
166
} // unnamed namespace
 
167
 
 
168
struct BasicSetupTest
 
169
{
 
170
    BasicSetupTest(bool enable_word_engine = true)
 
171
        : editor(EditorOptions(), new Model::Text, new Logic::WordEngineProbe, new Logic::LanguageFeatures, 0)
 
172
        , host()
 
173
        , notifier()
 
174
    {
 
175
        editor.setHost(&host);
 
176
        editor.wordEngine()->setEnabled(enable_word_engine);
 
177
 
 
178
        QObject::connect(&notifier, SIGNAL(cursorPositionChanged(int, QString)),
 
179
                         &editor,   SLOT(onCursorPositionChanged(int, QString)));
 
180
 
 
181
    }
 
182
 
 
183
    Editor editor;
 
184
    InputMethodHostProbe host;
 
185
    UpdateNotifier notifier;
 
186
};
 
187
 
 
188
class SetupTest
 
189
    : public BasicSetupTest
 
190
{
 
191
public:
 
192
    Model::Layout layout;
 
193
    Logic::LayoutUpdater layout_updater;
 
194
    Logic::LayoutHelper layout_helper;
 
195
    Logic::EventHandler event_handler;
 
196
    SharedStyle style;
 
197
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface;
 
198
    QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface;
 
199
    KeyArea key_area;
 
200
 
 
201
    SetupTest(Logic::LayoutHelper::Orientation orientation = Logic::LayoutHelper::Landscape,
 
202
              bool enable_word_engine = true)
 
203
        : BasicSetupTest(enable_word_engine)
 
204
        , layout()
 
205
        , layout_updater()
 
206
        , layout_helper()
 
207
        , event_handler(&layout, &layout_updater)
 
208
        , style(new Style(qApp))
 
209
        , surface(Maliit::Plugins::createTestGraphicsViewSurface())
 
210
        , extended_surface(Maliit::Plugins::createTestGraphicsViewSurface(surface))
 
211
        , key_area(createAbcdArea())
 
212
    {
 
213
        // geometry stuff is usually done by maliit-server, so we need
 
214
        // to do it manually here:
 
215
        surface->view()->setSceneRect(0, 0, g_size, g_size);
 
216
        surface->scene()->setSceneRect(0, 0, g_size, g_size);
 
217
        layout_helper.setOrientation(orientation);
 
218
 
 
219
        Setup::connectEventHandlerToTextEditor(&event_handler, &editor);
 
220
 
 
221
        layout_helper.setExtendedPanel(key_area);
 
222
        layout_helper.setActivePanel(Logic::LayoutHelper::ExtendedPanel);
 
223
 
 
224
        layout_updater.setLayout(&layout_helper);
 
225
        layout_updater.setStyle(style);
 
226
 
 
227
        layout.setKeyArea(key_area);
 
228
    }
 
229
};
 
230
 
 
231
class TestPreeditString
 
232
    : public QObject
 
233
{
 
234
    Q_OBJECT
 
235
 
 
236
private:
 
237
    typedef QList<Maliit::PreeditTextFormat> FormatList;
 
238
 
 
239
    Q_SLOT void initTestCase()
 
240
    {
 
241
        qRegisterMetaType<QList<QMouseEvent*> >();
 
242
        qRegisterMetaType<Logic::LayoutHelper::Orientation>();
 
243
        qRegisterMetaType<FormatList>();
 
244
    }
 
245
 
 
246
    Q_SLOT void test_data()
 
247
    {
 
248
        QTest::addColumn<Logic::LayoutHelper::Orientation>("orientation");
 
249
        QTest::addColumn<QStringList>("keys");
 
250
        QTest::addColumn<QString>("expected_last_preedit_string");
 
251
        QTest::addColumn<QString>("expected_commit_string");
 
252
        QTest::addColumn<FormatList>("expected_preedit_format");
 
253
        QTest::addColumn<bool>("word_engine_enabled");
 
254
        QTest::addColumn<int>("expected_cursor_position");
 
255
 
 
256
        for (int orientation = 0; orientation < 1; ++orientation) {
 
257
            // FIXME: here should be 2          ^
 
258
            // FIXME: tests fail for portrait layouts
 
259
            const Logic::LayoutHelper::Orientation layout_orientation(orientation == 0
 
260
                                                                ? Logic::LayoutHelper::Landscape
 
261
                                                                : Logic::LayoutHelper::Portrait);
 
262
            QTest::newRow("No mouse events: expect empty commit string, should be no preedit face")
 
263
                << layout_orientation
 
264
                << (QStringList())
 
265
                << "" << "" << FormatList() << true << 0;
 
266
 
 
267
            QTest::newRow("Only return pressed: expect empty commit string, should be no preedit face")
 
268
                << layout_orientation
 
269
                << (QStringList() << "return")
 
270
                << "" << "" << FormatList() << true << 0;
 
271
 
 
272
            QTest::newRow("Release button over key 'a': expect commit string 'a', preedit face should be active.")
 
273
                << layout_orientation
 
274
                << (QStringList() << "a" << "return")
 
275
                << "a" << "a" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditActive)) << true << 0;
 
276
 
 
277
            QTest::newRow("Release button over key 'a', but no commit: expect empty commit string.")
 
278
                << layout_orientation
 
279
                << (QStringList() << "a")
 
280
                << "a" << "" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditActive)) << true << 1;
 
281
 
 
282
            QTest::newRow("Release button over keys 'c, b, d, a': expect commit string 'cbda', preedit face should be no candidates")
 
283
                << layout_orientation
 
284
                << (QStringList() << "c" << "b" << "d" << "a" << "space")
 
285
                << "cbda" << "cbda " << (FormatList() << Maliit::PreeditTextFormat(0, 4, Maliit::PreeditNoCandidates)) << true << 0;
 
286
 
 
287
            QTest::newRow("Typing two words: expect commit string 'ab cd', with last preedit being 'cd', preedit face should be no candidates.")
 
288
                << layout_orientation
 
289
                << (QStringList() << "a" << "b" << "space" << "c" << "d" << "return")
 
290
                << "cd" << "ab cd" << (FormatList() << Maliit::PreeditTextFormat(0, 2, Maliit::PreeditNoCandidates)) << true << 0;
 
291
 
 
292
            QTest::newRow("Typing one word 'abd': expect commit string 'abd', with last preedit being 'abd', preedit face should be default")
 
293
                << layout_orientation
 
294
                << (QStringList() << "a" << "b" << "d" << "return")
 
295
                << "abd" << "abd" << (FormatList() << Maliit::PreeditTextFormat(0, 3, Maliit::PreeditDefault)) << true << 0;
 
296
 
 
297
            // TODO: we probably should not sent any preedit formats when word engine is turned off.
 
298
            QTest::newRow("Typing one word 'abd' with word engine turned off: expect commit string 'abd', with preedit being last char, should be no preedit face")
 
299
                << layout_orientation
 
300
                << (QStringList() << "a" << "b" << "d")
 
301
                << "d" << "abd" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault)) << false << 0;
 
302
 
 
303
            QTest::newRow("Typing one word 'ab' with word engine turned off: expect commit string 'ab', with preedit being last char, should be no preedit face")
 
304
                << layout_orientation
 
305
                << (QStringList() << "a" << "b")
 
306
                << "b" << "ab" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault)) << false << 0;
 
307
 
 
308
            QTest::newRow("Typing one word 'bd' with word engine turned off: expect commit string 'bd', with preedit being last char, face should be for one char with default face")
 
309
                << layout_orientation
 
310
                << (QStringList() << "b" << "d")
 
311
                << "d" << "bd" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault)) << false << 0;
 
312
 
 
313
        }
 
314
    }
 
315
 
 
316
    Q_SLOT void test()
 
317
    {
 
318
        // FIXME: mikhas: We should have tests for the preedit &
 
319
        // preedit correctness stuff, and how it blends with word
 
320
        // prediction. I guess you will need to add
 
321
        // WordEngine::setSpellChecker() API so that you can inject a
 
322
        // fake spellchecker, for the tests. Otherwise, the test would
 
323
        // have to be skipped when there's no hunspell/presage, which
 
324
        // I wouldn't like to have.
 
325
 
 
326
        QFETCH(Logic::LayoutHelper::Orientation, orientation);
 
327
        QFETCH(QStringList, keys);
 
328
        QFETCH(QString, expected_last_preedit_string);
 
329
        QFETCH(QString, expected_commit_string);
 
330
        QFETCH(QList<Maliit::PreeditTextFormat>, expected_preedit_format);
 
331
        QFETCH(bool, word_engine_enabled);
 
332
        QFETCH(int, expected_cursor_position);
 
333
 
 
334
        SetupTest test_setup(orientation, word_engine_enabled);
 
335
 
 
336
        Q_FOREACH (const QString &k, keys) {
 
337
            test_setup.event_handler.onPressed(lookup(k));
 
338
            test_setup.event_handler.onReleased(lookup(k));
 
339
        }
 
340
 
 
341
        TestUtils::waitForSignal(&test_setup.event_handler, SIGNAL(keyReleased(Key)));
 
342
        QCOMPARE(test_setup.host.lastPreeditString(), expected_last_preedit_string);
 
343
        QCOMPARE(test_setup.host.commitStringHistory(), expected_commit_string);
 
344
        QCOMPARE(test_setup.host.lastPreeditTextFormatList(), expected_preedit_format);
 
345
        QCOMPARE(test_setup.editor.text()->cursorPosition(), expected_cursor_position);
 
346
    }
 
347
 
 
348
    Q_SLOT void testPreeditActivation_data()
 
349
    {
 
350
        QTest::addColumn<QString>("surrounding_text");
 
351
        QTest::addColumn<int>("cursor_position");
 
352
        QTest::addColumn<QString>("expected_preedit");
 
353
        QTest::addColumn<int>("expected_replace_start");
 
354
        QTest::addColumn<int>("expected_replace_length");
 
355
        QTest::addColumn<int>("expected_cursor_position");
 
356
        QTest::addColumn<bool>("expected_preedit_string_sent");
 
357
 
 
358
        QTest::newRow("'aaa bbb', select first 'a'")
 
359
            << "aaa bbbb" // surrounding text
 
360
            << 0 // chosen cursor position
 
361
            << "aaa" // expected preedit
 
362
            << 0 // expected replace start (relative to cursor position in a preedit)
 
363
            << 3 // expected replace length
 
364
            << 0 // expected cursor position (relative to the beginning of preedit)
 
365
            << true; // whether preedit is sent
 
366
 
 
367
        QTest::newRow("'aaa bbb', select second 'a'")
 
368
            << "aaa bbbb" // surrounding text
 
369
            << 1 // chosen cursor position
 
370
            << "aaa" // expected preedit
 
371
            << -1 // expected replace start (relative to cursor position in a preedit)
 
372
            << 3 // expected replace length
 
373
            << 1 // expected cursor position (relative to the beginning of preedit)
 
374
            << true; // whether preedit is sent
 
375
 
 
376
        QTest::newRow("'aaa bbb', select third 'a'")
 
377
            << "aaa bbbb" // surrounding text
 
378
            << 2 // chosen cursor position
 
379
            << "aaa" // expected preedit
 
380
            << -2 // expected replace start (relative to cursor position in a preedit)
 
381
            << 3 // expected replace length
 
382
            << 2 // expected cursor position (relative to the beginning of preedit)
 
383
            << true; // whether preedit is sent
 
384
 
 
385
        QTest::newRow("'aaa bbb', select space between words")
 
386
            << "aaa bbbb" // surrounding text
 
387
            << 3 // chosen cursor position
 
388
            << "aaa" // expected preedit
 
389
            << -3 // expected replace start (relative to cursor position in a preedit)
 
390
            << 3 // expected replace length
 
391
            << 3 // expected cursor position (relative to the beginning of preedit)
 
392
            << true; // whether preedit is sent
 
393
 
 
394
        QTest::newRow("'aaa bbb', select first 'b'")
 
395
            << "aaa bbbb" // surrounding text
 
396
            << 4 // chosen cursor position
 
397
            << "bbbb" // expected preedit
 
398
            << 0 // expected replace start (relative to cursor position in a preedit)
 
399
            << 4 // expected replace length
 
400
            << 0 // expected cursor position (relative to the beginning of preedit)
 
401
            << true; // whether preedit is sent
 
402
 
 
403
        QTest::newRow("'aaa bbb', select after last 'b'")
 
404
            << "aaa bbbb" // surrounding text
 
405
            << 8 // chosen cursor position
 
406
            << "bbbb" // expected preedit
 
407
            << -4 // expected replace start (relative to cursor position in a preedit)
 
408
            << 4 // expected replace length
 
409
            << 4 // expected cursor position (relative to the beginning of preedit)
 
410
            << true; // whether preedit is sent
 
411
 
 
412
        QTest::newRow("' aaa', select leading space")
 
413
            << " aaa" // surrounding text
 
414
            << 0 // chosen cursor position
 
415
            << "" // expected preedit
 
416
            << 0 // expected replace start (relative to cursor position in a preedit)
 
417
            << 0 // expected replace length
 
418
            << 0 // expected cursor position (relative to the beginning of preedit)
 
419
            << false; // whether preedit is sent
 
420
 
 
421
        QTest::newRow("'a  b', select space before 'b'")
 
422
            << "a  b" // surrounding text
 
423
            << 2 // chosen cursor position
 
424
            << "" // expected preedit
 
425
            << 0 // expected replace start (relative to cursor position in a preedit)
 
426
            << 0 // expected replace length
 
427
            << 0 // expected cursor position (relative to the beginning of preedit)
 
428
            << false; // whether preedit is sent
 
429
 
 
430
        QTest::newRow("'a  ', select last space")
 
431
            << "a  " // surrounding text
 
432
            << 2 // chosen cursor position
 
433
            << "" // expected preedit
 
434
            << 0 // expected replace start (relative to cursor position in a preedit)
 
435
            << 0 // expected replace length
 
436
            << 0 // expected cursor position (relative to the beginning of preedit)
 
437
            << false; // whether preedit is sent
 
438
 
 
439
        QTest::newRow("'a ', select after last space")
 
440
            << "a " // surrounding text
 
441
            << 2 // chosen cursor position
 
442
            << "" // expected preedit
 
443
            << 0 // expected replace start (relative to cursor position in a preedit)
 
444
            << 0 // expected replace length
 
445
            << 0 // expected cursor position (relative to the beginning of preedit)
 
446
            << false; // whether preedit is sent
 
447
 
 
448
        QTest::newRow("'aaa', select far after last char")
 
449
            << "aaa" // surrounding text
 
450
            << 200 // chosen cursor position
 
451
            << "aaa" // expected preedit
 
452
            << -3 // expected replace start (relative to cursor position in a preedit)
 
453
            << 3 // expected replace length
 
454
            << 3 // expected cursor position (relative to the beginning of preedit)
 
455
            << true; // whether preedit is sent
 
456
 
 
457
        QTest::newRow("'aaa', select far before first char")
 
458
            << "aaa" // surrounding text
 
459
            << -200 // chosen cursor position
 
460
            << "aaa" // expected preedit
 
461
            << 0 // expected replace start (relative to cursor position in a preedit)
 
462
            << 3 // expected replace length
 
463
            << 0 // expected cursor position (relative to the beginning of preedit)
 
464
            << true; // whether preedit is sent
 
465
 
 
466
        QTest::newRow("' aaa ', select trailing space")
 
467
            << " aaa " // surrounding text
 
468
            << 4 // chosen cursor position
 
469
            << "aaa" // expected preedit
 
470
            << -3 // expected replace start (relative to cursor position in a preedit)
 
471
            << 3 // expected replace length
 
472
            << 3 // expected cursor position (relative to the beginning of preedit)
 
473
            << true; // whether preedit is sent
 
474
    }
 
475
 
 
476
    Q_SLOT void testPreeditActivation()
 
477
    {
 
478
        QFETCH(QString, surrounding_text);
 
479
        QFETCH(int, cursor_position);
 
480
        QFETCH(QString, expected_preedit);
 
481
        QFETCH(int, expected_replace_start);
 
482
        QFETCH(int, expected_replace_length);
 
483
        QFETCH(int, expected_cursor_position);
 
484
        QFETCH(bool, expected_preedit_string_sent);
 
485
 
 
486
        BasicSetupTest test_setup;
 
487
        QScopedPointer<MImUpdateEvent> update_event(createUpdateEvent(surrounding_text,
 
488
                                                                      cursor_position));
 
489
 
 
490
        test_setup.notifier.notify(update_event.data());
 
491
 
 
492
        QCOMPARE(test_setup.host.preeditStringSent(), expected_preedit_string_sent);
 
493
        if (expected_preedit_string_sent) {
 
494
            QCOMPARE(test_setup.host.lastPreeditString(), expected_preedit);
 
495
            QCOMPARE(test_setup.host.lastReplaceStart(), expected_replace_start);
 
496
            QCOMPARE(test_setup.host.lastReplaceLength(), expected_replace_length);
 
497
            QCOMPARE(test_setup.host.lastCursorPos(), expected_cursor_position);
 
498
        }
 
499
        QCOMPARE(test_setup.editor.text()->preedit(), expected_preedit);
 
500
        QCOMPARE(test_setup.editor.text()->cursorPosition(), expected_cursor_position);
 
501
    }
 
502
 
 
503
    Q_SLOT void testPreeditActivationTyping_data()
 
504
    {
 
505
        QTest::addColumn<QString>("surrounding_text");
 
506
        QTest::addColumn<int>("cursor_position");
 
507
        QTest::addColumn<QStringList >("keys");
 
508
        QTest::addColumn<QString>("expected_preedit_string");
 
509
        QTest::addColumn<int>("expected_cursor_position");
 
510
 
 
511
        QTest::newRow("'aaa bbb', select first 'a', then type 'd'")
 
512
            << "aaa bbbb" // surrounding text
 
513
            << 0 // chosen cursor position
 
514
            << (QStringList() << "d")
 
515
            << "daaa" // expected preedit
 
516
            << 1; // expected cursor position (relative to the beginning of preedit)
 
517
 
 
518
        QTest::newRow("'aaa bbb', select second 'a', then type 'd'")
 
519
            << "aaa bbbb" // surrounding text
 
520
            << 1 // chosen cursor position
 
521
            << (QStringList() << "d")
 
522
            << "adaa" // expected preedit
 
523
            << 2; // expected cursor position (relative to the beginning of preedit)
 
524
 
 
525
        QTest::newRow("'aaa bbb', select third 'a', then type 'd'")
 
526
            << "aaa bbbb" // surrounding text
 
527
            << 2 // chosen cursor position
 
528
            << (QStringList() << "d")
 
529
            << "aada" // expected preedit
 
530
            << 3; // expected cursor position (relative to the beginning of preedit)
 
531
 
 
532
        QTest::newRow("'aaa bbb', select space between words, then type 'd'")
 
533
            << "aaa bbbb" // surrounding text
 
534
            << 3 // chosen cursor position
 
535
            << (QStringList() << "d")
 
536
            << "aaad" // expected preedit
 
537
            << 4; // expected cursor position (relative to the beginning of preedit)
 
538
 
 
539
        QTest::newRow("'aaa bbb', select first 'b', then type 'd'")
 
540
            << "aaa bbbb" // surrounding text
 
541
            << 4 // chosen cursor position
 
542
            << (QStringList() << "d")
 
543
            << "dbbbb" // expected preedit
 
544
            << 1; // expected cursor position (relative to the beginning of preedit)
 
545
 
 
546
        QTest::newRow("'aaa bbb', select after last 'b', then type 'd'")
 
547
            << "aaa bbbb" // surrounding text
 
548
            << 8 // chosen cursor position
 
549
            << (QStringList() << "d")
 
550
            << "bbbbd" // expected preedit
 
551
            << 5; // expected cursor position (relative to the beginning of preedit)
 
552
 
 
553
        QTest::newRow("' aaa', select leading space, then type 'd'")
 
554
            << " aaa" // surrounding text
 
555
            << 0 // chosen cursor position
 
556
            << (QStringList() << "d")
 
557
            << "d" // expected preedit
 
558
            << 1; // expected cursor position (relative to the beginning of preedit)
 
559
 
 
560
        QTest::newRow("'a  b', select space before 'b', then type 'd'")
 
561
            << "a  b" // surrounding text
 
562
            << 2 // chosen cursor position
 
563
            << (QStringList() << "d")
 
564
            << "d" // expected preedit
 
565
            << 1; // expected cursor position (relative to the beginning of preedit)
 
566
 
 
567
        QTest::newRow("'a  ', select last space, then type 'd'")
 
568
            << "a  " // surrounding text
 
569
            << 2 // chosen cursor position
 
570
            << (QStringList() << "d")
 
571
            << "d" // expected preedit
 
572
            << 1; // expected cursor position (relative to the beginning of preedit)
 
573
 
 
574
        QTest::newRow("'a ', select after last space, then type 'd'")
 
575
            << "a " // surrounding text
 
576
            << 2 // chosen cursor position
 
577
            << (QStringList() << "d")
 
578
            << "d" // expected preedit
 
579
            << 1; // expected cursor position (relative to the beginning of preedit)
 
580
 
 
581
        QTest::newRow("'aaa', select far after last char, then type 'd'")
 
582
            << "aaa" // surrounding text
 
583
            << 200 // chosen cursor position
 
584
            << (QStringList() << "d")
 
585
            << "aaad" // expected preedit
 
586
            << 4; // expected cursor position (relative to the beginning of preedit)
 
587
 
 
588
        QTest::newRow("'aaa', select far before first char, then type 'd'")
 
589
            << "aaa" // surrounding text
 
590
            << -200 // chosen cursor position
 
591
            << (QStringList() << "d")
 
592
            << "daaa" // expected preedit
 
593
            << 1; // expected cursor position (relative to the beginning of preedit)
 
594
 
 
595
        QTest::newRow("' aaa ', select trailing space, then type 'd'")
 
596
            << " aaa " // surrounding text
 
597
            << 4 // chosen cursor position
 
598
            << (QStringList() << "d")
 
599
            << "aaad" // expected preedit
 
600
            << 4; // expected cursor position (relative to the beginning of preedit)
 
601
    }
 
602
 
 
603
    Q_SLOT void testPreeditActivationTyping()
 
604
    {
 
605
        QFETCH(QString, surrounding_text);
 
606
        QFETCH(int, cursor_position);
 
607
        QFETCH(QStringList, keys);
 
608
        QFETCH(QString, expected_preedit_string);
 
609
        QFETCH(int, expected_cursor_position);
 
610
 
 
611
        SetupTest test_setup;
 
612
        QScopedPointer<MImUpdateEvent> update_event(createUpdateEvent(surrounding_text,
 
613
                                                                      cursor_position));
 
614
 
 
615
        test_setup.notifier.notify(update_event.data());
 
616
 
 
617
        Q_FOREACH (const QString &k, keys) {
 
618
            test_setup.event_handler.onPressed(lookup(k));
 
619
            test_setup.event_handler.onReleased(lookup(k));
 
620
        }
 
621
 
 
622
        TestUtils::waitForSignal(&test_setup.event_handler, SIGNAL(keyReleased(Key)));
 
623
        QCOMPARE(test_setup.host.lastPreeditString(), expected_preedit_string);
 
624
        QCOMPARE(test_setup.editor.text()->cursorPosition(), expected_cursor_position);
 
625
    }
 
626
};
 
627
 
 
628
QTEST_MAIN(TestPreeditString)
 
629
#include "main.moc"