McuSupport: basic test & required refactoring

Introduced Package interface for mocking purposes.
Made some functions visible in headers for testing.
Added basic test skeleton for mcu plugin.

run cmd: `qtcreator -test McuSupport`

Change-Id: I1011d49052bd8c894da393d8a285b241682f1f94
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Piotr Mućko
2022-02-11 13:51:42 +01:00
parent 03340f1fdf
commit 9917166b2e
17 changed files with 607 additions and 158 deletions

View File

@@ -101,6 +101,8 @@ if(Googletest_FOUND AND NOT TARGET Googletest)
GTEST_HAS_DEATH_TEST GTEST_HAS_DEATH_TEST
) )
set_target_properties(Googletest PROPERTIES AUTOMOC OFF AUTOUIC OFF) set_target_properties(Googletest PROPERTIES AUTOMOC OFF AUTOUIC OFF)
set_property(TARGET Googletest PROPERTY POSITION_INDEPENDENT_CODE ON)
target_compile_definitions(Googletest PUBLIC GOOGLE_TEST_IS_FOUND)
target_link_libraries(Googletest Threads::Threads) target_link_libraries(Googletest Threads::Threads)
endif() endif()

View File

@@ -7,7 +7,7 @@ add_qtc_plugin(McuSupport
mcusupport_global.h mcusupport_global.h
mcusupportconstants.h mcusupportconstants.h
mcusupportdevice.cpp mcusupportdevice.h mcusupportdevice.cpp mcusupportdevice.h
mcusupportoptions.cpp mcusupportoptions.h mcusupportoptions.cpp mcusupportoptions.h mcuabstractpackage.h
mcusupportoptionspage.cpp mcusupportoptionspage.h mcusupportoptionspage.cpp mcusupportoptionspage.h
mcupackage.cpp mcupackage.h mcupackage.cpp mcupackage.h
mcusupportplugin.cpp mcusupportplugin.h mcusupportplugin.cpp mcusupportplugin.h
@@ -16,3 +16,5 @@ add_qtc_plugin(McuSupport
mcusupportversiondetection.cpp mcusupportversiondetection.h mcusupportversiondetection.cpp mcusupportversiondetection.h
mcusupportcmakemapper.cpp mcusupportcmakemapper.h mcusupportcmakemapper.cpp mcusupportcmakemapper.h
) )
add_subdirectory(test)

View File

@@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QObject>
namespace Utils {
class FilePath;
} // namespace Utils
namespace McuSupport::Internal {
class McuAbstractPackage : public QObject
{
Q_OBJECT
public:
enum Status {
EmptyPath,
InvalidPath,
ValidPathInvalidPackage,
ValidPackageMismatchedVersion,
ValidPackage
};
virtual Utils::FilePath basePath() const = 0;
virtual Utils::FilePath path() const = 0;
virtual QString label() const = 0;
virtual Utils::FilePath defaultPath() const = 0;
virtual QString detectionPath() const = 0;
virtual QString statusText() const = 0;
virtual void updateStatus() = 0;
virtual Status status() const = 0;
virtual bool validStatus() const = 0;
virtual const QString &environmentVariableName() const = 0;
virtual void setAddToPath(bool) = 0;
virtual bool addToPath() const = 0;
virtual void writeGeneralSettings() const = 0;
virtual bool writeToSettings() const = 0;
virtual void setRelativePathModifier(const QString &) = 0;
virtual void setVersions(const QStringList &) = 0;
virtual bool automaticKitCreationEnabled() const = 0;
virtual void setAutomaticKitCreationEnabled(const bool enabled) = 0;
virtual QWidget *widget() = 0;
signals:
void changed();
void statusChanged();
}; // class McuAbstractPackage
} // namespace McuSupport::Internal

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "mcuabstractpackage.h"
#include "mcusupportversiondetection.h" #include "mcusupportversiondetection.h"
#include <utils/filepath.h> #include <utils/filepath.h>
@@ -46,48 +47,44 @@ class InfoLabel;
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class McuPackage : public QObject class McuPackage : public McuAbstractPackage
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Status { McuPackage(const QString &label,
EmptyPath, const Utils::FilePath &defaultPath,
InvalidPath, const QString &detectionPath,
ValidPathInvalidPackage, const QString &settingsKey,
ValidPackageMismatchedVersion, const QString &envVarName = {},
ValidPackage const QString &downloadUrl = {},
};
McuPackage(const QString &label, const Utils::FilePath &defaultPath,
const QString &detectionPath, const QString &settingsKey,
const QString &envVarName = {}, const QString &downloadUrl = {},
const McuPackageVersionDetector *versionDetector = nullptr); const McuPackageVersionDetector *versionDetector = nullptr);
virtual ~McuPackage() = default; ~McuPackage() override = default;
Utils::FilePath basePath() const; Utils::FilePath basePath() const override;
Utils::FilePath path() const; Utils::FilePath path() const override;
QString label() const; QString label() const override;
Utils::FilePath defaultPath() const; Utils::FilePath defaultPath() const override;
QString detectionPath() const; QString detectionPath() const override;
QString statusText() const; QString statusText() const override;
void updateStatus(); void updateStatus() override;
Status status() const; Status status() const override;
bool validStatus() const; bool validStatus() const override;
void setAddToPath(bool addToPath); void setAddToPath(bool addToPath) override;
bool addToPath() const; bool addToPath() const override;
void writeGeneralSettings() const; void writeGeneralSettings() const override;
bool writeToSettings() const; bool writeToSettings() const override;
void setRelativePathModifier(const QString &path); void setRelativePathModifier(const QString &path) override;
void setVersions(const QStringList &versions); void setVersions(const QStringList &versions) override;
bool automaticKitCreationEnabled() const; //TODO(piotr.mucko): Why every package knows about automatic kit creation. This should be outside of this class.
void setAutomaticKitCreationEnabled(const bool enabled); bool automaticKitCreationEnabled() const override;
void setAutomaticKitCreationEnabled(const bool enabled) override;
QWidget *widget(); QWidget *widget() override;
const QString &environmentVariableName() const; const QString &environmentVariableName() const override;
signals: signals:
void changed(); void changed();
@@ -116,7 +113,7 @@ private:
bool m_addToPath = false; bool m_addToPath = false;
bool m_automaticKitCreation = true; bool m_automaticKitCreation = true;
Status m_status = InvalidPath; Status m_status = Status::InvalidPath;
}; };
class McuToolChainPackage : public McuPackage class McuToolChainPackage : public McuPackage

