Warning, file /utilities/okteta/kasten/controllers/test/searchtooltest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2023 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "searchtooltest.hpp" 0010 0011 // test object 0012 #include <view/search/searchtool.hpp> 0013 #include <view/search/searchuserqueryable.hpp> 0014 // Okteta Kasten gui 0015 #include <Kasten/Okteta/ByteArrayView> 0016 // Okteta Kasten core 0017 #include <Kasten/Okteta/ByteArrayDocument> 0018 // Okteta Core 0019 #include <Okteta/PieceTableByteArrayModel> 0020 // Qt 0021 #include <QTest> 0022 0023 Q_DECLARE_METATYPE(Okteta::AddressRange) 0024 namespace Okteta { 0025 char* toString(const AddressRange& addressRange) 0026 { 0027 const QByteArray string(QByteArrayLiteral("Okteta::AddressRange(") + 0028 QByteArray::number(addressRange.start()) + '-' + 0029 QByteArray::number(addressRange.end()) + ')'); 0030 return qstrdup(string.data()); 0031 } 0032 } 0033 0034 Q_DECLARE_METATYPE(Kasten::FindDirection) 0035 0036 enum WrapQueryStatus 0037 { 0038 WrapNotQueried, 0039 WrapQueried 0040 }; 0041 Q_DECLARE_METATYPE(WrapQueryStatus) 0042 char* toString(const WrapQueryStatus& status) 0043 { 0044 if (status == WrapNotQueried) { 0045 return qstrdup("WrapNotQueried"); 0046 } 0047 return qstrdup("WrapQueried"); 0048 } 0049 0050 template<int N> QByteArray byteArrayFromLiteral(const char (&data)[N]) 0051 { 0052 return QByteArray::fromRawData(data, N-1); 0053 } 0054 0055 class TestSearchUserQueryable : public Kasten::If::SearchUserQueryable 0056 { 0057 public: 0058 TestSearchUserQueryable() = default; 0059 0060 public: 0061 WrapQueryStatus wrapQueryStatus() const { return mWrapQueryStatus; } 0062 0063 public: // If::SearchUserQueryable API 0064 bool queryContinue(Kasten::FindDirection direction) const override; 0065 0066 private: 0067 mutable WrapQueryStatus mWrapQueryStatus = WrapNotQueried; 0068 }; 0069 0070 bool TestSearchUserQueryable::queryContinue(Kasten::FindDirection direction) const 0071 { 0072 Q_UNUSED(direction); 0073 mWrapQueryStatus = WrapQueried; 0074 return true; 0075 } 0076 0077 /* 0078 Markup format: 0079 "_": cursor, ignored currently when there is a selection -> ViewData.cursorPosition 0080 "[]": selection -> ViewData.selection 0081 "{}": search match result -> ViewData.match 0082 */ 0083 ViewData SearchToolTest::parseToViewData(const QByteArray& viewMarkup) const 0084 { 0085 ViewData result; 0086 0087 bool cursorSeen = false; 0088 bool selectionBeginSeen = false; 0089 bool selectionEndSeen = false; 0090 bool matchBeginSeen = false; 0091 bool matchEndSeen = false; 0092 0093 for (const char c : viewMarkup) { 0094 if (c == '_') { 0095 Q_ASSERT(!cursorSeen); 0096 result.cursorPosition = result.data.size(); 0097 cursorSeen = true; 0098 } else if (c == '[') { 0099 Q_ASSERT(!selectionBeginSeen); 0100 result.selection.setStart(result.data.size()); 0101 selectionBeginSeen = true; 0102 } else if (c == ']') { 0103 Q_ASSERT(selectionBeginSeen && !selectionEndSeen); 0104 result.selection.setEnd(result.data.size() - 1); 0105 selectionEndSeen = true; 0106 } else if (c == '{') { 0107 Q_ASSERT(!matchBeginSeen); 0108 result.match.setStart(result.data.size()); 0109 matchBeginSeen = true; 0110 } else if (c == '}') { 0111 Q_ASSERT(matchBeginSeen && !matchEndSeen); 0112 result.match.setEnd(result.data.size() - 1); 0113 matchEndSeen = true; 0114 } else { 0115 result.data.append(c); 0116 } 0117 } 0118 0119 return result; 0120 } 0121 0122 void SearchToolTest::testParseToViewData_data() 0123 { 0124 QTest::addColumn<QByteArray>("viewMarkup"); 0125 QTest::addColumn<Okteta::Address>("cursorPosition"); 0126 QTest::addColumn<Okteta::AddressRange>("selection"); 0127 QTest::addColumn<Okteta::AddressRange>("match"); 0128 QTest::addColumn<QByteArray>("data"); 0129 0130 QTest::newRow("cursor-begin-selection-none") 0131 << byteArrayFromLiteral("_aaa") 0132 << Okteta::Address(0) 0133 << Okteta::AddressRange() 0134 << Okteta::AddressRange() 0135 << byteArrayFromLiteral("aaa"); 0136 0137 QTest::newRow("cursor-end-selection-none") 0138 << byteArrayFromLiteral("aaa_") 0139 << Okteta::Address(3) 0140 << Okteta::AddressRange() 0141 << Okteta::AddressRange() 0142 << byteArrayFromLiteral("aaa"); 0143 0144 QTest::newRow("cursor-begin-selection-all") 0145 << byteArrayFromLiteral("_[aaa]") 0146 << Okteta::Address(0) 0147 << Okteta::AddressRange(0, 2) 0148 << Okteta::AddressRange() 0149 << byteArrayFromLiteral("aaa"); 0150 0151 QTest::newRow("cursor-end-selection-all") 0152 << byteArrayFromLiteral("[aaa]_") 0153 << Okteta::Address(3) 0154 << Okteta::AddressRange(0, 2) 0155 << Okteta::AddressRange() 0156 << byteArrayFromLiteral("aaa"); 0157 0158 QTest::newRow("cursor-begin-selection-firsthalf") 0159 << byteArrayFromLiteral("_[aaa]bbb") 0160 << Okteta::Address(0) 0161 << Okteta::AddressRange(0, 2) 0162 << Okteta::AddressRange() 0163 << byteArrayFromLiteral("aaabbb"); 0164 0165 QTest::newRow("cursor-end-selection-firsthalf") 0166 << byteArrayFromLiteral("[aaa]_bbb") 0167 << Okteta::Address(3) 0168 << Okteta::AddressRange(0, 2) 0169 << Okteta::AddressRange() 0170 << byteArrayFromLiteral("aaabbb"); 0171 0172 QTest::newRow("cursor-begin-selection-secondhalf") 0173 << byteArrayFromLiteral("{aaa}_[bbb]") 0174 << Okteta::Address(3) 0175 << Okteta::AddressRange(3, 5) 0176 << Okteta::AddressRange(0, 2) 0177 << byteArrayFromLiteral("aaabbb"); 0178 0179 QTest::newRow("cursor-end-selection-secondhalf") 0180 << byteArrayFromLiteral("aaa{[bbb]}_") 0181 << Okteta::Address(6) 0182 << Okteta::AddressRange(3, 5) 0183 << Okteta::AddressRange(3, 5) 0184 << byteArrayFromLiteral("aaabbb"); 0185 } 0186 0187 void SearchToolTest::testParseToViewData() 0188 { 0189 QFETCH(const QByteArray, viewMarkup); 0190 QFETCH(const Okteta::Address, cursorPosition); 0191 QFETCH(const Okteta::AddressRange, selection); 0192 QFETCH(const Okteta::AddressRange, match); 0193 QFETCH(const QByteArray, data); 0194 0195 const ViewData viewData = parseToViewData(viewMarkup); 0196 0197 QCOMPARE(viewData.data, data); 0198 QCOMPARE(viewData.cursorPosition, cursorPosition); 0199 QCOMPARE(viewData.selection, selection); 0200 QCOMPARE(viewData.match, match); 0201 } 0202 0203 void SearchToolTest::testSearch_data() 0204 { 0205 QTest::addColumn<QByteArray>("viewMarkup"); 0206 QTest::addColumn<QByteArray>("searchData"); 0207 QTest::addColumn<Kasten::FindDirection>("direction"); 0208 QTest::addColumn<WrapQueryStatus>("wrapQueryStatus"); 0209 0210 QTest::newRow("cursor-begin-selection-none-forward-single") 0211 << byteArrayFromLiteral("_{a}bbbaaa") 0212 << byteArrayFromLiteral("a") 0213 << Kasten::FindForward 0214 << WrapNotQueried; 0215 0216 QTest::newRow("cursor-begin-selection-none-forward-single-nonlatin") 0217 << byteArrayFromLiteral("_{\xf0}bbb\xf0\xf0\xf0") 0218 << byteArrayFromLiteral("\xf0") 0219 << Kasten::FindForward 0220 << WrapNotQueried; 0221 0222 QTest::newRow("cursor-begin-selection-none-forward-multi") 0223 << byteArrayFromLiteral("_{aaa}bbbaaa") 0224 << byteArrayFromLiteral("aaa") 0225 << Kasten::FindForward 0226 << WrapNotQueried; 0227 0228 QTest::newRow("cursor-begin-selection-none-forward-multi-nonlatin") 0229 << byteArrayFromLiteral("_{aa\xf0}bbbaa\xf0") 0230 << byteArrayFromLiteral("aa\xf0") 0231 << Kasten::FindForward 0232 << WrapNotQueried; 0233 0234 QTest::newRow("cursor-begin-selection-partmatch-forward-multi") 0235 << byteArrayFromLiteral("_{[a]aa}bbbaaa") 0236 << byteArrayFromLiteral("aaa") 0237 << Kasten::FindForward 0238 << WrapNotQueried; 0239 0240 QTest::newRow("cursor-begin-selection-match-forward-single") 0241 << byteArrayFromLiteral("_[a]bbb{a}") 0242 << byteArrayFromLiteral("a") 0243 << Kasten::FindForward 0244 << WrapNotQueried; 0245 0246 QTest::newRow("cursor-begin-selection-match-forward-multi") 0247 << byteArrayFromLiteral("_[aaa]bbb{aaa}") 0248 << byteArrayFromLiteral("aaa") 0249 << Kasten::FindForward 0250 << WrapNotQueried; 0251 0252 QTest::newRow("cursor-begin-selection-match-overlap-forward-multi") 0253 << byteArrayFromLiteral("_[aaa]abb{aaa}") 0254 << byteArrayFromLiteral("aaa") 0255 << Kasten::FindForward 0256 << WrapNotQueried; 0257 0258 QTest::newRow("cursor-begin-selection-match-overlap-duplicate-forward-multi") 0259 << byteArrayFromLiteral("_[aaa]{aaa}aaa") 0260 << byteArrayFromLiteral("aaa") 0261 << Kasten::FindForward 0262 << WrapNotQueried; 0263 0264 QTest::newRow("cursor-beforeend-selection-none-forward-single") 0265 << byteArrayFromLiteral("aaabbb_{a}") 0266 << byteArrayFromLiteral("a") 0267 << Kasten::FindForward 0268 << WrapNotQueried; 0269 0270 QTest::newRow("cursor-beforeend-selection-none-forward-multi") 0271 << byteArrayFromLiteral("aaabbb_{aaa}") 0272 << byteArrayFromLiteral("aaa") 0273 << Kasten::FindForward 0274 << WrapNotQueried; 0275 0276 QTest::newRow("cursor-beforeend-selection-partmatch-forward-multi") 0277 << byteArrayFromLiteral("aaabbb{[aa]_a}") 0278 << byteArrayFromLiteral("aaa") 0279 << Kasten::FindForward 0280 << WrapNotQueried; 0281 0282 QTest::newRow("cursor-beforeend-selection-wrongpartmatch1-forward-multi") 0283 << byteArrayFromLiteral("{aaa}bbbaa[a]_") 0284 << byteArrayFromLiteral("aaa") 0285 << Kasten::FindForward 0286 << WrapQueried; 0287 0288 QTest::newRow("cursor-beforeend-selection-wrongpartmatch2-forward-multi") 0289 << byteArrayFromLiteral("{aaa}bbba[aa]_") 0290 << byteArrayFromLiteral("aaa") 0291 << Kasten::FindForward 0292 << WrapQueried; 0293 0294 QTest::newRow("cursor-end-selection-none-forward-single") 0295 << byteArrayFromLiteral("{a}bbbaaa_") 0296 << byteArrayFromLiteral("a") 0297 << Kasten::FindForward 0298 << WrapQueried; 0299 0300 QTest::newRow("cursor-end-selection-none-forward-multi") 0301 << byteArrayFromLiteral("{aaa}bbbaaa_") 0302 << byteArrayFromLiteral("aaa") 0303 << Kasten::FindForward 0304 << WrapQueried; 0305 0306 QTest::newRow("cursor-end-selection-match-forward-single") 0307 << byteArrayFromLiteral("{a}bbb[a]_") 0308 << byteArrayFromLiteral("a") 0309 << Kasten::FindForward 0310 << WrapQueried; 0311 0312 QTest::newRow("cursor-end-selection-match-forward-multi") 0313 << byteArrayFromLiteral("{aaa}bbb[aaa]_") 0314 << byteArrayFromLiteral("aaa") 0315 << Kasten::FindForward 0316 << WrapQueried; 0317 0318 QTest::newRow("cursor-end-selection-none-backward-single") 0319 << byteArrayFromLiteral("aaabbb{a}_") 0320 << byteArrayFromLiteral("a") 0321 << Kasten::FindBackward 0322 << WrapNotQueried; 0323 0324 QTest::newRow("cursor-end-selection-none-backward-multi") 0325 << byteArrayFromLiteral("aaabbb{aaa}_") 0326 << byteArrayFromLiteral("aaa") 0327 << Kasten::FindBackward 0328 << WrapNotQueried; 0329 0330 QTest::newRow("cursor-end-selection-partmatch-backward-multi") 0331 << byteArrayFromLiteral("aaabbb{aa[a]}_") 0332 << byteArrayFromLiteral("aaa") 0333 << Kasten::FindBackward 0334 << WrapNotQueried; 0335 0336 QTest::newRow("cursor-end-selection-match-backward-single") 0337 << byteArrayFromLiteral("{a}bbb[a]_") 0338 << byteArrayFromLiteral("a") 0339 << Kasten::FindBackward 0340 << WrapNotQueried; 0341 0342 QTest::newRow("cursor-end-selection-match-backward-multi") 0343 << byteArrayFromLiteral("{aaa}bbb[aaa]_") 0344 << byteArrayFromLiteral("aaa") 0345 << Kasten::FindBackward 0346 << WrapNotQueried; 0347 0348 QTest::newRow("cursor-end-selection-match-overlap-backward-multi") 0349 << byteArrayFromLiteral("{aaa}bba[aaa]_") 0350 << byteArrayFromLiteral("aaa") 0351 << Kasten::FindBackward 0352 << WrapNotQueried; 0353 0354 QTest::newRow("cursor-end-selection-match-overlap-duplicate-backward-multi") 0355 << byteArrayFromLiteral("aaa{aaa}[aaa]_") 0356 << byteArrayFromLiteral("aaa") 0357 << Kasten::FindBackward 0358 << WrapNotQueried; 0359 0360 QTest::newRow("cursor-begin-selection-none-backward-single") 0361 << byteArrayFromLiteral("_aaabbb{a}") 0362 << byteArrayFromLiteral("a") 0363 << Kasten::FindBackward 0364 << WrapQueried; 0365 0366 QTest::newRow("cursor-begin-selection-none-backward-single-nonlatin") 0367 << byteArrayFromLiteral("_\xf0\xf0\xf0""bbb{\xf0}") 0368 << byteArrayFromLiteral("\xf0") 0369 << Kasten::FindBackward 0370 << WrapQueried; 0371 0372 QTest::newRow("cursor-begin-selection-none-backward-multi") 0373 << byteArrayFromLiteral("_aaabbb{aaa}") 0374 << byteArrayFromLiteral("aaa") 0375 << Kasten::FindBackward 0376 << WrapQueried; 0377 0378 QTest::newRow("cursor-begin-selection-wrongpartmatch1-backward-multi") 0379 << byteArrayFromLiteral("[a]_aabbb{aaa}") 0380 << byteArrayFromLiteral("aaa") 0381 << Kasten::FindBackward 0382 << WrapQueried; 0383 0384 QTest::newRow("cursor-begin-selection-wrongpartmatch2-backward-multi") 0385 << byteArrayFromLiteral("[aa]_abbb{aaa}") 0386 << byteArrayFromLiteral("aaa") 0387 << Kasten::FindBackward 0388 << WrapQueried; 0389 0390 QTest::newRow("cursor-begin-selection-match-backward-single") 0391 << byteArrayFromLiteral("[a]_bbb{a}") 0392 << byteArrayFromLiteral("a") 0393 << Kasten::FindBackward 0394 << WrapQueried; 0395 0396 QTest::newRow("cursor-begin-selection-match-backward-multi") 0397 << byteArrayFromLiteral("[aaa]_bbb{aaa}") 0398 << byteArrayFromLiteral("aaa") 0399 << Kasten::FindBackward 0400 << WrapQueried; 0401 } 0402 0403 void SearchToolTest::testSearch() 0404 { 0405 QFETCH(const QByteArray, viewMarkup); 0406 QFETCH(const QByteArray, searchData); 0407 QFETCH(const Kasten::FindDirection, direction); 0408 QFETCH(const WrapQueryStatus, wrapQueryStatus); 0409 0410 const ViewData viewData = parseToViewData(viewMarkup); 0411 0412 auto* byteArray = new Okteta::PieceTableByteArrayModel(viewData.data); 0413 auto* document = new Kasten::ByteArrayDocument(byteArray, QStringLiteral("init")); 0414 auto* view = new Kasten::ByteArrayView(document, nullptr); 0415 0416 auto* queryAgent = new TestSearchUserQueryable(); 0417 auto* tool = new Kasten::SearchTool(); 0418 tool->setTargetModel(view); 0419 tool->setSearchData(searchData); 0420 tool->setUserQueryAgent(queryAgent); 0421 0422 if (viewData.selection.isValid()) { 0423 view->setSelection(viewData.selection.start(), viewData.selection.end()); 0424 } else { 0425 view->setCursorPosition(viewData.cursorPosition); 0426 } 0427 0428 const Okteta::AddressRange beforeMatch = view->selection(); 0429 0430 tool->search(direction, true, false); 0431 0432 const Okteta::AddressRange match = view->selection(); 0433 0434 QCOMPARE(match, viewData.match); 0435 QCOMPARE(queryAgent->wrapQueryStatus(), wrapQueryStatus); 0436 0437 delete tool; 0438 delete view; 0439 delete document; 0440 delete queryAgent; 0441 } 0442 0443 QTEST_MAIN(SearchToolTest) 0444 0445 #include "moc_searchtooltest.cpp"