File indexing completed on 2024-04-21 03:57:16

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "searchbar_test.h"
0009 
0010 #include "ui_searchbarincremental.h"
0011 #include "ui_searchbarpower.h"
0012 
0013 #include <KMessageBox>
0014 #include <kateconfig.h>
0015 #include <katedocument.h>
0016 #include <kateglobal.h>
0017 #include <katesearchbar.h>
0018 #include <kateview.h>
0019 #include <ktexteditor/movingrange.h>
0020 
0021 #include <QStringListModel>
0022 #include <QTest>
0023 
0024 QTEST_MAIN(SearchBarTest)
0025 
0026 #define testNewRow() (QTest::newRow(QStringLiteral("line %1").arg(__LINE__).toLatin1().data()))
0027 
0028 using namespace KTextEditor;
0029 
0030 SearchBarTest::SearchBarTest()
0031     : QObject()
0032 {
0033 }
0034 
0035 SearchBarTest::~SearchBarTest()
0036 {
0037 }
0038 
0039 void SearchBarTest::initTestCase()
0040 {
0041     KTextEditor::EditorPrivate::enableUnitTestMode();
0042     KMessageBox::saveDontShowAgainTwoActions(QLatin1String("DoNotShowAgainContinueSearchDialog"), KMessageBox::PrimaryAction);
0043 }
0044 
0045 void SearchBarTest::cleanupTestCase()
0046 {
0047 }
0048 
0049 void SearchBarTest::testFindNextIncremental()
0050 {
0051     KTextEditor::DocumentPrivate doc;
0052     doc.setText(QStringLiteral("a a a b b"));
0053 
0054     KTextEditor::ViewPrivate view(&doc, nullptr);
0055     KateViewConfig config(&view);
0056 
0057     KateSearchBar bar(false, &view, &config);
0058 
0059     bar.setSearchPattern(QStringLiteral("b"));
0060 
0061     QCOMPARE(view.selectionRange(), Range(0, 6, 0, 7));
0062 
0063     bar.findNext();
0064 
0065     QCOMPARE(view.selectionRange(), Range(0, 8, 0, 9));
0066 
0067     bar.setSearchPattern(QStringLiteral("a"));
0068 
0069     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0070 
0071     bar.findNext();
0072 
0073     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0074 
0075     bar.findNext();
0076 
0077     QCOMPARE(view.selectionRange(), Range(0, 4, 0, 5));
0078 
0079     bar.findNext();
0080 
0081     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0082 }
0083 
0084 void SearchBarTest::testFindNextZeroLengthMatch()
0085 {
0086     // Some regularexpression matches are zero length assertions
0087     // e.g. '$', '^', '\b', test that the cursor won't be stuck
0088     // on one match when using FindNext
0089     KTextEditor::DocumentPrivate doc;
0090     doc.setText(QStringLiteral("a\nb \nc\n\n"));
0091 
0092     KTextEditor::ViewPrivate view(&doc, nullptr);
0093     KateViewConfig config(&view);
0094     KateSearchBar bar(true, &view, &config);
0095     bar.setSearchMode(KateSearchBar::MODE_REGEX);
0096 
0097     bar.setSearchPattern(QStringLiteral("$"));
0098 
0099     QVERIFY(bar.isPower());
0100 
0101     bar.findNext();
0102     QCOMPARE(view.cursorPosition(), Cursor(0, 1));
0103 
0104     bar.findNext();
0105     QCOMPARE(view.cursorPosition(), Cursor(1, 2));
0106 
0107     bar.findNext();
0108     QCOMPARE(view.cursorPosition(), Cursor(2, 1));
0109 
0110     bar.findNext();
0111     QCOMPARE(view.cursorPosition(), Cursor(3, 0));
0112 
0113     // Test Unicode
0114     doc.setText(QStringLiteral("aéöz\n"));
0115     bar.setSearchPattern(QStringLiteral("\\w"));
0116     view.setCursorPosition(Cursor(0, 0));
0117 
0118     bar.findNext();
0119     QCOMPARE(view.cursorPosition(), Cursor(0, 1));
0120 
0121     bar.findNext();
0122     QCOMPARE(view.cursorPosition(), Cursor(0, 2));
0123 
0124     bar.findNext();
0125     QCOMPARE(view.cursorPosition(), Cursor(0, 3));
0126 
0127     bar.findNext();
0128     QCOMPARE(view.cursorPosition(), Cursor(0, 4));
0129 
0130     doc.setText(QStringLiteral("aé ö z\n"));
0131     bar.setSearchPattern(QStringLiteral("\\b"));
0132     view.setCursorPosition(Cursor(0, 0));
0133 
0134     bar.findNext();
0135     QCOMPARE(view.cursorPosition(), Cursor(0, 2));
0136     QCOMPARE(doc.text(Range(0, 1, 0, 2)), QStringLiteral("é"));
0137 
0138     bar.findNext();
0139     QCOMPARE(view.cursorPosition(), Cursor(0, 3));
0140     QCOMPARE(doc.text(Range(0, 3, 0, 4)), QStringLiteral("ö"));
0141 
0142     bar.findNext();
0143     QCOMPARE(view.cursorPosition(), Cursor(0, 4));
0144     QCOMPARE(doc.text(Range(0, 3, 0, 4)), QStringLiteral("ö"));
0145 
0146     bar.findNext();
0147     QCOMPARE(view.cursorPosition(), Cursor(0, 5));
0148     QCOMPARE(doc.text(Range(0, 5, 0, 6)), QStringLiteral("z"));
0149 
0150     bar.findNext();
0151     QCOMPARE(view.cursorPosition(), Cursor(0, 6));
0152     QCOMPARE(doc.text(Range(0, 5, 0, 6)), QStringLiteral("z"));
0153 
0154     bar.findNext();
0155     // Search wraps, back to before first char
0156     QCOMPARE(view.cursorPosition(), Cursor(0, 0));
0157     QCOMPARE(doc.text(Range(0, 0, 0, 1)), QStringLiteral("a"));
0158 }
0159 
0160 void SearchBarTest::testFindNextNoNewLineAtEnd()
0161 {
0162     // Testing with a document that doesn't end with a new line
0163     KTextEditor::DocumentPrivate doc;
0164     doc.setText(QStringLiteral(" \n \n "));
0165 
0166     KTextEditor::ViewPrivate view(&doc, nullptr);
0167     KateViewConfig config(&view);
0168     KateSearchBar bar(true, &view, &config);
0169     QVERIFY(bar.isPower());
0170     bar.setSearchMode(KateSearchBar::MODE_REGEX);
0171     bar.setSearchPattern(QStringLiteral("^ *\\n"));
0172 
0173     bar.findNext();
0174     QCOMPARE(view.selectionRange(), Range(0, 0, 1, 0));
0175 
0176     bar.findNext();
0177     QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0178 
0179     bar.findNext();
0180     // Search wraps
0181     QCOMPARE(view.selectionRange(), Range(0, 0, 1, 0));
0182 }
0183 
0184 void SearchBarTest::testSetMatchCaseIncremental()
0185 {
0186     KTextEditor::DocumentPrivate doc;
0187     KTextEditor::ViewPrivate view(&doc, nullptr);
0188     KateViewConfig config(&view);
0189 
0190     doc.setText(QStringLiteral("a A a"));
0191     KateSearchBar bar(false, &view, &config);
0192 
0193     QVERIFY(!bar.isPower());
0194     QVERIFY(!view.selection());
0195 
0196     bar.setMatchCase(false);
0197     bar.setSearchPattern(QStringLiteral("A"));
0198 
0199     QVERIFY(!bar.matchCase());
0200     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0201 
0202     bar.setMatchCase(true);
0203 
0204     QVERIFY(bar.matchCase());
0205     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0206 
0207     bar.setMatchCase(false);
0208 
0209     QVERIFY(!bar.matchCase());
0210     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0211 
0212     bar.setMatchCase(true);
0213 
0214     QVERIFY(bar.matchCase());
0215     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0216 }
0217 
0218 void SearchBarTest::testSetMatchCasePower()
0219 {
0220     KTextEditor::DocumentPrivate doc;
0221     KTextEditor::ViewPrivate view(&doc, nullptr);
0222     KateViewConfig config(&view);
0223 
0224     doc.setText(QStringLiteral("a A a"));
0225     view.setCursorPosition(Cursor(0, 0));
0226 
0227     KateSearchBar bar(true, &view, &config);
0228 
0229     QVERIFY(bar.isPower());
0230     QVERIFY(!view.selection());
0231 
0232     bar.setMatchCase(false);
0233     bar.setSearchPattern(QStringLiteral("A"));
0234     bar.findNext();
0235 
0236     QCOMPARE(bar.searchPattern(), QStringLiteral("A"));
0237     QVERIFY(!bar.matchCase());
0238     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0239 
0240     bar.setMatchCase(true);
0241 
0242     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0243 
0244     bar.findNext();
0245 
0246     QVERIFY(bar.matchCase());
0247     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0248 
0249     bar.setMatchCase(false);
0250 
0251     QVERIFY(!bar.matchCase());
0252     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0253 
0254     bar.findNext();
0255 
0256     QCOMPARE(view.selectionRange(), Range(0, 4, 0, 5));
0257 }
0258 
0259 void SearchBarTest::testSetSelectionOnlyPower()
0260 {
0261     KTextEditor::DocumentPrivate doc;
0262     KTextEditor::ViewPrivate view(&doc, nullptr);
0263     KateViewConfig config(&view);
0264 
0265     doc.setText(QStringLiteral("a a a a"));
0266     KateSearchBar bar(true, &view, &config);
0267 
0268     bar.setSearchPattern(QStringLiteral("a"));
0269 
0270     QVERIFY(bar.isPower());
0271     QVERIFY(!view.selection());
0272 
0273     bar.setSelectionOnly(false);
0274     bar.findNext();
0275 
0276     QVERIFY(!bar.selectionOnly());
0277     QCOMPARE(view.selectionRange(), Range(0, 0, 0, 1));
0278 
0279     view.setSelection(Range(0, 2, 0, 5));
0280     bar.setSelectionOnly(true);
0281 
0282     QVERIFY(bar.selectionOnly());
0283 
0284     bar.findNext();
0285 
0286     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0287     QVERIFY(bar.selectionOnly());
0288 
0289     bar.findNext();
0290 
0291     QCOMPARE(view.selectionRange(), Range(0, 4, 0, 5));
0292     QVERIFY(bar.selectionOnly());
0293 
0294     // Test Search wrap for selection only
0295     bar.findNext();
0296 
0297     QCOMPARE(view.selectionRange(), Range(0, 2, 0, 3));
0298     QVERIFY(bar.selectionOnly());
0299 
0300     bar.findPrevious();
0301 
0302     QCOMPARE(view.selectionRange(), Range(0, 4, 0, 5));
0303     QVERIFY(bar.selectionOnly());
0304 
0305     bar.setSelectionOnly(false);
0306     bar.findNext();
0307 
0308     QCOMPARE(view.selectionRange(), Range(0, 6, 0, 7));
0309     QVERIFY(!bar.selectionOnly());
0310 }
0311 
0312 void SearchBarTest::testSetSearchPattern_data()
0313 {
0314     QTest::addColumn<bool>("power");
0315     QTest::addColumn<int>("numMatches2");
0316 
0317     testNewRow() << false << 0;
0318     testNewRow() << true << 3;
0319 }
0320 
0321 void SearchBarTest::testSetSearchPattern()
0322 {
0323     QFETCH(bool, power);
0324     QFETCH(int, numMatches2);
0325 
0326     KTextEditor::DocumentPrivate doc;
0327     KTextEditor::ViewPrivate view(&doc, nullptr);
0328     KateViewConfig config(&view);
0329 
0330     doc.setText(QStringLiteral("a a a"));
0331 
0332     KateSearchBar bar(power, &view, &config);
0333 
0334     bar.setSearchPattern(QStringLiteral("a"));
0335     bar.findAll();
0336 
0337     QCOMPARE(bar.m_hlRanges.size(), 3);
0338 
0339     bar.setSearchPattern(QStringLiteral("a "));
0340 
0341     QCOMPARE(bar.m_hlRanges.size(), numMatches2);
0342 
0343     bar.findAll();
0344 
0345     QCOMPARE(bar.m_hlRanges.size(), 2);
0346 }
0347 
0348 void SearchBarTest::testSetSelectionOnly()
0349 {
0350     KTextEditor::DocumentPrivate doc;
0351     KTextEditor::ViewPrivate view(&doc, nullptr);
0352     KateViewConfig config(&view);
0353 
0354     doc.setText(QStringLiteral("a a a"));
0355     view.setSelection(Range(0, 0, 0, 3));
0356 
0357     KateSearchBar bar(false, &view, &config);
0358 
0359     bar.setSelectionOnly(false);
0360     bar.setSearchPattern(QStringLiteral("a"));
0361     bar.findAll();
0362 
0363     QCOMPARE(bar.m_hlRanges.size(), 3);
0364 
0365     bar.setSelectionOnly(true);
0366 
0367     QCOMPARE(bar.m_hlRanges.size(), 3);
0368 }
0369 
0370 void SearchBarTest::testFindAll_data()
0371 {
0372     QTest::addColumn<bool>("power");
0373     QTest::addColumn<int>("numMatches2");
0374     QTest::addColumn<int>("numMatches4");
0375 
0376     testNewRow() << false << 0 << 0;
0377     testNewRow() << true << 3 << 2;
0378 }
0379 
0380 void SearchBarTest::testFindAll()
0381 {
0382     QFETCH(bool, power);
0383     QFETCH(int, numMatches2);
0384     QFETCH(int, numMatches4);
0385 
0386     KTextEditor::DocumentPrivate doc;
0387     KTextEditor::ViewPrivate view(&doc, nullptr);
0388     KateViewConfig config(&view);
0389 
0390     doc.setText(QStringLiteral("a a a"));
0391     KateSearchBar bar(power, &view, &config);
0392 
0393     QCOMPARE(bar.isPower(), power);
0394 
0395     bar.setSearchPattern(QStringLiteral("a"));
0396     bar.findAll();
0397 
0398     QCOMPARE(bar.m_hlRanges.size(), 3);
0399     QCOMPARE(bar.m_hlRanges.at(0)->toRange(), Range(0, 0, 0, 1));
0400     QCOMPARE(bar.m_hlRanges.at(1)->toRange(), Range(0, 2, 0, 3));
0401     QCOMPARE(bar.m_hlRanges.at(2)->toRange(), Range(0, 4, 0, 5));
0402 
0403     bar.setSearchPattern(QStringLiteral("a "));
0404 
0405     QCOMPARE(bar.m_hlRanges.size(), numMatches2);
0406 
0407     bar.findAll();
0408 
0409     QCOMPARE(bar.m_hlRanges.size(), 2);
0410 
0411     bar.setSearchPattern(QStringLiteral("a  "));
0412 
0413     QCOMPARE(bar.m_hlRanges.size(), numMatches4);
0414 
0415     bar.findAll();
0416 
0417     QCOMPARE(bar.m_hlRanges.size(), 0);
0418 }
0419 
0420 void SearchBarTest::testReplaceInSelectionOnly()
0421 {
0422     KTextEditor::DocumentPrivate doc;
0423     KTextEditor::ViewPrivate view(&doc, nullptr);
0424     KateViewConfig config(&view);
0425 
0426     doc.setText(QStringLiteral("a\na\na\na\na"));
0427     KateSearchBar bar(true, &view, &config);
0428 
0429     bar.setSearchPattern(QStringLiteral("a\n"));
0430 
0431     view.setSelection(Range(1, 0, 4, 0));
0432     bar.setSelectionOnly(true);
0433 
0434     QVERIFY(bar.selectionOnly());
0435 
0436     bar.replaceNext();
0437 
0438     QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0439     QVERIFY(bar.selectionOnly());
0440 
0441     bar.replaceNext();
0442 
0443     QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0444     QVERIFY(bar.selectionOnly());
0445 
0446     bar.replaceNext();
0447 
0448     QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0449     QVERIFY(bar.selectionOnly());
0450 
0451     bar.replaceNext();
0452 
0453     QCOMPARE(view.selectionRange(), Range(1, 0, 1, 0));
0454     QCOMPARE(doc.text(), QStringLiteral("a\na"));
0455     QVERIFY(bar.selectionOnly());
0456 
0457     // Test undo (search selection range should still be preserved)
0458     doc.undo();
0459     doc.undo();
0460     doc.undo();
0461 
0462     QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0463     QVERIFY(bar.selectionOnly());
0464 
0465     bar.findPrevious();
0466 
0467     QCOMPARE(view.selectionRange(), Range(3, 0, 4, 0));
0468     QVERIFY(bar.selectionOnly());
0469 
0470     // TODO: Make sure deleted parts of the selection range are added back on undo (currently, the MovingRange just moves forward and does not add back the
0471     // deleted range) bar.findNext();
0472     //
0473     // QCOMPARE(view.selectionRange(), Range(1, 0, 2, 0));
0474     // QVERIFY(bar.selectionOnly());
0475 }
0476 
0477 void SearchBarTest::testReplaceAll()
0478 {
0479     KTextEditor::DocumentPrivate doc;
0480     KTextEditor::ViewPrivate view(&doc, nullptr);
0481     KateViewConfig config(&view);
0482 
0483     doc.setText(QStringLiteral("a a a"));
0484     KateSearchBar bar(true, &view, &config);
0485 
0486     bar.setSearchPattern(QStringLiteral("a"));
0487     bar.setReplacementPattern(QString());
0488     bar.replaceAll();
0489 
0490     QCOMPARE(bar.m_hlRanges.size(), 3);
0491     QCOMPARE(bar.m_hlRanges.at(0)->toRange(), Range(0, 0, 0, 0));
0492     QCOMPARE(bar.m_hlRanges.at(1)->toRange(), Range(0, 1, 0, 1));
0493     QCOMPARE(bar.m_hlRanges.at(2)->toRange(), Range(0, 2, 0, 2));
0494 
0495     bar.setSearchPattern(QStringLiteral(" "));
0496     bar.setReplacementPattern(QStringLiteral("b"));
0497     bar.replaceAll();
0498 
0499     QCOMPARE(bar.m_hlRanges.size(), 2);
0500     QCOMPARE(bar.m_hlRanges.at(0)->toRange(), Range(0, 0, 0, 1));
0501     QCOMPARE(bar.m_hlRanges.at(1)->toRange(), Range(0, 1, 0, 2));
0502 }
0503 
0504 void SearchBarTest::testFindSelectionForward_data()
0505 {
0506     QTest::addColumn<QString>("text");
0507     QTest::addColumn<bool>("selectionOnly");
0508     QTest::addColumn<Range>("selectionRange");
0509     QTest::addColumn<Range>("match");
0510 
0511     testNewRow() << QStringLiteral("a a a") << false << Range(0, 0, 0, 1) << Range(0, 0, 0, 2);
0512     testNewRow() << QStringLiteral("a a a") << true << Range(0, 0, 0, 1) << Range(0, 0, 0, 1);
0513 
0514     testNewRow() << QStringLiteral("a a a") << false << Range(0, 0, 0, 2) << Range(0, 2, 0, 4);
0515     testNewRow() << QStringLiteral("a a a") << true << Range(0, 0, 0, 2) << Range(0, 0, 0, 2);
0516 
0517     testNewRow() << QStringLiteral("a a a") << false << Range(0, 0, 0, 3) << Range(0, 0, 0, 2);
0518     testNewRow() << QStringLiteral("a a a") << true << Range(0, 0, 0, 3) << Range(0, 0, 0, 2);
0519 
0520     testNewRow() << QStringLiteral("a a a") << false << Range(0, 2, 0, 4) << Range(0, 0, 0, 2);
0521     testNewRow() << QStringLiteral("a a a") << true << Range(0, 2, 0, 4) << Range(0, 2, 0, 4);
0522 
0523     testNewRow() << QStringLiteral("a a a") << false << Range(0, 3, 0, 4) << Range(0, 0, 0, 2);
0524     testNewRow() << QStringLiteral("a a a") << true << Range(0, 3, 0, 4) << Range(0, 3, 0, 4);
0525 }
0526 
0527 void SearchBarTest::testFindSelectionForward()
0528 {
0529     QFETCH(QString, text);
0530     QFETCH(bool, selectionOnly);
0531     QFETCH(Range, selectionRange);
0532     QFETCH(Range, match);
0533 
0534     KTextEditor::DocumentPrivate doc;
0535     KTextEditor::ViewPrivate view(&doc, nullptr);
0536     KateViewConfig config(&view);
0537 
0538     doc.setText(text);
0539 
0540     view.setSelection(Range(0, 0, 0, 2));
0541 
0542     KateSearchBar bar(true, &view, &config);
0543     QVERIFY(bar.searchPattern() == QStringLiteral("a "));
0544 
0545     view.setSelection(selectionRange);
0546     QCOMPARE(view.selectionRange(), selectionRange);
0547     bar.setSelectionOnly(selectionOnly);
0548 
0549     bar.findNext();
0550 
0551     QCOMPARE(view.selectionRange(), match);
0552 }
0553 
0554 void SearchBarTest::testRemoveWithSelectionForward_data()
0555 {
0556     QTest::addColumn<Range>("selectionRange");
0557     QTest::addColumn<Range>("match");
0558 
0559     testNewRow() << Range(0, 0, 0, 1) << Range(0, 0, 0, 2);
0560     testNewRow() << Range(0, 0, 0, 2) << Range(0, 0, 0, 2);
0561     testNewRow() << Range(0, 0, 0, 3) << Range(0, 0, 0, 2);
0562     testNewRow() << Range(0, 2, 0, 4) << Range(0, 0, 0, 2);
0563     testNewRow() << Range(0, 3, 0, 4) << Range(0, 0, 0, 2);
0564 }
0565 
0566 void SearchBarTest::testRemoveWithSelectionForward()
0567 {
0568     QFETCH(Range, selectionRange);
0569     QFETCH(Range, match);
0570 
0571     KTextEditor::DocumentPrivate doc;
0572     KTextEditor::ViewPrivate view(&doc, nullptr);
0573     KateViewConfig config(&view);
0574 
0575     doc.setText(QStringLiteral("a a a"));
0576     view.setSelection(selectionRange);
0577 
0578     KateSearchBar bar(true, &view, &config);
0579     bar.setSearchPattern(QStringLiteral("a "));
0580     bar.setSelectionOnly(false);
0581 
0582     bar.replaceNext();
0583 
0584     QCOMPARE(view.selectionRange(), match);
0585 }
0586 
0587 void SearchBarTest::testRemoveInSelectionForward_data()
0588 {
0589     QTest::addColumn<Range>("selectionRange");
0590     QTest::addColumn<Range>("match");
0591 
0592     testNewRow() << Range(0, 0, 0, 1) << Range(0, 0, 0, 1);
0593     testNewRow() << Range(0, 0, 0, 2) << Range(0, 0, 0, 0);
0594     testNewRow() << Range(0, 0, 0, 3) << Range(0, 0, 0, 2);
0595     testNewRow() << Range(0, 0, 0, 4) << Range(0, 0, 0, 2);
0596     testNewRow() << Range(0, 2, 0, 4) << Range(0, 2, 0, 2);
0597     testNewRow() << Range(0, 3, 0, 4) << Range(0, 3, 0, 4);
0598 }
0599 
0600 void SearchBarTest::testRemoveInSelectionForward()
0601 {
0602     QFETCH(Range, selectionRange);
0603     QFETCH(Range, match);
0604 
0605     KTextEditor::DocumentPrivate doc;
0606     KTextEditor::ViewPrivate view(&doc, nullptr);
0607     KateViewConfig config(&view);
0608 
0609     doc.setText(QStringLiteral("a a a"));
0610     view.setSelection(selectionRange);
0611 
0612     KateSearchBar bar(true, &view, &config);
0613     bar.setSearchPattern(QStringLiteral("a "));
0614     bar.setSelectionOnly(true);
0615 
0616     QVERIFY(bar.replacementPattern().isEmpty());
0617 
0618     bar.replaceNext();
0619 
0620     QCOMPARE(view.selectionRange(), match);
0621 }
0622 
0623 void SearchBarTest::testReplaceWithDoubleSelecion_data()
0624 {
0625     QTest::addColumn<QString>("text");
0626     QTest::addColumn<Range>("selectionRange");
0627     QTest::addColumn<QString>("result");
0628     QTest::addColumn<Range>("match");
0629 
0630     //  testNewRow() << "a"  << Range(0, 0, 0, 1) << "aa" << Range(?, ?, ?, ?);
0631     testNewRow() << QStringLiteral("aa") << Range(0, 1, 0, 2) << QStringLiteral("aaa") << Range(0, 0, 0, 1);
0632     testNewRow() << QStringLiteral("aa") << Range(0, 0, 0, 1) << QStringLiteral("aaa") << Range(0, 2, 0, 3);
0633 
0634     //  testNewRow() << "ab"  << Range(0, 0, 0, 1) << "aab"  << Range(?, ?, ?, ?);
0635     testNewRow() << QStringLiteral("aab") << Range(0, 0, 0, 1) << QStringLiteral("aaab") << Range(0, 2, 0, 3);
0636     testNewRow() << QStringLiteral("aba") << Range(0, 0, 0, 1) << QStringLiteral("aaba") << Range(0, 3, 0, 4);
0637 
0638     //  testNewRow() << "ab"   << Range(0, 0, 0, 2) << "abab"   << Range(?, ?, ?, ?);
0639     testNewRow() << QStringLiteral("abab") << Range(0, 0, 0, 2) << QStringLiteral("ababab") << Range(0, 4, 0, 6);
0640     testNewRow() << QStringLiteral("abab") << Range(0, 2, 0, 4) << QStringLiteral("ababab") << Range(0, 0, 0, 2);
0641 }
0642 
0643 void SearchBarTest::testReplaceWithDoubleSelecion()
0644 {
0645     QFETCH(QString, text);
0646     QFETCH(Range, selectionRange);
0647     QFETCH(QString, result);
0648     QFETCH(Range, match);
0649 
0650     KTextEditor::DocumentPrivate doc;
0651     KTextEditor::ViewPrivate view(&doc, nullptr);
0652     KateViewConfig config(&view);
0653 
0654     doc.setText(text);
0655     view.setSelection(selectionRange);
0656 
0657     KateSearchBar bar(true, &view, &config);
0658 
0659     bar.setSelectionOnly(false);
0660     bar.setReplacementPattern(bar.searchPattern() + bar.searchPattern());
0661     bar.replaceNext();
0662 
0663     QCOMPARE(doc.text(), result);
0664     QCOMPARE(view.selectionRange(), match);
0665 }
0666 
0667 void SearchBarTest::testReplaceDollar()
0668 {
0669     KTextEditor::DocumentPrivate doc;
0670     KTextEditor::ViewPrivate view(&doc, nullptr);
0671     KateViewConfig config(&view);
0672 
0673     doc.setText(QStringLiteral("aaa\nbbb\nccc\n\n\naaa\nbbb\nccc\nddd\n"));
0674 
0675     KateSearchBar bar(true, &view, &config);
0676 
0677     bar.setSearchPattern(QStringLiteral("$"));
0678     bar.setSearchMode(KateSearchBar::MODE_REGEX);
0679     bar.setReplacementPattern(QStringLiteral("D"));
0680     bar.replaceAll();
0681     QCOMPARE(doc.text(), QStringLiteral("aaaD\nbbbD\ncccD\nD\nD\naaaD\nbbbD\ncccD\ndddD\n"));
0682 }
0683 
0684 void SearchBarTest::testSearchHistoryIncremental()
0685 {
0686     KTextEditor::DocumentPrivate doc;
0687     KTextEditor::ViewPrivate view(&doc, nullptr);
0688     KateViewConfig *const config = view.config();
0689     KTextEditor::EditorPrivate::self()->searchHistoryModel()->setStringList(QStringList());
0690 
0691     doc.setText(QStringLiteral("foo bar"));
0692 
0693     KateSearchBar bar(false, &view, config);
0694 
0695     bar.setSearchPattern(QStringLiteral("foo"));
0696     bar.findNext();
0697 
0698     QCOMPARE(bar.m_incUi->pattern->findText(QStringLiteral("foo")), 0);
0699 
0700     bar.setSearchPattern(QStringLiteral("bar"));
0701     bar.findNext();
0702 
0703     QCOMPARE(bar.m_incUi->pattern->findText(QStringLiteral("bar")), 0);
0704     QCOMPARE(bar.m_incUi->pattern->findText(QStringLiteral("foo")), 1);
0705 
0706     KTextEditor::DocumentPrivate doc2;
0707     KTextEditor::ViewPrivate view2(&doc2, nullptr);
0708     KateViewConfig *const config2 = view2.config();
0709     KateSearchBar bar2(false, &view2, config2);
0710 
0711     QCOMPARE(bar2.m_incUi->pattern->findText(QStringLiteral("bar")), 0);
0712     QCOMPARE(bar2.m_incUi->pattern->findText(QStringLiteral("foo")), 1);
0713 
0714     // testcase for https://bugs.kde.org/show_bug.cgi?id=248305
0715     bar2.m_incUi->pattern->setCurrentIndex(1);
0716     QCOMPARE(bar2.searchPattern(), QLatin1String("foo"));
0717     bar2.findNext();
0718     QCOMPARE(bar2.searchPattern(), QLatin1String("foo"));
0719 }
0720 
0721 void SearchBarTest::testSearchHistoryPower()
0722 {
0723     KTextEditor::DocumentPrivate doc;
0724     KTextEditor::ViewPrivate view(&doc, nullptr);
0725     KateViewConfig *const config = view.config();
0726     KTextEditor::EditorPrivate::self()->searchHistoryModel()->setStringList(QStringList());
0727 
0728     doc.setText(QStringLiteral("foo bar"));
0729 
0730     KateSearchBar bar(true, &view, config);
0731 
0732     QCOMPARE(bar.m_powerUi->pattern->count(), 0);
0733 
0734     bar.setSearchPattern(QStringLiteral("foo"));
0735     bar.findNext();
0736 
0737     QCOMPARE(bar.m_powerUi->pattern->findText(QStringLiteral("foo")), 0);
0738 
0739     bar.findNext();
0740 
0741     QCOMPARE(bar.m_powerUi->pattern->findText(QStringLiteral("foo")), 0);
0742     QCOMPARE(bar.m_powerUi->pattern->count(), 1);
0743 
0744     bar.setSearchPattern(QStringLiteral("bar"));
0745     bar.findNext();
0746 
0747     QCOMPARE(bar.m_powerUi->pattern->findText(QStringLiteral("bar")), 0);
0748     QCOMPARE(bar.m_powerUi->pattern->findText(QStringLiteral("foo")), 1);
0749     QCOMPARE(bar.m_powerUi->pattern->count(), 2);
0750 
0751     KTextEditor::DocumentPrivate doc2;
0752     KTextEditor::ViewPrivate view2(&doc2, nullptr);
0753     KateViewConfig *const config2 = view2.config();
0754     KateSearchBar bar2(true, &view2, config2);
0755 
0756     QCOMPARE(bar2.m_powerUi->pattern->findText(QStringLiteral("bar")), 0);
0757     QCOMPARE(bar2.m_powerUi->pattern->findText(QStringLiteral("foo")), 1);
0758 }
0759 
0760 // Make sure Kate doesn't replace anything outside selection in block mode (see bug 253191)
0761 void SearchBarTest::testReplaceInBlockMode()
0762 {
0763     KTextEditor::DocumentPrivate doc;
0764     KTextEditor::ViewPrivate view(&doc, nullptr);
0765     view.setInputMode(View::NormalInputMode);
0766     KateViewConfig config(&view);
0767 
0768     doc.setText(QStringLiteral("111\n111"));
0769     view.setBlockSelection(true);
0770     view.setSelection(KTextEditor::Range(0, 1, 1, 2));
0771 
0772     KateSearchBar bar(true, &view, &config);
0773 
0774     bar.setSearchPattern(QStringLiteral("1"));
0775     bar.setReplacementPattern(QStringLiteral("2"));
0776     bar.replaceAll();
0777 
0778     QCOMPARE(doc.text(), QStringLiteral("121\n121"));
0779 }
0780 
0781 // Bug 456367 happens when all these conditions are met :
0782 // - block selection mode is checked
0783 // - option "search in the selection only" is not checked
0784 // - some text is selected
0785 //
0786 // In this case it should find/replace all occurrences in the whole document.
0787 void SearchBarTest::testNonEmptyBlockSelectionAndSearchInSelectionOnlyDisabled()
0788 {
0789     KTextEditor::DocumentPrivate doc;
0790     KTextEditor::ViewPrivate view(&doc, nullptr);
0791     KateViewConfig config(&view);
0792 
0793     // Last line is required to reproduce the bug :
0794     doc.setText(QStringLiteral("111\n111\n"));
0795     view.setBlockSelection(true);
0796     view.setSelection(KTextEditor::Range(0, 1, 1, 2));
0797 
0798     KateSearchBar bar(true, &view, &config);
0799 
0800     bar.setSearchPattern(QStringLiteral("1"));
0801     bar.setReplacementPattern(QStringLiteral("2"));
0802     bar.setSelectionOnly(false);
0803     bar.replaceAll();
0804 
0805     // Should replace all occurrences in the whole document.
0806     QCOMPARE(doc.text(), QStringLiteral("222\n222\n"));
0807 }
0808 
0809 void SearchBarTest::testReplaceManyCapturesBug365124()
0810 {
0811     KTextEditor::DocumentPrivate doc;
0812     KTextEditor::ViewPrivate view(&doc, nullptr);
0813     KateViewConfig config(&view);
0814 
0815     doc.setText(QStringLiteral("one two three four five six seven eight nine ten eleven twelve thirteen\n"));
0816 
0817     KateSearchBar bar(true, &view, &config);
0818 
0819     bar.setSearchPattern(QStringLiteral("^(.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*) (.*)$"));
0820     bar.setSearchMode(KateSearchBar::MODE_REGEX);
0821     bar.setReplacementPattern(QStringLiteral("\\{1}::\\2::\\3::\\4::\\5::\\6::\\7::\\8::\\9::\\{10}::\\{11}::\\{12}::\\{13}"));
0822 
0823     bar.replaceAll();
0824 
0825     QCOMPARE(doc.text(), QStringLiteral("one::two::three::four::five::six::seven::eight::nine::ten::eleven::twelve::thirteen\n"));
0826 }
0827 
0828 void SearchBarTest::testReplaceEscapeSequence_data()
0829 {
0830     QTest::addColumn<QString>("textBefore");
0831     QTest::addColumn<QString>("textAfter");
0832     QTest::addColumn<Cursor>("cursorBefore");
0833     QTest::addColumn<Cursor>("cursorAfter");
0834 
0835     testNewRow() << QStringLiteral("a\n") << QStringLiteral("a ") << Cursor(1, 0) << Cursor(0, 2);
0836     testNewRow() << QStringLiteral("a\nb\n") << QStringLiteral("a b ") << Cursor(2, 0) << Cursor(0, 4);
0837     testNewRow() << QStringLiteral("\n\n\n") << QStringLiteral("   ") << Cursor(3, 0) << Cursor(0, 3);
0838 }
0839 
0840 void SearchBarTest::testReplaceEscapeSequence()
0841 {
0842     QFETCH(QString, textBefore);
0843     QFETCH(QString, textAfter);
0844     QFETCH(Cursor, cursorBefore);
0845     QFETCH(Cursor, cursorAfter);
0846 
0847     // testcase for https://bugs.kde.org/show_bug.cgi?id=381080
0848     KTextEditor::DocumentPrivate doc;
0849     KTextEditor::ViewPrivate view(&doc, nullptr);
0850     KateViewConfig config(&view);
0851 
0852     doc.setText(textBefore);
0853     view.setCursorPosition(cursorBefore);
0854     QCOMPARE(view.cursorPosition(), cursorBefore);
0855 
0856     KateSearchBar bar(true, &view, &config);
0857 
0858     bar.setSearchMode(KateSearchBar::MODE_ESCAPE_SEQUENCES);
0859     bar.setSearchPattern(QStringLiteral("\\n"));
0860     bar.setReplacementPattern(QStringLiteral(" "));
0861 
0862     bar.replaceAll();
0863 
0864     QCOMPARE(doc.text(), textAfter);
0865     QCOMPARE(view.cursorPosition(), cursorAfter);
0866 }
0867 
0868 #include "moc_searchbar_test.cpp"