Warning, file /utilities/okteta/kasten/controllers/test/replacejobtest.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: 2019 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 "replacejobtest.hpp" 0010 0011 // test object 0012 #include "../view/replace/replacejob.hpp" 0013 #include "../view/replace/replaceuserqueryable.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 #include <QSignalSpy> 0023 0024 0025 Q_DECLARE_METATYPE(QVector<Kasten::ReplaceBehaviour>) 0026 0027 class TestReplaceUserQueryAgent : public QObject 0028 , public Kasten::If::ReplaceUserQueryable 0029 { 0030 Q_OBJECT 0031 Q_INTERFACES( 0032 Kasten::If::ReplaceUserQueryable 0033 ) 0034 0035 public: 0036 explicit TestReplaceUserQueryAgent(const QVector<Kasten::ReplaceBehaviour>& replies) 0037 : m_replies(replies) 0038 {} 0039 0040 public: 0041 int noOfReplacements() const { return m_noOfReplacements; } 0042 0043 public: // If::ReplaceUserQueryable API 0044 void queryContinue(Kasten::FindDirection direction, int noOfReplacements) override; 0045 void queryReplaceCurrent() override; 0046 0047 Q_SIGNALS: // If::ReplaceUserQueryable API 0048 void queryContinueFinished(bool result) override; 0049 void queryReplaceCurrentFinished(Kasten::ReplaceBehaviour result) override; 0050 0051 private: 0052 QVector<Kasten::ReplaceBehaviour> m_replies; 0053 int m_noOfReplacements = 0; 0054 }; 0055 0056 void TestReplaceUserQueryAgent::queryContinue(Kasten::FindDirection direction, int noOfReplacements) 0057 { 0058 Q_UNUSED(direction); 0059 m_noOfReplacements = noOfReplacements; 0060 emit queryContinueFinished(true); 0061 } 0062 0063 void TestReplaceUserQueryAgent::queryReplaceCurrent() 0064 { 0065 Q_ASSERT(!m_replies.isEmpty()); 0066 emit queryReplaceCurrentFinished(m_replies.takeFirst()); 0067 } 0068 0069 0070 void ReplaceJobTest::compare(const Okteta::PieceTableByteArrayModel* byteArrayModel, 0071 const QByteArray& expectedData) 0072 { 0073 QByteArray actualData(byteArrayModel->size(), 'd'); 0074 byteArrayModel->copyTo(reinterpret_cast<Okteta::Byte*>(actualData.data()), 0, byteArrayModel->size()); 0075 0076 QCOMPARE(actualData, expectedData); 0077 } 0078 0079 template<int N> QByteArray byteArrayFromLiteral(const char (&data)[N]) 0080 { 0081 return QByteArray::fromRawData(data, N-1); 0082 } 0083 0084 void ReplaceJobTest::init() 0085 { 0086 qRegisterMetaType<Okteta::AddressRange>("Okteta::AddressRange"); 0087 } 0088 0089 void ReplaceJobTest::testReplace_data() 0090 { 0091 QTest::addColumn<QByteArray>("originalData"); 0092 QTest::addColumn<QByteArray>("searchData"); 0093 QTest::addColumn<QByteArray>("replaceData"); 0094 QTest::addColumn<QByteArray>("expectedData"); 0095 QTest::addColumn<int>("expectedReplacementCount"); 0096 QTest::addColumn<Okteta::Address>("startIndex"); 0097 QTest::addColumn<bool>("backwards"); 0098 QTest::addColumn<QVector<Kasten::ReplaceBehaviour>>("replies"); 0099 0100 const struct { 0101 QString name; 0102 QByteArray originalData; 0103 QByteArray expectedData; 0104 int expectedReplacementCount; 0105 QByteArray searchData; 0106 QByteArray replaceData; 0107 } 0108 testData[] = {{ 0109 QStringLiteral("full-1-1"), 0110 byteArrayFromLiteral("11111111"), 0111 byteArrayFromLiteral("22222222"), 0112 8, 0113 byteArrayFromLiteral("1"), 0114 byteArrayFromLiteral("2") 0115 }, { 0116 QStringLiteral("full-1-2"), 0117 byteArrayFromLiteral("11111111"), 0118 byteArrayFromLiteral("2323232323232323"), 0119 8, 0120 byteArrayFromLiteral("1"), 0121 byteArrayFromLiteral("23"), 0122 }, { 0123 QStringLiteral("full-2-1"), 0124 byteArrayFromLiteral("1313131313131313"), 0125 byteArrayFromLiteral("22222222"), 0126 8, 0127 byteArrayFromLiteral("13"), 0128 byteArrayFromLiteral("2") 0129 }, { 0130 QStringLiteral("partial-1-1"), 0131 byteArrayFromLiteral("01001000"), 0132 byteArrayFromLiteral("02002000"), 0133 2, 0134 byteArrayFromLiteral("1"), 0135 byteArrayFromLiteral("2") 0136 }, { 0137 QStringLiteral("partial-1-2"), 0138 byteArrayFromLiteral("01001000"), 0139 byteArrayFromLiteral("0230023000"), 0140 2, 0141 byteArrayFromLiteral("1"), 0142 byteArrayFromLiteral("23"), 0143 }, { 0144 QStringLiteral("partial-2-1"), 0145 byteArrayFromLiteral("0130013000"), 0146 byteArrayFromLiteral("02002000"), 0147 2, 0148 byteArrayFromLiteral("13"), 0149 byteArrayFromLiteral("2") 0150 }}; 0151 0152 for (auto& data : testData) { 0153 QTest::newRow(QString(data.name+QLatin1String("-forward-frombegin")).toLatin1().constData()) 0154 << data.originalData << data.searchData 0155 << data.replaceData << data.expectedData << data.expectedReplacementCount 0156 << Okteta::Address(0) << false << QVector<Kasten::ReplaceBehaviour>(); 0157 QTest::newRow(QString(data.name+QLatin1String("-backward-fromend")).toLatin1().constData()) 0158 << data.originalData << data.searchData 0159 << data.replaceData << data.expectedData << data.expectedReplacementCount 0160 << Okteta::Address(data.originalData.length()) << true << QVector<Kasten::ReplaceBehaviour>(); 0161 QTest::newRow(QString(data.name+QLatin1String("-forward-frommiddle")).toLatin1().constData()) 0162 << data.originalData << data.searchData 0163 << data.replaceData << data.expectedData << data.expectedReplacementCount 0164 << Okteta::Address(4) << false << QVector<Kasten::ReplaceBehaviour>(); 0165 QTest::newRow(QString(data.name+QLatin1String("-backward-frommiddle")).toLatin1().constData()) 0166 << data.originalData << data.searchData 0167 << data.replaceData << data.expectedData << data.expectedReplacementCount 0168 << Okteta::Address(3) << true << QVector<Kasten::ReplaceBehaviour>(); 0169 } 0170 0171 { 0172 const QByteArray originalData = byteArrayFromLiteral("11111111"); 0173 const QByteArray expectedData = byteArrayFromLiteral("22222222"); 0174 const int expectedReplacementCount = 8; 0175 const QByteArray searchData = byteArrayFromLiteral("1"); 0176 const QByteArray replaceData = byteArrayFromLiteral("2"); 0177 0178 QTest::newRow("replies-forward-replaceall") 0179 << originalData << searchData 0180 << replaceData << expectedData << expectedReplacementCount 0181 << Okteta::Address(0) << false 0182 << QVector<Kasten::ReplaceBehaviour>{ Kasten::ReplaceAll }; 0183 0184 QTest::newRow("replies-forward-replace8x") 0185 << originalData << searchData 0186 << replaceData << expectedData << expectedReplacementCount 0187 << Okteta::Address(0) << false 0188 << QVector<Kasten::ReplaceBehaviour>(8, Kasten::ReplaceCurrent); 0189 0190 QTest::newRow("replies-forward-replace3xreplaceall") 0191 << originalData << searchData 0192 << replaceData << expectedData << expectedReplacementCount 0193 << Okteta::Address(0) << false 0194 << QVector<Kasten::ReplaceBehaviour>{Kasten::ReplaceCurrent, Kasten::ReplaceCurrent, Kasten::ReplaceCurrent, Kasten::ReplaceAll }; 0195 } 0196 0197 { 0198 QTest::newRow("replies-forward-replaceskipalternate") 0199 << byteArrayFromLiteral("11111111") << byteArrayFromLiteral("1") 0200 << byteArrayFromLiteral("2") << byteArrayFromLiteral("12121212") << 4 0201 << Okteta::Address(0) << false 0202 << QVector<Kasten::ReplaceBehaviour>{ Kasten::SkipCurrent, Kasten::ReplaceCurrent, 0203 Kasten::SkipCurrent, Kasten::ReplaceCurrent, Kasten::SkipCurrent, Kasten::ReplaceCurrent, 0204 Kasten::SkipCurrent, Kasten::ReplaceCurrent }; 0205 } 0206 0207 { 0208 const QByteArray originalData = byteArrayFromLiteral("11111111"); 0209 const QByteArray expectedData = byteArrayFromLiteral("11111111"); 0210 const int expectedReplacementCount = 0; 0211 const QByteArray searchData = byteArrayFromLiteral("1"); 0212 const QByteArray replaceData = byteArrayFromLiteral("2"); 0213 0214 QTest::newRow("replies-forward-cancel") 0215 << originalData << searchData 0216 << replaceData << expectedData << expectedReplacementCount 0217 << Okteta::Address(0) << false 0218 << QVector<Kasten::ReplaceBehaviour>{ Kasten::CancelReplacing }; 0219 0220 QTest::newRow("replies-forward-skip8x") 0221 << originalData << searchData 0222 << replaceData << expectedData << expectedReplacementCount 0223 << Okteta::Address(0) << false 0224 << QVector<Kasten::ReplaceBehaviour>(8, Kasten::SkipCurrent); 0225 0226 QTest::newRow("replies-forward-skip3xcancel") 0227 << originalData << searchData 0228 << replaceData << expectedData << expectedReplacementCount 0229 << Okteta::Address(0) << false 0230 << QVector<Kasten::ReplaceBehaviour>{Kasten::SkipCurrent, Kasten::SkipCurrent, Kasten::SkipCurrent, Kasten::CancelReplacing }; 0231 } 0232 } 0233 0234 void ReplaceJobTest::testReplace() 0235 { 0236 QFETCH(Okteta::Address, startIndex); 0237 QFETCH(bool, backwards); 0238 QFETCH(QByteArray, originalData); 0239 QFETCH(QByteArray, searchData); 0240 QFETCH(QByteArray, replaceData); 0241 QFETCH(QByteArray, expectedData); 0242 QFETCH(int, expectedReplacementCount); 0243 QFETCH(QVector<Kasten::ReplaceBehaviour>, replies); 0244 0245 TestReplaceUserQueryAgent* queryAgent = replies.isEmpty() ? nullptr : new TestReplaceUserQueryAgent(replies); 0246 0247 auto byteArray = new Okteta::PieceTableByteArrayModel(originalData); 0248 auto document = new Kasten::ByteArrayDocument(byteArray, QStringLiteral("init")); 0249 auto view = new Kasten::ByteArrayView(document, nullptr); 0250 0251 Okteta::Address replaceFirstIndex; 0252 Okteta::Address replaceLastIndex; 0253 if (!backwards && startIndex > 0) { 0254 replaceFirstIndex = startIndex; 0255 replaceLastIndex = startIndex - 1; 0256 } else if (backwards && startIndex < byteArray->size()) { 0257 replaceFirstIndex = startIndex + 1; 0258 replaceLastIndex = startIndex; 0259 } else { 0260 replaceFirstIndex = 0; 0261 replaceLastIndex = byteArray->size() - 1; 0262 } 0263 0264 auto job = new Kasten::ReplaceJob(view, byteArray, queryAgent); 0265 job->setSearchData(searchData); 0266 job->setReplaceData(replaceData); 0267 job->setRange(replaceFirstIndex, replaceLastIndex, 0268 backwards ? Kasten::FindBackward : Kasten::FindForward); 0269 job->setDoPrompt(queryAgent != nullptr); 0270 0271 QSignalSpy finishedSpy(job, &Kasten::ReplaceJob::finished); 0272 0273 job->start(); 0274 if (finishedSpy.count() == 0) { 0275 QVERIFY(finishedSpy.wait()); 0276 } 0277 0278 QCOMPARE(finishedSpy.count(), 1); 0279 0280 compare(byteArray, expectedData); 0281 0282 const int beforeWrap = queryAgent ? queryAgent->noOfReplacements() : 0; 0283 const QList<QVariant> arguments = finishedSpy.takeFirst(); 0284 QCOMPARE(arguments.at(0).toBool(), true); 0285 QCOMPARE(arguments.at(1).toInt() + beforeWrap, expectedReplacementCount); 0286 0287 delete job; 0288 delete view; 0289 delete document; 0290 0291 delete queryAgent; 0292 } 0293 0294 QTEST_MAIN(ReplaceJobTest) 0295 0296 #include "replacejobtest.moc" 0297 #include "moc_replacejobtest.cpp"