forked from qt-creator/qt-creator
QmlDesigner: Improve NodeMetaInfo
Change-Id: I1b31a1b08332f6bdba74c46af3d0a190901e9607 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -50,6 +50,8 @@ public:
|
||||
|
||||
bool isValid() const;
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
TypeId id() const { return m_typeId; }
|
||||
bool isFileComponent() const;
|
||||
bool hasProperty(::Utils::SmallStringView propertyName) const;
|
||||
PropertyMetaInfos properties() const;
|
||||
|
@@ -49,6 +49,9 @@ public:
|
||||
return bool(m_nodeMetaInfoPrivateData);
|
||||
#endif
|
||||
}
|
||||
|
||||
PropertyDeclarationId id() const { return m_id; }
|
||||
|
||||
PropertyName name() const;
|
||||
NodeMetaInfo propertyType() const;
|
||||
bool isWritable() const;
|
||||
|
@@ -1421,7 +1421,7 @@ bool NodeMetaInfo::isValid() const
|
||||
bool NodeMetaInfo::isFileComponent() const
|
||||
{
|
||||
if constexpr (useProjectStorage())
|
||||
return bool(typeData().traits & Storage::TypeTraits::IsFileComponent);
|
||||
return isValid() && bool(typeData().traits & Storage::TypeTraits::IsFileComponent);
|
||||
else
|
||||
return isValid() && m_privateData->isFileComponent();
|
||||
}
|
||||
@@ -1429,7 +1429,7 @@ bool NodeMetaInfo::isFileComponent() const
|
||||
bool NodeMetaInfo::hasProperty(Utils::SmallStringView propertyName) const
|
||||
{
|
||||
if constexpr (useProjectStorage())
|
||||
return bool(m_projectStorage->propertyDeclarationId(m_typeId, propertyName));
|
||||
return isValid() && bool(m_projectStorage->propertyDeclarationId(m_typeId, propertyName));
|
||||
else
|
||||
return isValid() && m_privateData->properties().contains(propertyName);
|
||||
}
|
||||
@@ -1440,11 +1440,12 @@ PropertyMetaInfos NodeMetaInfo::properties() const
|
||||
return {};
|
||||
|
||||
if constexpr (useProjectStorage()) {
|
||||
return Utils::transform<PropertyMetaInfos>(
|
||||
m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) {
|
||||
return PropertyMetaInfo{id, m_projectStorage};
|
||||
});
|
||||
|
||||
if (isValid()) {
|
||||
return Utils::transform<PropertyMetaInfos>(
|
||||
m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) {
|
||||
return PropertyMetaInfo{id, m_projectStorage};
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const auto &properties = m_privateData->properties();
|
||||
|
||||
@@ -1456,15 +1457,19 @@ PropertyMetaInfos NodeMetaInfo::properties() const
|
||||
|
||||
return propertyMetaInfos;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
PropertyMetaInfos NodeMetaInfo::localProperties() const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
return Utils::transform<PropertyMetaInfos>(
|
||||
m_projectStorage->localPropertyDeclarationIds(m_typeId), [&](auto id) {
|
||||
return PropertyMetaInfo{id, m_projectStorage};
|
||||
});
|
||||
if (isValid()) {
|
||||
return Utils::transform<PropertyMetaInfos>(
|
||||
m_projectStorage->localPropertyDeclarationIds(m_typeId), [&](auto id) {
|
||||
return PropertyMetaInfo{id, m_projectStorage};
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const auto &properties = m_privateData->localProperties();
|
||||
|
||||
@@ -1476,15 +1481,21 @@ PropertyMetaInfos NodeMetaInfo::localProperties() const
|
||||
|
||||
return propertyMetaInfos;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
return {m_projectStorage->propertyDeclarationId(m_typeId, propertyName), m_projectStorage};
|
||||
if (isValid()) {
|
||||
return {m_projectStorage->propertyDeclarationId(m_typeId, propertyName),
|
||||
m_projectStorage};
|
||||
}
|
||||
} else {
|
||||
if (hasProperty(propertyName))
|
||||
if (hasProperty(propertyName)) {
|
||||
return PropertyMetaInfo{m_privateData, propertyName};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -1493,10 +1504,13 @@ PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const
|
||||
PropertyNameList NodeMetaInfo::signalNames() const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
return Utils::transform<PropertyNameList>(m_projectStorage->signalDeclarationNames(m_typeId),
|
||||
[&](const auto &name) {
|
||||
return name.toQByteArray();
|
||||
});
|
||||
if (isValid()) {
|
||||
return Utils::transform<PropertyNameList>(m_projectStorage->signalDeclarationNames(
|
||||
m_typeId),
|
||||
[&](const auto &name) {
|
||||
return name.toQByteArray();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isValid())
|
||||
return m_privateData->signalNames();
|
||||
@@ -1508,10 +1522,13 @@ PropertyNameList NodeMetaInfo::signalNames() const
|
||||
PropertyNameList NodeMetaInfo::slotNames() const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
return Utils::transform<PropertyNameList>(m_projectStorage->functionDeclarationNames(m_typeId),
|
||||
[&](const auto &name) {
|
||||
return name.toQByteArray();
|
||||
});
|
||||
if (isValid()) {
|
||||
return Utils::transform<PropertyNameList>(m_projectStorage->functionDeclarationNames(
|
||||
m_typeId),
|
||||
[&](const auto &name) {
|
||||
return name.toQByteArray();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isValid())
|
||||
return m_privateData->slotNames();
|
||||
@@ -1523,9 +1540,11 @@ PropertyNameList NodeMetaInfo::slotNames() const
|
||||
PropertyName NodeMetaInfo::defaultPropertyName() const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
if (auto name = m_projectStorage->propertyName(typeData().defaultPropertyId))
|
||||
return name->toQByteArray();
|
||||
return {};
|
||||
if (isValid()) {
|
||||
if (auto name = m_projectStorage->propertyName(typeData().defaultPropertyId)) {
|
||||
return name->toQByteArray();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isValid())
|
||||
return m_privateData->defaultPropertyName();
|
||||
@@ -1537,10 +1556,14 @@ PropertyName NodeMetaInfo::defaultPropertyName() const
|
||||
PropertyMetaInfo NodeMetaInfo::defaultProperty() const
|
||||
{
|
||||
if constexpr (useProjectStorage()) {
|
||||
return PropertyMetaInfo(typeData().defaultPropertyId, m_projectStorage);
|
||||
if (isValid()) {
|
||||
return PropertyMetaInfo(typeData().defaultPropertyId, m_projectStorage);
|
||||
}
|
||||
} else {
|
||||
return property(defaultPropertyName());
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
bool NodeMetaInfo::hasDefaultProperty() const
|
||||
{
|
||||
|
@@ -91,6 +91,16 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MatchAndExplain(const QByteArray &s, testing::MatchResultListener *listener) const
|
||||
{
|
||||
if (s.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*listener << "whose size is " << s.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
void DescribeTo(std::ostream *os) const { *os << "is empty"; }
|
||||
|
||||
void DescribeNegationTo(std::ostream *os) const { *os << "isn't empty"; }
|
||||
|
@@ -3,7 +3,16 @@
|
||||
|
||||
#include "projectstoragemock.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
#include <projectstorage/projectstorageinfotypes.h>
|
||||
|
||||
using QmlDesigner::ModuleId;
|
||||
using QmlDesigner::PropertyDeclarationId;
|
||||
using QmlDesigner::TypeId;
|
||||
using QmlDesigner::TypeIds;
|
||||
using QmlDesigner::Storage::PropertyDeclarationTraits;
|
||||
|
||||
namespace Storage = QmlDesigner::Storage;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename BasicId>
|
||||
@@ -12,62 +21,6 @@ void incrementBasicId(BasicId &id)
|
||||
id = BasicId::create(id.internalId() + 1);
|
||||
}
|
||||
|
||||
ModuleId createModule(ProjectStorageMock &mock, Utils::SmallStringView moduleName)
|
||||
{
|
||||
static ModuleId moduleId;
|
||||
incrementBasicId(moduleId);
|
||||
|
||||
ON_CALL(mock, moduleId(Eq(moduleName))).WillByDefault(Return(moduleId));
|
||||
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
PropertyDeclarationId createProperty(ProjectStorageMock &mock, TypeId typeId, Utils::SmallString name)
|
||||
{
|
||||
static PropertyDeclarationId propertyId;
|
||||
incrementBasicId(propertyId);
|
||||
|
||||
ON_CALL(mock, propertyDeclarationId(Eq(typeId), Eq(name))).WillByDefault(Return(propertyId));
|
||||
ON_CALL(mock, propertyName(Eq(propertyId))).WillByDefault(Return(name));
|
||||
|
||||
return propertyId;
|
||||
}
|
||||
|
||||
TypeId createType(ProjectStorageMock &mock,
|
||||
ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallString defaultPropertyName,
|
||||
Storage::TypeTraits typeTraits,
|
||||
TypeIds baseTypeIds = {})
|
||||
{
|
||||
static TypeId typeId;
|
||||
incrementBasicId(typeId);
|
||||
|
||||
ON_CALL(mock, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId));
|
||||
PropertyDeclarationId defaultPropertyDeclarationId;
|
||||
if (defaultPropertyName.size())
|
||||
defaultPropertyDeclarationId = createProperty(mock, typeId, defaultPropertyName);
|
||||
ON_CALL(mock, type(Eq(typeId)))
|
||||
.WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, typeTraits}));
|
||||
|
||||
ON_CALL(mock, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true));
|
||||
|
||||
for (TypeId baseTypeId : baseTypeIds)
|
||||
ON_CALL(mock, isBasedOn(Eq(typeId), Eq(baseTypeId))).WillByDefault(Return(true));
|
||||
|
||||
return typeId;
|
||||
}
|
||||
|
||||
TypeId createObject(ProjectStorageMock &mock,
|
||||
ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallString defaultPropertyName,
|
||||
TypeIds baseTypeIds = {})
|
||||
{
|
||||
return createType(
|
||||
mock, moduleId, typeName, defaultPropertyName, Storage::TypeTraits::Reference, baseTypeIds);
|
||||
}
|
||||
|
||||
void setupIsBasedOn(ProjectStorageMock &mock)
|
||||
{
|
||||
auto call = [&](TypeId typeId, auto... ids) -> bool {
|
||||
@@ -82,49 +35,208 @@ void setupIsBasedOn(ProjectStorageMock &mock)
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace QmlDesigner
|
||||
|
||||
ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName)
|
||||
{
|
||||
static ModuleId moduleId;
|
||||
incrementBasicId(moduleId);
|
||||
|
||||
ON_CALL(*this, moduleId(Eq(moduleName))).WillByDefault(Return(moduleId));
|
||||
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId,
|
||||
Utils::SmallString name,
|
||||
PropertyDeclarationTraits traits,
|
||||
TypeId propertyTypeId)
|
||||
{
|
||||
static PropertyDeclarationId propertyId;
|
||||
incrementBasicId(propertyId);
|
||||
|
||||
ON_CALL(*this, propertyDeclarationId(Eq(typeId), Eq(name))).WillByDefault(Return(propertyId));
|
||||
ON_CALL(*this, propertyName(Eq(propertyId))).WillByDefault(Return(name));
|
||||
|
||||
ON_CALL(*this, propertyDeclaration(Eq(propertyId)))
|
||||
.WillByDefault(Return(
|
||||
QmlDesigner::Storage::Info::PropertyDeclaration{typeId, name, traits, propertyTypeId}));
|
||||
|
||||
auto ids = localPropertyDeclarationIds(typeId);
|
||||
ids.push_back(propertyId);
|
||||
ON_CALL(*this, propertyDeclarationIds(Eq(typeId))).WillByDefault(Return(ids));
|
||||
ON_CALL(*this, localPropertyDeclarationIds(Eq(typeId))).WillByDefault(Return(ids));
|
||||
|
||||
return propertyId;
|
||||
}
|
||||
|
||||
QmlDesigner::PropertyDeclarationId ProjectStorageMock::createProperty(
|
||||
QmlDesigner::TypeId typeId, Utils::SmallString name, QmlDesigner::TypeId propertyTypeId)
|
||||
{
|
||||
return createProperty(typeId, name, {}, propertyTypeId);
|
||||
}
|
||||
|
||||
void ProjectStorageMock::createSignal(QmlDesigner::TypeId typeId, Utils::SmallString name)
|
||||
{
|
||||
auto signalNames = signalDeclarationNames(typeId);
|
||||
signalNames.push_back(name);
|
||||
ON_CALL(*this, signalDeclarationNames(Eq(typeId))).WillByDefault(Return(signalNames));
|
||||
}
|
||||
|
||||
void ProjectStorageMock::createFunction(QmlDesigner::TypeId typeId, Utils::SmallString name)
|
||||
{
|
||||
auto functionNames = functionDeclarationNames(typeId);
|
||||
functionNames.push_back(name);
|
||||
ON_CALL(*this, functionDeclarationNames(Eq(typeId))).WillByDefault(Return(functionNames));
|
||||
}
|
||||
|
||||
TypeId ProjectStorageMock::createType(ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView defaultPropertyName,
|
||||
PropertyDeclarationTraits defaultPropertyTraits,
|
||||
TypeId defaultPropertyTypeId,
|
||||
Storage::TypeTraits typeTraits,
|
||||
TypeIds baseTypeIds)
|
||||
{
|
||||
static TypeId typeId;
|
||||
incrementBasicId(typeId);
|
||||
|
||||
ON_CALL(*this, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId));
|
||||
PropertyDeclarationId defaultPropertyDeclarationId;
|
||||
if (defaultPropertyName.size()) {
|
||||
if (!defaultPropertyTypeId) {
|
||||
defaultPropertyTypeId = typeId;
|
||||
}
|
||||
|
||||
defaultPropertyDeclarationId = createProperty(typeId,
|
||||
defaultPropertyName,
|
||||
defaultPropertyTraits,
|
||||
defaultPropertyTypeId);
|
||||
}
|
||||
|
||||
ON_CALL(*this, type(Eq(typeId)))
|
||||
.WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, typeTraits}));
|
||||
|
||||
ON_CALL(*this, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true));
|
||||
|
||||
for (TypeId baseTypeId : baseTypeIds)
|
||||
ON_CALL(*this, isBasedOn(Eq(typeId), Eq(baseTypeId))).WillByDefault(Return(true));
|
||||
|
||||
return typeId;
|
||||
}
|
||||
|
||||
QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
QmlDesigner::Storage::TypeTraits typeTraits,
|
||||
QmlDesigner::TypeIds baseTypeIds)
|
||||
{
|
||||
return createType(moduleId, typeName, {}, {}, TypeId{}, typeTraits, baseTypeIds);
|
||||
}
|
||||
|
||||
TypeId ProjectStorageMock::createObject(ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView defaultPropertyName,
|
||||
PropertyDeclarationTraits defaultPropertyTraits,
|
||||
QmlDesigner::TypeId defaultPropertyTypeId,
|
||||
TypeIds baseTypeIds)
|
||||
{
|
||||
return createType(moduleId,
|
||||
typeName,
|
||||
defaultPropertyName,
|
||||
defaultPropertyTraits,
|
||||
defaultPropertyTypeId,
|
||||
Storage::TypeTraits::Reference,
|
||||
baseTypeIds);
|
||||
}
|
||||
|
||||
TypeId ProjectStorageMock::createObject(ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
TypeIds baseTypeIds)
|
||||
{
|
||||
return createType(moduleId, typeName, Storage::TypeTraits::Reference, baseTypeIds);
|
||||
}
|
||||
|
||||
void ProjectStorageMock::setupQtQtuick()
|
||||
{
|
||||
QmlDesigner::setupIsBasedOn(*this);
|
||||
setupIsBasedOn(*this);
|
||||
|
||||
auto qmlModuleId = QmlDesigner::createModule(*this, "QML");
|
||||
auto qtQmlModelsModuleId = QmlDesigner::createModule(*this, "QtQml.Models");
|
||||
auto qtQuickModuleId = QmlDesigner::createModule(*this, "QtQuick");
|
||||
auto qtQuickNativeModuleId = QmlDesigner::createModule(*this, "QtQuick-cppnative");
|
||||
auto qmlModuleId = createModule("QML");
|
||||
auto qtQmlModelsModuleId = createModule("QtQml.Models");
|
||||
auto qtQuickModuleId = createModule("QtQuick");
|
||||
auto qtQuickNativeModuleId = createModule("QtQuick-cppnative");
|
||||
|
||||
auto qtObjectId = QmlDesigner::createObject(*this, qmlModuleId, "QtObject", "children");
|
||||
auto intId = createType(qmlModuleId, "int", Storage::TypeTraits::Value);
|
||||
|
||||
QmlDesigner::createObject(*this, qtQmlModelsModuleId, "ListModel", "children", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQmlModelsModuleId, "ListElement", "children", {qtObjectId});
|
||||
auto qtObjectId = createObject(qmlModuleId,
|
||||
"QtObject",
|
||||
"children",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
TypeId{});
|
||||
|
||||
auto itemId = QmlDesigner::createObject(*this, qtQuickModuleId, "Item", "data", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQuickModuleId, "ListView", "data", {qtObjectId, itemId});
|
||||
QmlDesigner::createObject(*this, qtQuickModuleId, "StateGroup", "states", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQuickModuleId, "State", "changes", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQuickModuleId, "Transition", "animations", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQuickModuleId, "PropertyAnimation", "", {qtObjectId});
|
||||
auto stateOperationsId = QmlDesigner::createObject(*this,
|
||||
qtQuickNativeModuleId,
|
||||
" QQuickStateOperation",
|
||||
"",
|
||||
{qtObjectId});
|
||||
QmlDesigner::createObject(*this,
|
||||
qtQuickModuleId,
|
||||
"PropertyChanges",
|
||||
"",
|
||||
{qtObjectId, stateOperationsId});
|
||||
auto listElementId = createObject(qtQmlModelsModuleId, "ListElement", {qtObjectId});
|
||||
createObject(qtQmlModelsModuleId,
|
||||
"ListModel",
|
||||
"children",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
listElementId,
|
||||
{qtObjectId});
|
||||
|
||||
auto qtQuickTimelineModuleId = QmlDesigner::createModule(*this, "QtQuick.Timeline");
|
||||
QmlDesigner::createObject(*this, qtQuickTimelineModuleId, "KeyframeGroup", "keyframes", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, qtQuickTimelineModuleId, "Keyframe", "", {qtObjectId});
|
||||
auto itemId = createObject(qtQuickModuleId,
|
||||
"Item",
|
||||
"data",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId});
|
||||
createObject(qtQuickModuleId,
|
||||
"ListView",
|
||||
"data",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId, itemId});
|
||||
createObject(qtQuickModuleId, "StateGroup", {qtObjectId});
|
||||
createObject(qtQuickModuleId,
|
||||
"State",
|
||||
"changes",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId});
|
||||
auto animationId = createObject(qtQuickModuleId, "Animation", {qtObjectId});
|
||||
createObject(qtQuickModuleId,
|
||||
"Transition",
|
||||
"animations",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
animationId,
|
||||
{qtObjectId});
|
||||
createObject(qtQuickModuleId, "PropertyAnimation", {qtObjectId});
|
||||
auto stateOperationsId = createObject(qtQuickNativeModuleId,
|
||||
" QQuickStateOperation",
|
||||
{qtObjectId});
|
||||
createObject(qtQuickModuleId, "PropertyChanges", {qtObjectId, stateOperationsId});
|
||||
|
||||
auto flowViewModuleId = QmlDesigner::createModule(*this, "FlowView");
|
||||
QmlDesigner::createObject(*this, flowViewModuleId, "FlowActionArea", "data", {qtObjectId, itemId});
|
||||
QmlDesigner::createObject(*this, flowViewModuleId, "FlowWildcard", "data", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, flowViewModuleId, "FlowDecision", "", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, flowViewModuleId, "FlowTransition", "", {qtObjectId});
|
||||
QmlDesigner::createObject(*this, flowViewModuleId, "FlowItem", "data", {qtObjectId, itemId});
|
||||
auto qtQuickTimelineModuleId = createModule("QtQuick.Timeline");
|
||||
createObject(qtQuickTimelineModuleId, "KeyframeGroup", {qtObjectId});
|
||||
createObject(qtQuickTimelineModuleId, "Keyframe", {qtObjectId});
|
||||
|
||||
auto flowViewModuleId = createModule("FlowView");
|
||||
createObject(flowViewModuleId,
|
||||
"FlowActionArea",
|
||||
"data",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId, itemId});
|
||||
createObject(flowViewModuleId,
|
||||
"FlowWildcard",
|
||||
"data",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId});
|
||||
createObject(flowViewModuleId, "FlowDecision", {qtObjectId});
|
||||
createObject(flowViewModuleId, "FlowTransition", {qtObjectId});
|
||||
createObject(flowViewModuleId,
|
||||
"FlowItem",
|
||||
"data",
|
||||
PropertyDeclarationTraits::IsList,
|
||||
qtObjectId,
|
||||
{qtObjectId, itemId});
|
||||
}
|
||||
|
||||
void ProjectStorageMock::setupCommonTypeCache()
|
||||
|
@@ -18,6 +18,47 @@ public:
|
||||
void setupQtQtuick();
|
||||
void setupCommonTypeCache();
|
||||
|
||||
QmlDesigner::ModuleId createModule(Utils::SmallStringView moduleName);
|
||||
|
||||
QmlDesigner::TypeId createType(
|
||||
QmlDesigner::ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView defaultPropertyName,
|
||||
QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits,
|
||||
QmlDesigner::TypeId defaultPropertyTypeId,
|
||||
QmlDesigner::Storage::TypeTraits typeTraits,
|
||||
QmlDesigner::TypeIds baseTypeIds = {});
|
||||
|
||||
QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
QmlDesigner::Storage::TypeTraits typeTraits,
|
||||
QmlDesigner::TypeIds baseTypeIds = {});
|
||||
|
||||
QmlDesigner::TypeId createObject(
|
||||
QmlDesigner::ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView defaultPropertyName,
|
||||
QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits,
|
||||
QmlDesigner::TypeId defaultPropertyTypeId,
|
||||
QmlDesigner::TypeIds baseTypeIds = {});
|
||||
|
||||
QmlDesigner::TypeId createObject(QmlDesigner::ModuleId moduleId,
|
||||
Utils::SmallStringView typeName,
|
||||
QmlDesigner::TypeIds baseTypeIds = {});
|
||||
|
||||
QmlDesigner::PropertyDeclarationId createProperty(
|
||||
QmlDesigner::TypeId typeId,
|
||||
Utils::SmallString name,
|
||||
QmlDesigner::Storage::PropertyDeclarationTraits traits,
|
||||
QmlDesigner::TypeId propertyTypeId);
|
||||
|
||||
QmlDesigner::PropertyDeclarationId createProperty(QmlDesigner::TypeId typeId,
|
||||
Utils::SmallString name,
|
||||
QmlDesigner::TypeId propertyTypeId);
|
||||
|
||||
void createSignal(QmlDesigner::TypeId typeId, Utils::SmallString name);
|
||||
void createFunction(QmlDesigner::TypeId typeId, Utils::SmallString name);
|
||||
|
||||
MOCK_METHOD(void,
|
||||
synchronize,
|
||||
(QmlDesigner::Storage::Synchronization::SynchronizationPackage package),
|
||||
|
@@ -61,6 +61,7 @@ endfunction(unittest_copy_data_folder)
|
||||
|
||||
add_subdirectory(listmodeleditor)
|
||||
add_subdirectory(imagecache)
|
||||
add_subdirectory(metainfo)
|
||||
add_subdirectory(model)
|
||||
add_subdirectory(sqlite)
|
||||
add_subdirectory(projectstorage)
|
||||
|
5
tests/unit/tests/unittests/metainfo/CMakeLists.txt
Normal file
5
tests/unit/tests/unittests/metainfo/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# qmldesigner/designercore/model
|
||||
extend_qtc_test(unittest
|
||||
SOURCES
|
||||
nodemetainfo-test.cpp
|
||||
)
|
415
tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp
Normal file
415
tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
// Copyright (C) 2023 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"
|
||||
|
||||
#include "../mocks/projectstoragemock.h"
|
||||
|
||||
#include <designercore/include/model.h>
|
||||
#include <designercore/include/modelnode.h>
|
||||
#include <designercore/include/nodemetainfo.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using QmlDesigner::ModelNode;
|
||||
using QmlDesigner::ModelNodes;
|
||||
|
||||
template<typename Matcher>
|
||||
auto PropertyId(const Matcher &matcher)
|
||||
{
|
||||
return Property(&QmlDesigner::PropertyMetaInfo::id, matcher);
|
||||
}
|
||||
|
||||
class NodeMetaInfo : public testing::Test
|
||||
{
|
||||
protected:
|
||||
NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock;
|
||||
QmlDesigner::Model model{projectStorageMock, "QtQuick.Item"};
|
||||
ModelNode rootNode = model.rootModelNode();
|
||||
ModelNode item = model.createModelNode("QtQuick.Item");
|
||||
ModelNode object = model.createModelNode("QML.QtObject");
|
||||
QmlDesigner::NodeMetaInfo itemMetaInfo = item.metaInfo();
|
||||
QmlDesigner::NodeMetaInfo objectMetaInfo = object.metaInfo();
|
||||
QmlDesigner::TypeId intTypeId = projectStorageMock.typeId(projectStorageMock.moduleId("QML"),
|
||||
"int",
|
||||
QmlDesigner::Storage::Version{});
|
||||
};
|
||||
|
||||
TEST_F(NodeMetaInfo, is_true_if_meta_info_exists)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto isValid = bool(metaInfo);
|
||||
|
||||
ASSERT_TRUE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, is_valid_if_meta_info_exists)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto isValid = metaInfo.isValid();
|
||||
|
||||
ASSERT_TRUE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, is_false_if_meta_info_not_exists)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto isValid = bool(metaInfo);
|
||||
|
||||
ASSERT_FALSE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, default_is_false)
|
||||
{
|
||||
auto isValid = bool(QmlDesigner::NodeMetaInfo{});
|
||||
|
||||
ASSERT_FALSE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, is_invalid_if_meta_info_not_exists)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto isValid = metaInfo.isValid();
|
||||
|
||||
ASSERT_FALSE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, default_is_invalid)
|
||||
{
|
||||
auto isValid = QmlDesigner::NodeMetaInfo{}.isValid();
|
||||
|
||||
ASSERT_FALSE(isValid);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, item_is_based_on_object)
|
||||
{
|
||||
bool isBasedOn = itemMetaInfo.isBasedOn(objectMetaInfo);
|
||||
|
||||
ASSERT_TRUE(isBasedOn);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, item_is_based_on_item)
|
||||
{
|
||||
bool isBasedOn = itemMetaInfo.isBasedOn(itemMetaInfo);
|
||||
|
||||
ASSERT_TRUE(isBasedOn);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, object_is_no_based_on_item)
|
||||
{
|
||||
bool isBasedOn = objectMetaInfo.isBasedOn(itemMetaInfo);
|
||||
|
||||
ASSERT_FALSE(isBasedOn);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, object_is_not_file_component)
|
||||
{
|
||||
bool isFileComponent = objectMetaInfo.isFileComponent();
|
||||
|
||||
ASSERT_FALSE(isFileComponent);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, default_is_not_file_component)
|
||||
{
|
||||
bool isFileComponent = QmlDesigner::NodeMetaInfo{}.isFileComponent();
|
||||
|
||||
ASSERT_FALSE(isFileComponent);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, invalid_is_not_file_component)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
bool isFileComponent = metaInfo.isFileComponent();
|
||||
|
||||
ASSERT_FALSE(isFileComponent);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, component_is_file_component)
|
||||
{
|
||||
using QmlDesigner::Storage::TypeTraits;
|
||||
auto moduleId = projectStorageMock.createModule("/path/to/project");
|
||||
auto typeId = projectStorageMock.createType(moduleId,
|
||||
"Foo",
|
||||
TypeTraits::IsFileComponent | TypeTraits::Reference);
|
||||
QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock};
|
||||
|
||||
bool isFileComponent = metaInfo.isFileComponent();
|
||||
|
||||
ASSERT_TRUE(isFileComponent);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, has_property)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
projectStorageMock.createProperty(metaInfo.id(), "x", intTypeId);
|
||||
|
||||
bool hasProperty = metaInfo.hasProperty("x");
|
||||
|
||||
ASSERT_TRUE(hasProperty);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, has_not_property)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
bool hasProperty = metaInfo.hasProperty("foo");
|
||||
|
||||
ASSERT_FALSE(hasProperty);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, default_has_not_property)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
bool hasProperty = metaInfo.hasProperty("x");
|
||||
|
||||
ASSERT_FALSE(hasProperty);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, invalid_has_not_property)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
bool hasProperty = metaInfo.hasProperty("x");
|
||||
|
||||
ASSERT_FALSE(hasProperty);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_property)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
auto propertyId = projectStorageMock.createProperty(metaInfo.id(), "x", intTypeId);
|
||||
|
||||
auto property = metaInfo.property("x");
|
||||
|
||||
ASSERT_THAT(property, PropertyId(propertyId));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_invalid_property_if_not_exists)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto property = metaInfo.property("x");
|
||||
|
||||
ASSERT_THAT(property, PropertyId(IsFalse()));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_invalid_property_for_default)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto property = metaInfo.property("x");
|
||||
|
||||
ASSERT_THAT(property, PropertyId(IsFalse()));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_invalid_property_if_meta_info_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto property = metaInfo.property("x");
|
||||
|
||||
ASSERT_THAT(property, PropertyId(IsFalse()));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_properties)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
auto xPropertyId = projectStorageMock.createProperty(metaInfo.id(), "x", intTypeId);
|
||||
auto yPropertyId = projectStorageMock.createProperty(metaInfo.id(), "y", intTypeId);
|
||||
|
||||
auto properties = metaInfo.properties();
|
||||
|
||||
ASSERT_THAT(properties, IsSupersetOf({PropertyId(xPropertyId), PropertyId(yPropertyId)}));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_properties_for_default)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto properties = metaInfo.properties();
|
||||
|
||||
ASSERT_THAT(properties, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_properties_if_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto properties = metaInfo.properties();
|
||||
|
||||
ASSERT_THAT(properties, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_local_properties)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
auto xPropertyId = projectStorageMock.createProperty(metaInfo.id(), "x", intTypeId);
|
||||
auto yPropertyId = projectStorageMock.createProperty(metaInfo.id(), "y", intTypeId);
|
||||
|
||||
auto properties = metaInfo.localProperties();
|
||||
|
||||
ASSERT_THAT(properties, IsSupersetOf({PropertyId(xPropertyId), PropertyId(yPropertyId)}));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_local_properties_for_default_metainfo)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto properties = metaInfo.localProperties();
|
||||
|
||||
ASSERT_THAT(properties, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_local_properties_if_node_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto properties = metaInfo.localProperties();
|
||||
|
||||
ASSERT_THAT(properties, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_signal_names)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
projectStorageMock.createSignal(metaInfo.id(), "xChanged");
|
||||
projectStorageMock.createSignal(metaInfo.id(), "yChanged");
|
||||
|
||||
auto signalNames = metaInfo.signalNames();
|
||||
|
||||
ASSERT_THAT(signalNames, IsSupersetOf({"xChanged", "yChanged"}));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_signal_names_for_default_metainfo)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto signalNames = metaInfo.signalNames();
|
||||
|
||||
ASSERT_THAT(signalNames, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_signal_names_if_node_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto signalNames = metaInfo.signalNames();
|
||||
|
||||
ASSERT_THAT(signalNames, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_function_names)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
projectStorageMock.createFunction(metaInfo.id(), "setX");
|
||||
projectStorageMock.createFunction(metaInfo.id(), "setY");
|
||||
|
||||
auto functionNames = metaInfo.slotNames();
|
||||
|
||||
ASSERT_THAT(functionNames, IsSupersetOf({"setX", "setY"}));
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_function_names_for_default_metainfo)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto functionNames = metaInfo.slotNames();
|
||||
|
||||
ASSERT_THAT(functionNames, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_function_names_if_node_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto functionNames = metaInfo.slotNames();
|
||||
|
||||
ASSERT_THAT(functionNames, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_default_property)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
auto defaultProperty = metaInfo.property("data");
|
||||
|
||||
auto property = metaInfo.defaultProperty();
|
||||
|
||||
ASSERT_THAT(property, defaultProperty);
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_default_property_for_default_metainfo)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto property = metaInfo.defaultProperty();
|
||||
|
||||
ASSERT_THAT(property, IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_default_property_if_node_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto property = metaInfo.defaultProperty();
|
||||
|
||||
ASSERT_THAT(property, IsFalse());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_default_property_name)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Item");
|
||||
auto metaInfo = node.metaInfo();
|
||||
auto defaultProperty = metaInfo.property("data");
|
||||
|
||||
auto property = metaInfo.defaultPropertyName();
|
||||
|
||||
ASSERT_THAT(property, "data");
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_default_property_name_for_default_metainfo)
|
||||
{
|
||||
auto metaInfo = QmlDesigner::NodeMetaInfo{};
|
||||
|
||||
auto property = metaInfo.defaultPropertyName();
|
||||
|
||||
ASSERT_THAT(property, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(NodeMetaInfo, get_no_default_property_name_if_node_is_invalid)
|
||||
{
|
||||
auto node = model.createModelNode("QtQuick.Foo");
|
||||
auto metaInfo = node.metaInfo();
|
||||
|
||||
auto property = metaInfo.defaultPropertyName();
|
||||
|
||||
ASSERT_THAT(property, IsEmpty());
|
||||
}
|
||||
|
||||
} // namespace
|
@@ -3,6 +3,7 @@ extend_qtc_test(unittest
|
||||
SOURCES
|
||||
import-test.cpp
|
||||
model-test.cpp
|
||||
modelnode-test.cpp
|
||||
nodelistproperty-test.cpp
|
||||
modelresourcemanagement-test.cpp
|
||||
)
|
||||
|
27
tests/unit/tests/unittests/model/modelnode-test.cpp
Normal file
27
tests/unit/tests/unittests/model/modelnode-test.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 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"
|
||||
|
||||
#include "../mocks/projectstoragemock.h"
|
||||
|
||||
#include <designercore/include/model.h>
|
||||
#include <designercore/include/modelnode.h>
|
||||
#include <designercore/include/nodemetainfo.h>
|
||||
|
||||
namespace {
|
||||
|
||||
class ModelNode : public testing::Test
|
||||
{
|
||||
protected:
|
||||
NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock;
|
||||
QmlDesigner::Model model{projectStorageMock, "QtQuick.Item"};
|
||||
QmlDesigner::ModelNode rootNode = model.rootModelNode();
|
||||
};
|
||||
|
||||
TEST_F(ModelNode, get_meta_info)
|
||||
{
|
||||
auto metaInfo = rootNode.metaInfo();
|
||||
}
|
||||
|
||||
} // namespace
|
@@ -30,9 +30,11 @@ using testing::Gt;
|
||||
using testing::HasSubstr;
|
||||
using testing::InSequence;
|
||||
using testing::Invoke;
|
||||
using testing::IsFalse;
|
||||
using testing::IsNull;
|
||||
using testing::IsSubsetOf;
|
||||
using testing::IsSupersetOf;
|
||||
using testing::IsTrue;
|
||||
using testing::Le;
|
||||
using testing::Lt;
|
||||
using testing::Matcher;
|
||||
|
Reference in New Issue
Block a user