View File

@@ -15,6 +15,7 @@ QtcPlugin {
Depends { name: "QtSupport" } Depends { name: "QtSupport" }
files: [ files: [
"mcuabstractpackage.h",
"mcupackage.cpp", "mcupackage.cpp",
"mcupackage.h", "mcupackage.h",
"mcusupport.qrc", "mcusupport.qrc",

View File

@@ -67,6 +67,8 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QVariant> #include <QVariant>
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -82,22 +84,6 @@ static bool kitNeedsQtVersion()
return !HostOsInfo::isWindowsHost(); return !HostOsInfo::isWindowsHost();
} }
static void remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
{
using namespace CMakeProjectManager;
const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems);
const auto cmakeVarNames = Utils::transform(cmakeVars, &CMakeConfigItem::key);
// First filter out all Qul2.x CMake vars
auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit),
[&](const auto &configItem) {
return !cmakeVarNames.contains(configItem.key);
});
// Then append them with new values
config.append(cmakeVars);
CMakeConfigurationKitAspect::setConfiguration(kit, config);
}
static ToolChain *msvcToolChain(Id language) static ToolChain *msvcToolChain(Id language)
{ {
@@ -269,7 +255,7 @@ QVariant McuToolChainPackage::debuggerId() const
McuTarget::McuTarget(const QVersionNumber &qulVersion, McuTarget::McuTarget(const QVersionNumber &qulVersion,
const Platform &platform, const Platform &platform,
OS os, OS os,
const QVector<McuPackage *> &packages, const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage, const McuToolChainPackage *toolChainPackage,
int colorDepth) int colorDepth)
: m_qulVersion(qulVersion) : m_qulVersion(qulVersion)
@@ -281,7 +267,7 @@ McuTarget::McuTarget(const QVersionNumber &qulVersion,
{ {
} }
const QVector<McuPackage *> &McuTarget::packages() const const QVector<McuAbstractPackage *> &McuTarget::packages() const
{ {
return m_packages; return m_packages;
} }
@@ -303,7 +289,7 @@ const McuTarget::Platform &McuTarget::platform() const
bool McuTarget::isValid() const bool McuTarget::isValid() const
{ {
return Utils::allOf(packages(), [](McuPackage *package) { return Utils::allOf(packages(), [](McuAbstractPackage *package) {
package->updateStatus(); package->updateStatus();
return package->validStatus(); return package->validStatus();
}); });
@@ -319,7 +305,7 @@ void McuTarget::printPackageProblems() const
package->label(), package->label(),
package->statusText()), package->statusText()),
true); true);
if (package->status() == McuPackage::ValidPackageMismatchedVersion) if (package->status() == McuAbstractPackage::ValidPackageMismatchedVersion)
printMessage(tr("Warning creating kit for target %1, package %2: %3").arg( printMessage(tr("Warning creating kit for target %1, package %2: %3").arg(
McuSupportOptions::kitName(this), McuSupportOptions::kitName(this),
package->label(), package->label(),
@@ -350,7 +336,7 @@ McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent) : QObject(parent)
, qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage()) , qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
{ {
connect(qtForMCUsSdkPackage, &McuPackage::changed, connect(qtForMCUsSdkPackage, &McuAbstractPackage::changed,
this, &McuSupportOptions::populatePackagesAndTargets); this, &McuSupportOptions::populatePackagesAndTargets);
} }
@@ -421,7 +407,7 @@ void McuSupportOptions::setQulDir(const FilePath &dir)
if (qtForMCUsSdkPackage->validStatus()) if (qtForMCUsSdkPackage->validStatus())
Sdk::targetsAndPackages(dir, &sdkRepository); Sdk::targetsAndPackages(dir, &sdkRepository);
for (const auto &package : qAsConst(sdkRepository.packages)) for (const auto &package : qAsConst(sdkRepository.packages))
connect(package, &McuPackage::changed, this, &McuSupportOptions::changed); connect(package, &McuAbstractPackage::changed, this, &McuSupportOptions::changed);
emit changed(); emit changed();
} }
@@ -463,6 +449,22 @@ static void setKitProperties(const QString &kitName, Kit *k, const McuTarget *mc
k->setIrrelevantAspects(irrelevant); k->setIrrelevantAspects(irrelevant);
} }
void McuSupportOptions::remapQul2xCmakeVars(Kit *kit, const EnvironmentItems &envItems)
{
const auto cmakeVars = mapEnvVarsToQul2xCmakeVars(envItems);
const auto cmakeVarNames = Utils::transform(cmakeVars, &CMakeConfigItem::key);
// First filter out all Qul2.x CMake vars
auto config = Utils::filtered(CMakeConfigurationKitAspect::configuration(kit),
[&](const auto &configItem) {
return !cmakeVarNames.contains(configItem.key);
});
// Then append them with new values
config.append(cmakeVars);
CMakeConfigurationKitAspect::setConfiguration(kit, config);
}
static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage) static void setKitToolchains(Kit *k, const McuToolChainPackage *tcPackage)
{ {
switch (tcPackage->type()) { switch (tcPackage->type()) {
@@ -535,8 +537,8 @@ static bool expectsCmakeVars(const McuTarget *mcuTarget)
return mcuTarget->qulVersion() >= QVersionNumber{2,0}; return mcuTarget->qulVersion() >= QVersionNumber{2,0};
} }
static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget, void McuSupportOptions::setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
const McuPackage *qtForMCUsSdkPackage) const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
EnvironmentItems changes; EnvironmentItems changes;
QStringList pathAdditions; QStringList pathAdditions;
@@ -548,7 +550,7 @@ static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
&& !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi()) && !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi())
pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput()); pathAdditions.append(qtForMCUsSdkPackage->path().pathAppended("bin").toUserOutput());
auto processPackage = [&pathAdditions, &changes](const McuPackage *package) { auto processPackage = [&pathAdditions, &changes](const McuAbstractPackage *package) {
if (package->addToPath()) if (package->addToPath())
pathAdditions.append(package->path().toUserOutput()); pathAdditions.append(package->path().toUserOutput());
if (!package->environmentVariableName().isEmpty()) if (!package->environmentVariableName().isEmpty())
@@ -571,18 +573,18 @@ static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
// Hack, this problem should be solved in lower layer // Hack, this problem should be solved in lower layer
if (expectsCmakeVars(mcuTarget)) { if (expectsCmakeVars(mcuTarget)) {
remapQul2xCmakeVars(k, changes); McuSupportOptions::remapQul2xCmakeVars(k, changes);
} }
EnvironmentKitAspect::setEnvironmentChanges(k, changes); EnvironmentKitAspect::setEnvironmentChanges(k, changes);
} }
static void setKitDependencies(Kit *k, const McuTarget *mcuTarget, static void setKitDependencies(Kit *k, const McuTarget *mcuTarget,
const McuPackage *qtForMCUsSdkPackage) const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
NameValueItems dependencies; NameValueItems dependencies;
auto processPackage = [&dependencies](const McuPackage *package) { auto processPackage = [&dependencies](const McuAbstractPackage *package) {
if (!package->environmentVariableName().isEmpty()) if (!package->environmentVariableName().isEmpty())
dependencies.append({package->environmentVariableName(), dependencies.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->detectionPath())}); QDir::toNativeSeparators(package->detectionPath())});
@@ -598,7 +600,7 @@ static void setKitDependencies(Kit *k, const McuTarget *mcuTarget,
k->setIrrelevantAspects(irrelevant); k->setIrrelevantAspects(irrelevant);
} }
static void updateKitEnvironment(Kit *k, const McuTarget *mcuTarget) void McuSupportOptions::updateKitEnvironment(Kit *k, const McuTarget *mcuTarget)
{ {
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k); EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(k);
for (auto package : mcuTarget->packages()) { for (auto package : mcuTarget->packages()) {
@@ -730,14 +732,14 @@ QList<Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTarget)
}); });
} }
QList<Kit *> McuSupportOptions::matchingKits(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdkPackage) QList<Kit *> McuSupportOptions::matchingKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) { return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage); return kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
}); });
} }
QList<Kit *> McuSupportOptions::upgradeableKits(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdkPackage) QList<Kit *> McuSupportOptions::upgradeableKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) { return Utils::filtered(existingKits(mcuTarget), [mcuTarget, qtForMCUsSdkPackage](Kit *kit) {
return !kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage); return !kitUpToDate(kit, mcuTarget, qtForMCUsSdkPackage);
@@ -750,7 +752,7 @@ QList<Kit *> McuSupportOptions::kitsWithMismatchedDependencies(const McuTarget *
const auto environment = Utils::NameValueDictionary( const auto environment = Utils::NameValueDictionary(
Utils::NameValueItem::toStringList( Utils::NameValueItem::toStringList(
EnvironmentKitAspect::environmentChanges(kit))); EnvironmentKitAspect::environmentChanges(kit)));
return Utils::anyOf(mcuTarget->packages(), [&environment](const McuPackage *package) { return Utils::anyOf(mcuTarget->packages(), [&environment](const McuAbstractPackage *package) {
return !package->environmentVariableName().isEmpty() && return !package->environmentVariableName().isEmpty() &&
environment.value(package->environmentVariableName()) != package->path().toUserOutput(); environment.value(package->environmentVariableName()) != package->path().toUserOutput();
}); });
@@ -771,7 +773,7 @@ void McuSupportOptions::removeOutdatedKits()
KitManager::deregisterKit(kit); KitManager::deregisterKit(kit);
} }
Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdk) Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{ {
const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) { const auto init = [mcuTarget, qtForMCUsSdk](Kit *k) {
KitGuard kitGuard(k); KitGuard kitGuard(k);
@@ -818,7 +820,7 @@ static FilePath kitDependencyPath(const Kit *kit, const QString &variableName)
} }
bool McuSupportOptions::kitUpToDate(const Kit *kit, const McuTarget *mcuTarget, bool McuSupportOptions::kitUpToDate(const Kit *kit, const McuTarget *mcuTarget,
const McuPackage *qtForMCUsSdkPackage) const McuAbstractPackage *qtForMCUsSdkPackage)
{ {
return kitQulVersion(kit) == mcuTarget->qulVersion() && return kitQulVersion(kit) == mcuTarget->qulVersion() &&
kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput() == qtForMCUsSdkPackage->path().toUserOutput(); kitDependencyPath(kit, qtForMCUsSdkPackage->environmentVariableName()).toUserOutput() == qtForMCUsSdkPackage->path().toUserOutput();
@@ -858,7 +860,7 @@ void McuSupportOptions::createAutomaticKits()
qtForMCUsPackage->updateStatus(); qtForMCUsPackage->updateStatus();
if (!qtForMCUsPackage->validStatus()) { if (!qtForMCUsPackage->validStatus()) {
switch (qtForMCUsPackage->status()) { switch (qtForMCUsPackage->status()) {
case McuPackage::ValidPathInvalidPackage: { case McuAbstractPackage::ValidPathInvalidPackage: {
const QString displayPath = FilePath::fromString(qtForMCUsPackage->detectionPath()) const QString displayPath = FilePath::fromString(qtForMCUsPackage->detectionPath())
.toUserOutput(); .toUserOutput();
printMessage(tr("Path %1 exists, but does not contain %2.") printMessage(tr("Path %1 exists, but does not contain %2.")
@@ -866,13 +868,13 @@ void McuSupportOptions::createAutomaticKits()
true); true);
break; break;
} }
case McuPackage::InvalidPath: { case McuAbstractPackage::InvalidPath: {
printMessage(tr("Path %1 does not exist. Add the path in Tools > Options > Devices > MCU.") printMessage(tr("Path %1 does not exist. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->path().toUserOutput()), .arg(qtForMCUsPackage->path().toUserOutput()),
true); true);
break; break;
} }
case McuPackage::EmptyPath: { case McuAbstractPackage::EmptyPath: {
printMessage(tr("Missing %1. Add the path in Tools > Options > Devices > MCU.") printMessage(tr("Missing %1. Add the path in Tools > Options > Devices > MCU.")
.arg(qtForMCUsPackage->detectionPath()), .arg(qtForMCUsPackage->detectionPath()),
true); true);
@@ -964,7 +966,7 @@ void McuSupportOptions::upgradeKits(UpgradeOption upgradeOption)
delete qtForMCUsPackage; delete qtForMCUsPackage;
} }
void McuSupportOptions::upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdk) void McuSupportOptions::upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk)
{ {
setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path()); setKitProperties(kitName(mcuTarget), kit, mcuTarget, qtForMCUsSdk->path());
setKitEnvironment(kit, mcuTarget, qtForMCUsSdk); setKitEnvironment(kit, mcuTarget, qtForMCUsSdk);
@@ -980,7 +982,7 @@ void McuSupportOptions::fixKitsDependencies()
Sdk::targetsAndPackages(dir, &repo); Sdk::targetsAndPackages(dir, &repo);
for (const auto &target: qAsConst(repo.mcuTargets)) { for (const auto &target: qAsConst(repo.mcuTargets)) {
if (target->isValid()) { if (target->isValid()) {
for (auto kit : kitsWithMismatchedDependencies(target)) { for (auto* kit : kitsWithMismatchedDependencies(target)) {
updateKitEnvironment(kit, target); updateKitEnvironment(kit, target);
} }
} }

View File

@@ -1,7 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2021 ** Copyright (C) 2022 The Qt Company Ltd.
** The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of Qt Creator. ** This file is part of Qt Creator.
@@ -26,8 +25,7 @@
#pragma once #pragma once
#include "mcusupport_global.h" #include <utils/environmentfwd.h>
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
#include <QVersionNumber> #include <QVersionNumber>
@@ -43,12 +41,12 @@ class InfoLabel;
namespace ProjectExplorer { namespace ProjectExplorer {
class Kit; class Kit;
class ToolChain; class ToolChain;
} } // namespace ProjectExplorer
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class McuPackage; class McuAbstractPackage;
class McuToolChainPackage; class McuToolChainPackage;
void printMessage(const QString &message, bool important); void printMessage(const QString &message, bool important);
@@ -75,12 +73,12 @@ public:
McuTarget(const QVersionNumber &qulVersion, McuTarget(const QVersionNumber &qulVersion,
const Platform &platform, const Platform &platform,
OS os, OS os,
const QVector<McuPackage *> &packages, const QVector<McuAbstractPackage *> &packages,
const McuToolChainPackage *toolChainPackage, const McuToolChainPackage *toolChainPackage,
int colorDepth = UnspecifiedColorDepth); int colorDepth = UnspecifiedColorDepth);
const QVersionNumber &qulVersion() const; const QVersionNumber &qulVersion() const;
const QVector<McuPackage *> &packages() const; const QVector<McuAbstractPackage *> &packages() const;
const McuToolChainPackage *toolChainPackage() const; const McuToolChainPackage *toolChainPackage() const;
const Platform &platform() const; const Platform &platform() const;
OS os() const; OS os() const;
@@ -92,16 +90,16 @@ private:
const QVersionNumber m_qulVersion; const QVersionNumber m_qulVersion;
const Platform m_platform; const Platform m_platform;
const OS m_os; const OS m_os;
const QVector<McuPackage*> m_packages; const QVector<McuAbstractPackage *> m_packages;
const McuToolChainPackage *m_toolChainPackage; const McuToolChainPackage *m_toolChainPackage;
const int m_colorDepth; const int m_colorDepth;
}; }; // class McuTarget
class McuSdkRepository class McuSdkRepository
{ {
public: public:
QVector<McuPackage*> packages; QVector<McuAbstractPackage *> packages;
QVector<McuTarget*> mcuTargets; QVector<McuTarget *> mcuTargets;
void deletePackagesAndTargets(); void deletePackagesAndTargets();
}; };
@@ -117,28 +115,33 @@ public:
Replace Replace
}; };
McuSupportOptions(QObject *parent = nullptr); explicit McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override; ~McuSupportOptions() override;
McuPackage *qtForMCUsSdkPackage = nullptr; McuAbstractPackage *qtForMCUsSdkPackage = nullptr;
McuSdkRepository sdkRepository; McuSdkRepository sdkRepository;
void setQulDir(const Utils::FilePath &dir); void setQulDir(const Utils::FilePath &dir);
static void setKitEnvironment(ProjectExplorer::Kit *, const McuTarget *, const McuAbstractPackage *);
static void updateKitEnvironment(ProjectExplorer::Kit *, const McuTarget *);
static void remapQul2xCmakeVars(ProjectExplorer::Kit *, const Utils::EnvironmentItems &);
static Utils::FilePath qulDirFromSettings(); static Utils::FilePath qulDirFromSettings();
static QString kitName(const McuTarget* mcuTarget); static QString kitName(const McuTarget* mcuTarget);
static QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget); static QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdkPackage); static QList<ProjectExplorer::Kit *> matchingKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdkPackage); static QList<ProjectExplorer::Kit *> upgradeableKits(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdkPackage);
static QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget); static QList<ProjectExplorer::Kit *> kitsWithMismatchedDependencies(const McuTarget *mcuTarget);
static QList<ProjectExplorer::Kit *> outdatedKits(); static QList<ProjectExplorer::Kit *> outdatedKits();
static void removeOutdatedKits(); static void removeOutdatedKits();
static ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdk); static ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget, const McuAbstractPackage *qtForMCUsSdk);
static void createAutomaticKits(); static void createAutomaticKits();
static UpgradeOption askForKitUpgrades(); static UpgradeOption askForKitUpgrades();
static void upgradeKits(UpgradeOption upgradeOption); static void upgradeKits(UpgradeOption upgradeOption);
static void upgradeKitInPlace(ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdk); static void upgradeKitInPlace(ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdk);
static void fixKitsDependencies(); static void fixKitsDependencies();
void checkUpgradeableKits(); void checkUpgradeableKits();
static void fixExistingKits(); static void fixExistingKits();
@@ -149,7 +152,10 @@ public:
static const QVersionNumber &minimalQulVersion(); static const QVersionNumber &minimalQulVersion();
static QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit); static QVersionNumber kitQulVersion(const ProjectExplorer::Kit *kit);
static bool kitUpToDate(const ProjectExplorer::Kit *kit, const McuTarget *mcuTarget, const McuPackage *qtForMCUsSdkPackage); static bool kitUpToDate(const ProjectExplorer::Kit *kit,
const McuTarget *mcuTarget,
const McuAbstractPackage *qtForMCUsSdkPackage);
private: private:
void deletePackagesAndTargets(); void deletePackagesAndTargets();

