From 2860e033adab2477a9e61fd94c6de22ec17a60ba Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 13 Jul 2022 17:32:57 +0200 Subject: [PATCH] QmlDesigner: Add ProjectStorage::signalDeclarationNames As we changed the MetaInfo interface we can return ids too but as an intermediate step we return the sorted signal names. Beware that the sort is not matching the normal SmallString "<" operator because it is not using size. Task-number: QDS-7283 Change-Id: I767a4d9f589d2bb2d2e29788be90d29dbd5ac1e3 Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann --- .../projectstorage/projectstorage.h | 16 +++++ tests/unit/unittest/projectstorage-test.cpp | 63 ++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index a5cf6f86c30..eb7a7feee96 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -184,6 +184,12 @@ public: &propertyDeclarationId); } + std::vector signalDeclarationNames(TypeId typeId) const + { + return selectSignalDeclarationNamesForTypeStatement + .template valuesWithTransaction(32, &typeId); + } + Utils::optional propertyName(PropertyDeclarationId propertyDeclarationId) const { return selectPropertyNameStatement.template optionalValueWithTransaction( @@ -2939,6 +2945,16 @@ public: "FROM propertyDeclarations " "WHERE propertyDeclarationId=?1 LIMIT 1", database}; + mutable ReadStatement<1, 1> selectSignalDeclarationNamesForTypeStatement{ + "WITH RECURSIVE " + " typeChain(typeId) AS (" + " VALUES(?1)" + " UNION ALL " + " SELECT prototypeId FROM types JOIN typeChain " + " USING(typeId) WHERE prototypeId IS NOT NULL)" + "SELECT name FROM typeChain JOIN signalDeclarations " + " USING(typeId) ORDER BY name", + database}; }; extern template class ProjectStorage; } // namespace QmlDesigner diff --git a/tests/unit/unittest/projectstorage-test.cpp b/tests/unit/unittest/projectstorage-test.cpp index 9d809d5d194..802a5743e57 100644 --- a/tests/unit/unittest/projectstorage-test.cpp +++ b/tests/unit/unittest/projectstorage-test.cpp @@ -240,6 +240,13 @@ MATCHER(IsSorted, std::string(negation ? "isn't sorted" : "is sorted")) return std::is_sorted(begin(arg), end(arg)); } +MATCHER(StringsAreSorted, std::string(negation ? "isn't sorted" : "is sorted")) +{ + return std::is_sorted(begin(arg), end(arg), [](const auto &first, const auto &second) { + return Sqlite::compare(first, second) < 0; + }); +} + class ProjectStorage : public testing::Test { protected: @@ -779,7 +786,9 @@ protected: "children", Storage::Synchronization::ImportedType{"Object"}, Storage::PropertyDeclarationTraits::IsList - | Storage::PropertyDeclarationTraits::IsReadOnly}}}); + | Storage::PropertyDeclarationTraits::IsReadOnly}}, + {}, + {Storage::Synchronization::SignalDeclaration{"valuesChanged", {}}}}); package.types.push_back(Storage::Synchronization::Type{ "QObject2", Storage::Synchronization::ImportedType{"Object"}, @@ -796,7 +805,9 @@ protected: "children2", Storage::Synchronization::ImportedType{"Object3"}, Storage::PropertyDeclarationTraits::IsList - | Storage::PropertyDeclarationTraits::IsReadOnly}}}); + | Storage::PropertyDeclarationTraits::IsReadOnly}}, + {}, + {Storage::Synchronization::SignalDeclaration{"itemsChanged", {}}}}); package.types.push_back(Storage::Synchronization::Type{ "QObject3", Storage::Synchronization::ImportedType{"Object2"}, @@ -813,7 +824,9 @@ protected: "children3", Storage::Synchronization::ImportedType{"Object2"}, Storage::PropertyDeclarationTraits::IsList - | Storage::PropertyDeclarationTraits::IsReadOnly}}}); + | Storage::PropertyDeclarationTraits::IsReadOnly}}, + {}, + {Storage::Synchronization::SignalDeclaration{"objectsChanged", {}}}}); package.updatedSourceIds.push_back(sourceId1); @@ -5684,4 +5697,48 @@ TEST_F(ProjectStorage, GetInvalidOptionalPropertyDeclarationForInvalidPropertyDe ASSERT_THAT(property, Eq(Utils::nullopt)); } +TEST_F(ProjectStorage, GetSignalDeclarationNames) +{ + auto package{createPackageWithProperties()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId1, "QObject3"); + + auto signalNames = storage.signalDeclarationNames(typeId); + + ASSERT_THAT(signalNames, ElementsAre("itemsChanged", "objectsChanged", "valuesChanged")); +} + +TEST_F(ProjectStorage, GetSignalDeclarationNamesAreOrdered) +{ + auto package{createPackageWithProperties()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId1, "QObject3"); + + auto signalNames = storage.signalDeclarationNames(typeId); + + ASSERT_THAT(signalNames, StringsAreSorted()); +} + +TEST_F(ProjectStorage, GetNoSignalDeclarationNamesForInvalidTypeId) +{ + auto package{createPackageWithProperties()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId1, "WrongObject"); + + auto signalNames = storage.signalDeclarationNames(typeId); + + ASSERT_THAT(signalNames, IsEmpty()); +} + +TEST_F(ProjectStorage, GetOnlySignalDeclarationNamesFromUpIntoThePrototypeChain) +{ + auto package{createPackageWithProperties()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId1, "QObject2"); + + auto signalNames = storage.signalDeclarationNames(typeId); + + ASSERT_THAT(signalNames, ElementsAre("itemsChanged", "valuesChanged")); +} + } // namespace