forked from qt-creator/qt-creator
VcsManager: Add unit tests
Add some unit tests to the VcsManager to test the detection and caching of version control systems. Change-Id: I2b3f9218c12aebde8a8120fc869efc76c36ae41a Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
@@ -57,6 +57,12 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void fileOpenRequest(const QString&);
|
void fileOpenRequest(const QString&);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
#if defined(WITH_TESTS)
|
||||||
|
void testVcsManager_data();
|
||||||
|
void testVcsManager();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseArguments(const QStringList & arguments);
|
void parseArguments(const QStringList & arguments);
|
||||||
|
|
||||||
|
|||||||
@@ -52,4 +52,58 @@ IVersionControl::OpenSupportMode IVersionControl::openSupportMode(const QString
|
|||||||
return NoOpen;
|
return NoOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Core
|
||||||
|
|
||||||
|
#if defined(WITH_TESTS)
|
||||||
|
|
||||||
|
#include "vcsmanager.h"
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
TestVersionControl::~TestVersionControl()
|
||||||
|
{
|
||||||
|
VcsManager::instance()->clearVersionControlCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestVersionControl::setManagedDirectories(const QHash<QString, QString> &dirs)
|
||||||
|
{
|
||||||
|
m_managedDirs = dirs;
|
||||||
|
m_dirCount = 0;
|
||||||
|
VcsManager::instance()->clearVersionControlCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVersionControl::setManagedFiles(const QSet<QString> &files)
|
||||||
|
{
|
||||||
|
m_managedFiles = files;
|
||||||
|
m_fileCount = 0;
|
||||||
|
VcsManager::instance()->clearVersionControlCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestVersionControl::managesDirectory(const QString &filename, QString *topLevel) const
|
||||||
|
{
|
||||||
|
++m_dirCount;
|
||||||
|
|
||||||
|
if (m_managedDirs.contains(filename)) {
|
||||||
|
if (topLevel)
|
||||||
|
*topLevel = m_managedDirs.value(filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestVersionControl::managesFile(const QString &workingDirectory, const QString &fileName) const
|
||||||
|
{
|
||||||
|
++m_fileCount;
|
||||||
|
|
||||||
|
QFileInfo fi(workingDirectory + QLatin1Char('/') + fileName);
|
||||||
|
QString dir = fi.absolutePath();
|
||||||
|
if (!managesDirectory(dir, 0))
|
||||||
|
return false;
|
||||||
|
QString file = fi.absoluteFilePath();
|
||||||
|
return m_managedFiles.contains(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -188,4 +188,54 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Core::IVersionControl::SettingsFlags)
|
|||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
#if defined(WITH_TESTS)
|
||||||
|
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class CORE_EXPORT TestVersionControl : public IVersionControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TestVersionControl(Core::Id id, const QString &name) :
|
||||||
|
m_id(id), m_displayName(name), m_dirCount(0), m_fileCount(0)
|
||||||
|
{ }
|
||||||
|
~TestVersionControl();
|
||||||
|
|
||||||
|
void setManagedDirectories(const QHash<QString, QString> &dirs);
|
||||||
|
void setManagedFiles(const QSet<QString> &files);
|
||||||
|
|
||||||
|
int dirCount() const { return m_dirCount; }
|
||||||
|
int fileCount() const { return m_fileCount; }
|
||||||
|
|
||||||
|
// IVersionControl interface
|
||||||
|
QString displayName() const { return m_displayName; }
|
||||||
|
Id id() const { return m_id; }
|
||||||
|
bool managesDirectory(const QString &filename, QString *topLevel) const;
|
||||||
|
bool managesFile(const QString &workingDirectory, const QString &fileName) const;
|
||||||
|
bool isConfigured() const { return true; }
|
||||||
|
bool supportsOperation(Operation) const { return false; }
|
||||||
|
bool vcsOpen(const QString &) { return false; }
|
||||||
|
bool vcsAdd(const QString &) { return false; }
|
||||||
|
bool vcsDelete(const QString &) { return false; }
|
||||||
|
bool vcsMove(const QString &, const QString &) { return false; }
|
||||||
|
bool vcsCreateRepository(const QString &) { return false; }
|
||||||
|
bool vcsCheckout(const QString &, const QByteArray &) { return false; }
|
||||||
|
QString vcsGetRepositoryURL(const QString &) { return QString(); }
|
||||||
|
bool vcsAnnotate(const QString &, int) { return false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Id m_id;
|
||||||
|
QString m_displayName;
|
||||||
|
QHash<QString, QString> m_managedDirs;
|
||||||
|
QSet<QString> m_managedFiles;
|
||||||
|
mutable int m_dirCount;
|
||||||
|
mutable int m_fileCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // IVERSIONCONTROL_H
|
#endif // IVERSIONCONTROL_H
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ static inline VersionControlList allVersionControls()
|
|||||||
return ExtensionSystem::PluginManager::getObjects<IVersionControl>();
|
return ExtensionSystem::PluginManager::getObjects<IVersionControl>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WITH_TESTS)
|
||||||
|
const char TEST_PREFIX[] = "/8E3A9BA0-0B97-40DF-AEC1-2BDF9FC9EDBE/";
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---- VCSManagerPrivate:
|
// ---- VCSManagerPrivate:
|
||||||
// Maintains a cache of top-level directory->version control.
|
// Maintains a cache of top-level directory->version control.
|
||||||
|
|
||||||
@@ -274,6 +278,11 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input
|
|||||||
|
|
||||||
// Register Vcs(s) with the cache
|
// Register Vcs(s) with the cache
|
||||||
QString tmpDir = QFileInfo(directory).canonicalFilePath();
|
QString tmpDir = QFileInfo(directory).canonicalFilePath();
|
||||||
|
#if defined WITH_TESTS
|
||||||
|
// Force caching of test directories (even though they do not exist):
|
||||||
|
if (directory.startsWith(QLatin1String(TEST_PREFIX)))
|
||||||
|
tmpDir = directory;
|
||||||
|
#endif
|
||||||
// directory might refer to a historical directory which doesn't exist.
|
// directory might refer to a historical directory which doesn't exist.
|
||||||
// In this case, don't cache it.
|
// In this case, don't cache it.
|
||||||
if (!tmpDir.isEmpty()) {
|
if (!tmpDir.isEmpty()) {
|
||||||
@@ -450,3 +459,181 @@ void VcsManager::configureVcs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
#if defined(WITH_TESTS)
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
#include "coreplugin.h"
|
||||||
|
#include "iversioncontrol.h"
|
||||||
|
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
const char ID_VCS_A[] = "A";
|
||||||
|
const char ID_VCS_B[] = "B";
|
||||||
|
|
||||||
|
typedef QHash<QString, QString> FileHash;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class ObjectPoolGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObjectPoolGuard(T *watch) : m_watched(watch)
|
||||||
|
{
|
||||||
|
ExtensionSystem::PluginManager::addObject(watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() { return m_watched; }
|
||||||
|
bool operator !() { return !m_watched; }
|
||||||
|
T &operator*() { return *m_watched; }
|
||||||
|
T *operator->() { return m_watched; }
|
||||||
|
T *value() { return m_watched; }
|
||||||
|
|
||||||
|
~ObjectPoolGuard()
|
||||||
|
{
|
||||||
|
ExtensionSystem::PluginManager::removeObject(m_watched);
|
||||||
|
delete m_watched;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *m_watched;
|
||||||
|
};
|
||||||
|
|
||||||
|
static FileHash makeHash(const QStringList &list)
|
||||||
|
{
|
||||||
|
FileHash result;
|
||||||
|
foreach (const QString &i, list) {
|
||||||
|
QStringList parts = i.split(QLatin1Char(':'));
|
||||||
|
QTC_ASSERT(parts.count() == 2, continue);
|
||||||
|
result.insert(QString::fromLatin1(TEST_PREFIX) + parts.at(0),
|
||||||
|
QString::fromLatin1(TEST_PREFIX) + parts.at(1));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString makeString(const QString &s)
|
||||||
|
{
|
||||||
|
if (s.isEmpty())
|
||||||
|
return QString();
|
||||||
|
return QString::fromLatin1(TEST_PREFIX) + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorePlugin::testVcsManager_data()
|
||||||
|
{
|
||||||
|
// avoid conflicts with real files and directories:
|
||||||
|
|
||||||
|
QTest::addColumn<QStringList>("dirsVcsA"); // <directory>:<toplevel>
|
||||||
|
QTest::addColumn<QStringList>("dirsVcsB"); // <directory>:<toplevel>
|
||||||
|
// <directory>:<toplevel>:<vcsid>:<- from cache, * from VCS>
|
||||||
|
QTest::addColumn<QStringList>("results");
|
||||||
|
|
||||||
|
QTest::newRow("A and B next to each other")
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String("a:a") << QLatin1String("a/1:a") << QLatin1String("a/2:a")
|
||||||
|
<< QLatin1String("a/2/5:a") << QLatin1String("a/2/5/6:a"))
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String("b:b") << QLatin1String("b/3:b") << QLatin1String("b/4:b"))
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String(":::-") // empty directory to look up
|
||||||
|
<< QLatin1String("c:::*") // Neither in A nor B
|
||||||
|
<< QLatin1String("a:a:A:*") // in A
|
||||||
|
<< QLatin1String("b:b:B:*") // in B
|
||||||
|
<< QLatin1String("b/3:b:B:*") // in B
|
||||||
|
<< QLatin1String("b/4:b:B:*") // in B
|
||||||
|
<< QLatin1String("a/1:a:A:*") // in A
|
||||||
|
<< QLatin1String("a/2:a:A:*") // in A
|
||||||
|
<< QLatin1String(":::-") // empty directory to look up
|
||||||
|
<< QLatin1String("a/2/5/6:a:A:*") // in A
|
||||||
|
<< QLatin1String("a/2/5:a:A:-") // in A (cached from before!)
|
||||||
|
// repeat: These need to come from the cache now:
|
||||||
|
<< QLatin1String("c:::-") // Neither in A nor B
|
||||||
|
<< QLatin1String("a:a:A:-") // in A
|
||||||
|
<< QLatin1String("b:b:B:-") // in B
|
||||||
|
<< QLatin1String("b/3:b:B:-") // in B
|
||||||
|
<< QLatin1String("b/4:b:B:-") // in B
|
||||||
|
<< QLatin1String("a/1:a:A:-") // in A
|
||||||
|
<< QLatin1String("a/2:a:A:-") // in A
|
||||||
|
<< QLatin1String("a/2/5/6:a:A:-") // in A
|
||||||
|
<< QLatin1String("a/2/5:a:A:-") // in A
|
||||||
|
);
|
||||||
|
QTest::newRow("B in A")
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String("a:a") << QLatin1String("a/1:a") << QLatin1String("a/2:a")
|
||||||
|
<< QLatin1String("a/2/5:a") << QLatin1String("a/2/5/6:a"))
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String("a/1/b:a/1/b") << QLatin1String("a/1/b/3:a/1/b")
|
||||||
|
<< QLatin1String("a/1/b/4:a/1/b") << QLatin1String("a/1/b/3/5:a/1/b")
|
||||||
|
<< QLatin1String("a/1/b/3/5/6:a/1/b"))
|
||||||
|
<< (QStringList()
|
||||||
|
<< QLatin1String("a:a:A:*") // in A
|
||||||
|
<< QLatin1String("c:::*") // Neither in A nor B
|
||||||
|
<< QLatin1String("a/3:::*") // Neither in A nor B
|
||||||
|
<< QLatin1String("a/1/b/x:::*") // Neither in A nor B
|
||||||
|
<< QLatin1String("a/1/b:a/1/b:B:*") // in B
|
||||||
|
<< QLatin1String("a/1:a:A:*") // in A
|
||||||
|
<< QLatin1String("a/1/b/../../2:a:A:*") // in A
|
||||||
|
);
|
||||||
|
QTest::newRow("A and B") // first one wins...
|
||||||
|
<< (QStringList() << QLatin1String("a:a") << QLatin1String("a/1:a") << QLatin1String("a/2:a"))
|
||||||
|
<< (QStringList() << QLatin1String("a:a") << QLatin1String("a/1:a") << QLatin1String("a/2:a"))
|
||||||
|
<< (QStringList() << QLatin1String("a/2:a:A:*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CorePlugin::testVcsManager()
|
||||||
|
{
|
||||||
|
// setup:
|
||||||
|
ObjectPoolGuard<TestVersionControl> vcsA(new TestVersionControl(ID_VCS_A, QLatin1String("A")));
|
||||||
|
ObjectPoolGuard<TestVersionControl> vcsB(new TestVersionControl(ID_VCS_B, QLatin1String("B")));
|
||||||
|
|
||||||
|
// test:
|
||||||
|
QFETCH(QStringList, dirsVcsA);
|
||||||
|
QFETCH(QStringList, dirsVcsB);
|
||||||
|
QFETCH(QStringList, results);
|
||||||
|
|
||||||
|
vcsA->setManagedDirectories(makeHash(dirsVcsA));
|
||||||
|
vcsB->setManagedDirectories(makeHash(dirsVcsB));
|
||||||
|
|
||||||
|
QString realTopLevel = QLatin1String("ABC"); // Make sure this gets cleared if needed.
|
||||||
|
|
||||||
|
// From VCSes:
|
||||||
|
int expectedCount = 0;
|
||||||
|
foreach (const QString &result, results) {
|
||||||
|
// qDebug() << "Expecting:" << result;
|
||||||
|
|
||||||
|
QStringList split = result.split(QLatin1String(":"));
|
||||||
|
QCOMPARE(split.count(), 4);
|
||||||
|
QVERIFY(split.at(3) == QLatin1String("*") || split.at(3) == QLatin1String("-"));
|
||||||
|
|
||||||
|
|
||||||
|
const QString directory = split.at(0);
|
||||||
|
const QString topLevel = split.at(1);
|
||||||
|
const QString vcsId = split.at(2);
|
||||||
|
bool fromCache = split.at(3) == QLatin1String("-");
|
||||||
|
|
||||||
|
if (!fromCache && !directory.isEmpty())
|
||||||
|
++expectedCount;
|
||||||
|
|
||||||
|
IVersionControl *vcs;
|
||||||
|
vcs = VcsManager::findVersionControlForDirectory(makeString(directory), &realTopLevel);
|
||||||
|
QCOMPARE(realTopLevel, makeString(topLevel));
|
||||||
|
if (vcs)
|
||||||
|
QCOMPARE(vcs->id().toString(), vcsId);
|
||||||
|
else
|
||||||
|
QCOMPARE(QString(), vcsId);
|
||||||
|
QCOMPARE(vcsA->dirCount(), expectedCount);
|
||||||
|
QCOMPARE(vcsA->fileCount(), 0);
|
||||||
|
QCOMPARE(vcsB->dirCount(), expectedCount);
|
||||||
|
QCOMPARE(vcsB->fileCount(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// teardown:
|
||||||
|
// handled by guards
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Core
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user