2
* This file is part of Maliit Plugins
4
* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
6
* Contact: Mohammad Anwari <Mohammad.Anwari@nokia.com>
8
* Redistribution and use in source and binary forms, with or without modification,
9
* are permitted provided that the following conditions are met:
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.
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.
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"
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"
46
#include "view/setup.h"
47
#include "plugin/editor.h"
48
#include "plugin/updatenotifier.h"
49
#include "inputmethodhostprobe.h"
50
#include "wordengineprobe.h"
52
#include <maliit/plugins/testsurfacefactory.h>
53
#include <maliit/plugins/updateevent.h>
59
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
63
using namespace MaliitKeyboard;
64
Q_DECLARE_METATYPE(Logic::LayoutHelper::Orientation)
65
Q_DECLARE_METATYPE(QList<QMouseEvent*>)
68
const int g_size = 48;
69
const int g_divider = 3;
71
QPoint keyOriginLookup(const QString &name)
73
static const int distance = g_size / g_divider;
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);
92
Key createKey(Key::Action action,
95
static const QSize size(g_size / g_divider, g_size / g_divider);
98
result.setAction(action);
99
result.setOrigin(keyOriginLookup(text));
100
result.rArea().setSize(size);
101
result.rLabel().setText(text);
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.
113
KeyArea createAbcdArea()
117
area.setSize(QSize(g_size, g_size));
118
key_area.setArea(area);
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"));
130
int lookup(const QString &name)
134
} else if (name == "b") {
136
} else if (name == "c") {
138
} else if (name == "d") {
140
} else if (name == "space") {
142
} else if (name == "return") {
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));
153
MImUpdateEvent *createUpdateEvent(const QString &surrounding_text,
156
const char *const cur_pos("cursorPosition");
157
QStringList properties_changed(cur_pos);
158
QMap<QString, QVariant> update;
160
update.insert(cur_pos, cursor_position);
161
update.insert("surroundingText", surrounding_text);
163
return new MImUpdateEvent(update, properties_changed);
166
} // unnamed namespace
168
struct BasicSetupTest
170
BasicSetupTest(bool enable_word_engine = true)
171
: editor(EditorOptions(), new Model::Text, new Logic::WordEngineProbe, new Logic::LanguageFeatures, 0)
175
editor.setHost(&host);
176
editor.wordEngine()->setEnabled(enable_word_engine);
178
QObject::connect(¬ifier, SIGNAL(cursorPositionChanged(int, QString)),
179
&editor, SLOT(onCursorPositionChanged(int, QString)));
184
InputMethodHostProbe host;
185
UpdateNotifier notifier;
189
: public BasicSetupTest
192
Model::Layout layout;
193
Logic::LayoutUpdater layout_updater;
194
Logic::LayoutHelper layout_helper;
195
Logic::EventHandler event_handler;
197
QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface;
198
QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface;
201
SetupTest(Logic::LayoutHelper::Orientation orientation = Logic::LayoutHelper::Landscape,
202
bool enable_word_engine = true)
203
: BasicSetupTest(enable_word_engine)
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())
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);
219
Setup::connectEventHandlerToTextEditor(&event_handler, &editor);
221
layout_helper.setExtendedPanel(key_area);
222
layout_helper.setActivePanel(Logic::LayoutHelper::ExtendedPanel);
224
layout_updater.setLayout(&layout_helper);
225
layout_updater.setStyle(style);
227
layout.setKeyArea(key_area);
231
class TestPreeditString
237
typedef QList<Maliit::PreeditTextFormat> FormatList;
239
Q_SLOT void initTestCase()
241
qRegisterMetaType<QList<QMouseEvent*> >();
242
qRegisterMetaType<Logic::LayoutHelper::Orientation>();
243
qRegisterMetaType<FormatList>();
246
Q_SLOT void test_data()
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");
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
265
<< "" << "" << FormatList() << true << 0;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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.
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);
334
SetupTest test_setup(orientation, word_engine_enabled);
336
Q_FOREACH (const QString &k, keys) {
337
test_setup.event_handler.onPressed(lookup(k));
338
test_setup.event_handler.onReleased(lookup(k));
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);
348
Q_SLOT void testPreeditActivation_data()
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");
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
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
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
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
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
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
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
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
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
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
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
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
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
476
Q_SLOT void testPreeditActivation()
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);
486
BasicSetupTest test_setup;
487
QScopedPointer<MImUpdateEvent> update_event(createUpdateEvent(surrounding_text,
490
test_setup.notifier.notify(update_event.data());
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);
499
QCOMPARE(test_setup.editor.text()->preedit(), expected_preedit);
500
QCOMPARE(test_setup.editor.text()->cursorPosition(), expected_cursor_position);
503
Q_SLOT void testPreeditActivationTyping_data()
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");
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
603
Q_SLOT void testPreeditActivationTyping()
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);
611
SetupTest test_setup;
612
QScopedPointer<MImUpdateEvent> update_event(createUpdateEvent(surrounding_text,
615
test_setup.notifier.notify(update_event.data());
617
Q_FOREACH (const QString &k, keys) {
618
test_setup.event_handler.onPressed(lookup(k));
619
test_setup.event_handler.onReleased(lookup(k));
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);
628
QTEST_MAIN(TestPreeditString)