File indexing completed on 2024-04-28 17:01:43
0001 /* 0002 SPDX-FileCopyrightText: 2011 Dmitry Risenberg <dmitry.risenberg@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "interactivedifftest.h" 0008 0009 #include <QTest> 0010 #include "diffmodel.h" 0011 #include "diffmodellist.h" 0012 #include "parser.h" 0013 0014 using namespace Diff2; 0015 0016 typedef QHash<int, QPair<QStringList, QStringList> > DifferenceHash; 0017 Q_DECLARE_METATYPE(DifferenceHash); 0018 typedef QHash<int, QPair<int, int> > LineNumberHash; 0019 Q_DECLARE_METATYPE(LineNumberHash); 0020 0021 void InteractiveDiffTest::CompareDifferenceStringList(const DifferenceStringList& actual, const QStringList& expected) 0022 { 0023 DifferenceStringListConstIterator actualIter; 0024 QStringList::const_iterator expectedIter; 0025 for (actualIter = actual.constBegin(), expectedIter = expected.constBegin(); actualIter != actual.constEnd() && expectedIter != expected.constEnd(); ++actualIter, ++expectedIter) { 0026 QCOMPARE((*actualIter)->string(), *expectedIter); 0027 } 0028 if (actualIter != actual.constEnd()) { 0029 QFAIL(QStringLiteral("Actual has too many items, starting with '%1', line %2").arg((*actualIter)->string()).arg(actualIter - actual.constBegin()).toLatin1().constData()); 0030 } 0031 if (expectedIter != expected.constEnd()) { 0032 QFAIL(QStringLiteral("Actual has too few items, no match for '%1', line %2").arg(*expectedIter).arg(expectedIter - expected.constBegin()).toLatin1().constData()); 0033 } 0034 } 0035 0036 // The most basic test - something is actually working 0037 void InteractiveDiffTest::testOneLineChange() 0038 { 0039 DiffModel* model = new DiffModel(); 0040 QStringList newLines; 0041 newLines << "newline\n"; 0042 QStringList oldLines; 0043 oldLines << "oldline\n"; 0044 model->linesChanged(oldLines, newLines, 2); 0045 QCOMPARE(model->differences()->size(), 1); 0046 0047 QCOMPARE(model->differenceCount(), 1); 0048 const Difference* diff = model->differenceAt(0); 0049 CompareDifferenceStringList(diff->sourceLines(), oldLines); 0050 CompareDifferenceStringList(diff->destinationLines(), newLines); 0051 QCOMPARE(diff->type(), int(Difference::Change)); 0052 } 0053 0054 void InteractiveDiffTest::testSameLine() 0055 { 0056 DiffModel* model = new DiffModel(); 0057 QStringList newLines; 0058 newLines << "oldline2\n"; 0059 QStringList oldLines; 0060 oldLines << "oldline1\n" << "oldline2\n"; 0061 model->linesChanged(oldLines, newLines, 2); 0062 0063 QCOMPARE(model->differenceCount(), 1); 0064 const Difference* diff = model->differenceAt(0); 0065 CompareDifferenceStringList(diff->sourceLines(), QStringList() << "oldline1\n"); 0066 CompareDifferenceStringList(diff->destinationLines(), QStringList()); 0067 QCOMPARE(diff->type(), int(Difference::Delete)); 0068 } 0069 0070 void InteractiveDiffTest::testDifferenceContents() 0071 { 0072 QFETCH(QStringList, patch); 0073 Parser parser(nullptr); 0074 bool malformed; 0075 DiffModelList* models = parser.parse(patch, &malformed); 0076 QVERIFY(!malformed); 0077 QCOMPARE(models->size(), 1); 0078 DiffModel* model = models->at(0); 0079 0080 QFETCH(QStringList, oldLines); 0081 QFETCH(QStringList, newLines); 0082 QFETCH(int, editLineNumber); 0083 QFETCH(bool, isAlreadyApplied); 0084 model->applyAllDifferences(isAlreadyApplied); 0085 model->linesChanged(oldLines, newLines, editLineNumber); 0086 QFETCH(int, expectedDifferenceCount); 0087 QCOMPARE(model->differenceCount(), expectedDifferenceCount); 0088 0089 QFETCH(DifferenceHash, expectedDifferences); 0090 for (DifferenceHash::ConstIterator iter = expectedDifferences.constBegin(); iter != expectedDifferences.constEnd(); ++iter) { 0091 const Difference* diff = model->differenceAt(iter.key()); 0092 CompareDifferenceStringList(diff->sourceLines(), iter.value().first); 0093 CompareDifferenceStringList(diff->destinationLines(), iter.value().second); 0094 } 0095 } 0096 0097 void InteractiveDiffTest::testDifferenceContents_data() 0098 { 0099 QTest::addColumn<QStringList>("patch"); 0100 QTest::addColumn<QStringList>("oldLines"); // lines that are replaced 0101 QTest::addColumn<QStringList>("newLines"); // replacement lines 0102 QTest::addColumn<int>("editLineNumber"); 0103 QTest::addColumn<bool>("isAlreadyApplied"); 0104 QTest::addColumn<int>("expectedDifferenceCount"); 0105 QTest::addColumn<DifferenceHash>("expectedDifferences"); 0106 0107 { 0108 QStringList patch; 0109 patch << 0110 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0111 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0112 "@@ -1,5 +1,5 @@\n" << 0113 " abcd\n" << 0114 "-delete1\n" << 0115 "+insert1\n" << 0116 " efgh\n" << 0117 "-delete2\n" << 0118 "+insert2\n" << 0119 " ijkl\n"; 0120 0121 QStringList newLines; 0122 newLines << "newline1\n" << "newline2\n"; 0123 QStringList oldLines; 0124 oldLines << "efgh\n"; 0125 QStringList sourceLines; 0126 sourceLines << "delete1\n" << "efgh\n" << "delete2\n"; 0127 QStringList destinationLines; 0128 destinationLines << "insert1\n" << "newline1\n" << "newline2\n" << "insert2\n"; 0129 DifferenceHash expectedDifferences; 0130 expectedDifferences.insert(0, qMakePair(sourceLines, destinationLines)); 0131 0132 QTest::newRow("Merge adjacent differences") << patch << oldLines << newLines << 3 << true << 1 << expectedDifferences; 0133 } 0134 { 0135 QStringList patch; 0136 patch << 0137 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0138 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0139 "@@ -1,4 +1,4 @@\n" << 0140 " abcd\n" << 0141 "-delete1\n" << 0142 "-delete2\n" << 0143 "+insert1\n" << 0144 "+insert2\n" << 0145 " efgh\n"; 0146 0147 QStringList newLines; 0148 newLines << "newline1\n"; 0149 QStringList oldLines; 0150 oldLines << "efgh\n"; 0151 QStringList sourceLines; 0152 sourceLines << "delete1\n" << "delete2\n" << "efgh\n"; 0153 QStringList destinationLines; 0154 destinationLines << "insert1\n" << "insert2\n" << "newline1\n"; 0155 DifferenceHash expectedDifferences; 0156 expectedDifferences.insert(0, qMakePair(sourceLines, destinationLines)); 0157 0158 // Append a line to a multiline diff 0159 QTest::newRow("Append multiline") << patch << oldLines << newLines << 4 << true << 1 << expectedDifferences; 0160 } 0161 { 0162 QStringList patch; 0163 patch << 0164 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0165 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0166 "@@ -1,3 +1,3 @@\n" << 0167 " abcd\n" << 0168 "-delete1\n" << 0169 "+insert1\n" << 0170 " efgh\n"; 0171 0172 QStringList newLines; 0173 newLines << "delete1\n"; 0174 QStringList oldLines; 0175 oldLines << "insert1\n"; 0176 QTest::newRow("Revert existing difference") << patch << oldLines << newLines << 2 << true << 0 << DifferenceHash(); 0177 } 0178 { 0179 QStringList patch; 0180 patch << 0181 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0182 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0183 "@@ -1,3 +1,2 @@\n" << 0184 " abcd\n" << 0185 "-delete1\n" << 0186 " efgh\n"; 0187 0188 QStringList newLines; 0189 newLines << "abcd\n" << "delete1\n"; 0190 QStringList oldLines; 0191 oldLines << "abcd\n"; 0192 QTest::newRow("Revert deletion") << patch << oldLines << newLines << 1 << true << 0 << DifferenceHash(); 0193 } 0194 { 0195 QStringList patch; 0196 patch << 0197 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0198 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0199 "@@ -1,4 +1,5 @@\n" << 0200 " abcd\n" << 0201 "-delete1\n" << 0202 "-delete2\n" << 0203 "+insert1\n" << 0204 "+insert2\n" << 0205 "+insert3\n" << 0206 " efgh\n"; 0207 0208 QStringList newLines; 0209 newLines << "delete2\n"; 0210 QStringList oldLines; 0211 oldLines << "insert2\n"; 0212 DifferenceHash expectedDifferences; 0213 expectedDifferences.insert(0, qMakePair(QStringList() << "delete1\n", QStringList() << "insert1\n")); 0214 expectedDifferences.insert(1, qMakePair(QStringList(), QStringList() << "insert3\n")); 0215 0216 QTest::newRow("Partial reversion") << patch << oldLines << newLines << 3 << true << 2 << expectedDifferences; 0217 } 0218 { 0219 QStringList patch; 0220 patch << 0221 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0222 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0223 "@@ -1,4 +1,4 @@\n" << 0224 " abcd\n" << 0225 "-delete1\n" << 0226 "-delete2\n" << 0227 "+insert1\n" << 0228 "+insert2\n" << 0229 " efgh\n"; 0230 0231 QStringList newLines; 0232 newLines << "newline1\n" << "newline2\n"; 0233 QStringList oldLines; 0234 oldLines << "abcd\n" << "insert1\n" << "insert2\n" << "efgh\n"; 0235 QStringList sourceLines; 0236 sourceLines << "abcd\n" << "delete1\n" << "delete2\n" << "efgh\n"; 0237 QStringList destinationLines; 0238 destinationLines << "newline1\n" << "newline2\n"; 0239 DifferenceHash expectedDifferences; 0240 expectedDifferences.insert(0, qMakePair(sourceLines, destinationLines)); 0241 0242 // The first existing difference inside the edit 0243 QTest::newRow("First inside") << patch << oldLines << newLines << 1 << true << 1 << expectedDifferences; 0244 } 0245 { 0246 QStringList patch; 0247 patch << 0248 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0249 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0250 "@@ -1,4 +1,4 @@\n" << 0251 " abcd\n" << 0252 "-delete1\n" << 0253 "-delete2\n" << 0254 "+insert1\n" << 0255 "+insert2\n" << 0256 " efgh\n"; 0257 0258 QStringList newLines; 0259 newLines << "newline1\n" << "newline2\n"; 0260 QStringList oldLines; 0261 oldLines << "insert2\n" << "efgh\n"; 0262 QStringList sourceLines; 0263 sourceLines << "delete1\n" << "delete2\n" << "efgh\n"; 0264 QStringList destinationLines; 0265 destinationLines << "insert1\n" << "newline1\n" << "newline2\n"; 0266 DifferenceHash expectedDifferences; 0267 expectedDifferences.insert(0, qMakePair(sourceLines, destinationLines)); 0268 0269 // The first existing difference intersects with the edit 0270 QTest::newRow("First intersects") << patch << oldLines << newLines << 3 << true << 1 << expectedDifferences; 0271 } 0272 { 0273 QStringList patch; 0274 patch << 0275 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0276 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0277 "@@ -1,2 +1,3 @@\n" << 0278 " abcd\n" << 0279 "+\n" << 0280 " efgh\n"; 0281 0282 QStringList newLines; 0283 newLines << "a\n"; 0284 QStringList oldLines; 0285 oldLines << "\n"; 0286 DifferenceHash expectedDifferences; 0287 expectedDifferences.insert(0, qMakePair(QStringList(), QStringList() << "a\n")); 0288 0289 QTest::newRow("Replace empty line") << patch << oldLines << newLines << 2 << true << 1 << expectedDifferences; 0290 } 0291 { 0292 QStringList patch; 0293 patch << 0294 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0295 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0296 "@@ -1,3 +1,3 @@\n" << 0297 " abcd\n" << 0298 "+insert1\n" << 0299 "+insert2\n" << 0300 "+insert3\n" << 0301 "+insert4\n" << 0302 "+insert5\n" << 0303 " efgh\n" << 0304 "@@ -10,3 +15,3 @@\n" << 0305 " abcd\n" << 0306 "-delete1\n" << 0307 "+insert1\n" << 0308 " efgh\n"; 0309 0310 QStringList newLines; 0311 newLines << "newline1\n"; 0312 QStringList oldLines; 0313 oldLines << "delete1\n"; 0314 DifferenceHash expectedDifferences; 0315 expectedDifferences.insert(1, qMakePair(QStringList() << "delete1\n", QStringList() << "newline1\n")); 0316 0317 QTest::newRow("Replace line in source") << patch << oldLines << newLines << 11 << false << 2 << expectedDifferences; 0318 } 0319 } 0320 0321 void InteractiveDiffTest::testLineNumbers_data() 0322 { 0323 QTest::addColumn<QStringList>("patch"); 0324 QTest::addColumn<QStringList>("oldLines"); // lines that are replaced 0325 QTest::addColumn<QStringList>("newLines"); // replacement lines 0326 QTest::addColumn<int>("editLineNumber"); 0327 QTest::addColumn<int>("expectedDifferenceCount"); 0328 QTest::addColumn<LineNumberHash>("expectedLineNumbers"); 0329 0330 { 0331 QStringList patch; 0332 patch << 0333 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0334 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0335 "@@ -1,4 +1,6 @@\n" << 0336 " abcd\n" << 0337 "-delete1\n" << 0338 "-delete2\n" << 0339 "+insert1\n" << 0340 "+insert2\n" << 0341 "+insert3\n" << 0342 "+insert4\n" << 0343 " efgh\n" << 0344 "@@ -15,3 +17,4 @@\n" << 0345 " abcd\n" << 0346 "-delete1\n" << 0347 "+insert1\n" << 0348 "+insert2\n" << 0349 " efgh\n"; 0350 0351 QStringList newLines; 0352 newLines << "newline1\n" << "newline2\n" << "newline2\n"; 0353 QStringList oldLines; 0354 oldLines << "oldline1\n"; 0355 LineNumberHash expectedLineNumbers; 0356 expectedLineNumbers.insert(0, qMakePair(2, 2)); 0357 expectedLineNumbers.insert(2, qMakePair(16, 20)); 0358 QTest::newRow("Update existing line numbers") << patch << oldLines << newLines << 10 << 3 << expectedLineNumbers; 0359 } 0360 { 0361 QStringList patch; 0362 patch << 0363 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0364 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0365 "@@ -1,4 +1,6 @@\n" << 0366 " abcd\n" << 0367 "-delete1\n" << 0368 "-delete2\n" << 0369 "+insert1\n" << 0370 "+insert2\n" << 0371 "+insert3\n" << 0372 "+insert4\n" << 0373 " efgh\n" << 0374 "@@ -15,3 +17,4 @@\n" << 0375 " abcd\n" << 0376 "-delete1\n" << 0377 "+insert1\n" << 0378 "+insert2\n" << 0379 " efgh\n"; 0380 0381 QStringList newLines; 0382 newLines << "newline1\n"; 0383 QStringList oldLines; 0384 oldLines << "oldline1\n"; 0385 LineNumberHash expectedLineNumbers; 0386 expectedLineNumbers.insert(2, qMakePair(22, 25)); 0387 0388 // Line numbers assigned to new difference when it is inserted after all existing differences 0389 QTest::newRow("Last edit line number") << patch << oldLines << newLines << 25 << 3 << expectedLineNumbers; 0390 } 0391 { 0392 QStringList patch; 0393 patch << 0394 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0395 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0396 "@@ -1,4 +1,6 @@\n" << 0397 " abcd\n" << 0398 "-delete1\n" << 0399 "-delete2\n" << 0400 "+insert1\n" << 0401 "+insert2\n" << 0402 "+insert3\n" << 0403 "+insert4\n" << 0404 " efgh\n" << 0405 "@@ -15,3 +17,4 @@\n" << 0406 " abcd\n" << 0407 "-delete1\n" << 0408 "+insert1\n" << 0409 "+insert2\n" << 0410 " efgh\n"; 0411 0412 QStringList newLines; 0413 newLines << "newline1\n"; 0414 QStringList oldLines; 0415 oldLines << "oldline1\n"; 0416 LineNumberHash expectedLineNumbers; 0417 expectedLineNumbers.insert(1, qMakePair(11, 13)); 0418 0419 // Line numbers assigned to new difference when it is inserted between existing differences 0420 QTest::newRow("Middle edit line number") << patch << oldLines << newLines << 13 << 3 << expectedLineNumbers; 0421 } 0422 { 0423 QStringList patch; 0424 patch << 0425 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0426 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0427 "@@ -10,4 +10,4 @@\n" << 0428 " abcd\n" << 0429 "-delete1\n" << 0430 "-delete2\n" << 0431 "+insert1\n" << 0432 "+insert2\n" << 0433 " efgh\n"; 0434 0435 QStringList newLines; 0436 newLines << "newline1\n"; 0437 QStringList oldLines; 0438 oldLines << "oldline1\n"; 0439 LineNumberHash expectedLineNumbers; 0440 expectedLineNumbers.insert(0, qMakePair(5, 5)); 0441 0442 // Line numbers assigned to new difference when it is inserted before all existing differences 0443 QTest::newRow("First edit line number") << patch << oldLines << newLines << 5 << 2 << expectedLineNumbers; 0444 } 0445 { 0446 QStringList patch; 0447 patch << 0448 "--- file1\t2011-01-01 20:23:45.000000000 +0300\n" << 0449 "+++ file2\t2011-01-01 20:24:02.000000000 +0300\n" << 0450 "@@ -1,3 +1,4 @@\n" << 0451 " abcd\n" << 0452 "-delete1\n" << 0453 "+insert1\n" << 0454 "+insert2\n" << 0455 " efgh\n" << 0456 "@@ -11,4 +12,5 @@\n" << 0457 " abcd\n" << 0458 "-delete2\n" << 0459 "-delete3\n" << 0460 "+insert3\n" << 0461 "+insert4\n" << 0462 "+insert5\n" << 0463 " efgh\n" << 0464 "@@ -21,4 +23,3 @@\n" << 0465 " abcd\n" << 0466 "-delete4\n" << 0467 "-delete5\n" << 0468 "+insert6\n" << 0469 " efgh\n"; 0470 0471 QStringList newLines; 0472 newLines << "delete2\n"; 0473 QStringList oldLines; 0474 oldLines << "insert4\n"; 0475 LineNumberHash expectedLineNumbers; 0476 expectedLineNumbers.insert(0, qMakePair(2, 2)); 0477 expectedLineNumbers.insert(1, qMakePair(12, 13)); 0478 expectedLineNumbers.insert(2, qMakePair(13, 15)); 0479 expectedLineNumbers.insert(3, qMakePair(22, 24)); 0480 0481 QTest::newRow("Partial reversion") << patch << oldLines << newLines << 14 << 4 << expectedLineNumbers; 0482 } 0483 } 0484 0485 void InteractiveDiffTest::testLineNumbers() 0486 { 0487 QFETCH(QStringList, patch); 0488 Parser parser(nullptr); 0489 bool malformed; 0490 DiffModelList* models = parser.parse(patch, &malformed); 0491 QVERIFY(!malformed); 0492 QCOMPARE(models->size(), 1); 0493 DiffModel* model = models->at(0); 0494 model->applyAllDifferences(true); 0495 0496 QFETCH(QStringList, oldLines); 0497 QFETCH(QStringList, newLines); 0498 QFETCH(int, editLineNumber); 0499 model->linesChanged(oldLines, newLines, editLineNumber); 0500 QFETCH(int, expectedDifferenceCount); 0501 QCOMPARE(model->differenceCount(), expectedDifferenceCount); 0502 0503 QFETCH(LineNumberHash, expectedLineNumbers); 0504 for (LineNumberHash::ConstIterator iter = expectedLineNumbers.constBegin(); iter != expectedLineNumbers.constEnd(); ++iter) { 0505 const Difference* diff = model->differenceAt(iter.key()); 0506 QCOMPARE(diff->sourceLineNumber(), iter.value().first); 0507 QCOMPARE(diff->trackingDestinationLineNumber(), iter.value().second); 0508 } 0509 } 0510 0511 // When the new diff and an existing unapplied one are on neighbour lines, do not merge the unapplied with the new. 0512 void InteractiveDiffTest::testAppliedTouch() 0513 { 0514 Difference* first = new Difference(2, 2); 0515 first->addSourceLine(QString("delete1")); 0516 first->addDestinationLine(QString("insert1")); 0517 first->apply(false); 0518 Difference* second = new Difference(4, 4); 0519 second->addSourceLine(QString("delete2")); 0520 second->addDestinationLine(QString("insert2")); 0521 second->apply(false); 0522 DiffModel model; 0523 model.addDiff(first); 0524 model.addDiff(second); 0525 model.linesChanged(QStringList() << "oldline\n", QStringList() << "newline\n", 3); 0526 QCOMPARE(model.differenceCount(), 3); 0527 QCOMPARE(model.differenceAt(0), first); 0528 QCOMPARE(model.differenceAt(2), second); 0529 } 0530 0531 // When the new diff and an existing unapplied one intersect, the unapplied one should be removed 0532 void InteractiveDiffTest::testAppliedIntersect() 0533 { 0534 Difference* first = new Difference(2, 2); 0535 first->addSourceLine(QString("delete1")); 0536 first->addSourceLine(QString("delete2")); 0537 first->addDestinationLine(QString("insert1")); 0538 first->addDestinationLine(QString("insert2")); 0539 first->apply(false); 0540 Difference* second = new Difference(5, 5); 0541 second->addSourceLine(QString("delete3")); 0542 second->addSourceLine(QString("delete4")); 0543 second->addDestinationLine(QString("insert3")); 0544 second->addDestinationLine(QString("insert4")); 0545 second->apply(false); 0546 DiffModel model; 0547 model.addDiff(first); 0548 model.addDiff(second); 0549 QStringList removedLines; 0550 removedLines << "delete2\n" << "oldline1\n" << "delete3\n"; 0551 QStringList insertedLines; 0552 insertedLines << "newline1\n"; 0553 model.linesChanged(removedLines, insertedLines, 3); 0554 QCOMPARE(model.differenceCount(), 1); 0555 const Difference* newDiff = model.differenceAt(0); 0556 QCOMPARE(newDiff->applied(), true); 0557 QCOMPARE(newDiff->sourceLineNumber(), 3); 0558 QCOMPARE(newDiff->trackingDestinationLineNumber(), 3); 0559 CompareDifferenceStringList(newDiff->sourceLines(), removedLines); 0560 CompareDifferenceStringList(newDiff->destinationLines(), insertedLines); 0561 } 0562 0563 void InteractiveDiffTest::testExistingAndApplied() 0564 { 0565 Difference* first = new Difference(2, 2); 0566 first->addSourceLine(QString("delete1")); 0567 first->addDestinationLine(QString("insert1")); 0568 first->apply(true); 0569 Difference* second = new Difference(3, 3); 0570 second->addSourceLine(QString("delete2")); 0571 second->addDestinationLine(QString("insert2")); 0572 second->apply(false); 0573 DiffModel model; 0574 model.addDiff(first); 0575 model.addDiff(second); 0576 QStringList removedLines; 0577 removedLines << "delete1\n"; 0578 QStringList insertedLines; 0579 insertedLines << "newline1\n"; 0580 model.linesChanged(removedLines, insertedLines, 2); 0581 QCOMPARE(model.differenceCount(), 2); 0582 QVERIFY(model.differenceAt(0)->applied()); 0583 QVERIFY(!model.differenceAt(1)->applied()); 0584 } 0585 0586 void InteractiveDiffTest::testOneLineDeletionUnapplied() 0587 { 0588 Difference* unappliedDeletion = new Difference(1, 1); 0589 unappliedDeletion->addSourceLine("delete1\n"); 0590 unappliedDeletion->apply(false); 0591 DiffModel model; 0592 model.addDiff(unappliedDeletion); 0593 QStringList removedLines; 0594 removedLines << "delete1\n"; 0595 QStringList insertedLines; 0596 insertedLines << "newline1\n"; 0597 model.linesChanged(removedLines, insertedLines, 1); 0598 QCOMPARE(model.differenceCount(), 1); 0599 const Difference* actual = model.differenceAt(0); 0600 CompareDifferenceStringList(actual->sourceLines(), removedLines); 0601 CompareDifferenceStringList(actual->destinationLines(), insertedLines); 0602 } 0603 0604 void InteractiveDiffTest::testApplyUnapply() 0605 { 0606 QStringList patch; 0607 patch << 0608 "--- file1\t2011-01-01 20:23:45 +0300\n" << 0609 "+++ file2\t2011-01-01 20:24:02 +0300\n" << 0610 "@@ -1,3 +1,4 @@\n" << 0611 " line1\n" << 0612 "-delete1\n" << 0613 "+insert1\n" << 0614 "+insert2\n" << 0615 " line2\n" << 0616 "@@ -11,4 +12,5 @@\n" << 0617 " line3\n" << 0618 "-delete2\n" << 0619 "-delete3\n" << 0620 "+insert3\n" << 0621 "+insert4\n" << 0622 "+insert5\n" << 0623 " line4\n" << 0624 "@@ -21,4 +23,2 @@\n" << 0625 " line5\n" << 0626 "-delete4\n" << 0627 "-delete5\n" << 0628 " line6\n" << 0629 "@@ -31,3 +31,3 @@\n" << 0630 " line7\n" << 0631 "-delete6\n" << 0632 "+insert6\n" << 0633 " line8\n"; 0634 Parser parser(nullptr); 0635 bool malformed; 0636 DiffModelList* models = parser.parse(patch, &malformed); 0637 QVERIFY(!malformed); 0638 QCOMPARE(models->size(), 1); 0639 DiffModel* model = models->at(0); 0640 QCOMPARE(model->differenceCount(), 4); 0641 model->applyAllDifferences(true); 0642 0643 const auto differences = *model->differences(); 0644 for (Difference* diff : differences) { 0645 QVERIFY(diff->applied()); 0646 } 0647 model->applyAllDifferences(false); 0648 QVERIFY(!model->differenceAt(0)->applied()); 0649 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 2); 0650 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 2); 0651 QVERIFY(!model->differenceAt(1)->applied()); 0652 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 12); 0653 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 12); 0654 QVERIFY(!model->differenceAt(2)->applied()); 0655 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0656 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 22); 0657 QVERIFY(!model->differenceAt(3)->applied()); 0658 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0659 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 32); 0660 0661 model->differenceAt(1)->apply(true); 0662 QVERIFY(model->differenceAt(1)->applied()); 0663 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 12); 0664 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 12); 0665 QVERIFY(!model->differenceAt(2)->applied()); 0666 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0667 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 23); 0668 QVERIFY(!model->differenceAt(3)->applied()); 0669 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0670 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 33); 0671 0672 model->differenceAt(1)->apply(true); 0673 QVERIFY(model->differenceAt(1)->applied()); 0674 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 12); 0675 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 12); 0676 QVERIFY(!model->differenceAt(2)->applied()); 0677 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0678 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 23); 0679 QVERIFY(!model->differenceAt(3)->applied()); 0680 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0681 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 33); 0682 0683 model->differenceAt(2)->apply(true); 0684 QVERIFY(model->differenceAt(2)->applied()); 0685 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0686 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 23); 0687 QVERIFY(!model->differenceAt(3)->applied()); 0688 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0689 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 31); 0690 0691 model->applyAllDifferences(true); 0692 QVERIFY(model->differenceAt(0)->applied()); 0693 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 2); 0694 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 2); 0695 QVERIFY(model->differenceAt(1)->applied()); 0696 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 12); 0697 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 13); 0698 QVERIFY(model->differenceAt(2)->applied()); 0699 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0700 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 24); 0701 QVERIFY(model->differenceAt(3)->applied()); 0702 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0703 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 32); 0704 0705 model->applyAllDifferences(true); 0706 QVERIFY(model->differenceAt(0)->applied()); 0707 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 2); 0708 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 2); 0709 QVERIFY(model->differenceAt(1)->applied()); 0710 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 12); 0711 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 13); 0712 QVERIFY(model->differenceAt(2)->applied()); 0713 QCOMPARE(model->differenceAt(2)->sourceLineNumber(), 22); 0714 QCOMPARE(model->differenceAt(2)->trackingDestinationLineNumber(), 24); 0715 QVERIFY(model->differenceAt(3)->applied()); 0716 QCOMPARE(model->differenceAt(3)->sourceLineNumber(), 32); 0717 QCOMPARE(model->differenceAt(3)->trackingDestinationLineNumber(), 32); 0718 } 0719 0720 static void 0721 contextDiff1() 0722 { 0723 QStringList patch; 0724 patch << 0725 "commit 7377fcc682e85ef9784adb2a2da2c8c6756f9018 (HEAD, KDE/4.11)\n" << 0726 "Author: Dr. ChocholouĊĦek <bla@zin.ec>\n" << 0727 "AuthorDate: Sat Jan 25 17:30:01 2014 +0100\n" << 0728 "\n" << 0729 " Fake diff.\n" << 0730 "\n" << 0731 "diff --git a/libdiff2/diffmodel.cpp b/libdiff2/diffmodel.cpp\n" << 0732 "new file mode 100644\n" << 0733 "index a42e82d..a8da0c9\n" << 0734 "*** a/libdiff2/diffmodel.cpp\n" << // note the missing timestamps 0735 "--- b/libdiff2/diffmodel.cpp\n" << 0736 "*************** DiffModel::DiffModel() :\n" << 0737 "*** 58,64 ****\n" << 0738 " m_sourceFile( "" ),\n" << 0739 " m_destinationFile( "" ),\n" << 0740 " m_sourceTimestamp( "" ),\n" << 0741 "! m_destinationTimestamp( "" ),\n" << 0742 " m_sourceRevision( "" ),\n" << 0743 " m_destinationRevision( "" ),\n" << 0744 " m_appliedCount( 0 ),\n" << 0745 "--- 58,64 ----\n" << 0746 " m_sourceFile( "" ),\n" << 0747 " m_destinationFile( "" ),\n" << 0748 " m_sourceTimestamp( "" ),\n" << 0749 "! m_destinationTimestamp( \"doh\" ),\n" << 0750 " m_sourceRevision( "" ),\n" << 0751 " m_destinationRevision( "" ),\n" << 0752 " m_appliedCount( 0 ),\n" << 0753 "*************** void DiffModel::splitSourceInPathAndFile\n" << 0754 "*** 84,89 ****\n" << 0755 "--- 84,91 ----\n" << 0756 " if( ( pos = m_source.lastIndexOf( \"/\" ) ) >= 0 )\n" << 0757 " m_sourcePath = m_source.mid( 0, pos+1 );\n" << 0758 " \n" << 0759 "+ add_this;\n" << 0760 "+ \n" << 0761 " if( ( pos = m_source.lastIndexOf( \"/\" ) ) >= 0 )\n" << 0762 " m_sourceFile = m_source.mid( pos+1, m_source.length() - pos );\n" << 0763 " else\n"; 0764 Parser parser(nullptr); 0765 bool malformed; 0766 DiffModelList* models = parser.parse(patch, &malformed); 0767 QVERIFY(!malformed); 0768 QCOMPARE(models->size(), 1); 0769 DiffModel* model = models->at(0); 0770 QCOMPARE(model->differenceCount(), 2); 0771 model->applyAllDifferences(true); 0772 QVERIFY(model->differenceAt(0)->applied()); 0773 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 61); 0774 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 61); 0775 QCOMPARE(model->differenceAt(1)->sourceLineNumber(), 87); 0776 QCOMPARE(model->differenceAt(1)->trackingDestinationLineNumber(), 87); 0777 } 0778 0779 static void 0780 contextDiff2() 0781 { 0782 QStringList patch; 0783 patch << 0784 "*** a/libdiff2/diffmodel.cpp\n" << 0785 "--- b/libdiff2/diffmodel.cpp\n" << 0786 "***************\n" << 0787 "*** 55,60 **** DiffModel::DiffModel() :\n" << // note the context here 0788 "--- 55,61 ----\n" << 0789 " m_destination( "" ),\n" << 0790 " m_sourcePath( "" ),\n" << 0791 " m_destinationPath( "" ),\n" << 0792 "+ m_hoh ( "" );\n" << 0793 " m_sourceFile( "" ),\n" << 0794 " m_destinationFile( "" ),\n" << 0795 " m_sourceTimestamp( "" ),\n"; 0796 0797 Parser parser(nullptr); 0798 bool malformed; 0799 DiffModelList* models = parser.parse(patch, &malformed); 0800 QVERIFY(!malformed); 0801 QCOMPARE(models->size(), 1); 0802 DiffModel* model = models->at(0); 0803 QCOMPARE(model->differenceCount(), 1); 0804 model->applyAllDifferences(true); 0805 QVERIFY(model->differenceAt(0)->applied()); 0806 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 58); 0807 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 58); 0808 } 0809 0810 void InteractiveDiffTest::testContextDiff() 0811 { 0812 contextDiff1(); 0813 contextDiff2(); 0814 } 0815 0816 void InteractiveDiffTest::testNormalDiff() 0817 { 0818 QStringList patch; 0819 patch << 0820 "1c1\n" << 0821 "< a\n" << 0822 "---\n" << 0823 "> b\n"; 0824 Parser parser(nullptr); 0825 bool malformed; 0826 DiffModelList* models = parser.parse(patch, &malformed); 0827 QVERIFY(!malformed); 0828 QCOMPARE(models->size(), 1); 0829 DiffModel* model = models->at(0); 0830 QCOMPARE(model->differenceCount(), 1); 0831 model->applyAllDifferences(true); 0832 QVERIFY(model->differenceAt(0)->applied()); 0833 QCOMPARE(model->differenceAt(0)->sourceLineNumber(), 1); 0834 QCOMPARE(model->differenceAt(0)->trackingDestinationLineNumber(), 1); 0835 } 0836 0837 QTEST_GUILESS_MAIN(InteractiveDiffTest); 0838 0839 #include "moc_interactivedifftest.cpp"