diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 4aaa404065c..a5d484c1bc2 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -44,14 +44,14 @@ namespace ProjectExplorer { -static const Core::Id KIT_IS_TEMPORARY("PE.TempKit"); -static const Core::Id KIT_TEMPORARY_NAME("PE.TempName"); -static const Core::Id KIT_FINAL_NAME("PE.FinalName"); -static const Core::Id TEMPORARY_OF_PROJECTS("PE.TempProject"); +static const Core::Id KIT_IS_TEMPORARY("PE.tmp.isTemporary"); +static const Core::Id KIT_TEMPORARY_NAME("PE.tmp.Name"); +static const Core::Id KIT_FINAL_NAME("PE.tmp.FinalName"); +static const Core::Id TEMPORARY_OF_PROJECTS("PE.tmp.ForProjects"); static Core::Id fullId(Core::Id id) { - const QString prefix = "PE.Temporary."; + const QString prefix = "PE.tmp."; const QString idStr = id.toString(); QTC_ASSERT(!idStr.startsWith(prefix), return Core::Id::fromString(idStr)); @@ -64,7 +64,7 @@ static bool hasOtherUsers(Core::Id id, const QVariant &v, Kit *k) return Utils::contains(KitManager::kits(), [id, v, k](Kit *in) -> bool { if (in == k) return false; - QVariantList tmp = in->value(id).toList(); + const QVariantList tmp = in->value(id).toList(); return tmp.contains(v); }); } @@ -107,7 +107,9 @@ QList ProjectImporter::import(const Utils::FileName &importPath, bo const QList tmp = Utils::filtered(KitManager::kits(), [this, data](Kit *k) { return matchKit(data, k); }); if (tmp.isEmpty()) { - kitList += createKit(data); + Kit *k = createKit(data); + if (k) + kitList.append(k); qCDebug(log) << " no matching kit found, temporary kit created."; } else { kitList += tmp; @@ -122,8 +124,6 @@ QList ProjectImporter::import(const Utils::FileName &importPath, bo continue; } - addProject(k); - foreach (BuildInfo *i, infoList) { if (!Utils::contains(result, [i](const BuildInfo *o) { return (*i) == (*o); })) result += i; @@ -206,34 +206,41 @@ void ProjectImporter::makePersistent(Kit *k) const // Mark permanent in all other kits: foreach (Kit *ok, KitManager::kits()) { - if (ok == k) + if (ok == k || !ok->hasValue(fid)) continue; - - QVariantList otherTemporaryValues = ok->value(fid).toList(); - otherTemporaryValues = Utils::filtered(otherTemporaryValues, [&temporaryValues](const QVariant &v) { - return temporaryValues.contains(v); + const QVariantList otherTemporaryValues + = Utils::filtered(ok->value(fid).toList(), [&temporaryValues](const QVariant &v) { + return !temporaryValues.contains(v); }); ok->setValueSilently(fid, otherTemporaryValues); } // persist: tih.persist(k, temporaryValues); + k->removeKeySilently(fid); } } -void ProjectImporter::cleanupKit(Kit *k) +void ProjectImporter::cleanupKit(Kit *k) const { foreach (const TemporaryInformationHandler &tih, m_temporaryHandlers) { const Core::Id fid = fullId(tih.id); - QVariantList temporaryValues = k->value(fid).toList(); - temporaryValues = Utils::filtered(temporaryValues, [fid, k](const QVariant &v) { + const QVariantList temporaryValues + = Utils::filtered(k->value(fid).toList(), [fid, k](const QVariant &v) { return !hasOtherUsers(fid, v, k); }); tih.cleanup(k, temporaryValues); + k->removeKeySilently(fid); } + + // remove keys to manage temporary state of kit: + k->removeKeySilently(KIT_IS_TEMPORARY); + k->removeKeySilently(TEMPORARY_OF_PROJECTS); + k->removeKeySilently(KIT_FINAL_NAME); + k->removeKeySilently(KIT_TEMPORARY_NAME); } -void ProjectImporter::addProject(Kit *k) +void ProjectImporter::addProject(Kit *k) const { if (!k->hasValue(KIT_IS_TEMPORARY)) return; @@ -244,7 +251,7 @@ void ProjectImporter::addProject(Kit *k) k->setValueSilently(TEMPORARY_OF_PROJECTS, projects); } -void ProjectImporter::removeProject(Kit *k) +void ProjectImporter::removeProject(Kit *k) const { if (!k->hasValue(KIT_IS_TEMPORARY)) return; @@ -253,10 +260,12 @@ void ProjectImporter::removeProject(Kit *k) QStringList projects = k->value(TEMPORARY_OF_PROJECTS, QStringList()).toStringList(); projects.removeOne(m_projectPath); - if (projects.isEmpty()) + if (projects.isEmpty()) { + cleanupKit(k); KitManager::deregisterKit(k); - else + } else { k->setValueSilently(TEMPORARY_OF_PROJECTS, projects); + } } bool ProjectImporter::isTemporaryKit(Kit *k) const @@ -271,13 +280,18 @@ Kit *ProjectImporter::createTemporaryKit(const KitSetupFunction &setup) const { KitGuard kitGuard(k); k->setUnexpandedDisplayName(QCoreApplication::translate("ProjectExplorer::ProjectImporter", "Imported Kit"));; - markKitAsTemporary(k); - - setup(k); // Set up values: foreach (KitInformation *ki, KitManager::kitInformation()) ki->setup(k); + + setup(k); + + foreach (KitInformation *ki, KitManager::kitInformation()) + ki->fix(k); + + markKitAsTemporary(k); + addProject(k); } // ~KitGuard, sending kitUpdated KitManager::registerKit(k); // potentially adds kits to other targetsetuppages return k; diff --git a/src/plugins/projectexplorer/projectimporter.h b/src/plugins/projectexplorer/projectimporter.h index c44829e713e..50d98b275a6 100644 --- a/src/plugins/projectexplorer/projectimporter.h +++ b/src/plugins/projectexplorer/projectimporter.h @@ -54,12 +54,12 @@ public: bool isUpdating() const { return m_isUpdating; } void makePersistent(Kit *k) const; - void cleanupKit(Kit *k); + void cleanupKit(Kit *k) const; bool isTemporaryKit(Kit *k) const; - void addProject(Kit *k); - void removeProject(Kit *k); + void addProject(Kit *k) const; + void removeProject(Kit *k) const; protected: class UpdateGuard diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp index 112e4b06b68..48891e8b522 100644 --- a/src/plugins/qtsupport/qtprojectimporter.cpp +++ b/src/plugins/qtsupport/qtprojectimporter.cpp @@ -58,9 +58,7 @@ QtProjectImporter::findOrCreateQtVersion(const Utils::FileName &qmakePath) const result.qt = Utils::findOrDefault(QtVersionManager::unsortedVersions(), [&qmakePath](BaseQtVersion *v) -> bool { - QFileInfo vfi = v->qmakeCommand().toFileInfo(); - Utils::FileName current = Utils::FileName::fromString(vfi.canonicalFilePath()); - return current == qmakePath; + return qmakePath == v->qmakeCommand(); }); if (result.qt) { @@ -87,10 +85,12 @@ Kit *QtProjectImporter::createTemporaryKit(const QtVersionData &versionData, { return ProjectImporter::createTemporaryKit([&additionalSetup, &versionData, this](Kit *k) -> void { QtKitInformation::setQtVersion(k, versionData.qt); - if (versionData.isTemporary) - addTemporaryData(QtKitInformation::id(), versionData.qt->uniqueId(), k); + if (versionData.qt) { + if (versionData.isTemporary) + addTemporaryData(QtKitInformation::id(), versionData.qt->uniqueId(), k); - k->setUnexpandedDisplayName(versionData.qt->displayName());; + k->setUnexpandedDisplayName(versionData.qt->displayName());; + } additionalSetup(k); }); @@ -106,18 +106,22 @@ static BaseQtVersion *versionFromVariant(const QVariant &v) void QtProjectImporter::cleanupTemporaryQt(Kit *k, const QVariantList &vl) { - Q_UNUSED(k); - + if (vl.isEmpty()) + return; // No temporary Qt QTC_ASSERT(vl.count() == 1, return); BaseQtVersion *version = versionFromVariant(vl.at(0)); QTC_ASSERT(version, return); QtVersionManager::removeVersion(version); + QtKitInformation::setQtVersion(k, nullptr); // Always mark Kit as not using this Qt } void QtProjectImporter::persistTemporaryQt(Kit *k, const QVariantList &vl) { + if (vl.isEmpty()) + return; // No temporary Qt QTC_ASSERT(vl.count() == 1, return); - BaseQtVersion *tmpVersion = versionFromVariant(vl.at(0)); + const QVariant data = vl.at(0); + BaseQtVersion *tmpVersion = versionFromVariant(data); BaseQtVersion *actualVersion = QtKitInformation::qtVersion(k); // User changed Kit away from temporary Qt that was set up: @@ -125,4 +129,491 @@ void QtProjectImporter::persistTemporaryQt(Kit *k, const QVariantList &vl) QtVersionManager::removeVersion(tmpVersion); } +#if WITH_TESTS +} // namespace QtSupport + +#include "qtsupportplugin.h" +#include "desktopqtversion.h" + +#include +#include + +#include + +#include + +namespace QtSupport { +namespace Internal { + +struct DirectoryData { + DirectoryData(const QString &ip, + Kit *k = nullptr, bool ink = false, + const Utils::FileName &qp = Utils::FileName(), bool inq = false) : + isNewKit(ink), isNewQt(inq), + importPath(Utils::FileName::fromString(ip)), + kit(k), qmakePath(qp) + { } + + DirectoryData(const DirectoryData &other) : + isNewKit(other.isNewKit), + isNewQt(other.isNewQt), + importPath(other.importPath), + kit(other.kit), + qmakePath(other.qmakePath) + { } + + const bool isNewKit = false; + const bool isNewQt = false; + const Utils::FileName importPath; + Kit *const kit = nullptr; + const Utils::FileName qmakePath; +}; + +class TestQtProjectImporter : public QtProjectImporter +{ +public: + TestQtProjectImporter(const QString &pp, const QList &testData) : + QtProjectImporter(pp), + m_testData(testData) + { } + + QStringList importCandidates() override; + + bool allDeleted() const { return m_deletedTestData.count() == m_testData.count(); } + +protected: + QList examineDirectory(const Utils::FileName &importPath) const override; + bool matchKit(void *directoryData, const Kit *k) const override; + Kit *createKit(void *directoryData) const override; + QList buildInfoListForKit(const Kit *k, void *directoryData) const override; + void deleteDirectoryData(void *directoryData) const override; + +private: + const QList m_testData; + mutable Utils::FileName m_path; + mutable QVector m_deletedTestData; + + QList m_deletedKits; +}; + +QStringList TestQtProjectImporter::importCandidates() +{ + return QStringList(); +} + +QList TestQtProjectImporter::examineDirectory(const Utils::FileName &importPath) const +{ + m_path = importPath; + + assert(m_deletedTestData.isEmpty()); + + return m_testData; +} + +bool TestQtProjectImporter::matchKit(void *directoryData, const Kit *k) const +{ + assert(m_testData.contains(directoryData)); + assert(!m_deletedTestData.contains(directoryData)); + const DirectoryData *dd = static_cast(directoryData); + assert(dd->importPath == m_path); + return dd->kit->displayName() == k->displayName(); +} + +Kit *TestQtProjectImporter::createKit(void *directoryData) const +{ + assert(m_testData.contains(directoryData)); + assert(!m_deletedTestData.contains(directoryData)); + const DirectoryData *dd = static_cast(directoryData); + assert(dd->importPath == m_path); + + if (KitManager::instance()->find(dd->kit->id())) // known kit + return dd->kit; + + // New temporary kit: + return createTemporaryKit(findOrCreateQtVersion(dd->qmakePath), + [dd](Kit *k) { + BaseQtVersion *qt = QtKitInformation::qtVersion(k); + QMap toKeep; + for (const Core::Id &key : k->allKeys()) { + if (key.toString().startsWith("PE.tmp.")) + toKeep.insert(key, k->value(key)); + } + k->copyFrom(dd->kit); + for (auto i = toKeep.constBegin(); i != toKeep.constEnd(); ++i) + k->setValue(i.key(), i.value()); + QtKitInformation::setQtVersion(k, qt); + }); +} + +QList TestQtProjectImporter::buildInfoListForKit(const Kit *k, void *directoryData) const +{ + assert(m_testData.contains(directoryData)); + assert(!m_deletedTestData.contains(directoryData)); + assert(static_cast(directoryData)->importPath == m_path); + + BuildInfo *info = new BuildInfo(nullptr); + info->displayName = "Test Build info"; + info->typeName = "Debug"; + info->buildDirectory = m_path; + info->kitId = k->id(); + info->buildType = BuildConfiguration::Debug; + + return { info }; +} + +void TestQtProjectImporter::deleteDirectoryData(void *directoryData) const +{ + assert(m_testData.contains(directoryData)); + assert(!m_deletedTestData.contains(directoryData)); + assert(static_cast(directoryData)->importPath == m_path); + + // Clean up in-the-wild + m_deletedTestData.append(directoryData); + delete static_cast(directoryData); +} + +static Utils::FileName setupQmake(const BaseQtVersion *qt, const QString &path) +{ + const QFileInfo fi = QFileInfo(qt->qmakeCommand().toFileInfo().canonicalFilePath()); + const QString qmakeFile = path + "/" + fi.fileName(); + if (!QFile::copy(fi.absoluteFilePath(), qmakeFile)) + return Utils::FileName(); + + return Utils::FileName::fromString(qmakeFile); +} + +void QtSupportPlugin::testQtProjectImporter_oneProject_data() +{ + // In the next two lists: 0 is the defaultKit/Qt, anything > 0 is a new kit/Qt + QTest::addColumn>("kitIndexList"); // List of indices from the kitTemplate below. + QTest::addColumn>("qtIndexList"); // List of indices from the qmakePaths below. + + QTest::addColumn>("operationList"); // Persist (true) or cleanup (false) the result. + QTest::addColumn>("kitIsPersistentList"); // Is the Kit still there after operation? + QTest::addColumn>("qtIsPersistentList"); // Is the Qt still there after operation? + + QTest::newRow("nothing to import") + << QList() << QList() << QList() + << QList() << QList(); + + QTest::newRow("existing kit, cleanup") + << QList({ 0 }) << QList({ 0 }) << QList({ false }) + << QList({ true }) << QList({ true }); + QTest::newRow("existing kit, persist") + << QList({ 0 }) << QList({ 0 }) << QList({ true }) + << QList({ true }) << QList({ true }); + + QTest::newRow("new kit, existing Qt, cleanup") + << QList({ 1 }) << QList({ 0 }) << QList({ false }) + << QList({ false }) << QList({ true }); + QTest::newRow("new kit, existing Qt, persist") + << QList({ 1 }) << QList({ 0 }) << QList({ true }) + << QList({ true }) << QList({ true }); + + QTest::newRow("new kit, new Qt, cleanup") + << QList({ 1 }) << QList({ 1 }) << QList({ false }) + << QList({ false }) << QList({ false }); + QTest::newRow("new kit, new Qt, persist") + << QList({ 1 }) << QList({ 1 }) << QList({ true }) + << QList({ true }) << QList({ true }); + + QTest::newRow("2 new kit, same existing Qt, cleanup-cleanup") + << QList({ 1, 2 }) << QList({ 0, 0 }) << QList({ false, false }) + << QList({ false, false }) << QList({ true, true }); + QTest::newRow("2 new kit, same existing Qt, persist-cleanup") + << QList({ 1, 2 }) << QList({ 0, 0 }) << QList({ true, false }) + << QList({ true, false }) << QList({ true, true }); + QTest::newRow("2 new kit, same existing Qt, cleanup-persist") + << QList({ 1, 2 }) << QList({ 0, 0 }) << QList({ false, true }) + << QList({ false, true }) << QList({ true, true }); + QTest::newRow("2 new kit, same existing Qt, persist-persist") + << QList({ 1, 2 }) << QList({ 0, 0 }) << QList({ true, true }) + << QList({ true, true }) << QList({ true, true }); + + QTest::newRow("2 new kit, same new Qt, cleanup-cleanup") + << QList({ 1, 2 }) << QList({ 1, 1 }) << QList({ false, false }) + << QList({ false, false }) << QList({ true, false }); + QTest::newRow("2 new kit, same new Qt, persist-cleanup") + << QList({ 1, 2 }) << QList({ 1, 1 }) << QList({ true, false }) + << QList({ true, false }) << QList({ true, true }); + QTest::newRow("2 new kit, same new Qt, cleanup-persist") + << QList({ 1, 2 }) << QList({ 1, 1 }) << QList({ false, true }) + << QList({ false, true }) << QList({ true, true }); + QTest::newRow("2 new kit, same new Qt, persist-persist") + << QList({ 1, 2 }) << QList({ 1, 1 }) << QList({ true, true }) + << QList({ true, true }) << QList({ true, true }); + + QTest::newRow("2 new kit, 2 new Qt, cleanup-cleanup") + << QList({ 1, 2 }) << QList({ 1, 2 }) << QList({ false, false }) + << QList({ false, false }) << QList({ false, false }); + QTest::newRow("2 new kit, 2 new Qt, persist-cleanup") + << QList({ 1, 2 }) << QList({ 1, 2 }) << QList({ true, false }) + << QList({ true, false }) << QList({ true, false }); + QTest::newRow("2 new kit, 2 new Qt, cleanup-persist") + << QList({ 1, 2 }) << QList({ 1, 2 }) << QList({ false, true }) + << QList({ false, true }) << QList({ false, true }); + QTest::newRow("2 new kit, 2 new Qt, persist-persist") + << QList({ 1, 2 }) << QList({ 1, 2 }) << QList({ true, true }) + << QList({ true, true }) << QList({ true, true }); +} + +void QtSupportPlugin::testQtProjectImporter_oneProject() +{ + // -------------------------------------------------------------------- + // Setup: + // -------------------------------------------------------------------- + + Kit *defaultKit = KitManager::defaultKit(); + QVERIFY(defaultKit); + + BaseQtVersion *defaultQt = QtKitInformation::qtVersion(defaultKit); + QVERIFY(defaultQt); + + const QTemporaryDir tempDir1; + const QTemporaryDir tempDir2; + + const QString appDir = QCoreApplication::applicationDirPath(); + + // Templates referrenced by test data: + QVector kitTemplates = { defaultKit, defaultKit->clone(), defaultKit->clone() }; + // Customize kit numbers 1 and 2: + QtKitInformation::setQtVersion(kitTemplates[1], nullptr); + QtKitInformation::setQtVersion(kitTemplates[2], nullptr); + SysRootKitInformation::setSysRoot(kitTemplates[1], Utils::FileName::fromString("/some/path")); + SysRootKitInformation::setSysRoot(kitTemplates[2], Utils::FileName::fromString("/some/other/path")); + + QVector qmakePaths = { defaultQt->qmakeCommand(), + setupQmake(defaultQt, tempDir1.path()), + setupQmake(defaultQt, tempDir2.path()) }; + + for (int i = 1; i < qmakePaths.count(); ++i) { + const Utils::FileName qp = qmakePaths.at(i); + QVERIFY(!Utils::contains(QtVersionManager::versions(), + [qp](BaseQtVersion *qt) { return qt->qmakeCommand() == qp; })); + } + + QList testData; + + QFETCH(QList, kitIndexList); + QFETCH(QList, qtIndexList); + QFETCH(QList, operationList); + QFETCH(QList, kitIsPersistentList); + QFETCH(QList, qtIsPersistentList); + + QCOMPARE(kitIndexList.count(), qtIndexList.count()); + QCOMPARE(kitIndexList.count(), operationList.count()); + QCOMPARE(kitIndexList.count(), kitIsPersistentList.count()); + QCOMPARE(kitIndexList.count(), qtIsPersistentList.count()); + + for (int i = 0; i < kitIndexList.count(); ++i) { + const int kitIndex = kitIndexList.at(i); + const int qtIndex = qtIndexList.at(i); + + testData.append(new DirectoryData(appDir, + (kitIndex < 0) ? nullptr : kitTemplates.at(kitIndex), + (kitIndex > 0), /* new Kit */ + (qtIndex < 0) ? Utils::FileName() : qmakePaths.at(qtIndex), + (qtIndex > 0) /* new Qt */)); + } + + // Finally set up importer: + // Copy the directoryData so that importer is free to delete it later. + TestQtProjectImporter importer(tempDir1.path(), + Utils::transform(testData, [](DirectoryData *i) { + return static_cast(new DirectoryData(*i)); + })); + + // -------------------------------------------------------------------- + // Test: Import: + // -------------------------------------------------------------------- + + // choose an existing directory to "import" + const QList buildInfo = importer.import(Utils::FileName::fromString(appDir), true); + + // VALIDATE: Basic TestImporter state: + QCOMPARE(importer.projectFilePath(), tempDir1.path()); + QCOMPARE(importer.allDeleted(), true); + + // VALIDATE: Result looks reasonable: + QCOMPARE(buildInfo.count(), testData.count()); + + QList newKits; + + // VALIDATE: Validate result: + for (int i = 0; i < buildInfo.count(); ++i) { + const DirectoryData *dd = testData.at(i); + const BuildInfo *bi = buildInfo.at(i); + + // VALIDATE: Kit id is unchanged (unless it is a new kit) + if (!dd->isNewKit) + QCOMPARE(bi->kitId, defaultKit->id()); + + // VALIDATE: Kit is registered with the KitManager + Kit *newKit = KitManager::find(bi->kitId); + QVERIFY(newKit); + + const int newQtId = QtKitInformation::qtVersionId(newKit); + + // VALIDATE: Qt id is unchanged (unless it is a new Qt) + if (!dd->isNewQt) + QCOMPARE(newQtId, defaultQt->uniqueId()); + + // VALIDATE: Qt is known to QtVersionManager + BaseQtVersion *newQt = QtVersionManager::version(newQtId); + QVERIFY(newQt); + + // VALIDATE: Qt has the expected qmakePath + QCOMPARE(dd->qmakePath, newQt->qmakeCommand()); + + // VALIDATE: All keys are unchanged: + QList newKitKeys = newKit->allKeys(); + const QList templateKeys = dd->kit->allKeys(); + + if (dd->isNewKit) + QVERIFY(templateKeys.count() < newKitKeys.count()); // new kit will have extra keys! + else + QCOMPARE(templateKeys.count(), newKitKeys.count()); // existing kit needs to be unchanged! + + for (Core::Id id : templateKeys) { + if (id == QtKitInformation::id()) + continue; // with the exception of the Qt one... + QVERIFY(newKit->hasValue(id)); + QVERIFY(dd->kit->value(id) == newKit->value(id)); + } + + newKits.append(newKit); + } + + // VALIDATE: No kit got lost;-) + QCOMPARE(newKits.count(), buildInfo.count()); + + QList toUnregisterLater; + + for (int i = 0; i < operationList.count(); ++i) { + Kit *newKit = newKits.at(i); + + const bool toPersist = operationList.at(i); + const bool kitIsPersistent = kitIsPersistentList.at(i); + const bool qtIsPersistent = qtIsPersistentList.at(i); + + DirectoryData *dd = testData.at(i); + + // Create a templateKit with the expected data: + Kit *templateKit = nullptr; + if (newKit == defaultKit) { + templateKit = defaultKit; + } else { + templateKit = dd->kit->clone(true); + QtKitInformation::setQtVersionId(templateKit, QtKitInformation::qtVersionId(newKit)); + } + const QList templateKitKeys = templateKit->allKeys(); + + if (newKit != defaultKit) + toUnregisterLater.append(newKit); + + const Core::Id newKitIdAfterImport = newKit->id(); + + if (toPersist) { + // -------------------------------------------------------------------- + // Test: persist kit + // -------------------------------------------------------------------- + + importer.makePersistent(newKit); + } else { + // -------------------------------------------------------------------- + // Test: cleanup kit + // -------------------------------------------------------------------- + + importer.cleanupKit(newKit); + } + + const QList newKitKeys = newKit->allKeys(); + const Core::Id newKitId = newKit->id(); + const int qtId = QtKitInformation::qtVersionId(newKit); + + // VALIDATE: Kit Id has not changed + QCOMPARE(newKitId, newKitIdAfterImport); + + // VALIDATE: Importer state + QCOMPARE(importer.projectFilePath(), tempDir1.path()); + QCOMPARE(importer.allDeleted(), true); + + if (kitIsPersistent) { + // The kit was persistet. This can happen after makePersistent, but + // cleanup can also end up here (provided the kit was persistet earlier + // in the test run) + + // VALIDATE: All the kit values are as set up in the template before + QCOMPARE(newKitKeys.count(), templateKitKeys.count()); + for (Core::Id id : templateKitKeys) { + if (id == QtKitInformation::id()) + continue; + QVERIFY(newKit->hasValue(id)); + QVERIFY(newKit->value(id) == templateKit->value(id)); + } + + // VALIDATE: DefaultKit is still visible in KitManager + QVERIFY(KitManager::find(newKit->id())); + } else { + // Validate that the kit was cleaned up. + + // VALIDATE: All keys that got added during import are gone + QCOMPARE(newKitKeys.count(), templateKitKeys.count()); + for (Core::Id id : newKitKeys) { + if (id == QtKitInformation::id()) + continue; // Will be checked by Qt version later + QVERIFY(templateKit->hasValue(id)); + QVERIFY(newKit->value(id) == templateKit->value(id)); + } + } + + if (qtIsPersistent) { + // VALIDATE: Qt is used in the Kit: + QVERIFY(QtKitInformation::qtVersionId(newKit) == qtId); + + // VALIDATE: Qt is still in QtVersionManager + QVERIFY(QtVersionManager::version(qtId)); + + // VALIDATE: Qt points to the expected qmake path: + QCOMPARE(QtVersionManager::version(qtId)->qmakeCommand(), dd->qmakePath); + + // VALIDATE: Kit uses the expected Qt + QCOMPARE(QtKitInformation::qtVersionId(newKit), qtId); + } else { + // VALIDATE: Qt was reset in the kit + QVERIFY(QtKitInformation::qtVersionId(newKit) == -1); + + // VALIDATE: New kit is still visible in KitManager + QVERIFY(KitManager::find(newKitId)); // Cleanup Kit does not unregister Kits, so it does + // not matter here whether the kit is new or not. + + // VALIDATE: Qt was cleaned up (new Qt!) + QVERIFY(!QtVersionManager::version(qtId)); + + // VALIDATE: Qt version was reset on the kit + QVERIFY(newKit->value(QtKitInformation::id()).toInt() == -1); // new Qt will be reset to invalid! + } + + if (templateKit != defaultKit) + KitManager::deleteKit(templateKit); + } + + // -------------------------------------------------------------------- + // Teardown: + // -------------------------------------------------------------------- + + qDeleteAll(buildInfo); + qDeleteAll(testData); + + foreach (Kit *k, toUnregisterLater) + KitManager::deregisterKit(k); + + // Delete kit templates: + for (int i = 1; i < kitTemplates.count(); ++i) + KitManager::deleteKit(kitTemplates.at(i)); +} + +} // namespace Internal +#endif // WITH_TESTS + } // namespace QtSupport diff --git a/src/plugins/qtsupport/qtsupportplugin.h b/src/plugins/qtsupport/qtsupportplugin.h index e62791533b3..fe0585c50fc 100644 --- a/src/plugins/qtsupport/qtsupportplugin.h +++ b/src/plugins/qtsupport/qtsupportplugin.h @@ -50,6 +50,17 @@ private slots: void testQtOutputFormatter_appendMessage_data(); void testQtOutputFormatter_appendMessage(); void testQtOutputFormatter_appendMixedAssertAndAnsi(); + + void testQtProjectImporter_oneProject_data(); + void testQtProjectImporter_oneProject(); +#if 0 + void testQtProjectImporter_oneProjectExistingKit(); + void testQtProjectImporter_oneProjectNewKitExistingQt(); + void testQtProjectImporter_oneProjectNewKitNewQt(); + void testQtProjectImporter_oneProjectTwoNewKitSameNewQt_pc(); + void testQtProjectImporter_oneProjectTwoNewKitSameNewQt_cp(); + void testQtProjectImporter_oneProjectTwoNewKitSameNewQt_cc(); +#endif #endif };