View File

@@ -119,7 +119,7 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
layout->addWidget(m_mcuTargetsComboBox); layout->addWidget(m_mcuTargetsComboBox);
connect(m_mcuTargetsComboBox, &QComboBox::currentTextChanged, connect(m_mcuTargetsComboBox, &QComboBox::currentTextChanged,
this, &McuSupportOptionsWidget::showMcuTargetPackages); this, &McuSupportOptionsWidget::showMcuTargetPackages);
connect(m_options.qtForMCUsSdkPackage, &McuPackage::changed, connect(m_options.qtForMCUsSdkPackage, &McuAbstractPackage::changed,
this, &McuSupportOptionsWidget::populateMcuTargetsComboBox); this, &McuSupportOptionsWidget::populateMcuTargetsComboBox);
} }

View File

@@ -31,6 +31,10 @@
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcusupportrunconfiguration.h" #include "mcusupportrunconfiguration.h"
#if defined(WITH_TESTS) && defined(GOOGLE_TEST_IS_FOUND)
#include "test/unittest.h"
#endif
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -61,14 +65,9 @@ public:
}; };
McuSupportOptionsPage optionsPage; McuSupportOptionsPage optionsPage;
McuDependenciesKitAspect environmentPathsKitAspect; McuDependenciesKitAspect environmentPathsKitAspect;
}; }; // class McuSupportPluginPrivate
static McuSupportPluginPrivate *dd = nullptr; static McuSupportPluginPrivate* dd{nullptr};
McuSupportPlugin::McuSupportPlugin()
{
setObjectName("McuSupportPlugin");
}
McuSupportPlugin::~McuSupportPlugin() McuSupportPlugin::~McuSupportPlugin()
{ {
@@ -76,11 +75,12 @@ McuSupportPlugin::~McuSupportPlugin()
dd = nullptr; dd = nullptr;
} }
bool McuSupportPlugin::initialize(const QStringList& arguments, QString* errorString) bool McuSupportPlugin::initialize(const QStringList &arguments, QString *errorString)
{ {
Q_UNUSED(arguments) Q_UNUSED(arguments)
Q_UNUSED(errorString) Q_UNUSED(errorString)
setObjectName("McuSupportPlugin");
dd = new McuSupportPluginPrivate; dd = new McuSupportPluginPrivate;
McuSupportOptions::registerQchFiles(); McuSupportOptions::registerQchFiles();
@@ -150,5 +150,14 @@ void McuSupportPlugin::askUserAboutMcuSupportKitsUpgrade()
ICore::infoBar()->addInfo(info); ICore::infoBar()->addInfo(info);
} }
QVector<QObject *> McuSupportPlugin::createTestObjects() const
{
QVector<QObject *> tests;
#if defined(WITH_TESTS) && defined(GOOGLE_TEST_IS_FOUND)
tests << new Test::McuSupportTest;
#endif
return tests;
}
} // namespace Internal } // namespace Internal
} // namespace McuSupport } // namespace McuSupport

