File indexing completed on 2024-04-28 11:44:45

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"