File indexing completed on 2025-03-23 12:47:14
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams\gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "completion_test.h" 0009 #include "codecompletiontestmodels.h" 0010 // #include "codecompletiontestmodels.moc" 0011 0012 #include <ksycoca.h> 0013 0014 #include <ktexteditor/document.h> 0015 #include <ktexteditor/editor.h> 0016 0017 #include <katecompletionmodel.h> 0018 #include <katecompletiontree.h> 0019 #include <katecompletionwidget.h> 0020 #include <kateconfig.h> 0021 #include <kateglobal.h> 0022 #include <katerenderer.h> 0023 #include <kateview.h> 0024 0025 #include <QKeyEvent> 0026 #include <QtTestWidgets> 0027 0028 QTEST_MAIN(CompletionTest) 0029 0030 using namespace KTextEditor; 0031 0032 int countItems(KateCompletionModel *model) 0033 { 0034 const int topLevel = model->rowCount(QModelIndex()); 0035 if (!model->hasGroups()) { 0036 return topLevel; 0037 } 0038 int ret = 0; 0039 for (int i = 0; i < topLevel; ++i) { 0040 ret += model->rowCount(model->index(i, 0)); 0041 } 0042 return ret; 0043 } 0044 0045 static void verifyCompletionStarted(KTextEditor::ViewPrivate *view) 0046 { 0047 QTRY_VERIFY_WITH_TIMEOUT(view->completionWidget()->isCompletionActive(), 1000); 0048 } 0049 0050 static void verifyCompletionAborted(KTextEditor::ViewPrivate *view) 0051 { 0052 QTRY_VERIFY_WITH_TIMEOUT(!view->completionWidget()->isCompletionActive(), 1000); 0053 } 0054 0055 static void invokeCompletionBox(KTextEditor::ViewPrivate *view) 0056 { 0057 view->userInvokedCompletion(); 0058 verifyCompletionStarted(view); 0059 } 0060 0061 void CompletionTest::init() 0062 { 0063 KTextEditor::EditorPrivate::enableUnitTestMode(); 0064 Editor *editor = KTextEditor::Editor::instance(); 0065 QVERIFY(editor); 0066 0067 m_doc = editor->createDocument(this); 0068 QVERIFY(m_doc); 0069 m_doc->setText(QStringLiteral("aa bb cc\ndd")); 0070 0071 KTextEditor::View *v = m_doc->createView(nullptr); 0072 QApplication::setActiveWindow(v); 0073 m_view = static_cast<KTextEditor::ViewPrivate *>(v); 0074 Q_ASSERT(m_view); 0075 0076 // view needs to be shown as completion won't work if the cursor is off screen 0077 m_view->show(); 0078 } 0079 0080 void CompletionTest::cleanup() 0081 { 0082 delete m_view; 0083 delete m_doc; 0084 } 0085 0086 void CompletionTest::testFilterEmptyRange() 0087 { 0088 KateCompletionModel *model = m_view->completionWidget()->model(); 0089 0090 new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0091 m_view->setCursorPosition(Cursor(0, 0)); 0092 invokeCompletionBox(m_view); 0093 0094 QCOMPARE(countItems(model), 40); 0095 m_view->insertText(QStringLiteral("aa")); 0096 QTest::qWait(1000); // process events 0097 QCOMPARE(countItems(model), 14); 0098 } 0099 0100 void CompletionTest::testFilterWithRange() 0101 { 0102 KateCompletionModel *model = m_view->completionWidget()->model(); 0103 0104 CodeCompletionTestModel *testModel = new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0105 m_view->setCursorPosition(Cursor(0, 2)); 0106 invokeCompletionBox(m_view); 0107 0108 Range complRange = *m_view->completionWidget()->completionRange(testModel); 0109 QCOMPARE(complRange, Range(Cursor(0, 0), Cursor(0, 2))); 0110 QCOMPARE(countItems(model), 14); 0111 0112 m_view->insertText(QStringLiteral("a")); 0113 QTest::qWait(1000); // process events 0114 QCOMPARE(countItems(model), 1); 0115 } 0116 0117 void CompletionTest::testAbortCursorMovedOutOfRange() 0118 { 0119 KateCompletionModel *model = m_view->completionWidget()->model(); 0120 0121 new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0122 m_view->setCursorPosition(Cursor(0, 2)); 0123 invokeCompletionBox(m_view); 0124 0125 QCOMPARE(countItems(model), 14); 0126 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0127 0128 m_view->setCursorPosition(Cursor(0, 4)); 0129 QTest::qWait(1000); // process events 0130 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0131 } 0132 0133 void CompletionTest::testAbortInvalidText() 0134 { 0135 KateCompletionModel *model = m_view->completionWidget()->model(); 0136 0137 new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0138 m_view->setCursorPosition(Cursor(0, 2)); 0139 invokeCompletionBox(m_view); 0140 0141 QCOMPARE(countItems(model), 14); 0142 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0143 0144 m_view->insertText(QStringLiteral(".")); 0145 verifyCompletionAborted(m_view); 0146 } 0147 0148 void CompletionTest::testCustomRange1() 0149 { 0150 m_doc->setText(QStringLiteral("$aa bb cc\ndd")); 0151 KateCompletionModel *model = m_view->completionWidget()->model(); 0152 0153 CodeCompletionTestModel *testModel = new CustomRangeModel(m_view, QStringLiteral("$a")); 0154 m_view->setCursorPosition(Cursor(0, 3)); 0155 invokeCompletionBox(m_view); 0156 0157 Range complRange = *m_view->completionWidget()->completionRange(testModel); 0158 qDebug() << complRange; 0159 QCOMPARE(complRange, Range(Cursor(0, 0), Cursor(0, 3))); 0160 QCOMPARE(countItems(model), 14); 0161 0162 m_view->insertText(QStringLiteral("a")); 0163 QTest::qWait(1000); // process events 0164 QCOMPARE(countItems(model), 1); 0165 } 0166 0167 void CompletionTest::testCustomRange2() 0168 { 0169 m_doc->setText(QStringLiteral("$ bb cc\ndd")); 0170 KateCompletionModel *model = m_view->completionWidget()->model(); 0171 0172 CodeCompletionTestModel *testModel = new CustomRangeModel(m_view, QStringLiteral("$a")); 0173 m_view->setCursorPosition(Cursor(0, 1)); 0174 invokeCompletionBox(m_view); 0175 0176 Range complRange = *m_view->completionWidget()->completionRange(testModel); 0177 QCOMPARE(complRange, Range(Cursor(0, 0), Cursor(0, 1))); 0178 QCOMPARE(countItems(model), 40); 0179 0180 m_view->insertText(QStringLiteral("aa")); 0181 QTest::qWait(1000); // process events 0182 QCOMPARE(countItems(model), 14); 0183 } 0184 0185 void CompletionTest::testCustomRangeMultipleModels() 0186 { 0187 m_doc->setText(QStringLiteral("$a bb cc\ndd")); 0188 KateCompletionModel *model = m_view->completionWidget()->model(); 0189 0190 CodeCompletionTestModel *testModel1 = new CustomRangeModel(m_view, QStringLiteral("$a")); 0191 CodeCompletionTestModel *testModel2 = new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0192 m_view->setCursorPosition(Cursor(0, 1)); 0193 invokeCompletionBox(m_view); 0194 0195 QCOMPARE(Range(*m_view->completionWidget()->completionRange(testModel1)), Range(Cursor(0, 0), Cursor(0, 2))); 0196 QCOMPARE(Range(*m_view->completionWidget()->completionRange(testModel2)), Range(Cursor(0, 1), Cursor(0, 2))); 0197 QCOMPARE(model->currentCompletion(testModel1), QStringLiteral("$")); 0198 QCOMPARE(model->currentCompletion(testModel2), QString()); 0199 QCOMPARE(countItems(model), 80); 0200 0201 m_view->insertText(QStringLiteral("aa")); 0202 QTest::qWait(1000); // process events 0203 QCOMPARE(model->currentCompletion(testModel1), QStringLiteral("$aa")); 0204 QCOMPARE(model->currentCompletion(testModel2), QStringLiteral("aa")); 0205 QCOMPARE(countItems(model), 14 * 2); 0206 } 0207 0208 void CompletionTest::testAbortController() 0209 { 0210 KateCompletionModel *model = m_view->completionWidget()->model(); 0211 0212 new CustomRangeModel(m_view, QStringLiteral("$a")); 0213 m_view->setCursorPosition(Cursor(0, 0)); 0214 invokeCompletionBox(m_view); 0215 0216 QCOMPARE(countItems(model), 40); 0217 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0218 0219 m_view->insertText(QStringLiteral("$a")); 0220 QTest::qWait(1000); // process events 0221 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0222 0223 m_view->insertText(QStringLiteral(".")); 0224 verifyCompletionAborted(m_view); 0225 } 0226 0227 void CompletionTest::testAbortControllerMultipleModels() 0228 { 0229 KateCompletionModel *model = m_view->completionWidget()->model(); 0230 0231 CodeCompletionTestModel *testModel1 = new CodeCompletionTestModel(m_view, QStringLiteral("aa")); 0232 CodeCompletionTestModel *testModel2 = new CustomAbortModel(m_view, QStringLiteral("a-")); 0233 m_view->setCursorPosition(Cursor(0, 0)); 0234 invokeCompletionBox(m_view); 0235 0236 QCOMPARE(countItems(model), 80); 0237 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0238 0239 m_view->insertText(QStringLiteral("a")); 0240 QTest::qWait(1000); // process events 0241 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0242 QCOMPARE(countItems(model), 80); 0243 0244 m_view->insertText(QStringLiteral("-")); 0245 QTest::qWait(1000); // process events 0246 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0247 QVERIFY(!m_view->completionWidget()->completionRanges().contains(testModel1)); 0248 QVERIFY(m_view->completionWidget()->completionRanges().contains(testModel2)); 0249 0250 QCOMPARE(countItems(model), 40); 0251 0252 m_view->insertText(QLatin1String(" ")); 0253 QTest::qWait(1000); // process events 0254 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0255 } 0256 0257 void CompletionTest::testEmptyFilterString() 0258 { 0259 KateCompletionModel *model = m_view->completionWidget()->model(); 0260 0261 new EmptyFilterStringModel(m_view, QStringLiteral("aa")); 0262 m_view->setCursorPosition(Cursor(0, 0)); 0263 invokeCompletionBox(m_view); 0264 0265 QCOMPARE(countItems(model), 40); 0266 0267 m_view->insertText(QStringLiteral("a")); 0268 QTest::qWait(1000); // process events 0269 QCOMPARE(countItems(model), 40); 0270 0271 m_view->insertText(QStringLiteral("bam")); 0272 QTest::qWait(1000); // process events 0273 QCOMPARE(countItems(model), 40); 0274 } 0275 0276 void CompletionTest::testUpdateCompletionRange() 0277 { 0278 m_doc->setText(QStringLiteral("ab bb cc\ndd")); 0279 KateCompletionModel *model = m_view->completionWidget()->model(); 0280 0281 CodeCompletionTestModel *testModel = new UpdateCompletionRangeModel(m_view, QStringLiteral("ab ab")); 0282 m_view->setCursorPosition(Cursor(0, 3)); 0283 invokeCompletionBox(m_view); 0284 0285 QCOMPARE(countItems(model), 40); 0286 QCOMPARE(Range(*m_view->completionWidget()->completionRange(testModel)), Range(Cursor(0, 3), Cursor(0, 3))); 0287 0288 m_view->insertText(QStringLiteral("ab")); 0289 QTest::qWait(1000); // process events 0290 QCOMPARE(Range(*m_view->completionWidget()->completionRange(testModel)), Range(Cursor(0, 0), Cursor(0, 5))); 0291 QCOMPARE(countItems(model), 40); 0292 } 0293 0294 void CompletionTest::testCustomStartCompl() 0295 { 0296 KateCompletionModel *model = m_view->completionWidget()->model(); 0297 0298 m_view->completionWidget()->setAutomaticInvocationDelay(1); 0299 0300 new StartCompletionModel(m_view, QStringLiteral("aa")); 0301 0302 m_view->setCursorPosition(Cursor(0, 0)); 0303 m_view->insertText("%"); 0304 QTest::qWait(1000); 0305 0306 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0307 QCOMPARE(countItems(model), 40); 0308 } 0309 0310 void CompletionTest::testKateCompletionModel() 0311 { 0312 KateCompletionModel *model = m_view->completionWidget()->model(); 0313 CodeCompletionTestModel *testModel1 = new CodeCompletionTestModel(m_view, QStringLiteral("aa")); 0314 CodeCompletionTestModel *testModel2 = new CodeCompletionTestModel(m_view, QStringLiteral("bb")); 0315 0316 model->setCompletionModel(testModel1); 0317 QCOMPARE(countItems(model), 40); 0318 0319 model->addCompletionModel(testModel2); 0320 QCOMPARE(countItems(model), 80); 0321 0322 model->removeCompletionModel(testModel2); 0323 QCOMPARE(countItems(model), 40); 0324 } 0325 0326 void CompletionTest::testAbortImmideatelyAfterStart() 0327 { 0328 new ImmideatelyAbortCompletionModel(m_view); 0329 m_view->setCursorPosition(Cursor(0, 3)); 0330 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0331 Q_EMIT m_view->userInvokedCompletion(); 0332 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0333 } 0334 0335 void CompletionTest::testJumpToListBottomAfterCursorUpWhileAtTop() 0336 { 0337 new CodeCompletionTestModel(m_view, QStringLiteral("aa")); 0338 invokeCompletionBox(m_view); 0339 0340 m_view->completionWidget()->cursorUp(); 0341 m_view->completionWidget()->bottom(); 0342 // TODO - better way of finding the index? 0343 QCOMPARE(m_view->completionWidget()->treeView()->selectionModel()->currentIndex().row(), 39); 0344 } 0345 0346 void CompletionTest::testAbbreviationEngine() 0347 { 0348 int s = 0; 0349 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("fb"), s)); 0350 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("foob"), s)); 0351 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("fbar"), s)); 0352 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("fba"), s)); 0353 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("foba"), s)); 0354 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarBazBang"), QStringLiteral("fbbb"), s)); 0355 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("foo_bar_cat"), QStringLiteral("fbc"), s)); 0356 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("foo_bar_cat"), QStringLiteral("fb"), s)); 0357 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fba"), s)); 0358 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fbara"), s)); 0359 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fobaar"), s)); 0360 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fb"), s)); 0361 0362 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("QualifiedIdentifier"), QStringLiteral("qid"), s)); 0363 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("QualifiedIdentifier"), QStringLiteral("qualid"), s)); 0364 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("QualifiedIdentifier"), QStringLiteral("qualidentifier"), s)); 0365 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("QualifiedIdentifier"), QStringLiteral("qi"), s)); 0366 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kcmodel"), s)); 0367 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kc"), s)); 0368 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kcomplmodel"), s)); 0369 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kacomplmodel"), s)); 0370 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kacom"), s)); 0371 0372 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("QualifiedIdentifier"), QStringLiteral("identifier"), s)); 0373 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fobaara"), s)); 0374 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBarArr"), QStringLiteral("fbac"), s)); 0375 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kamodel"), s)); 0376 0377 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("AbcdefBcdefCdefDefEfFzZ"), QStringLiteral("AbcdefBcdefCdefDefEfFzZ"), s)); 0378 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("AbcdefBcdefCdefDefEfFzZ"), QStringLiteral("ABCDEFX"), s)); 0379 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("AaaaaaBbbbbCcccDddEeFzZ"), QStringLiteral("XZYBFA"), s)); 0380 0381 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("fb"), s)); 0382 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("FooBar"), QStringLiteral("FB"), s)); 0383 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("kcmodel"), s)); 0384 QVERIFY(KateCompletionModel::matchesAbbreviation(QStringLiteral("KateCompletionModel"), QStringLiteral("KCModel"), s)); 0385 } 0386 0387 void CompletionTest::testAutoCompletionPreselectFirst() 0388 { 0389 new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0390 0391 m_view->config()->setValue(KateViewConfig::AutomaticCompletionPreselectFirst, false); 0392 // When AutomaticCompletionPreselectFirst is disabled, immediately pressing enter 0393 // should result into a newline instead of completion 0394 m_doc->setText("a"); 0395 m_view->setCursorPosition(Cursor(0, 1)); 0396 m_view->completionWidget()->automaticInvocation(); 0397 verifyCompletionStarted(m_view); 0398 auto enterKeyEvent = QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); 0399 QApplication::sendEvent(m_view->focusProxy(), &enterKeyEvent); 0400 0401 verifyCompletionAborted(m_view); 0402 QCOMPARE(m_doc->text(), "a\n"); 0403 } 0404 0405 void CompletionTest::testTabCompletion() 0406 { 0407 new CodeCompletionTestModel(m_view, QStringLiteral("a")); 0408 0409 m_view->config()->setValue(KateViewConfig::TabCompletion, true); 0410 0411 // First entry already selected 0412 m_view->config()->setValue(KateViewConfig::AutomaticCompletionPreselectFirst, true); 0413 0414 // Nothing to do, already selected 0415 m_doc->setText("a"); 0416 m_view->completionWidget()->automaticInvocation(); 0417 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0418 m_view->completionWidget()->execute(); 0419 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0420 QCOMPARE(m_doc->text(), "aaa0"); 0421 0422 // First entry already selected, going down will select the next completion 0423 m_doc->setText("a"); 0424 m_view->completionWidget()->automaticInvocation(); 0425 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0426 m_view->completionWidget()->tabCompletion(KateCompletionWidget::Down); 0427 m_view->completionWidget()->execute(); 0428 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0429 QCOMPARE(m_doc->text(), "aad3"); 0430 0431 // First entry _not_ already selected... 0432 m_view->config()->setValue(KateViewConfig::AutomaticCompletionPreselectFirst, false); 0433 0434 m_doc->setText("a"); 0435 m_view->completionWidget()->automaticInvocation(); 0436 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0437 // ... Tab will select the first entry 0438 m_view->completionWidget()->tabCompletion(KateCompletionWidget::Down); 0439 m_view->completionWidget()->execute(); 0440 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0441 QCOMPARE(m_doc->text(), "aaa0"); 0442 0443 // While at the top, going up, cycles to the bottom of the list 0444 m_doc->setText("a"); 0445 m_view->completionWidget()->automaticInvocation(); 0446 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0447 m_view->completionWidget()->cursorDown(); // Select first entry 0448 m_view->completionWidget()->tabCompletion(KateCompletionWidget::Up); 0449 m_view->completionWidget()->execute(); 0450 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0451 QCOMPARE(m_doc->text(), "ac\u008738"); 0452 0453 // While at the bottom, going down cycles to the top of the list 0454 m_doc->setText("a"); 0455 m_view->completionWidget()->automaticInvocation(); 0456 QVERIFY(m_view->completionWidget()->isCompletionActive()); 0457 m_view->completionWidget()->cursorDown(); // Select first entry 0458 m_view->completionWidget()->tabCompletion(KateCompletionWidget::Up); // Go to bottom 0459 // While at the bottom, Tab goes to the top of the list 0460 m_view->completionWidget()->tabCompletion(KateCompletionWidget::Down); 0461 m_view->completionWidget()->execute(); 0462 QVERIFY(!m_view->completionWidget()->isCompletionActive()); 0463 QCOMPARE(m_doc->text(), "aaa0"); 0464 } 0465 0466 void CompletionTest::benchAbbreviationEngineGoodCase() 0467 { 0468 int s = 0; 0469 QBENCHMARK { 0470 for (int i = 0; i < 10000; i++) { 0471 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("AaaaaaBbbbbCcccDddEeFzZ"), QStringLiteral("XZYBFA"), s)); 0472 } 0473 } 0474 } 0475 0476 void CompletionTest::benchAbbreviationEngineNormalCase() 0477 { 0478 int s = 0; 0479 QBENCHMARK { 0480 for (int i = 0; i < 10000; i++) { 0481 QVERIFY(!KateCompletionModel::matchesAbbreviation(QStringLiteral("AaaaaaBbbbbCcccDddEeFzZ"), QStringLiteral("ABCDEFX"), s)); 0482 } 0483 } 0484 } 0485 0486 void CompletionTest::benchAbbreviationEngineWorstCase() 0487 { 0488 int s = 0; 0489 QBENCHMARK { 0490 for (int i = 0; i < 10000; i++) { 0491 // This case is quite horrible, because it requires a branch at every letter. 0492 // The current code will at some point drop out and just return false. 0493 KateCompletionModel::matchesAbbreviation(QStringLiteral("XxBbbbbbBbbbbbBbbbbBbbbBbbbbbbBbbbbbBbbbbbBbbbFox"), 0494 QStringLiteral("XbbbbbbbbbbbbbbbbbbbbFx"), 0495 s); 0496 } 0497 } 0498 } 0499 0500 void CompletionTest::testAbbrevAndContainsMatching() 0501 { 0502 KateCompletionModel *model = m_view->completionWidget()->model(); 0503 0504 new AbbreviationCodeCompletionTestModel(m_view, QString()); 0505 0506 m_view->document()->setText(QStringLiteral("SCA")); 0507 invokeCompletionBox(m_view); 0508 QCOMPARE(model->filteredItemCount(), (uint)6); 0509 0510 m_view->document()->setText(QStringLiteral("SC")); 0511 invokeCompletionBox(m_view); 0512 QCOMPARE(model->filteredItemCount(), (uint)9); 0513 0514 m_view->document()->setText(QStringLiteral("sca")); 0515 invokeCompletionBox(m_view); 0516 QCOMPARE(model->filteredItemCount(), (uint)6); 0517 0518 m_view->document()->setText(QStringLiteral("contains")); 0519 invokeCompletionBox(m_view); 0520 QCOMPARE(model->filteredItemCount(), (uint)3); 0521 0522 m_view->document()->setText(QStringLiteral("CONTAINS")); 0523 invokeCompletionBox(m_view); 0524 QCOMPARE(model->filteredItemCount(), (uint)3); 0525 0526 m_view->document()->setText(QStringLiteral("containssome")); 0527 invokeCompletionBox(m_view); 0528 QCOMPARE(model->filteredItemCount(), (uint)2); 0529 0530 m_view->document()->setText(QStringLiteral("matched")); 0531 m_view->userInvokedCompletion(); 0532 QApplication::processEvents(); 0533 QCOMPARE(model->filteredItemCount(), (uint)1); 0534 } 0535 0536 void CompletionTest::testAsyncMatching() 0537 { 0538 KateCompletionModel *model = m_view->completionWidget()->model(); 0539 0540 auto asyncModel = new AsyncCodeCompletionTestModel(m_view, QString()); 0541 0542 m_view->document()->setText(QStringLiteral("matched")); 0543 0544 m_view->userInvokedCompletion(); 0545 QApplication::processEvents(); 0546 asyncModel->setItems({QStringLiteral("this_should_be_matched"), QStringLiteral("do_not_find_this")}); 0547 QCOMPARE(model->filteredItemCount(), (uint)1); 0548 } 0549 0550 void CompletionTest::benchCompletionModel() 0551 { 0552 const int testFactor = 1; 0553 const QString text("abcdefg abcdef"); 0554 m_doc->setText(text); 0555 CodeCompletionTestModel *testModel1 = new CodeCompletionTestModel(m_view, QStringLiteral("abcdefg")); 0556 testModel1->setRowCount(50 * testFactor); 0557 CodeCompletionTestModel *testModel2 = new CodeCompletionTestModel(m_view, QStringLiteral("abcdef")); 0558 testModel2->setRowCount(50 * testFactor); 0559 CodeCompletionTestModel *testModel3 = new CodeCompletionTestModel(m_view, QStringLiteral("abcde")); 0560 testModel3->setRowCount(50 * testFactor); 0561 CodeCompletionTestModel *testModel4 = new CodeCompletionTestModel(m_view, QStringLiteral("abcd")); 0562 testModel4->setRowCount(500 * testFactor); 0563 QBENCHMARK_ONCE { 0564 for (int i = 0; i < text.size(); ++i) { 0565 m_view->setCursorPosition(Cursor(0, i)); 0566 invokeCompletionBox(m_view); 0567 } 0568 } 0569 } 0570 0571 #include "moc_completion_test.cpp"