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