File indexing completed on 2024-10-06 09:42:53

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2004 Arend van Beelen jr. <arend@auton.nl>
0004     SPDX-FileCopyrightText: 2010 David Faure <faure@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kfindtest.h"
0010 
0011 #include <kfind.h>
0012 
0013 #include <QRegularExpression>
0014 #include <QTest>
0015 
0016 #include <assert.h>
0017 
0018 void KFindRecorder::changeText(int line, const QString &text)
0019 {
0020     Q_ASSERT(line < m_text.count());
0021     Q_ASSERT(m_find != nullptr);
0022 
0023     m_line = line;
0024     m_text[line] = text;
0025     m_find->setData(line, text);
0026 }
0027 
0028 KFindRecorder::KFindRecorder(const QStringList &text)
0029     : QObject(nullptr)
0030     , m_text(text)
0031     , m_line(0)
0032 {
0033 }
0034 
0035 KFindRecorder::~KFindRecorder()
0036 {
0037 }
0038 
0039 void KFindRecorder::find(const QString &pattern, long options)
0040 {
0041     m_find.reset(new KFind(pattern, options, nullptr));
0042     // Prevent dialogs from popping up
0043     m_find->closeFindNextDialog();
0044 
0045 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 81)
0046     connect(m_find.get(), qOverload<const QString &, int, int>(&KFind::highlight), this, qOverload<const QString &, int, int>(&KFindRecorder::slotHighlight));
0047 
0048     connect(m_find.get(), qOverload<int, int, int>(&KFind::highlight), this, qOverload<int, int, int>(&KFindRecorder::slotHighlight));
0049 #else
0050     connect(m_find.get(), &KFind::textFound, this, [this](const QString &text, int matchingIndex, int matchedLength) {
0051         slotHighlight(text, matchingIndex, matchedLength);
0052     });
0053 
0054     connect(m_find.get(), &KFind::textFoundAtId, this, [this](int id, int matchingIndex, int matchedLength) {
0055         slotHighlight(id, matchingIndex, matchedLength);
0056     });
0057 #endif
0058 
0059     m_line = 0;
0060     KFind::Result result = KFind::NoMatch;
0061     do {
0062         if (options & KFind::FindIncremental) {
0063             m_find->setData(m_line, m_text[m_line]);
0064         } else {
0065             m_find->setData(m_text[m_line]);
0066         }
0067 
0068         m_line++;
0069 
0070         result = m_find->find();
0071     } while (result == KFind::NoMatch && m_line < m_text.count());
0072 }
0073 
0074 bool KFindRecorder::findNext(const QString &pattern)
0075 {
0076     Q_ASSERT(m_find != nullptr);
0077 
0078     if (!pattern.isNull()) {
0079         m_find->setPattern(pattern);
0080     }
0081 
0082     KFind::Result result = KFind::NoMatch;
0083     do {
0084         // qDebug() << "m_line: " << m_line;
0085 
0086         result = m_find->find();
0087 
0088         if (result == KFind::NoMatch && m_line < m_text.count()) {
0089             // qDebug() << "incrementing m_line...";
0090             if (m_find->options() & KFind::FindIncremental) {
0091                 m_find->setData(m_line, m_text[m_line]);
0092             } else {
0093                 m_find->setData(m_text[m_line]);
0094             }
0095 
0096             m_line++;
0097         }
0098     } while (result == KFind::NoMatch && m_line < m_text.count());
0099     // qDebug() << "find next completed" << m_line;
0100 
0101     return result != KFind::NoMatch;
0102 }
0103 
0104 void KFindRecorder::slotHighlight(const QString &text, int index, int matchedLength)
0105 {
0106     m_hits.append(QLatin1String("line: \"") + text + QLatin1String("\", index: ") + QString::number(index) + QLatin1String(", length: ")
0107                   + QString::number(matchedLength) + QLatin1Char('\n'));
0108 }
0109 
0110 void KFindRecorder::slotHighlight(int id, int index, int matchedLength)
0111 {
0112     m_hits.append(QLatin1String("line: \"") + m_text[id] + QLatin1String("\", index: ") + QString::number(index) + QLatin1String(", length: ")
0113                   + QString::number(matchedLength) + QLatin1Char('\n'));
0114 }
0115 
0116 ////
0117 
0118 TestKFind::TestKFind()
0119     : QObject()
0120 {
0121     m_text = QLatin1String("This file is part of the KDE project.\n") + QLatin1String("This library is free software; you can redistribute it and/or\n")
0122         + QLatin1String("modify it under the terms of the GNU Library General Public\n")
0123         + QLatin1String("License version 2, as published by the Free Software Foundation.\n") + QLatin1Char('\n')
0124         + QLatin1String("    This library is distributed in the hope that it will be useful,\n")
0125         + QLatin1String("    but WITHOUT ANY WARRANTY; without even the implied warranty of\n")
0126         + QLatin1String("    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n")
0127         + QLatin1String("    Library General Public License for more details.\n") + QLatin1Char('\n')
0128         + QLatin1String("    You should have received a copy of the GNU Library General Public License\n")
0129         + QLatin1String("    along with this library; see the file COPYING.LIB.  If not, write to\n")
0130         + QLatin1String("    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n") + QLatin1String("    Boston, MA 02110-1301, USA.\n");
0131 }
0132 
0133 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 70)
0134 void TestKFind::testStaticFindString_data()
0135 {
0136     // Tests for the core method "static KFind::find"
0137     QTest::addColumn<QString>("text");
0138     QTest::addColumn<QString>("pattern");
0139     QTest::addColumn<int>("startIndex");
0140     QTest::addColumn<int>("options");
0141     QTest::addColumn<int>("expectedResult");
0142     QTest::addColumn<int>("expectedMatchedLength");
0143 
0144     /* clang-format off */
0145     QTest::newRow("simple (0)") << "abc" << "a" << 0 << 0 << 0 << 1;
0146     QTest::newRow("simple (1)") << "abc" << "b" << 0 << 0 << 1 << 1;
0147     QTest::newRow("not found") << "abca" << "ba" << 0 << 0 << -1 << 0;
0148     QTest::newRow("from index") << "abc bc" << "b" << 3 << 0 << 4 << 1;
0149     QTest::newRow("from exact index") << "abc bc" << "b" << 4 << 0 << 4 << 1;
0150     QTest::newRow("past index (not found)") << "abc bc" << "b" << 5 << 0 << -1 << 0;
0151     QTest::newRow("dot") << "ab." << "b." << 0 << 0 << 1 << 2;
0152     QTest::newRow("^should fail") << "text" << "^tex" << 0 << 0 << -1 << 0;
0153     QTest::newRow("multiline with \\n") << "foo\nbar" << "o\nb" << 0 << 0 << 2 << 3;
0154     QTest::newRow("whole words ok") << "abc bcbc bc bmore be" << "bc" << 0 << int(KFind::WholeWordsOnly) << 9 << 2;
0155     QTest::newRow("whole words not found") << "abab abx" << "ab" << 0 << int(KFind::WholeWordsOnly) << -1 << 0;
0156     QTest::newRow("whole words not found (_)") << "abab ab_" << "ab" << 0 << int(KFind::WholeWordsOnly) << -1 << 0;
0157     QTest::newRow("whole words ok (.)") << "ab." << "ab" << 0 << int(KFind::WholeWordsOnly) << 0 << 2;
0158     QTest::newRow("backwards") << "abc bcbc8bc" << "bc" << 10 << int(KFind::FindBackwards) << 9 << 2;
0159     QTest::newRow("backwards again") << "abc bcbc8bc" << "bc" << 8 << int(KFind::FindBackwards) << 6 << 2;
0160     QTest::newRow("backwards 2") << "abc bcbc8bc" << "bc" << 5 << int(KFind::FindBackwards) << 4 << 2;
0161     QTest::newRow("backwards 3") << "abc bcbc8bc" << "bc" << 3 << int(KFind::FindBackwards) << 1 << 2;
0162     QTest::newRow("empty (0)") << "a" << "" << 0 << int(0) << 0 << 0;
0163     QTest::newRow("empty (1)") << "a" << "" << 1 << int(0) << 1 << 0; // kreplacetest testReplaceBlankSearch relies on this
0164     QTest::newRow("at end, not found") << "a" << "b" << 1 << int(0) << -1 << 0; // just for catching the while(index<text.length()) bug
0165     QTest::newRow("back, not found") << "a" << "b" << 0 << int(KFind::FindBackwards) << -1 << 0;
0166     QTest::newRow("back, at begin, found") << "a" << "a" << 0 << int(KFind::FindBackwards) << 0 << 1;
0167     QTest::newRow("back, at end, found") << "a" << "a" << 1 << int(KFind::FindBackwards) << 0 << 1;
0168     QTest::newRow("back, text shorter than pattern") << "a" << "abcd" << 0 << int(KFind::FindBackwards) << -1 << 0;
0169     /* clang-format on */
0170 }
0171 #endif
0172 
0173 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 70)
0174 void TestKFind::testStaticFindString()
0175 {
0176     // Tests for the core method "static KFind::find(text, regexp)"
0177     QFETCH(QString, text);
0178     QFETCH(QString, pattern);
0179     QFETCH(int, startIndex);
0180     QFETCH(int, options);
0181     QFETCH(int, expectedResult);
0182     QFETCH(int, expectedMatchedLength);
0183 
0184     int matchedLength;
0185     const int result = KFind::find(text, pattern, startIndex, options, &matchedLength);
0186     QCOMPARE(result, expectedResult);
0187     QCOMPARE(matchedLength, expectedMatchedLength);
0188 }
0189 #endif
0190 
0191 void TestKFind::testStaticFindRegexp_data()
0192 {
0193     // Tests for the core method "static KFind::find"
0194     QTest::addColumn<QString>("text");
0195     QTest::addColumn<QString>("pattern");
0196     QTest::addColumn<int>("startIndex");
0197     QTest::addColumn<int>("options");
0198     QTest::addColumn<int>("expectedResult");
0199     QTest::addColumn<int>("expectedMatchedLength");
0200 
0201     /* clang-format off */
0202     QTest::newRow("simple (0)") << "abc" << "a" << 0 << 0 << 0 << 1;
0203     QTest::newRow("simple (1)") << "abc" << "b" << 0 << 0 << 1 << 1;
0204     QTest::newRow("not found") << "abca" << "ba" << 0 << 0 << -1 << 0;
0205     QTest::newRow("from index") << "abc bc" << "b" << 3 << 0 << 4 << 1;
0206     QTest::newRow("from exact index") << "abc bc" << "b" << 4 << 0 << 4 << 1;
0207     QTest::newRow("past index (not found)") << "abc bc" << "b" << 5 << 0 << -1 << 0;
0208     QTest::newRow("dot") << "abc" << "b." << 0 << 0 << 1 << 2;
0209     QTest::newRow("^simple") << "text" << "^tex" << 0 << 0 << 0 << 3;
0210     QTest::newRow("^multiline first") << "foo\nbar" << "^f" << 0 << 0 << 0 << 1;
0211     QTest::newRow("^multiline last") << "foo\nbar" << "^bar" << 0 << 0 << 4 << 3;
0212     QTest::newRow("^multiline with index") << "boo\nbar" << "^b" << 1 << 0 << 4 << 1;
0213     QTest::newRow("simple$") << "text" << "xt$" << 0 << 0 << 2 << 2;
0214     QTest::newRow("$ backwards") << "text" << "xt$" << 4 << int(KFind::FindBackwards) << 2 << 2;
0215     QTest::newRow("multiline$") << "foo\nbar" << "oo$" << 0 << 0 << 1 << 2;
0216     QTest::newRow("multiline$ intermediary line") << "foo\nbar\nagain bar" << "r$" << 0 << 0 << 6 << 1;
0217     QTest::newRow("multiline$ with index, last line") << "foo\nbar\nagain bar" << "r$" << 7 << 0 << 16 << 1;
0218     QTest::newRow("multiline$ backwards") << "foo\nbar" << "oo$" << 7 << int(KFind::FindBackwards) << 1 << 2;
0219     QTest::newRow("multiline with \\n") << "foo\nbar" << "o\nb" << 0 << 0 << 2 << 3;
0220     QTest::newRow("whole words ok") << "abc bcbc bc bmore be" << "b." << 0 << int(KFind::WholeWordsOnly) << 9 << 2;
0221     QTest::newRow("whole words not found") << "abab abx" << "ab" << 0 << int(KFind::WholeWordsOnly) << -1 << 0;
0222     QTest::newRow("whole words not found (_)") << "abab ab_" << "ab" << 0 << int(KFind::WholeWordsOnly) << -1 << 0;
0223     QTest::newRow("whole words ok (.)") << "ab." << "ab" << 0 << int(KFind::WholeWordsOnly) << 0 << 2;
0224     QTest::newRow("backwards") << "abc bcbc bc" << "b." << 10 << int(KFind::FindBackwards) << 9 << 2;
0225     QTest::newRow("empty (0)") << "a" << "" << 0 << int(0) << 0 << 0;
0226     QTest::newRow("empty (1)") << "a" << "" << 1 << int(0) << 1 << 0; // kreplacetest testReplaceBlankSearch relies on this
0227     QTest::newRow("at end, not found") << "a" << "b" << 1 << int(0) << -1 << 0; // just for catching the while(index<text.length()) bug
0228     QTest::newRow("back, not found") << "a" << "b" << 0 << int(KFind::FindBackwards) << -1 << 0;
0229     QTest::newRow("back, at begin, found") << "a" << "a" << 0 << int(KFind::FindBackwards) << 0 << 1;
0230     QTest::newRow("back, at end, found") << "a" << "a" << 1 << int(KFind::FindBackwards) << 0 << 1;
0231     QTest::newRow("back, text shorter than pattern") << "a" << "abcd" << 0 << int(KFind::FindBackwards) << -1 << 0;
0232     /* clang-format on */
0233 }
0234 
0235 void TestKFind::testStaticFindRegexp()
0236 {
0237     // Tests for the core method "static KFind::find(text, regexp)"
0238     QFETCH(QString, text);
0239     QFETCH(QString, pattern);
0240     QFETCH(int, startIndex);
0241     QFETCH(int, options);
0242     QFETCH(int, expectedResult);
0243     QFETCH(int, expectedMatchedLength);
0244 
0245     int matchedLength = 0;
0246 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 70)
0247     const int result = KFind::find(text, QRegExp(pattern), startIndex, options, &matchedLength);
0248     QCOMPARE(result, expectedResult);
0249     QCOMPARE(matchedLength, expectedMatchedLength);
0250 
0251     matchedLength = 0;
0252 #endif
0253     const int result2 = KFind::find(text, pattern, startIndex, options | KFind::RegularExpression, &matchedLength, nullptr);
0254     QCOMPARE(result2, expectedResult);
0255     QCOMPARE(matchedLength, expectedMatchedLength);
0256 }
0257 
0258 void TestKFind::testRegexpUnicode_data()
0259 {
0260     QTest::addColumn<QString>("text");
0261     QTest::addColumn<QString>("pattern");
0262     QTest::addColumn<int>("startIndex");
0263     QTest::addColumn<int>("options");
0264     QTest::addColumn<int>("expectedResult");
0265     QTest::addColumn<int>("expectedMatchedLength");
0266 
0267     /* clang-format off */
0268     // Test matching with Unicode properties in QRegularExpression
0269     QTest::newRow("unicode-word-boundary") << "aoé" << "\\b" << 1 << 0 << 3 << 0;
0270     QTest::newRow("unicode-word-char") << "aoé" << "\\w$" << 0 << 0 << 2 << 1;
0271     QTest::newRow("unicode-non-word-char") << "aoé" << "\\W" << 0 << 0 << -1 << 0;
0272     /* clang-format on */
0273 }
0274 
0275 void TestKFind::testRegexpUnicode()
0276 {
0277     // Tests for the core method "static KFind::find(text, regexp)"
0278     QFETCH(QString, text);
0279     QFETCH(QString, pattern);
0280     QFETCH(int, startIndex);
0281     QFETCH(int, options);
0282     QFETCH(int, expectedResult);
0283     QFETCH(int, expectedMatchedLength);
0284 
0285     int matchedLength = 0;
0286 
0287     const int result = KFind::find(text, pattern, startIndex, options | KFind::RegularExpression, &matchedLength, nullptr);
0288     QCOMPARE(result, expectedResult);
0289     QCOMPARE(matchedLength, expectedMatchedLength);
0290 }
0291 
0292 void TestKFind::testSimpleSearch()
0293 {
0294     // first we do a simple text searching the text and doing a few find nexts
0295     KFindRecorder test(m_text.split(QLatin1Char('\n')));
0296     test.find(QStringLiteral("This"), 0);
0297     while (test.findNext()) { }
0298 
0299     const QString output1 = QLatin1String("line: \"This file is part of the KDE project.\", index: 0, length: 4\n")
0300         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 0, length: 4\n")
0301         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 4, length: 4\n")
0302         + QLatin1String("line: \"    along with this library; see the file COPYING.LIB.  If not, write to\", index: 15, length: 4\n");
0303 
0304     QCOMPARE(test.hits().join(QString()), output1);
0305 }
0306 
0307 void TestKFind::testSimpleRegexp()
0308 {
0309     KFindRecorder test(m_text.split(QLatin1Char('\n')));
0310     test.find(QStringLiteral("W.R+ANT[YZ]"), KFind::RegularExpression | KFind::CaseSensitive);
0311     while (test.findNext()) { }
0312     const QString output = QStringLiteral("line: \"    but WITHOUT ANY WARRANTY; without even the implied warranty of\", index: 20, length: 8\n");
0313     QCOMPARE(test.hits().join(QString()), output);
0314 }
0315 
0316 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 70)
0317 void TestKFind::testLineBeginRegexp()
0318 {
0319     // Let's see what QRegExp can do on a big text (like in KTextEdit)
0320     {
0321         const QString foobar = QStringLiteral("foo\nbar");
0322         const int idx = foobar.indexOf(QRegExp(QStringLiteral("^bar")));
0323         QCOMPARE(idx, -1); // it doesn't find it. No /m support, as they say. Too bad.
0324     }
0325 
0326     // If we split, it works, but then looking for "foo\nbar" won't work...
0327     KFindRecorder test(m_text.split(QLatin1Char('\n')));
0328     test.find(QStringLiteral("^License"), KFind::RegularExpression);
0329     while (test.findNext()) { }
0330     const QString output = QStringLiteral("line: \"License version 2, as published by the Free Software Foundation.\", index: 0, length: 7\n");
0331     QCOMPARE(test.hits().join(QString()), output);
0332 }
0333 #endif
0334 
0335 void TestKFind::testLineBeginRegularExpression()
0336 {
0337     int matchedLength;
0338     QRegularExpressionMatch match;
0339     KFind::find(m_text, QStringLiteral("^License.+"), 0, KFind::RegularExpression, &matchedLength, &match);
0340     QCOMPARE(match.captured(0), QStringLiteral("License version 2, as published by the Free Software Foundation."));
0341 }
0342 
0343 void TestKFind::testFindIncremental()
0344 {
0345     // FindIncremental with static contents...
0346 
0347     KFindRecorder test(m_text.split(QLatin1Char('\n')));
0348     test.find(QString(), KFind::FindIncremental);
0349     test.findNext(QStringLiteral("i"));
0350     test.findNext(QStringLiteral("is"));
0351     test.findNext(QStringLiteral("ist"));
0352     test.findNext();
0353     test.findNext(QStringLiteral("istri"));
0354     test.findNext(QStringLiteral("istr"));
0355     test.findNext(QStringLiteral("ist"));
0356     test.findNext(QStringLiteral("is"));
0357     test.findNext(QStringLiteral("W"));
0358     test.findNext(QStringLiteral("WA"));
0359     test.findNext(QStringLiteral("WARRANTY"));
0360     test.findNext(QStringLiteral("Free"));
0361     test.findNext(QStringLiteral("Software Foundation"));
0362 
0363     const QString output2 = QLatin1String("line: \"This file is part of the KDE project.\", index: 0, length: 0\n")
0364         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 1\n")
0365         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 2\n")
0366         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 42, length: 3\n")
0367         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 3\n")
0368         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 5\n")
0369         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 4\n")
0370         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 3\n")
0371         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 2\n")
0372         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 25, length: 1\n")
0373         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 25, length: 2\n")
0374         + QLatin1String("line: \"    but WITHOUT ANY WARRANTY; without even the implied warranty of\", index: 20, length: 8\n")
0375         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 16, length: 4\n")
0376         + QLatin1String("line: \"License version 2, as published by the Free Software Foundation.\", index: 44, length: 19\n");
0377 
0378     QCOMPARE(test.hits().join(QString()), output2);
0379 }
0380 
0381 void TestKFind::testFindIncrementalDynamic()
0382 {
0383     // Now do that again but with pages that change between searches
0384     KFindRecorder test(m_text.split(QLatin1Char('\n')));
0385 
0386     test.find(QString(), KFind::FindIncremental);
0387     test.findNext(QStringLiteral("i"));
0388     test.findNext(QStringLiteral("is"));
0389     test.findNext(QStringLiteral("ist"));
0390     test.findNext(QStringLiteral("istr"));
0391     test.findNext();
0392     test.changeText(1, QStringLiteral("The second line now looks a whole lot different."));
0393     test.findNext(QStringLiteral("istri"));
0394     test.findNext(QStringLiteral("istr"));
0395     test.findNext(QStringLiteral("ist"));
0396     test.findNext(QStringLiteral("is"));
0397     test.findNext(QStringLiteral("i"));
0398     test.findNext(QStringLiteral("W"));
0399     test.findNext(QStringLiteral("WA"));
0400     test.findNext(QStringLiteral("WARRANTY"));
0401     test.changeText(6, QStringLiteral("    but WITHOUT ANY xxxx; without even the implied warranty of"));
0402     test.findNext(QStringLiteral("WARRAN"));
0403     test.findNext(QStringLiteral("Free"));
0404     test.findNext(QStringLiteral("Software Foundation"));
0405 
0406     const QString output3 = QLatin1String("line: \"This file is part of the KDE project.\", index: 0, length: 0\n")
0407         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 1\n")
0408         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 2\n")
0409         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 42, length: 3\n")
0410         + QLatin1String("line: \"This library is free software; you can redistribute it and/or\", index: 42, length: 4\n")
0411         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 4\n")
0412         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 5\n")
0413         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 4\n")
0414         + QLatin1String("line: \"    This library is distributed in the hope that it will be useful,\", index: 21, length: 3\n")
0415         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 2\n")
0416         + QLatin1String("line: \"This file is part of the KDE project.\", index: 2, length: 1\n")
0417         + QLatin1String("line: \"The second line now looks a whole lot different.\", index: 18, length: 1\n")
0418         + QLatin1String("line: \"License version 2, as published by the Free Software Foundation.\", index: 48, length: 2\n")
0419         + QLatin1String("line: \"    but WITHOUT ANY WARRANTY; without even the implied warranty of\", index: 20, length: 8\n")
0420         + QLatin1String("line: \"    but WITHOUT ANY xxxx; without even the implied warranty of\", index: 51, length: 6\n")
0421         + QLatin1String("line: \"License version 2, as published by the Free Software Foundation.\", index: 39, length: 4\n")
0422         + QLatin1String("line: \"License version 2, as published by the Free Software Foundation.\", index: 44, length: 19\n");
0423 
0424     QCOMPARE(test.hits().join(QString()), output3);
0425 }
0426 
0427 QTEST_MAIN(TestKFind)
0428 
0429 #include "moc_kfindtest.cpp"