QmlProjectManager: Generate .qmlproject file based on qmldir (McuModuleProjectItem)

Task-number: QDS-13811
Change-Id: I187f04fbc4ba7752e9e1d7eb634c0904abae3a2f
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Rafal Stawarski
2024-10-18 12:04:45 +02:00
parent 82f990558b
commit b32bd7f236
23 changed files with 786 additions and 0 deletions

View File

@@ -53,6 +53,13 @@ extend_qtc_plugin(QmlProjectManager
boilerplate.qrc
)
extend_qtc_plugin(QmlProjectManager
PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/qmldirtoqmlproject
SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/qmldirtoqmlproject
SOURCES
mcumoduleprojectitem.cpp mcumoduleprojectitem.h
)
add_qtc_library(QmlProjectManagerLib OBJECT
CONDITION WITH_TESTS AND Qt6_VERSION VERSION_GREATER_EQUAL 6.4.3
EXCLUDE_FROM_INSTALL
@@ -66,4 +73,5 @@ add_qtc_library(QmlProjectManagerLib OBJECT
buildsystem/projectitem/qmlprojectitem.cpp buildsystem/projectitem/qmlprojectitem.h
buildsystem/projectitem/converters.cpp buildsystem/projectitem/converters.h
qmlprojectexporter/filetypes.cpp qmlprojectexporter/filetypes.h
qmldirtoqmlproject/mcumoduleprojectitem.cpp qmldirtoqmlproject/mcumoduleprojectitem.h
)

View File

@@ -0,0 +1,261 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "mcumoduleprojectitem.h"
#include <qmljs/qmljssimplereader.h>
#include <utils/algorithm.h>
#include <QJsonArray>
#include <QLoggingCategory>
using namespace Qt::Literals::StringLiterals;
namespace Constants {
namespace QmlDir {
constexpr auto QMLDIR = "qmldir"_L1;
constexpr auto MODULE = "module"_L1;
constexpr auto QML_FILE_FILTER = "*.qml"_L1;
} // namespace QmlDir
namespace Json {
constexpr auto MODULE_URI = "moduleUri"_L1;
constexpr auto QML_FILES = "qmlFiles"_L1;
constexpr auto QMLPROJECT_PATH = "qmlProjectPath"_L1;
} // namespace Json
namespace QmlProject {
constexpr auto QMLPROJECT_EXTENSION = ".qmlproject"_L1;
constexpr auto MCU_MODULE = "MCU.Module"_L1;
constexpr auto URI = "uri"_L1;
constexpr auto QML_FILES = "QmlFiles"_L1;
constexpr auto FILES = "files"_L1;
const auto QMLPROJECT_TEMPLATE = QString(R"(/* File generated by Qt Design Studio */
import QmlProject 1.3
Project {
MCU.Module {
uri: %1
}
QmlFiles {
files: [
%2
]
}
}
)");
} // namespace QmlProject
} // namespace Constants
namespace {
Q_LOGGING_CATEGORY(log, "QmlProjectManager.McuModuleProjectItem")
bool isValidQmlProjectPath(const Utils::FilePath &path)
{
return path.endsWith(Constants::QmlProject::QMLPROJECT_EXTENSION)
&& (path.ensureExistingFile() || path.parentDir().isWritableDir());
}
QJsonObject parseQmlProjectFile(const Utils::FilePath &qmlproject)
{
auto qmlprojectPathStr = qmlproject.toFSPathString();
if (!qmlproject.exists()) {
qCCritical(log) << "qmlproject file not found:" << qmlprojectPathStr;
return {};
}
QmlJS::SimpleReader reader;
QmlJS::SimpleReaderNode::Ptr rootNode = reader.readFile(qmlprojectPathStr);
if (!reader.errors().isEmpty() || !rootNode->isValid()) {
qCCritical(log) << "Unable to parse:" << qmlprojectPathStr;
qCCritical(log) << reader.errors();
return {};
}
QJsonObject result;
result.insert(Constants::Json::QMLPROJECT_PATH, qmlprojectPathStr);
auto checkNodeName = [](const QString &node, const QString &expecedName) {
return node.compare(expecedName, Qt::CaseInsensitive) == 0;
};
//expected just two nodes: MCU.Module and QmlFiles
for (const auto &childNode : rootNode->children()) {
auto nodeName = childNode->name();
if (checkNodeName(nodeName, Constants::QmlProject::MCU_MODULE)) {
result.insert(Constants::Json::MODULE_URI,
childNode->property(Constants::QmlProject::URI).value.toString());
} else if (checkNodeName(nodeName, Constants::QmlProject::QML_FILES)) {
result.insert(Constants::Json::QML_FILES,
childNode->property(Constants::QmlProject::FILES).value.toJsonArray());
} else {
qCWarning(log) << "Unsupported node:" << nodeName;
}
}
return result;
}
} // namespace
namespace QmlProjectManager {
McuModuleProjectItem::McuModuleProjectItem(const QJsonObject &project)
: m_project(project)
{}
McuModuleProjectItem::McuModuleProjectItem(const Utils::FilePath &qmlprojectFile)
: m_qmlProjectFile(qmlprojectFile)
, m_project(parseQmlProjectFile(m_qmlProjectFile))
{
}
std::optional<McuModuleProjectItem> McuModuleProjectItem::fromQmldirModule(const Utils::FilePath &qmldirFile)
{
auto qmldirFileStr = qmldirFile.toFSPathString();
// check qmldirFile
if (!qmldirFile.exists()) {
qCWarning(log) << "File not found:" << qmldirFileStr;
return {};
}
if (qmldirFile.fileName() != Constants::QmlDir::QMLDIR) {
qCWarning(log) << "It's not qmldir file:" << qmldirFileStr;
return {};
}
auto qmldirContents = qmldirFile.fileContents();
if (!qmldirContents) {
qCWarning(log) << "Unable to read the file:" << qmldirFileStr
<< ", error:" << qmldirContents.error();
return {};
}
// find module name
QByteArray fileContents = qmldirContents.value();
QTextStream ts(fileContents);
QString moduleName;
while (!ts.atEnd()) {
QString line = ts.readLine().trimmed();
if (line.startsWith(Constants::QmlDir::MODULE, Qt::CaseInsensitive)) {
auto list = line.split(' ');
if (list.size() != 2) {
qCWarning(log) << "Invalid module identifier:" << line;
return {};
}
moduleName = list.last();
break;
}
}
if (moduleName.isEmpty()) {
qCWarning(log) << "Module name not found in the qmldir";
return {};
}
// list qml files
const auto qmldirParent = qmldirFile.parentDir();
auto qmlDirEntries = qmldirParent.dirEntries(Utils::FileFilter{{Constants::QmlDir::QML_FILE_FILTER},
QDir::NoFilter,
QDirIterator::Subdirectories});
if (qmlDirEntries.empty()) {
qCWarning(log) << "No qml files found in:" << qmldirParent;
return {};
}
auto qmlFiles = Utils::transform<QStringList>(qmlDirEntries, [qmldirParent](const Utils::FilePath &path) {
return path.relativePathFrom(qmldirParent).toFSPathString();
});
// build mcu module project
QJsonObject result;
result.insert(Constants::Json::MODULE_URI, moduleName);
result.insert(Constants::Json::QML_FILES, QJsonArray::fromStringList(qmlFiles));
auto filename = moduleName.replace('.', '_');
auto qmlprojectPath = qmldirParent.resolvePath(
Utils::FilePath::fromString(filename + Constants::QmlProject::QMLPROJECT_EXTENSION));
result.insert(Constants::Json::QMLPROJECT_PATH, qmlprojectPath.toFSPathString());
return McuModuleProjectItem(result);
}
bool McuModuleProjectItem::isValid() const noexcept
{
return !uri().isEmpty() && !qmlFiles().isEmpty() && isValidQmlProjectPath(qmlProjectPath());
}
QString McuModuleProjectItem::uri() const noexcept
{
return m_project[Constants::Json::MODULE_URI].toString();
}
void McuModuleProjectItem::setUri(const QString &moduleUri)
{
m_project[Constants::Json::MODULE_URI] = moduleUri;
}
QStringList McuModuleProjectItem::qmlFiles() const noexcept
{
return m_project[Constants::Json::QML_FILES].toVariant().toStringList();
}
void McuModuleProjectItem::setQmlFiles(const QStringList &files)
{
m_project[Constants::Json::QML_FILES] = QJsonArray::fromStringList(files);
}
Utils::FilePath McuModuleProjectItem::qmlProjectPath() const noexcept
{
return Utils::FilePath::fromString(m_project[Constants::Json::QMLPROJECT_PATH].toString());
}
void McuModuleProjectItem::setQmlProjectPath(const Utils::FilePath &path)
{
m_project[Constants::Json::QMLPROJECT_PATH] = path.toFSPathString();
}
QJsonObject McuModuleProjectItem::project() const noexcept
{
return m_project;
}
bool McuModuleProjectItem::saveQmlProjectFile() const
{
if (!isValid()) {
return false;
}
auto path = qmlProjectPath();
if (path.exists()) {
if (McuModuleProjectItem old(path); old == *this) {
return false;
}
}
QTC_ASSERT_EXPECTED(path.writeFileContents(jsonToQmlproject()), return false);
return true;
}
bool McuModuleProjectItem::operator==(const McuModuleProjectItem &other) const noexcept
{
return this->project() == other.project();
}
QByteArray McuModuleProjectItem::jsonToQmlproject() const
{
auto quoted = [](const QString &s) { return QString("\"%1\"").arg(s); };
auto indent = [](int tabs = 1) { return QString(" ").repeated(tabs * 4); };
auto quotedQmlFiles = Utils::transform<QStringList>(qmlFiles(), [quoted](const QString &file) {
return quoted(file);
});
QString qmlFilesSeparator;
QTextStream ts(&qmlFilesSeparator);
ts << "," << Qt::endl << indent(3);
return Constants::QmlProject::QMLPROJECT_TEMPLATE
.arg(quoted(uri()), quotedQmlFiles.join(qmlFilesSeparator))
.toUtf8();
}
} // namespace QmlProjectManager

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include "../qmlprojectmanager_global.h"
#include <utils/filepath.h>
#include <QJsonObject>
#ifndef UNIT_TESTS
# define MCUMODULEPROJEC_EXPORT QMLPROJECTMANAGER_EXPORT
#else
# define MCUMODULEPROJEC_EXPORT
#endif
namespace QmlProjectManager {
class MCUMODULEPROJEC_EXPORT McuModuleProjectItem
{
public:
explicit McuModuleProjectItem(const QJsonObject &project);
explicit McuModuleProjectItem(const Utils::FilePath &qmlprojectFile);
static std::optional<McuModuleProjectItem> fromQmldirModule(const Utils::FilePath &qmldirFile);
bool isValid() const noexcept;
QString uri() const noexcept;
void setUri(const QString &moduleUri);
QStringList qmlFiles() const noexcept;
void setQmlFiles(const QStringList &files);
Utils::FilePath qmlProjectPath() const noexcept;
void setQmlProjectPath(const Utils::FilePath &path);
QJsonObject project() const noexcept;
bool saveQmlProjectFile() const;
bool operator==(const McuModuleProjectItem &other) const noexcept;
private:
QByteArray jsonToQmlproject() const;
Utils::FilePath m_qmlProjectFile;
QJsonObject m_project;
};
} // namespace QmlProjectManager

View File

@@ -6,6 +6,7 @@ extend_qtc_test(unittest
SOURCES
converters-test.cpp
projectitem-test.cpp
mcumoduleprojectitem-test.cpp
)
unittest_copy_data_folder()

View File

@@ -70,3 +70,13 @@ Some main points for qmlproject files for MCU projects:
Test data contains an example project folders that file filters will be initialized and tested.
* **filelist.txt**: List of the files need to be found by the file filters.
## Qml to qmlproject test data
Input data for the McuModuleProjectItem tests. McuModuleProjectItem represents the MCU module and can be generated from a regular QML module (based on qmldir).
* **existing_qmlproject**: read and process valid .qmlproject module
* **incorrect_module_name_qmldir**: generate .qmlproject based on qmldir (failure - module name is wrong)
* **invalid_qmlproject**: read and process invalid .qmlproject module
* **missing_module_name_qmldir**: generate .qmlproject based on qmldir (failure - missing module name)
* **missing_qml_files_qmldir**: generate .qmlproject based on qmldir (failure - missing qml files)
* **missing_qmlproject**: generate .qmlproject based on qmldir (success)

View File

@@ -0,0 +1,5 @@
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,5 @@
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,6 @@
pragma Singleton
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,3 @@
# test comment
module test.module
singleton TestSingleton 1.0 TestSingleton.qml

View File

@@ -0,0 +1,16 @@
import QmlProject 1.3
Project {
MCU.Module {
uri: "test.module"
}
QmlFiles {
files: [
"TestSingleton.qml",
"File1.qml",
"File2.qml",
"Internal/File3.qml"
]
}
}

View File

@@ -0,0 +1,6 @@
pragma Singleton
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,3 @@
# test comment
module test module
singleton TestSingleton 1.0 TestSingleton.qml

View File

@@ -0,0 +1,5 @@
import QmlProject 1.3
Project {
}

View File

@@ -0,0 +1,6 @@
pragma Singleton
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,2 @@
# test comment
singleton TestSingleton 1.0 TestSingleton.qml

View File

@@ -0,0 +1,2 @@
# test comment
module test.module

View File

@@ -0,0 +1,5 @@
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,5 @@
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,5 @@
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,6 @@
pragma Singleton
import QtQuick
QtObject {
}

View File

@@ -0,0 +1,3 @@
# test comment
module test.module
singleton TestSingleton 1.0 TestSingleton.qml

View File

@@ -0,0 +1,368 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "../utils/googletest.h" // IWYU pragma: keep
#include <qmlprojectmanager/qmldirtoqmlproject/mcumoduleprojectitem.h>
#include <QJsonDocument>
namespace {
constexpr QLatin1String localTestDataDir{UNITTEST_DIR "/qmlprojectmanager/data"};
constexpr QLatin1String jsonProject{R"(
{
"moduleUri": "test.module",
"qmlFiles": [
"TestSingleton.qml",
"File1.qml",
"File2.qml",
"Internal/File3.qml"
],
"qmlProjectPath": "%1"
}
)"};
class McuModuleProjectItem : public testing::Test
{
protected:
static void SetUpTestSuite()
{
existingQmlProject = std::make_unique<const QmlProjectManager::McuModuleProjectItem>(
Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/existing_qmlproject/test_module.qmlproject"));
auto fromQmldir = QmlProjectManager::McuModuleProjectItem::fromQmldirModule(
Utils::FilePath::fromString(localTestDataDir
+ "/qmldirtoqmlproject/missing_qmlproject/qmldir"));
missingQmlProject = std::make_unique<const QmlProjectManager::McuModuleProjectItem>(
fromQmldir ? *fromQmldir : QmlProjectManager::McuModuleProjectItem{QJsonObject{}});
invalidQmlProject = std::make_unique<const QmlProjectManager::McuModuleProjectItem>(
Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/invalid_qmlproject/test_module.qmlproject"));
fromJsonObject = std::make_unique<const QmlProjectManager::McuModuleProjectItem>(
QJsonDocument::fromJson(
jsonProject.arg(localTestDataDir + "/qmldirtoqmlproject/test_module.qmlproject").toUtf8())
.object());
fromIncompleteJsonObject = std::make_unique<const QmlProjectManager::McuModuleProjectItem>(
QJsonDocument::fromJson(jsonProject.toString().toUtf8()).object());
createFromEmpty = std::make_unique<QmlProjectManager::McuModuleProjectItem>(QJsonObject{});
}
static void TearDownTestSuite()
{
existingQmlProject.reset();
missingQmlProject->qmlProjectPath().removeFile();
missingQmlProject.reset();
invalidQmlProject.reset();
fromJsonObject.reset();
fromIncompleteJsonObject.reset();
createFromEmpty->qmlProjectPath().removeFile();
createFromEmpty.reset();
}
protected:
inline static std::unique_ptr<const QmlProjectManager::McuModuleProjectItem> existingQmlProject;
inline static std::unique_ptr<const QmlProjectManager::McuModuleProjectItem> missingQmlProject;
inline static std::unique_ptr<const QmlProjectManager::McuModuleProjectItem> invalidQmlProject;
inline static std::unique_ptr<const QmlProjectManager::McuModuleProjectItem> fromJsonObject;
inline static std::unique_ptr<const QmlProjectManager::McuModuleProjectItem> fromIncompleteJsonObject;
inline static std::unique_ptr<QmlProjectManager::McuModuleProjectItem> createFromEmpty;
};
} // namespace
TEST_F(McuModuleProjectItem, is_valid_existing_qmlproject)
{
auto isValid = existingQmlProject->isValid();
ASSERT_TRUE(isValid);
}
TEST_F(McuModuleProjectItem, get_uri_existing_qmlproject)
{
auto uri = existingQmlProject->uri();
ASSERT_THAT(uri, Eq("test.module"));
}
TEST_F(McuModuleProjectItem, get_qml_files_existing_qmlproject)
{
auto files = existingQmlProject->qmlFiles();
ASSERT_THAT(files,
UnorderedElementsAre("Internal/File3.qml", "File2.qml", "File1.qml", "TestSingleton.qml"));
}
TEST_F(McuModuleProjectItem, get_qmlproject_path_existing_qmlproject)
{
auto path = existingQmlProject->qmlProjectPath();
auto expectedPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/existing_qmlproject/test_module.qmlproject");
ASSERT_THAT(path, Eq(expectedPath));
}
TEST_F(McuModuleProjectItem, get_project_existing_qmlproject)
{
auto project = existingQmlProject->project();
auto expectedJsonProject = QJsonDocument::fromJson(
jsonProject
.arg(localTestDataDir + "/qmldirtoqmlproject/existing_qmlproject/test_module.qmlproject")
.toUtf8())
.object();
ASSERT_THAT(project, Eq(expectedJsonProject));
}
TEST_F(McuModuleProjectItem, save_qmlproject_file_existing_qmlproject)
{
bool saved = existingQmlProject->saveQmlProjectFile();
ASSERT_FALSE(saved);
}
TEST_F(McuModuleProjectItem, is_valid_missing_qmlproject)
{
auto isValid = missingQmlProject->isValid();
ASSERT_TRUE(isValid);
}
TEST_F(McuModuleProjectItem, get_uri_missing_qmlproject)
{
auto uri = missingQmlProject->uri();
ASSERT_THAT(uri, Eq("test.module"));
}
TEST_F(McuModuleProjectItem, get_qml_files_missing_qmlproject)
{
auto files = missingQmlProject->qmlFiles();
ASSERT_THAT(files,
UnorderedElementsAre("Internal/File3.qml", "File2.qml", "File1.qml", "TestSingleton.qml"));
}
TEST_F(McuModuleProjectItem, get_qmlproject_path_missing_qmlproject)
{
auto path = missingQmlProject->qmlProjectPath();
auto expectedPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/missing_qmlproject/test_module.qmlproject");
ASSERT_THAT(path, Eq(expectedPath));
}
TEST_F(McuModuleProjectItem, check_saved_qmlproject_file_missing_qmlproject)
{
auto projectPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/missing_qmlproject/test_module.qmlproject");
missingQmlProject->saveQmlProjectFile();
QmlProjectManager::McuModuleProjectItem savedQmlProject(projectPath);
ASSERT_THAT(*missingQmlProject, Eq(savedQmlProject));
}
TEST_F(McuModuleProjectItem, is_valid_invalid_qmlproject)
{
auto isValid = invalidQmlProject->isValid();
ASSERT_FALSE(isValid);
}
TEST_F(McuModuleProjectItem, get_uri_invalid_qmlproject)
{
auto uri = invalidQmlProject->uri();
ASSERT_THAT(uri, IsEmpty());
}
TEST_F(McuModuleProjectItem, get_qml_files_invalid_qmlproject)
{
auto files = invalidQmlProject->qmlFiles();
ASSERT_THAT(files, IsEmpty());
}
TEST_F(McuModuleProjectItem, get_qmlproject_path_invalid_qmlproject)
{
auto path = invalidQmlProject->qmlProjectPath();
auto expectedPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/invalid_qmlproject/test_module.qmlproject");
ASSERT_THAT(path, Eq(expectedPath));
}
TEST_F(McuModuleProjectItem, save_qmlproject_file_invalid_qmlproject)
{
bool saved = invalidQmlProject->saveQmlProjectFile();
ASSERT_FALSE(saved);
}
TEST_F(McuModuleProjectItem, is_valid_from_json_object)
{
auto isValid = fromJsonObject->isValid();
ASSERT_TRUE(isValid);
}
TEST_F(McuModuleProjectItem, get_uri_from_json_object)
{
auto uri = fromJsonObject->uri();
ASSERT_THAT(uri, Eq("test.module"));
}
TEST_F(McuModuleProjectItem, get_qml_files_from_json_object)
{
auto files = fromJsonObject->qmlFiles();
ASSERT_THAT(files,
UnorderedElementsAre("Internal/File3.qml", "File2.qml", "File1.qml", "TestSingleton.qml"));
}
TEST_F(McuModuleProjectItem, get_qmlproject_path_from_json_object)
{
auto path = fromJsonObject->qmlProjectPath();
auto expectedPath = Utils::FilePath::fromString(localTestDataDir
+ "/qmldirtoqmlproject/test_module.qmlproject");
ASSERT_THAT(path, Eq(expectedPath));
}
TEST_F(McuModuleProjectItem, get_project_from_json_object)
{
auto project = fromJsonObject->project();
auto expectedJsonProject = QJsonDocument::fromJson(
jsonProject
.arg(localTestDataDir
+ "/qmldirtoqmlproject/test_module.qmlproject")
.toUtf8())
.object();
ASSERT_THAT(project, Eq(expectedJsonProject));
}
TEST_F(McuModuleProjectItem, is_valid_from_incomplete_json_object)
{
auto isValid = fromIncompleteJsonObject->isValid();
ASSERT_FALSE(isValid);
}
TEST_F(McuModuleProjectItem, get_uri_from_incomplete_json_object)
{
auto uri = fromIncompleteJsonObject->uri();
ASSERT_THAT(uri, Eq("test.module"));
}
TEST_F(McuModuleProjectItem, get_qml_files_from_incomplete_json_object)
{
auto files = fromIncompleteJsonObject->qmlFiles();
ASSERT_THAT(files,
UnorderedElementsAre("Internal/File3.qml", "File2.qml", "File1.qml", "TestSingleton.qml"));
}
TEST_F(McuModuleProjectItem, get_qmlproject_path_from_incomplete_json_object)
{
auto path = fromIncompleteJsonObject->qmlProjectPath();
ASSERT_FALSE(path.endsWith(".qmlproject"));
}
TEST_F(McuModuleProjectItem, save_qmlproject_from_incomplete_json_object)
{
bool saved = fromIncompleteJsonObject->saveQmlProjectFile();
ASSERT_FALSE(saved);
}
TEST_F(McuModuleProjectItem, set_uri_create_from_empty)
{
createFromEmpty->setUri("test.module");
ASSERT_THAT(createFromEmpty->uri(), Eq("test.module"));
}
TEST_F(McuModuleProjectItem, set_qml_files_create_from_empty)
{
createFromEmpty->setQmlFiles({"File1.qml", "File2.qml"});
ASSERT_THAT(createFromEmpty->qmlFiles(), UnorderedElementsAre("File1.qml", "File2.qml"));
}
TEST_F(McuModuleProjectItem, set_qmlproject_path_create_from_empty)
{
auto projectPath = Utils::FilePath::fromString(localTestDataDir
+ "/qmldirtoqmlproject/test_module.qmlproject");
createFromEmpty->setQmlProjectPath(projectPath);
ASSERT_THAT(createFromEmpty->qmlProjectPath(), Eq(projectPath));
}
TEST_F(McuModuleProjectItem, is_valid_create_from_empty)
{
bool isValid = createFromEmpty->isValid();
ASSERT_TRUE(isValid);
}
TEST_F(McuModuleProjectItem, check_saved_qmlproject_create_from_empty)
{
auto projectPath = Utils::FilePath::fromString(localTestDataDir
+ "/qmldirtoqmlproject/test_module.qmlproject");
createFromEmpty->saveQmlProjectFile();
QmlProjectManager::McuModuleProjectItem savedQmlProject(projectPath);
ASSERT_THAT(*createFromEmpty, Eq(savedQmlProject));
}
TEST_F(McuModuleProjectItem, create_from_nonexisting_file)
{
auto projectPath = Utils::FilePath::fromString(localTestDataDir
+ "/qmldirtoqmlproject/nonexisting");
auto projectItem = QmlProjectManager::McuModuleProjectItem::fromQmldirModule(projectPath);
ASSERT_FALSE(projectItem);
}
TEST_F(McuModuleProjectItem, create_from_missing_module_name_qmldir)
{
auto projectPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/missing_module_name_qmldir/qmldir");
auto projectItem = QmlProjectManager::McuModuleProjectItem::fromQmldirModule(projectPath);
ASSERT_FALSE(projectItem);
}
TEST_F(McuModuleProjectItem, create_from_incorrect_module_name_qmldir)
{
auto projectPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/incorrect_module_name_qmldir/qmldir");
auto projectItem = QmlProjectManager::McuModuleProjectItem::fromQmldirModule(projectPath);
ASSERT_FALSE(projectItem);
}
TEST_F(McuModuleProjectItem, create_from_missing_qml_files_qmldir)
{
auto projectPath = Utils::FilePath::fromString(
localTestDataDir + "/qmldirtoqmlproject/missing_qml_files_qmldir/qmldir");
auto projectItem = QmlProjectManager::McuModuleProjectItem::fromQmldirModule(projectPath);
ASSERT_FALSE(projectItem);
}