View File

@@ -29,23 +29,25 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
namespace McuSupport { namespace McuSupport::Internal {
namespace Internal {
class McuSupportPlugin : public ExtensionSystem::IPlugin class McuSupportPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "McuSupport.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "McuSupport.json")
public: public:
McuSupportPlugin(); ~McuSupportPlugin() final;
~McuSupportPlugin() override;
bool initialize(const QStringList &arguments, QString *errorString) final;
void extensionsInitialized() final;
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override;
static void askUserAboutMcuSupportKitsSetup(); static void askUserAboutMcuSupportKitsSetup();
static void askUserAboutMcuSupportKitsUpgrade(); static void askUserAboutMcuSupportKitsUpgrade();
};
} // namespace Internal private:
} // namespace McuSupport QVector<QObject *> createTestObjects() const final;
}; // class McuSupportPlugin
} // namespace McuSupport::Internal

View File

@@ -34,8 +34,8 @@
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h> #include <projectexplorer/toolchainmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <QDir> #include <QDir>
#include <QDirIterator> #include <QDirIterator>
@@ -336,39 +336,7 @@ static McuPackage *createRenesasProgrammerPackage()
return result; return result;
} }
struct McuTargetDescription static McuPackageVersionDetector *generatePackageVersionDetector(QString envVar)
{
enum class TargetType {
MCU,
Desktop
};
QString qulVersion;
QString compatVersion;
struct {
QString id;
QString name;
QString vendor;
QVector<int> colorDepths;
TargetType type;
} platform;
struct {
QString id;
QStringList versions;
} toolchain;
struct {
QString name;
QString defaultPath;
QString envVar;
QStringList versions;
} boardSdk;
struct {
QString envVar;
QString boardSdkSubDir;
} freeRTOS;
};
static McuPackageVersionDetector* generatePackageVersionDetector(QString envVar)
{ {
if (envVar.startsWith("EVK")) if (envVar.startsWith("EVK"))
return new McuPackageXmlVersionDetector("*_manifest_*.xml", "ksdk", "version", ".*"); return new McuPackageXmlVersionDetector("*_manifest_*.xml", "ksdk", "version", ".*");
@@ -461,9 +429,9 @@ struct McuTargetFactory
return createTargetsImpl(description); return createTargetsImpl(description);
} }
QVector<McuPackage *> getMcuPackages() const QVector<McuAbstractPackage *> getMcuPackages() const
{ {
QVector<McuPackage *> packages; QVector<McuAbstractPackage *> packages;
for (auto *package : qAsConst(boardSdkPkgs)) for (auto *package : qAsConst(boardSdkPkgs))
packages.append(package); packages.append(package);
for (auto *package : qAsConst(freeRTOSPkgs)) for (auto *package : qAsConst(freeRTOSPkgs))
@@ -481,7 +449,7 @@ protected:
tcPkg = createUnsupportedToolChainPackage(); tcPkg = createUnsupportedToolChainPackage();
for (auto os : {McuTarget::OS::BareMetal, McuTarget::OS::FreeRTOS}) { for (auto os : {McuTarget::OS::BareMetal, McuTarget::OS::FreeRTOS}) {
for (int colorDepth : desc.platform.colorDepths) { for (int colorDepth : desc.platform.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs = { tcPkg }; QVector<McuAbstractPackage*> required3rdPartyPkgs = { tcPkg };
if (vendorPkgs.contains(desc.platform.vendor)) if (vendorPkgs.contains(desc.platform.vendor))
required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platform.vendor)); required3rdPartyPkgs.push_back(vendorPkgs.value(desc.platform.vendor));
@@ -555,7 +523,7 @@ protected:
} else } else
tcPkg = createUnsupportedToolChainPackage(); tcPkg = createUnsupportedToolChainPackage();
for (int colorDepth : desc.platform.colorDepths) { for (int colorDepth : desc.platform.colorDepths) {
QVector<McuPackage*> required3rdPartyPkgs; QVector<McuAbstractPackage*> required3rdPartyPkgs;
// Desktop toolchains don't need any additional settings // Desktop toolchains don't need any additional settings
if (tcPkg if (tcPkg
&& !tcPkg->isDesktopToolchain() && !tcPkg->isDesktopToolchain()
@@ -608,10 +576,10 @@ private:
QHash<QString, McuPackage *> boardSdkPkgs; QHash<QString, McuPackage *> boardSdkPkgs;
QHash<QString, McuPackage *> freeRTOSPkgs; QHash<QString, McuPackage *> freeRTOSPkgs;
}; }; // struct McuTargetFactory
static QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescription> &descriptions, QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescription> &descriptions,
QVector<McuPackage *> *packages) QVector<McuAbstractPackage *> *packages)
{ {
const QHash<QString, McuToolChainPackage *> tcPkgs = { const QHash<QString, McuToolChainPackage *> tcPkgs = {
{{"armgcc"}, createArmGccPackage()}, {{"armgcc"}, createArmGccPackage()},
@@ -639,7 +607,7 @@ static QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescrip
mcuTargets.append(newTargets); mcuTargets.append(newTargets);
} }
packages->append(Utils::transform<QVector<McuPackage *> >( packages->append(Utils::transform<QVector<McuAbstractPackage *> >(
tcPkgs.values(), [&](McuToolChainPackage *tcPkg) { return tcPkg; })); tcPkgs.values(), [&](McuToolChainPackage *tcPkg) { return tcPkg; }));
for (auto *package : vendorPkgs) for (auto *package : vendorPkgs)
packages->append(package); packages->append(package);
@@ -732,7 +700,7 @@ static McuTargetDescription parseDescriptionJsonV2x(const QString &qulVersion, c
return description; return description;
} }
static McuTargetDescription parseDescriptionJson(const QByteArray &data) McuTargetDescription parseDescriptionJson(const QByteArray &data)
{ {
const QJsonDocument document = QJsonDocument::fromJson(data); const QJsonDocument document = QJsonDocument::fromJson(data);
const QJsonObject target = document.object(); const QJsonObject target = document.object();

View File

@@ -25,28 +25,65 @@
#pragma once #pragma once
#include "utils/filepath.h"
#include <QSettings> #include <QSettings>
#include <QVector> #include <QVector>
namespace Utils {
class FilePath;
}
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
#define MAX_COMPATIBILITY_VERSION 1 #define MAX_COMPATIBILITY_VERSION 1
class McuSdkRepository; class McuSdkRepository;
class McuAbstractPackage;
class McuPackage; class McuPackage;
class McuTarget;
namespace Sdk { namespace Sdk {
struct McuTargetDescription
{
enum class TargetType { MCU, Desktop };
QString qulVersion;
QString compatVersion;
struct
{
QString id;
QString name;
QString vendor;
QVector<int> colorDepths;
TargetType type;
} platform;
struct
{
QString id;
QStringList versions;
} toolchain;
struct
{
QString name;
QString defaultPath;
QString envVar;
QStringList versions;
} boardSdk;
struct
{
QString envVar;
QString boardSdkSubDir;
} freeRTOS;
};
McuPackage *createQtForMCUsPackage(); McuPackage *createQtForMCUsPackage();
bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message); bool checkDeprecatedSdkError(const Utils::FilePath &qulDir, QString &message);
void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo); void targetsAndPackages(const Utils::FilePath &qulDir, McuSdkRepository *repo);
McuTargetDescription parseDescriptionJson(const QByteArray &);
QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescription> &, QVector<McuAbstractPackage *> *);
Utils::FilePath kitsPath(const Utils::FilePath &dir); Utils::FilePath kitsPath(const Utils::FilePath &dir);
Utils::FilePath packagePathFromSettings(const QString &settingsKey, Utils::FilePath packagePathFromSettings(const QString &settingsKey,

View File

@@ -0,0 +1,13 @@
find_package(Googletest MODULE)
if(TARGET Googletest)
message("Googletest target is present")
extend_qtc_plugin(McuSupport
CONDITION WITH_TESTS
DEPENDS Googletest
SOURCES
unittest.h unittest.cpp packagemock.h
)
else()
message("Googletest target is missing")
endif()

View File

@@ -0,0 +1,93 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
constexpr auto nxp_1064_json = R"({
"boardSdk": {
"cmakeCacheEntries": [
{
"cmakeOptionName": "QUL_BOARD_SDK_DIR",
"description": "Board SDK for MIMXRT1064-EVK",
"id": "NXP_SDK_DIR",
"optional": false,
"type": "path"
}
],
"envVar": "EVK_MIMXRT1064_SDK_PATH",
"versions": ["2.10.0"]
},
"compatVersion": "1",
"freeRTOS": {
"cmakeCacheEntries": [
{
"cmakeOptionName": "FREERTOS_DIR",
"defaultValue": "$QUL_BOARD_SDK_DIR/rtos/freertos/freertos_kernel",
"description": "FreeRTOS SDK for MIMXRT1064-EVK",
"id": "NXP_FREERTOS_DIR",
"optional": false,
"type": "path"
}
],
"envVar": "IMXRT1064_FREERTOS_DIR"
},
"platform": {
"cmakeCacheEntries": [
{
"cmakeOptionName": "Qul_ROOT",
"description": "Qt for MCUs SDK",
"id": "Qul_DIR",
"optional": false,
"type": "path"
},
{
"cmakeOptionName": "MCUXPRESSO_IDE_PATH",
"defaultValue": {
"unix": "/usr/local/mcuxpressoide/",
"windows": "$ROOT/nxp/MCUXpressoIDE*"
}
}
],
"colorDepths": [16],
"environmentEntries": [],
"id": "MIMXRT1064-EVK-FREERTOS",
"pathEntries": [],
"vendor": "NXP"
},
"qulVersion": "2.0.0",
"toolchain": {
"cmakeCacheEntries": [
{
"cmakeOptionName": "QUL_TARGET_TOOLCHAIN_DIR",
"description": "IAR ARM Compiler",
"id": "IAR_DIR",
"optional": false,
"type": "path"
}
],
"id": "iar",
"versions": ["8.50.9"]
}
})";

View File

@@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "mcuabstractpackage.h"
#include <utils/filepath.h>
#include <gmock/gmock.h>
namespace McuSupport::Internal {
class PackageMock : public McuAbstractPackage
{
public:
MOCK_METHOD(Utils::FilePath, basePath, (), (const));
MOCK_METHOD(Utils::FilePath, path, (), (const));
MOCK_METHOD(QString, label, (), (const));
MOCK_METHOD(Utils::FilePath, defaultPath, (), (const));
MOCK_METHOD(QString, detectionPath, (), (const));
MOCK_METHOD(QString, statusText, (), (const));
MOCK_METHOD(void, updateStatus, ());
MOCK_METHOD(Status, status, (), (const));
MOCK_METHOD(bool, validStatus, (), (const));
MOCK_METHOD(void, setDownloadUrl, (const QString &) );
MOCK_METHOD(void, setEnvironmentVariableName, (const QString &) );
MOCK_METHOD(const QString&, environmentVariableName, (), (const));
MOCK_METHOD(void, setAddToPath, (bool) );
MOCK_METHOD(bool, addToPath, (), (const));
MOCK_METHOD(void, writeGeneralSettings, (), (const));
MOCK_METHOD(bool, writeToSettings, (), (const));
MOCK_METHOD(void, setRelativePathModifier, (const QString &) );
MOCK_METHOD(void, setVersions, (const QStringList &) );
MOCK_METHOD(bool, automaticKitCreationEnabled, (), (const));
MOCK_METHOD(void, setAutomaticKitCreationEnabled, (const bool enabled));
MOCK_METHOD(QWidget *, widget, ());
}; // class PackageMock
} // namespace McuSupport::Internal

View File

@@ -0,0 +1,97 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "nxp_1064_json.h"
#include "unittest.h"
#include "utils/filepath.h"
#include <cmakeprojectmanager/cmakeconfigitem.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <gmock/gmock.h>
#include <QJsonArray>
#include <QJsonDocument>
namespace McuSupport::Internal::Test {
using CMakeProjectManager::CMakeConfigItem;
using CMakeProjectManager::CMakeConfigurationKitAspect;
using ProjectExplorer::EnvironmentKitAspect;
using ProjectExplorer::KitManager;
using testing::Return;
using testing::ReturnRef;
using Utils::FilePath;
void McuSupportTest::initTestCase()
{
EXPECT_CALL(freeRtosPackage, environmentVariableName()).WillRepeatedly(ReturnRef(freeRtosEnvVar));
EXPECT_CALL(freeRtosPackage, validStatus()).WillRepeatedly(Return(true));
EXPECT_CALL(freeRtosPackage, path())
.WillRepeatedly(Return(FilePath::fromString(defaultfreeRtosPath)));
}
void McuSupportTest::test_parseBasicInfoFromJson()
{
const auto description = Sdk::parseDescriptionJson(nxp_1064_json);
QVERIFY(not description.freeRTOS.envVar.isEmpty());
QVERIFY(description.freeRTOS.boardSdkSubDir.isEmpty());
}
void McuSupportTest::test_addNewKit()
{
auto &kitManager{*KitManager::instance()};
QSignalSpy kitAddedSpy(&kitManager, &KitManager::kitAdded);
auto *newKit{McuSupportOptions::newKit(&mcuTarget, &freeRtosPackage)};
QVERIFY(newKit != nullptr);
QCOMPARE(kitAddedSpy.count(), 1);
QList<QVariant> arguments = kitAddedSpy.takeFirst();
auto *createdKit = qvariant_cast<Kit *>(arguments.at(0));
QVERIFY(createdKit != nullptr);
QCOMPARE(createdKit, newKit);
auto cmakeAspect{CMakeConfigurationKitAspect{}};
QVERIFY(createdKit->hasValue(cmakeAspect.id()));
QVERIFY(createdKit->value(cmakeAspect.id(), freeRtosCmakeVar).isValid());
}
void McuSupportTest::test_addFreeRtosCmakeVarToKit()
{
McuSupportOptions::updateKitEnvironment(&kit, &mcuTarget);
QVERIFY(kit.hasValue(EnvironmentKitAspect::id()));
QVERIFY(kit.isValid());
QVERIFY(not kit.allKeys().empty());
const auto &cmakeConfig{CMakeConfigurationKitAspect::configuration(&kit)};
QCOMPARE(cmakeConfig.size(), 1);
CMakeConfigItem expectedCmakeVar{freeRtosCmakeVar.toLocal8Bit(),
defaultfreeRtosPath.toLocal8Bit()};
QVERIFY(cmakeConfig.contains(expectedCmakeVar));
}
} // namespace McuSupport::Internal::Test

View File

@@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "mcusupportoptions.h"
#include "mcusupportplugin.h"
#include "mcusupportsdk.h"
#include "mcupackage.h"
#include "packagemock.h"
#include <projectexplorer/kit.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <utils/filepath.h>
#include <utils/fileutils.h>
#include <QObject>
#include <QSignalSpy>
#include <QTest>
namespace McuSupport::Internal::Test {
using ProjectExplorer::Kit;
class McuSupportTest : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void test_addFreeRtosCmakeVarToKit();
void test_addNewKit();
void test_parseBasicInfoFromJson();
private:
QVersionNumber currentQulVersion{2, 0};
const QString id{"target_id"};
const QString name{"target_name"};
const QString vendor{"target_vendor"};
const QString freeRtosEnvVar{"EVK_MIMXRT1170_FREERTOS_PATH"};
const QString freeRtosCmakeVar{"FREERTOS_DIR"};
const QString defaultfreeRtosPath{"/opt/freertos/default"};
PackageMock freeRtosPackage;
Kit kit;
McuToolChainPackage toolchainPackage{{}, {}, {}, {}, {}};
const McuTarget::Platform platform{id, name, vendor};
McuTarget mcuTarget{currentQulVersion,
platform,
McuTarget::OS::FreeRTOS,
{&freeRtosPackage},
&toolchainPackage};
}; // class McuSupportTest
} // namespace McuSupport::Internal::Test