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"