File indexing completed on 2024-05-12 04:40:01
0001 /* 0002 This file was partly taken from KDevelop's cvs plugin 0003 SPDX-FileCopyrightText: 2007 Robert Gruber <rgruber@users.sourceforge.net> 0004 0005 Adapted for Git 0006 SPDX-FileCopyrightText: 2008 Evgeniy Ivanov <powerfox@kde.ru> 0007 0008 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0009 */ 0010 0011 #include "test_git.h" 0012 0013 #include <QTest> 0014 #include <tests/testcore.h> 0015 #include <tests/autotestshell.h> 0016 #include <QUrl> 0017 #include <QDebug> 0018 0019 #include <vcs/dvcs/dvcsjob.h> 0020 #include <vcs/vcsannotation.h> 0021 #include "../gitplugin.h" 0022 0023 #define VERIFYJOB(j) \ 0024 do { QVERIFY(j); QVERIFY(j->exec()); QVERIFY((j)->status() == KDevelop::VcsJob::JobSucceeded); } while(0) 0025 0026 #define VERIFYJOBFAILURE(j) \ 0027 do { QVERIFY(j); QVERIFY(((!j->exec()) || ((j)->status() != KDevelop::VcsJob::JobSucceeded))); } while(0) 0028 0029 inline QString tempDir() { return QDir::tempPath(); } 0030 inline QString gitTest_BaseDir() { return tempDir() + "/kdevGit_testdir/"; } 0031 inline QString gitRepo() { return gitTest_BaseDir() + ".git"; } 0032 inline QString gitSrcDir() { return gitTest_BaseDir() + "src/"; } 0033 inline QString gitTest_FileName() { return QStringLiteral("testfile"); } 0034 inline QString gitTest_FileName2() { return QStringLiteral("foo"); } 0035 inline QString gitTest_FileName3() { return QStringLiteral("bar"); } 0036 0037 using namespace KDevelop; 0038 0039 bool writeFile(const QString &path, const QString& content, QIODevice::OpenModeFlag mode = QIODevice::WriteOnly) 0040 { 0041 QFile f(path); 0042 0043 if (!f.open(mode)) { 0044 return false; 0045 } 0046 0047 QTextStream input(&f); 0048 input << content; 0049 0050 return true; 0051 } 0052 0053 void GitInitTest::initTestCase() 0054 { 0055 AutoTestShell::init({QStringLiteral("kdevgit")}); 0056 TestCore::initialize(); 0057 0058 m_plugin = new GitPlugin(TestCore::self()); 0059 } 0060 0061 void GitInitTest::cleanupTestCase() 0062 { 0063 delete m_plugin; 0064 0065 TestCore::shutdown(); 0066 } 0067 0068 void GitInitTest::init() 0069 { 0070 // Now create the basic directory structure 0071 QDir tmpdir(tempDir()); 0072 tmpdir.mkdir(gitTest_BaseDir()); 0073 tmpdir.mkdir(gitSrcDir()); 0074 } 0075 0076 void GitInitTest::cleanup() 0077 { 0078 removeTempDirs(); 0079 } 0080 0081 0082 void GitInitTest::repoInit() 0083 { 0084 qDebug() << "Trying to init repo"; 0085 // make job that creates the local repository 0086 VcsJob* j = m_plugin->init(QUrl::fromLocalFile(gitTest_BaseDir())); 0087 VERIFYJOB(j); 0088 0089 //check if the CVSROOT directory in the new local repository exists now 0090 QVERIFY(QFileInfo::exists(gitRepo())); 0091 0092 //check if isValidDirectory works 0093 QVERIFY(m_plugin->isValidDirectory(QUrl::fromLocalFile(gitTest_BaseDir()))); 0094 //and for non-git dir, I hope nobody has /tmp under git 0095 QVERIFY(!m_plugin->isValidDirectory(QUrl::fromLocalFile(tempDir()))); 0096 0097 //we have nothing, so output should be empty 0098 DVcsJob * j2 = m_plugin->gitRevParse(gitRepo(), QStringList(QStringLiteral("--branches"))); 0099 QVERIFY(j2); 0100 QVERIFY(j2->exec()); 0101 QVERIFY(j2->output().isEmpty()); 0102 0103 // Make sure to set the Git identity so unit tests don't depend on that 0104 auto j3 = m_plugin->setConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), 0105 QStringLiteral("user.email"), QStringLiteral("me@example.com")); 0106 VERIFYJOB(j3); 0107 auto j4 = m_plugin->setConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), 0108 QStringLiteral("user.name"), QStringLiteral("My Name")); 0109 VERIFYJOB(j4); 0110 } 0111 0112 void GitInitTest::addFiles() 0113 { 0114 qDebug() << "Adding files to the repo"; 0115 0116 //we start it after repoInit, so we still have empty git repo 0117 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("HELLO WORLD"))); 0118 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName2(), QStringLiteral("No, bar()!"))); 0119 0120 //test git-status exitCode (see DVcsJob::setExitCode). 0121 VcsJob* j = m_plugin->status(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0122 VERIFYJOB(j); 0123 0124 // /tmp/kdevGit_testdir/ and testfile 0125 j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + gitTest_FileName())); 0126 VERIFYJOB(j); 0127 0128 QVERIFY(writeFile(gitSrcDir() + gitTest_FileName3(), QStringLiteral("No, foo()! It's bar()!"))); 0129 0130 //test git-status exitCode again 0131 j = m_plugin->status(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0132 VERIFYJOB(j); 0133 0134 //repository path without trailing slash and a file in a parent directory 0135 // /tmp/repo and /tmp/repo/src/bar 0136 j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitSrcDir() + gitTest_FileName3())); 0137 VERIFYJOB(j); 0138 0139 //let's use absolute path, because it's used in ContextMenus 0140 j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + gitTest_FileName2())); 0141 VERIFYJOB(j); 0142 0143 //Now let's create several files and try "git add file1 file2 file3" 0144 const QStringList files{QStringLiteral("file1"), QStringLiteral("file2"), QStringLiteral("la la")}; 0145 QList<QUrl> multipleFiles; 0146 for (const QString& file : files) { 0147 QVERIFY(writeFile(gitTest_BaseDir() + file, file)); 0148 multipleFiles << QUrl::fromLocalFile(gitTest_BaseDir() + file); 0149 } 0150 j = m_plugin->add(multipleFiles); 0151 VERIFYJOB(j); 0152 } 0153 0154 void GitInitTest::commitFiles() 0155 { 0156 qDebug() << "Committing..."; 0157 //we start it after addFiles, so we just have to commit 0158 VcsJob* j = m_plugin->commit(QStringLiteral("Test commit"), QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0159 VERIFYJOB(j); 0160 0161 //test git-status exitCode one more time. 0162 j = m_plugin->status(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0163 VERIFYJOB(j); 0164 0165 //since we committed the file to the "pure" repository, .git/refs/heads/master should exist 0166 //TODO: maybe other method should be used 0167 QString headRefName(gitRepo() + "/refs/heads/master"); 0168 QVERIFY(QFileInfo::exists(headRefName)); 0169 0170 //Test the results of the "git add" 0171 auto* jobLs = new DVcsJob(gitTest_BaseDir(), m_plugin); 0172 *jobLs << "git" << "ls-tree" << "--name-only" << "-r" << "HEAD"; 0173 0174 if (jobLs->exec() && jobLs->status() == KDevelop::VcsJob::JobSucceeded) { 0175 QStringList files = jobLs->output().split('\n'); 0176 QVERIFY(files.contains(gitTest_FileName())); 0177 QVERIFY(files.contains(gitTest_FileName2())); 0178 QVERIFY(files.contains("src/" + gitTest_FileName3())); 0179 } 0180 0181 QString firstCommit; 0182 0183 QFile headRef(headRefName); 0184 0185 if (headRef.open(QIODevice::ReadOnly)) { 0186 QTextStream output(&headRef); 0187 output >> firstCommit; 0188 } 0189 headRef.close(); 0190 0191 QVERIFY(!firstCommit.isEmpty()); 0192 0193 qDebug() << "Committing one more time"; 0194 //let's try to change the file and test "git commit -a" 0195 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("Just another HELLO WORLD\n"))); 0196 0197 //add changes 0198 j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + gitTest_FileName())); 0199 VERIFYJOB(j); 0200 0201 j = m_plugin->commit(QStringLiteral("KDevelop's Test commit2"), QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0202 VERIFYJOB(j); 0203 0204 QString secondCommit; 0205 0206 if (headRef.open(QIODevice::ReadOnly)) { 0207 QTextStream output(&headRef); 0208 output >> secondCommit; 0209 } 0210 headRef.close(); 0211 0212 QVERIFY(!secondCommit.isEmpty()); 0213 QVERIFY(firstCommit != secondCommit); 0214 0215 } 0216 0217 void GitInitTest::testInit() 0218 { 0219 repoInit(); 0220 } 0221 0222 static QString runCommand(const QString& cmd, const QStringList& args) 0223 { 0224 QProcess proc; 0225 proc.setWorkingDirectory(gitTest_BaseDir()); 0226 proc.start(cmd, args); 0227 proc.waitForFinished(); 0228 return proc.readAllStandardOutput().trimmed(); 0229 } 0230 0231 void GitInitTest::testReadAndSetConfigOption() 0232 { 0233 repoInit(); 0234 0235 { 0236 qDebug() << "read non-existing config option"; 0237 QString nameFromPlugin = m_plugin->readConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), 0238 QStringLiteral("notexisting.asdads")); 0239 QVERIFY(nameFromPlugin.isEmpty()); 0240 } 0241 0242 { 0243 qDebug() << "write user.name = \"John Tester\""; 0244 auto job = m_plugin->setConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), 0245 QStringLiteral("user.name"), QStringLiteral("John Tester")); 0246 VERIFYJOB(job); 0247 const auto name = runCommand(QStringLiteral("git"), {"config", "--get", QStringLiteral("user.name")}); 0248 QCOMPARE(name, QStringLiteral("John Tester")); 0249 } 0250 0251 { 0252 qDebug() << "read user.name"; 0253 const QString nameFromPlugin = m_plugin->readConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), 0254 QStringLiteral("user.name")); 0255 QCOMPARE(nameFromPlugin, QStringLiteral("John Tester")); 0256 const auto name = runCommand(QStringLiteral("git"), {"config", "--get", QStringLiteral("user.name")}); 0257 QCOMPARE(name, QStringLiteral("John Tester")); 0258 } 0259 } 0260 0261 void GitInitTest::testAdd() 0262 { 0263 repoInit(); 0264 addFiles(); 0265 } 0266 0267 void GitInitTest::testCommit() 0268 { 0269 repoInit(); 0270 addFiles(); 0271 commitFiles(); 0272 } 0273 0274 void GitInitTest::testBranch(const QString& newBranch) 0275 { 0276 //Already tested, so I assume that it works 0277 const QUrl baseUrl = QUrl::fromLocalFile(gitTest_BaseDir()); 0278 QString oldBranch = runSynchronously(m_plugin->currentBranch(baseUrl)).toString(); 0279 0280 VcsRevision rev; 0281 rev.setRevisionValue(oldBranch, KDevelop::VcsRevision::GlobalNumber); 0282 VcsJob* j = m_plugin->branch(baseUrl, rev, newBranch); 0283 VERIFYJOB(j); 0284 QVERIFY(runSynchronously(m_plugin->branches(baseUrl)).toStringList().contains(newBranch)); 0285 0286 // switch branch 0287 j = m_plugin->switchBranch(baseUrl, newBranch); 0288 VERIFYJOB(j); 0289 QCOMPARE(runSynchronously(m_plugin->currentBranch(baseUrl)).toString(), newBranch); 0290 0291 // get into detached head state 0292 j = m_plugin->switchBranch(baseUrl, QStringLiteral("HEAD~1")); 0293 VERIFYJOB(j); 0294 QCOMPARE(runSynchronously(m_plugin->currentBranch(baseUrl)).toString(), QString()); 0295 0296 // switch back 0297 j = m_plugin->switchBranch(baseUrl, newBranch); 0298 VERIFYJOB(j); 0299 QCOMPARE(runSynchronously(m_plugin->currentBranch(baseUrl)).toString(), newBranch); 0300 0301 j = m_plugin->deleteBranch(baseUrl, oldBranch); 0302 VERIFYJOB(j); 0303 QVERIFY(!runSynchronously(m_plugin->branches(baseUrl)).toStringList().contains(oldBranch)); 0304 0305 // Test that we can't delete branch on which we currently are 0306 j = m_plugin->deleteBranch(baseUrl, newBranch); 0307 VERIFYJOBFAILURE(j); 0308 QVERIFY(runSynchronously(m_plugin->branches(baseUrl)).toStringList().contains(newBranch)); 0309 0310 // Test branching off HEAD 0311 rev = KDevelop::VcsRevision::createSpecialRevision(KDevelop::VcsRevision::Head); 0312 j = m_plugin->branch(baseUrl, rev, newBranch+QStringLiteral("-new")); 0313 VERIFYJOB(j); 0314 QVERIFY(runSynchronously(m_plugin->branches(baseUrl)).toStringList().contains(newBranch+QStringLiteral("-new"))); 0315 } 0316 0317 void GitInitTest::testMerge() 0318 { 0319 const QString branchNames[] = {QStringLiteral("aBranchToBeMergedIntoMaster"), QStringLiteral("AnotherBranch")}; 0320 0321 const QString files[]={QStringLiteral("First File to Appear after merging"),QStringLiteral("Second File to Appear after merging"), QStringLiteral("Another_File.txt")}; 0322 0323 const QString content=QStringLiteral("Testing merge."); 0324 0325 repoInit(); 0326 addFiles(); 0327 commitFiles(); 0328 0329 const QUrl baseUrl = QUrl::fromLocalFile(gitTest_BaseDir()); 0330 VcsJob* j = m_plugin->branches(baseUrl); 0331 VERIFYJOB(j); 0332 QString curBranch = runSynchronously(m_plugin->currentBranch(baseUrl)).toString(); 0333 QCOMPARE(curBranch, QStringLiteral("master")); 0334 0335 VcsRevision rev; 0336 rev.setRevisionValue("master", KDevelop::VcsRevision::GlobalNumber); 0337 0338 j = m_plugin->branch(baseUrl, rev, branchNames[0]); 0339 VERIFYJOB(j); 0340 0341 qDebug() << "Adding files to the new branch"; 0342 0343 //we start it after repoInit, so we still have empty git repo 0344 QVERIFY(writeFile(gitTest_BaseDir() + files[0], content)); 0345 QVERIFY(writeFile(gitTest_BaseDir() + files[1], content)); 0346 0347 QList<QUrl> listOfAddedFiles{QUrl::fromLocalFile(gitTest_BaseDir() + files[0]), 0348 QUrl::fromLocalFile(gitTest_BaseDir() + files[1])}; 0349 0350 j = m_plugin->add(listOfAddedFiles); 0351 VERIFYJOB(j); 0352 0353 j = m_plugin->commit(QStringLiteral("Committing to the new branch"), QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0354 VERIFYJOB(j); 0355 0356 j = m_plugin->switchBranch(baseUrl, QStringLiteral("master")); 0357 VERIFYJOB(j); 0358 0359 j = m_plugin->mergeBranch(baseUrl, branchNames[0]); 0360 VERIFYJOB(j); 0361 0362 auto jobLs = new DVcsJob(gitTest_BaseDir(), m_plugin); 0363 *jobLs << "git" << "ls-tree" << "--name-only" << "-r" << "HEAD" ; 0364 0365 if (jobLs->exec() && jobLs->status() == KDevelop::VcsJob::JobSucceeded) { 0366 QStringList files = jobLs->output().split('\n'); 0367 qDebug() << "Files in this Branch: " << files; 0368 QVERIFY(files.contains(files[0])); 0369 QVERIFY(files.contains(files[1])); 0370 } 0371 0372 //Testing one more time. 0373 j = m_plugin->switchBranch(baseUrl, branchNames[0]); 0374 VERIFYJOB(j); 0375 rev.setRevisionValue(branchNames[0], KDevelop::VcsRevision::GlobalNumber); 0376 j = m_plugin->branch(baseUrl, rev, branchNames[1]); 0377 VERIFYJOB(j); 0378 QVERIFY(writeFile(gitTest_BaseDir() + files[2], content)); 0379 j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + files[2])); 0380 VERIFYJOB(j); 0381 j = m_plugin->commit(QStringLiteral("Committing to AnotherBranch"), QList<QUrl>() << baseUrl); 0382 VERIFYJOB(j); 0383 j = m_plugin->switchBranch(baseUrl, branchNames[0]); 0384 VERIFYJOB(j); 0385 j = m_plugin->mergeBranch(baseUrl, branchNames[1]); 0386 VERIFYJOB(j); 0387 qDebug() << j->errorString() ; 0388 0389 jobLs = new DVcsJob(gitTest_BaseDir(), m_plugin); 0390 *jobLs << "git" << "ls-tree" << "--name-only" << "-r" << "HEAD" ; 0391 0392 if (jobLs->exec() && jobLs->status() == KDevelop::VcsJob::JobSucceeded) { 0393 QStringList files = jobLs->output().split('\n'); 0394 QVERIFY(files.contains(files[2])); 0395 qDebug() << "Files in this Branch: " << files; 0396 } 0397 0398 j = m_plugin->switchBranch(baseUrl, QStringLiteral("master")); 0399 VERIFYJOB(j); 0400 j = m_plugin->mergeBranch(baseUrl, branchNames[1]); 0401 VERIFYJOB(j); 0402 qDebug() << j->errorString() ; 0403 0404 jobLs = new DVcsJob(gitTest_BaseDir(), m_plugin); 0405 *jobLs << "git" << "ls-tree" << "--name-only" << "-r" << "HEAD" ; 0406 0407 if (jobLs->exec() && jobLs->status() == KDevelop::VcsJob::JobSucceeded) { 0408 QStringList files = jobLs->output().split('\n'); 0409 QVERIFY(files.contains(files[2])); 0410 qDebug() << "Files in this Branch: " << files; 0411 } 0412 0413 } 0414 0415 void GitInitTest::testBranching() 0416 { 0417 repoInit(); 0418 addFiles(); 0419 commitFiles(); 0420 0421 const QUrl baseUrl = QUrl::fromLocalFile(gitTest_BaseDir()); 0422 VcsJob* j = m_plugin->branches(baseUrl); 0423 VERIFYJOB(j); 0424 0425 QString curBranch = runSynchronously(m_plugin->currentBranch(baseUrl)).toString(); 0426 QCOMPARE(curBranch, QStringLiteral("master")); 0427 0428 testBranch(QStringLiteral("new")); 0429 testBranch(QStringLiteral("averylongbranchnamejusttotestlongnames")); 0430 testBranch(QStringLiteral("KDE/4.10")); 0431 } 0432 0433 void GitInitTest::revHistory() 0434 { 0435 repoInit(); 0436 addFiles(); 0437 commitFiles(); 0438 0439 const QVector<KDevelop::DVcsEvent> commits = m_plugin->allCommits(gitTest_BaseDir()); 0440 QVERIFY(!commits.isEmpty()); 0441 QStringList logMessages; 0442 0443 for (auto& commit : commits) 0444 logMessages << commit.log(); 0445 0446 QCOMPARE(commits.count(), 2); 0447 0448 QCOMPARE(logMessages[0], QStringLiteral("KDevelop's Test commit2")); //0 is later than 1! 0449 0450 QCOMPARE(logMessages[1], QStringLiteral("Test commit")); 0451 0452 QVERIFY(commits[1].parents().isEmpty()); //0 is later than 1! 0453 0454 QVERIFY(!commits[0].parents().isEmpty()); //initial commit is on the top 0455 0456 QVERIFY(commits[1].commit().contains(QRegExp("^\\w{,40}$"))); 0457 0458 QVERIFY(commits[0].commit().contains(QRegExp("^\\w{,40}$"))); 0459 0460 QVERIFY(commits[0].parents()[0].contains(QRegExp("^\\w{,40}$"))); 0461 } 0462 0463 void GitInitTest::testAnnotation() 0464 { 0465 repoInit(); 0466 addFiles(); 0467 commitFiles(); 0468 0469 // called after commitFiles 0470 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("An appended line"), QIODevice::Append)); 0471 0472 VcsJob* j = m_plugin->commit(QStringLiteral("KDevelop's Test commit3"), QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0473 VERIFYJOB(j); 0474 0475 j = m_plugin->annotate(QUrl::fromLocalFile(gitTest_BaseDir() + gitTest_FileName()), VcsRevision::createSpecialRevision(VcsRevision::Head)); 0476 VERIFYJOB(j); 0477 0478 QList<QVariant> results = j->fetchResults().toList(); 0479 QCOMPARE(results.size(), 2); 0480 QVERIFY(results.at(0).canConvert<VcsAnnotationLine>()); 0481 VcsAnnotationLine annotation = results.at(0).value<VcsAnnotationLine>(); 0482 QCOMPARE(annotation.lineNumber(), 0); 0483 QCOMPARE(annotation.commitMessage(), QStringLiteral("KDevelop's Test commit2")); 0484 0485 QVERIFY(results.at(1).canConvert<VcsAnnotationLine>()); 0486 annotation = results.at(1).value<VcsAnnotationLine>(); 0487 QCOMPARE(annotation.lineNumber(), 1); 0488 QCOMPARE(annotation.commitMessage(), QStringLiteral("KDevelop's Test commit3")); 0489 } 0490 0491 void GitInitTest::testRemoveEmptyFolder() 0492 { 0493 repoInit(); 0494 0495 QDir d(gitTest_BaseDir()); 0496 d.mkdir(QStringLiteral("emptydir")); 0497 0498 VcsJob* j = m_plugin->remove(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir()+"emptydir/")); 0499 if (j) VERIFYJOB(j); 0500 0501 QVERIFY(!d.exists(QStringLiteral("emptydir"))); 0502 } 0503 0504 void GitInitTest::testRemoveEmptyFolderInFolder() 0505 { 0506 repoInit(); 0507 0508 QDir d(gitTest_BaseDir()); 0509 d.mkdir(QStringLiteral("dir")); 0510 0511 QDir d2(gitTest_BaseDir()+"dir"); 0512 d2.mkdir(QStringLiteral("emptydir")); 0513 0514 VcsJob* j = m_plugin->remove(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir()+"dir/")); 0515 if (j) VERIFYJOB(j); 0516 0517 QVERIFY(!d.exists(QStringLiteral("dir"))); 0518 } 0519 0520 void GitInitTest::testRemoveUnindexedFile() 0521 { 0522 repoInit(); 0523 0524 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("An appended line"), QIODevice::Append)); 0525 0526 VcsJob* j = m_plugin->remove(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + gitTest_FileName())); 0527 if (j) VERIFYJOB(j); 0528 0529 QVERIFY(!QFile::exists(gitTest_BaseDir() + gitTest_FileName())); 0530 } 0531 0532 void GitInitTest::testRemoveFolderContainingUnversionedFiles() 0533 { 0534 repoInit(); 0535 0536 QDir d(gitTest_BaseDir()); 0537 d.mkdir(QStringLiteral("dir")); 0538 0539 QVERIFY(writeFile(gitTest_BaseDir() + "dir/foo", QStringLiteral("An appended line"), QIODevice::Append)); 0540 VcsJob* j = m_plugin->add(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir()+"dir")); 0541 VERIFYJOB(j); 0542 j = m_plugin->commit(QStringLiteral("initial commit"), QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir())); 0543 VERIFYJOB(j); 0544 0545 QVERIFY(writeFile(gitTest_BaseDir() + "dir/bar", QStringLiteral("An appended line"), QIODevice::Append)); 0546 0547 j = m_plugin->remove(QList<QUrl>() << QUrl::fromLocalFile(gitTest_BaseDir() + "dir")); 0548 if (j) VERIFYJOB(j); 0549 0550 QVERIFY(!QFile::exists(gitTest_BaseDir() + "dir")); 0551 0552 } 0553 0554 0555 void GitInitTest::removeTempDirs() 0556 { 0557 const auto dirPath = gitTest_BaseDir(); 0558 QDir dir(dirPath); 0559 if (dir.exists() && !dir.removeRecursively()) { 0560 qDebug() << "QDir::removeRecursively(" << dirPath << ") returned false"; 0561 } 0562 } 0563 0564 void GitInitTest::testDiff() 0565 { 0566 repoInit(); 0567 addFiles(); 0568 commitFiles(); 0569 0570 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("something else"))); 0571 0572 VcsRevision srcrev = VcsRevision::createSpecialRevision(VcsRevision::Base); 0573 VcsRevision dstrev = VcsRevision::createSpecialRevision(VcsRevision::Working); 0574 VcsJob* j = m_plugin->diff(QUrl::fromLocalFile(gitTest_BaseDir()), srcrev, dstrev, IBasicVersionControl::Recursive); 0575 VERIFYJOB(j); 0576 0577 KDevelop::VcsDiff d = j->fetchResults().value<KDevelop::VcsDiff>(); 0578 QVERIFY(d.baseDiff().isLocalFile()); 0579 QString path = d.baseDiff().toLocalFile(); 0580 QVERIFY(QDir().exists(path+"/.git")); 0581 } 0582 0583 void GitInitTest::testStash() 0584 { 0585 repoInit(); 0586 addFiles(); 0587 commitFiles(); 0588 const QVector<KDevelop::DVcsEvent> commits = m_plugin->allCommits(gitTest_BaseDir()); 0589 QVERIFY(!commits.isEmpty()); 0590 QStringList logMessages; 0591 0592 for (auto& commit : commits) 0593 logMessages << commit.log(); 0594 0595 auto repo_url = QUrl::fromLocalFile(gitTest_BaseDir()); 0596 0597 // No stash 0598 QVERIFY(!m_plugin->hasStashes(gitTest_BaseDir())); 0599 VcsJob* j = m_plugin->stashList(gitTest_BaseDir()); 0600 VERIFYJOB(j); 0601 QVERIFY(j->fetchResults().value<QList<GitPlugin::StashItem>>().isEmpty()); 0602 0603 // Do some changes 0604 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), QStringLiteral("NEW CONTENT TO STASH"))); 0605 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName2(), QStringLiteral("No, REALLY NEW FOOO()!"))); 0606 0607 // Verify stashing works 0608 j = m_plugin->gitStash(gitTest_BaseDir(), {}, OutputJob::Silent); 0609 VERIFYJOB(j); 0610 QVERIFY(m_plugin->hasStashes(gitTest_BaseDir())); 0611 0612 // Verify stash list gives us the single stash 0613 j = m_plugin->stashList(gitTest_BaseDir()); 0614 VERIFYJOB(j); 0615 auto items = j->fetchResults().value<QList<GitPlugin::StashItem>>(); 0616 QVERIFY(items.length() == 1); 0617 QVERIFY(items[0].stackDepth == 0); 0618 QVERIFY(items[0].branch == runSynchronously(m_plugin->currentBranch(repo_url)).toString()); 0619 QVERIFY(commits[0].commit() == items[0].parentSHA); 0620 0621 // Verify stash on new branch gives us correct parent branch 0622 // 0623 // 1. switch to a new branch 0624 auto rev = KDevelop::VcsRevision::createSpecialRevision(KDevelop::VcsRevision::Head); 0625 j = m_plugin->branch(repo_url, rev, QStringLiteral("my-new-branch")); 0626 VERIFYJOB(j); 0627 j = m_plugin->switchBranch(repo_url, QStringLiteral("my-new-branch")); 0628 VERIFYJOB(j); 0629 0630 // 2. Do more changes & stash them 0631 QString testFileContent = QStringLiteral("2. NEW CONTENT TO STASH"); 0632 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName(), testFileContent)); 0633 QVERIFY(writeFile(gitTest_BaseDir() + gitTest_FileName2(), QStringLiteral("2. No, REALLY NEW FOOO()!"))); 0634 j = m_plugin->gitStash(gitTest_BaseDir(), {}, OutputJob::Silent); 0635 VERIFYJOB(j); 0636 QFile testFile(gitTest_BaseDir() + gitTest_FileName()); 0637 testFile.open(QIODevice::ReadOnly); 0638 auto testFileContentAfterStash = QString::fromUtf8(testFile.readAll()); 0639 testFile.close(); 0640 QVERIFY(testFileContent != testFileContentAfterStash); 0641 0642 0643 // 3. Verify stash list gives us a new stash 0644 j = m_plugin->stashList(gitTest_BaseDir()); 0645 VERIFYJOB(j); 0646 items = j->fetchResults().value<QList<GitPlugin::StashItem>>(); 0647 QVERIFY(items.length() == 2); 0648 0649 // 4. Find the newest stash 0650 bool found = false; 0651 for(const auto& item : items) { 0652 if (item.stackDepth != 0) continue; 0653 // 5. Verify that the new branch is parent of the new stash 0654 QVERIFY(item.branch == QStringLiteral("my-new-branch")); 0655 found = true; 0656 } 0657 QVERIFY(found); 0658 0659 // Verify that stash pop recreates the contents and drops the stash item 0660 j = m_plugin->gitStash(gitTest_BaseDir(), {QStringLiteral("pop")}, OutputJob::Silent); 0661 VERIFYJOB(j); 0662 testFile.open(QIODevice::ReadOnly); 0663 auto testFileContentAfterPop = QString::fromUtf8(testFile.readAll()); 0664 QVERIFY(testFileContentAfterPop == testFileContent); 0665 j = m_plugin->stashList(gitTest_BaseDir()); 0666 VERIFYJOB(j); 0667 items = j->fetchResults().value<QList<GitPlugin::StashItem>>(); 0668 QVERIFY(items.length() == 1); 0669 0670 } 0671 0672 QTEST_MAIN(GitInitTest) 0673 0674 // #include "gittest.moc" 0675 #include "moc_test_git.cpp"