2
* This file is part of Maliit Plugins
4
* Copyright (C) 2012 Openismus GmbH. All rights reserved.
6
* Contact: maliit-discuss@lists.maliit.org
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.
33
#include "wordengineprobe.h"
34
#include "common/inputmethodhostprobe.h"
36
#include "plugin/editor.h"
37
#include "models/key.h"
38
#include "models/text.h"
39
#include "logic/languagefeatures.h"
40
#include "logic/layouthelper.h"
41
#include "logic/layoutupdater.h"
42
#include "logic/style.h"
43
#include "view/setup.h"
48
using namespace MaliitKeyboard;
50
Q_DECLARE_METATYPE(WordCandidateList)
54
void appendToPreedit(Editor *editor,
55
const QString &appendix)
58
QCOMPARE(k.action(), Key::ActionInsert);
60
k.rLabel().setText(appendix);
61
editor->onKeyReleased(k);
65
void enforceCommit(Editor *editor)
68
space.setAction(Key::ActionSpace);
69
editor->onKeyReleased(space);
74
class TestWordCandidates
80
Q_SLOT void initTestCase()
82
qRegisterMetaType<WordCandidateList>("WordCandidateList");
85
Q_SLOT void testPrediction_data()
87
QTest::addColumn<bool>("enable_preedit");
88
QTest::addColumn<bool>("enable_auto_correct");
89
QTest::addColumn<QString>("preedit");
90
QTest::addColumn<int>("expected_word_candidate_updates");
91
QTest::addColumn<QString>("expected_word_candidate");
92
QTest::addColumn<QString>("expected_commit_history");
94
QTest::newRow("preedit enabled")
95
<< true << false << "preedit" << 7 << "tideerp" << "preedit ";
97
QTest::newRow("preedit + auto-correct enabled")
98
<< true << true << "preedit" << 7 << "tideerp" << "tideerp ";
100
QTest::newRow("punctuated preedit + auto-correct enabled")
101
<< true << true << "preedit." << 7 << "tideerp" << "tideerp. ";
103
QTest::newRow("preedit + auto-correct disabled")
104
<< false << false << "commit" << 0 << "" << "commit ";
106
QTest::newRow("preedit disabled, auto-correct enabled")
107
<< false << true << "commit" << 0 << "" << "commit ";
110
Q_SLOT void testPrediction()
112
QFETCH(bool, enable_preedit);
113
QFETCH(bool, enable_auto_correct);
114
QFETCH(QString, preedit);
115
QFETCH(int, expected_word_candidate_updates);
116
QFETCH(QString, expected_word_candidate);
117
QFETCH(QString, expected_commit_history);
119
Editor editor(EditorOptions(), new Model::Text, new Logic::WordEngineProbe, new Logic::LanguageFeatures);
120
QSignalSpy spy(&editor, SIGNAL(wordCandidatesChanged(WordCandidateList)));
121
QSignalSpy preedit_enabled_spy(&editor, SIGNAL(preeditEnabledChanged(bool)));
122
QSignalSpy auto_correct_enabled_spy(&editor, SIGNAL(autoCorrectEnabledChanged(bool)));
124
InputMethodHostProbe host;
125
editor.setHost(&host);
127
QVERIFY(not editor.isPreeditEnabled());
128
editor.wordEngine()->setEnabled(enable_preedit);
129
QCOMPARE(preedit_enabled_spy.count(), enable_preedit ? 1 : 0);
130
QCOMPARE(editor.isPreeditEnabled(), enable_preedit);
132
QVERIFY(not editor.isAutoCorrectEnabled());
133
editor.setAutoCorrectEnabled(enable_auto_correct);
134
QCOMPARE(auto_correct_enabled_spy.count(), enable_auto_correct ? 1 : 0);
135
QCOMPARE(editor.isAutoCorrectEnabled(), enable_auto_correct);
137
Q_FOREACH(const QChar &c, preedit) {
138
appendToPreedit(&editor, QString(c));
141
QCOMPARE(editor.text()->primaryCandidate(), expected_word_candidate);
142
QCOMPARE(spy.count(), expected_word_candidate_updates);
144
if (spy.count() > 0) {
145
WordCandidateList expected_word_candidate_list;
146
expected_word_candidate_list.append(WordCandidate(WordCandidate::SourcePrediction, expected_word_candidate));
147
QCOMPARE(spy.last().first().value<WordCandidateList>(), expected_word_candidate_list);
150
enforceCommit(&editor);
151
QCOMPARE(editor.text()->preedit(), QString());
152
QCOMPARE(host.commitStringHistory(), expected_commit_history);
154
if (spy.count() > 0) {
155
QCOMPARE(spy.takeLast().first().value<WordCandidateList>(), WordCandidateList());
160
Q_SLOT void testWordCandidatesChanged()
162
Editor editor(EditorOptions(), new Model::Text, new Logic::WordEngineProbe, new Logic::LanguageFeatures);
163
QSignalSpy spy(&editor, SIGNAL(wordCandidatesChanged(WordCandidateList)));
165
InputMethodHostProbe host;
166
editor.setHost(&host);
168
// no preedit => auto-commit:
169
appendToPreedit(&editor, "a");
170
QCOMPARE(spy.count(), 0);
171
QCOMPARE(host.commitStringHistory(), QString("a"));
173
// preedit changes => new word candidates:
174
editor.wordEngine()->setEnabled(true);
175
appendToPreedit(&editor, "b");
176
QCOMPARE(spy.count(), 1);
178
// check disabled-before-commit corner case:
179
editor.wordEngine()->setEnabled(false);
180
QCOMPARE(spy.count(), 2);
182
// word engine already disabled
183
// => clearCandidates() skips signal emission:
184
enforceCommit(&editor);
185
QCOMPARE(spy.count(), 2);
186
QCOMPARE(host.commitStringHistory(), QString("ab "));
188
// preedit changes => new word candidates:
189
editor.wordEngine()->setEnabled(true);
190
appendToPreedit(&editor, "c");
191
QCOMPARE(spy.count(), 3);
193
// preedit gets committed
194
// => candidates get cleared & candidatesChanged() emitted:
195
enforceCommit(&editor);
196
QCOMPARE(spy.count(), 4);
197
QCOMPARE(host.commitStringHistory(), QString("ab c "));
200
Q_SLOT void testWordRibbonVisible()
202
Editor editor(EditorOptions(), new Model::Text, new Logic::WordEngineProbe, new Logic::LanguageFeatures);
203
InputMethodHostProbe host;
204
editor.setHost(&host);
206
Logic::LayoutUpdater updater;
207
Logic::LayoutHelper layout;
208
updater.setLayout(&layout);
210
SharedStyle style(new Style);
211
style->setProfile("nokia-n9");
212
updater.setStyle(style);
214
Setup::connectLayoutUpdaterToTextEditor(&updater, &editor);
215
QSignalSpy spy(&updater, SIGNAL(wordRibbonVisibleChanged(bool)));
216
QCOMPARE(editor.wordEngine()->isEnabled(), false);
217
QCOMPARE(editor.isPreeditEnabled(), false);
218
QCOMPARE(updater.isWordRibbonVisible(), false);
220
appendToPreedit(&editor, "a");
221
QCOMPARE(host.commitStringHistory(), QString("a"));
222
QCOMPARE(layout.wordRibbon()->candidates().isEmpty(), true);
224
editor.wordEngine()->setEnabled(true);
225
QCOMPARE(spy.count(), 1);
226
QCOMPARE(editor.wordEngine()->isEnabled(), true);
227
QCOMPARE(editor.isPreeditEnabled(), true);
228
QCOMPARE(updater.isWordRibbonVisible(), true);
230
appendToPreedit(&editor, "bcd");
231
const WordCandidate &candidate(layout.wordRibbon()->candidates().first());
232
QCOMPARE(candidate.label().text(), QString("dcb"));
234
editor.wordEngine()->setEnabled(false);
235
QCOMPARE(spy.count(), 2);
236
QCOMPARE(editor.wordEngine()->isEnabled(), false);
237
QCOMPARE(editor.isPreeditEnabled(), false);
238
QCOMPARE(updater.isWordRibbonVisible(), false);
239
QCOMPARE(layout.wordRibbon()->candidates().isEmpty(), true);
243
QTEST_MAIN(TestWordCandidates)