diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 5121e6a663c..5208428ca42 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -2985,7 +2985,8 @@ PropertyMetaInfo::~PropertyMetaInfo() = default; NodeMetaInfo PropertyMetaInfo::propertyType() const { if constexpr (useProjectStorage()) { - return {propertyData().typeId, m_projectStorage}; + if (isValid()) + return {propertyData().propertyTypeId, m_projectStorage}; } else { if (isValid()) return NodeMetaInfo{nodeMetaInfoPrivateData()->model(), @@ -3012,7 +3013,7 @@ PropertyName PropertyMetaInfo::name() const bool PropertyMetaInfo::isWritable() const { if constexpr (useProjectStorage()) - return !(propertyData().traits & Storage::PropertyDeclarationTraits::IsReadOnly); + return isValid() && !(propertyData().traits & Storage::PropertyDeclarationTraits::IsReadOnly); else return isValid() && nodeMetaInfoPrivateData()->isPropertyWritable(propertyName()); } @@ -3020,7 +3021,7 @@ bool PropertyMetaInfo::isWritable() const bool PropertyMetaInfo::isListProperty() const { if constexpr (useProjectStorage()) - return propertyData().traits & Storage::PropertyDeclarationTraits::IsList; + return isValid() && propertyData().traits & Storage::PropertyDeclarationTraits::IsList; else return isValid() && nodeMetaInfoPrivateData()->isPropertyList(propertyName()); } @@ -3036,7 +3037,7 @@ bool PropertyMetaInfo::isEnumType() const bool PropertyMetaInfo::isPrivate() const { if constexpr (useProjectStorage()) - return propertyData().name.startsWith("__"); + return isValid() && propertyData().name.startsWith("__"); else return isValid() && propertyName().startsWith("__"); } @@ -3044,15 +3045,23 @@ bool PropertyMetaInfo::isPrivate() const bool PropertyMetaInfo::isPointer() const { if constexpr (useProjectStorage()) - return propertyData().traits & Storage::PropertyDeclarationTraits::IsPointer; + return isValid() && (propertyData().traits & Storage::PropertyDeclarationTraits::IsPointer); else return isValid() && nodeMetaInfoPrivateData()->isPropertyPointer(propertyName()); } +namespace { +template +bool isType(const QMetaType &type, const QMetaTypes &...types) +{ + return ((type == types) || ...); +} +} // namespace + QVariant PropertyMetaInfo::castedValue(const QVariant &value) const { if (!isValid()) - return value; + return {}; if constexpr (!useProjectStorage()) { const QVariant variant = value; @@ -3064,7 +3073,7 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const QVariant::Type typeId = nodeMetaInfoPrivateData()->variantTypeId(propertyName()); - if (variant.typeId() == QVariant::UserType && variant.typeId() == ModelNode::variantTypeId()) { + if (variant.typeId() == ModelNode::variantTypeId()) { return variant; } else if (typeId == QVariant::UserType && typeName == "QVariant") { return variant; @@ -3093,18 +3102,25 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const } } else { - if (isEnumType() || value.canConvert()) + if (isEnumType() && value.canConvert()) return value; - const TypeId &typeId = propertyData().typeId; + const TypeId &typeId = propertyData().propertyTypeId; + + static constexpr auto boolType = QMetaType::fromType(); + static constexpr auto intType = QMetaType::fromType(); + static constexpr auto longType = QMetaType::fromType(); + static constexpr auto longLongType = QMetaType::fromType(); + static constexpr auto floatType = QMetaType::fromType(); + static constexpr auto doubleType = QMetaType::fromType(); + static constexpr auto qStringType = QMetaType::fromType(); + static constexpr auto qUrlType = QMetaType::fromType(); + static constexpr auto qColorType = QMetaType::fromType(); if (value.typeId() == QVariant::UserType && value.typeId() == ModelNode::variantTypeId()) { return value; } else if (typeId == m_projectStorage->builtinTypeId()) { return value; - } else if (value.typeId() == QVariant::List) { - // TODO: check the contents of the list - return value; } else if (typeId == m_projectStorage->builtinTypeId()) { return value.toDouble(); } else if (typeId == m_projectStorage->builtinTypeId()) { @@ -3112,32 +3128,35 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const } else if (typeId == m_projectStorage->builtinTypeId()) { return value.toInt(); } else if (typeId == m_projectStorage->builtinTypeId()) { - return value.toBool(); + return isType(value.metaType(), boolType, intType, longType, longLongType, floatType, doubleType) + && value.toBool(); } else if (typeId == m_projectStorage->builtinTypeId()) { - return value.toString(); + if (isType(value.metaType(), qStringType)) + return value; + else + return QString{}; } else if (typeId == m_projectStorage->builtinTypeId()) { return value.toDateTime(); } else if (typeId == m_projectStorage->builtinTypeId()) { - return value.toUrl(); + if (isType(value.metaType(), qUrlType)) + return value; + else + return QUrl{}; } else if (typeId == m_projectStorage->builtinTypeId()) { - return value.value(); + if (isType(value.metaType(), qColorType)) + return value; + else + return QColor{}; } else if (typeId == m_projectStorage->builtinTypeId()) { return value.value(); } else if (typeId == m_projectStorage->builtinTypeId()) { return value.value(); } else if (typeId == m_projectStorage->builtinTypeId()) { return value.value(); - } else { - const auto typeName = propertyTypeName(); - const auto metaType = QMetaType::fromName(typeName); - auto copy = value; - bool converted = copy.convert(metaType); - if (converted) - return copy; } } - return Internal::PropertyParser::variantFromString(value.toString()); + return {}; } const Storage::Info::PropertyDeclaration &PropertyMetaInfo::propertyData() const diff --git a/tests/unit/tests/unittests/metainfo/CMakeLists.txt b/tests/unit/tests/unittests/metainfo/CMakeLists.txt index 7f2728f078b..77a9760cc23 100644 --- a/tests/unit/tests/unittests/metainfo/CMakeLists.txt +++ b/tests/unit/tests/unittests/metainfo/CMakeLists.txt @@ -2,4 +2,5 @@ extend_qtc_test(unittest SOURCES nodemetainfo-test.cpp + propertymetainfo-test.cpp ) diff --git a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp new file mode 100644 index 00000000000..43620baeb91 --- /dev/null +++ b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp @@ -0,0 +1,940 @@ +// 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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace { + +using QmlDesigner::Enumeration; +using QmlDesigner::ModelNode; +using QmlDesigner::ModelNodes; +using QmlDesigner::Storage::PropertyDeclarationTraits; +using QmlDesigner::Storage::TypeTraits; + +class PropertyMetaInfo : public ::testing::Test +{ +protected: + QmlDesigner::NodeMetaInfo createNodeMetaInfo(Utils::SmallStringView moduleName, + Utils::SmallStringView typeName, + QmlDesigner::Storage::TypeTraits typeTraits = {}) + { + auto moduleId = projectStorageMock.createModule(moduleName); + auto typeId = projectStorageMock.createType(moduleId, typeName, typeTraits); + + return QmlDesigner::NodeMetaInfo{typeId, &projectStorageMock}; + } + +protected: + NiceMock pathCache{"/path/foo.qml"}; + NiceMock projectStorageMock{pathCache.sourceId}; + QmlDesigner::Model model{{projectStorageMock, pathCache}, + "Item", + {QmlDesigner::Import::createLibraryImport("QML"), + QmlDesigner::Import::createLibraryImport("QtQuick"), + QmlDesigner::Import::createLibraryImport("QtQml.Models")}, + QUrl::fromLocalFile(pathCache.path.toQString())}; + QmlDesigner::NodeMetaInfo nodeInfo = createNodeMetaInfo("QtQuick", "Foo"); +}; + +TEST_F(PropertyMetaInfo, name) +{ + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + auto name = propertyInfo.name(); + + ASSERT_THAT(name, "bar"); +} + +TEST_F(PropertyMetaInfo, default_has_no_name) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + auto name = propertyInfo.name(); + + ASSERT_THAT(name, IsEmpty()); +} + +TEST_F(PropertyMetaInfo, property_type) +{ + auto barInfo = createNodeMetaInfo("QtQuick", "Bar"); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, barInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + auto type = propertyInfo.propertyType(); + + ASSERT_THAT(type, barInfo); +} + +TEST_F(PropertyMetaInfo, default_hads_invalid_property_type) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + auto type = propertyInfo.propertyType(); + + ASSERT_THAT(type, IsFalse()); +} + +TEST_F(PropertyMetaInfo, is_writable) +{ + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isList = propertyInfo.isWritable(); + + ASSERT_THAT(isList, IsTrue()); +} + +TEST_F(PropertyMetaInfo, is_not_writable) +{ + projectStorageMock.createProperty(nodeInfo.id(), + "bar", + PropertyDeclarationTraits::IsReadOnly, + nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isList = propertyInfo.isWritable(); + + ASSERT_THAT(isList, IsFalse()); +} + +TEST_F(PropertyMetaInfo, default_is_not_writable) +{ + projectStorageMock.createProperty(nodeInfo.id(), + "bar", + PropertyDeclarationTraits::IsReadOnly, + nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isList = propertyInfo.isWritable(); + + ASSERT_THAT(isList, IsFalse()); +} + +TEST_F(PropertyMetaInfo, is_list) +{ + projectStorageMock.createProperty(nodeInfo.id(), + "bar", + PropertyDeclarationTraits::IsList, + nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isList = propertyInfo.isListProperty(); + + ASSERT_THAT(isList, IsTrue()); +} + +TEST_F(PropertyMetaInfo, is_not_list) +{ + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isList = propertyInfo.isListProperty(); + + ASSERT_THAT(isList, IsFalse()); +} + +TEST_F(PropertyMetaInfo, default_is_not_list) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + bool isList = propertyInfo.isListProperty(); + + ASSERT_THAT(isList, IsFalse()); +} + +TEST_F(PropertyMetaInfo, is_enumeration) +{ + auto enumInfo = createNodeMetaInfo("QtQuick", "MyEnum", TypeTraits::IsEnum); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, enumInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isEnum = propertyInfo.isEnumType(); + + ASSERT_THAT(isEnum, IsTrue()); +} + +TEST_F(PropertyMetaInfo, is_not_enumeration) +{ + auto notEnumInfo = createNodeMetaInfo("QtQuick", "NoEnum", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, notEnumInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isEnum = propertyInfo.isEnumType(); + + ASSERT_THAT(isEnum, IsFalse()); +} + +TEST_F(PropertyMetaInfo, default_is_not_enumeration) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + bool isEnum = propertyInfo.isEnumType(); + + ASSERT_THAT(isEnum, IsFalse()); +} + +TEST_F(PropertyMetaInfo, is_private) +{ + projectStorageMock.createProperty(nodeInfo.id(), "__bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("__bar"); + + bool isPrivate = propertyInfo.isPrivate(); + + ASSERT_THAT(isPrivate, IsTrue()); +} + +TEST_F(PropertyMetaInfo, is_not_private) +{ + projectStorageMock.createProperty(nodeInfo.id(), "_bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("_bar"); + + bool isPrivate = propertyInfo.isPrivate(); + + ASSERT_THAT(isPrivate, IsFalse()); +} + +TEST_F(PropertyMetaInfo, default_is_not_private) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + bool isPrivate = propertyInfo.isPrivate(); + + ASSERT_THAT(isPrivate, IsFalse()); +} + +TEST_F(PropertyMetaInfo, is_pointer) +{ + projectStorageMock.createProperty(nodeInfo.id(), + "bar", + PropertyDeclarationTraits::IsPointer, + nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isPointer = propertyInfo.isPointer(); + + ASSERT_THAT(isPointer, IsTrue()); +} + +TEST_F(PropertyMetaInfo, is_not_pointer) +{ + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, nodeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + + bool isPointer = propertyInfo.isPointer(); + + ASSERT_THAT(isPointer, IsFalse()); +} + +TEST_F(PropertyMetaInfo, default_is_not_pointer) +{ + QmlDesigner::PropertyMetaInfo propertyInfo; + + bool isPointer = propertyInfo.isPointer(); + + ASSERT_THAT(isPointer, IsFalse()); +} + +TEST_F(PropertyMetaInfo, cast_to_enumeration) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", TypeTraits::IsEnum); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + Enumeration enumeration{"MyEnum.Foo"}; + auto value = QVariant::fromValue(enumeration); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(enumeration)); +} + +TEST_F(PropertyMetaInfo, dont_to_cast_enumeration_if_property_type_is_not_enumeration) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + Enumeration enumeration{"MyEnum.Foo"}; + auto value = QVariant::fromValue(enumeration); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, QVariantIsValid(IsFalse())); +} + +TEST_F(PropertyMetaInfo, dont_to_cast_enumeration_if_value_is_not_Enumeration) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", TypeTraits::IsEnum); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"enumeration"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, QVariantIsValid(IsFalse())); +} + +TEST_F(PropertyMetaInfo, cast_to_model_node) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "var", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(model.rootModelNode()); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, value); +} + +TEST_F(PropertyMetaInfo, cast_to_qvariant_always_returns_the_save_variant_if_the_property_type_is_var) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "var", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant("foo")); +} + +TEST_F(PropertyMetaInfo, cast_double_to_double) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14.2); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14.2)); +} + +TEST_F(PropertyMetaInfo, cast_int_to_double_returns_number_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14.0)); +} + +TEST_F(PropertyMetaInfo, cast_default_to_double_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_qstring_to_double_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_float_to_float) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14.2f); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14.2f)); +} + +TEST_F(PropertyMetaInfo, cast_int_to_float_returns_number_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14.0)); +} + +TEST_F(PropertyMetaInfo, cast_default_to_float_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_qstring_to_float_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_int_to_int) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14)); +} + +TEST_F(PropertyMetaInfo, cast_double_to_int_returns_number_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14.2); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(14)); +} + +TEST_F(PropertyMetaInfo, cast_default_to_int_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_qstring_to_int_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(0)); +} + +TEST_F(PropertyMetaInfo, cast_bool_to_bool) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(true); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_float_to_bool_returns_boolean_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14.2f); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_double_to_bool_returns_boolean_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14.2); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_int_to_bool_returns_boolean_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_long_to_bool_returns_boolean_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14L); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_long_long_to_bool_returns_boolean_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14LL); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(true)); +} + +TEST_F(PropertyMetaInfo, cast_default_to_bool_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(false)); +} + +TEST_F(PropertyMetaInfo, cast_qstring_to_bool_returns_zero_variant) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(false)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_string) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant("foo")); +} + +TEST_F(PropertyMetaInfo, cast_QByteArray_to_empty_string) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QByteArray{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsEmpty())); +} + +TEST_F(PropertyMetaInfo, cast_int_to_empty_string) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsEmpty())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_empty_string) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsEmpty())); +} + +TEST_F(PropertyMetaInfo, cast_datatime_to_datetime) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto dataTime = QDateTime::currentDateTime(); + auto value = QVariant::fromValue(dataTime); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(dataTime)); +} + +TEST_F(PropertyMetaInfo, cast_int_to_datetime_returns_default_datetime) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_string_to_datetime_returns_default_datetime) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"Monday"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_datetime_returns_default_datetime) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_url_to_url) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto url = QUrl("http://www.qt.io/future"); + auto value = QVariant::fromValue(url); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(url)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_empty_url) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant::fromValue(QString{"http://www.qt.io/future"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsEmpty())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_empty_url) +{ + auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsEmpty())); +} + +TEST_F(PropertyMetaInfo, cast_color_to_color) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto color = QColor(Qt::red); + auto value = QVariant(color); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(color)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_null_color) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant("red"); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(Not(IsValid()))); +} + +TEST_F(PropertyMetaInfo, cast_int_to_null_color) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(14); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(Not(IsValid()))); +} + +TEST_F(PropertyMetaInfo, cast_default_to_null_color) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(Not(IsValid()))); +} + +TEST_F(PropertyMetaInfo, cast_vector2d_to_vector2d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto vector2d = QVector2D{32.2f, 2.2f}; + auto value = QVariant(vector2d); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(vector2d)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_vector2d_returns_an_empty_vector2d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_int_to_vector2d_returns_an_empty_vector2d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(12); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_vector3d_to_vector2d_returns_an_empty_vector2d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QVector3D{32.2f, 2.2f, 784.f}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_vector2d_returns_an_empty_vector2d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_vector3d_to_vector3d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto vector3d = QVector3D{32.2f, 2.2f, 44.4f}; + auto value = QVariant(vector3d); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(vector3d)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_vector3d_returns_an_empty_vector3d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_int_to_vector3d_returns_an_empty_vector3d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(12); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_vector4d_to_vector3d_returns_an_empty_vector3d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QVector4D{32.2f, 2.2f, 784.f, 99.f}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_vector3d_returns_an_empty_vector3d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_vector4d_to_vector4d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto vector4d = QVector4D{32.2f, 2.2f, 44.4f, 23.f}; + auto value = QVariant(vector4d); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(vector4d)); +} + +TEST_F(PropertyMetaInfo, cast_string_to_vector4d_returns_an_empty_vector4d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QString{"foo"}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_int_to_vector4d_returns_an_empty_vector4d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(12); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_vector2d_to_vector4d_returns_an_empty_vector4d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(QVector2D{32.2f, 2.2f}); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, cast_default_to_vector4d_returns_an_empty_vector4d) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, IsQVariant(IsNull())); +} + +TEST_F(PropertyMetaInfo, default_cast_to_invalid_variant) +{ + auto propertyInfo = QmlDesigner::PropertyMetaInfo{}; + auto value = QVariant(43); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, Not(IsValid())); +} + +TEST_F(PropertyMetaInfo, not_existing_property_cast_returns_invalid_value) +{ + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyInfo = nodeInfo.property("bar"); + auto value = QVariant(43); + + auto castedValue = propertyInfo.castedValue(value); + + ASSERT_THAT(castedValue, Not(IsValid())); +} +} // namespace