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