From e7bc9846d1749c7609208ef0e1a0ebb163ab53f9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 12 Jul 2023 12:26:53 +0200 Subject: [PATCH] QmlDesigner: Add exportedTypeNames(TypeId) to project storage Task-number: QDS-10265 Change-Id: If440f87b6719b865216e3890c8492c3682cf42dd Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Vikas Pachdha --- .../projectstorage/projectstorage.h | 8 +- .../projectstorage/projectstorageinfotypes.h | 105 ++++++++++++++++++ .../projectstorage/projectstorageinterface.h | 1 + .../projectstorage/projectstoragetypes.h | 64 ----------- tests/unit/tests/matchers/CMakeLists.txt | 2 + tests/unit/tests/matchers/import-matcher.h | 30 +---- .../matchers/info_exportedtypenames-matcher.h | 33 ++++++ tests/unit/tests/matchers/version-matcher.h | 34 ++++++ tests/unit/tests/mocks/projectstoragemock.h | 5 + .../tests/printers/gtest-creator-printing.cpp | 5 + .../tests/printers/gtest-creator-printing.h | 2 + tests/unit/tests/unittests/CMakeLists.txt | 21 ---- .../projectstorage/projectstorage-test.cpp | 27 +++++ 13 files changed, 223 insertions(+), 114 deletions(-) create mode 100644 tests/unit/tests/matchers/info_exportedtypenames-matcher.h create mode 100644 tests/unit/tests/matchers/version-matcher.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 1c8f161f076..d2eb46bed8d 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -153,6 +153,12 @@ public: return Sqlite::withDeferredTransaction(database, [&] { return fetchTypeId(typeNameId); }); } + Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const override + { + return selectExportedTypesByTypeIdStatement + .template valuesWithTransaction(4, typeId); + } + ImportId importId(const Storage::Import &import) const override { return Sqlite::withDeferredTransaction(database, [&] { @@ -2748,7 +2754,7 @@ public: " ON defaultPropertyId=propertyDeclarationId WHERE t.typeId=?", database}; mutable ReadStatement<4, 1> selectExportedTypesByTypeIdStatement{ - "SELECT moduleId, name, majorVersion, minorVersion FROM " + "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1) FROM " "exportedTypeNames WHERE typeId=?", database}; mutable ReadStatement<7> selectTypesStatement{ diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h index fdf50591509..02328f5e616 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h @@ -63,10 +63,115 @@ constexpr TypeTraits operator&(TypeTraits first, TypeTraits second) using TypeNameString = ::Utils::BasicSmallString<63>; +class VersionNumber +{ +public: + explicit VersionNumber() = default; + explicit VersionNumber(int value) + : value{value} + {} + + explicit operator bool() const { return value >= 0; } + + friend bool operator==(VersionNumber first, VersionNumber second) noexcept + { + return first.value == second.value; + } + + friend bool operator!=(VersionNumber first, VersionNumber second) noexcept + { + return !(first == second); + } + + friend bool operator<(VersionNumber first, VersionNumber second) noexcept + { + return first.value < second.value; + } + +public: + int value = -1; +}; + +class Version +{ +public: + explicit Version() = default; + explicit Version(VersionNumber major, VersionNumber minor = VersionNumber{}) + : major{major} + , minor{minor} + {} + + explicit Version(int major, int minor) + : major{major} + , minor{minor} + {} + + explicit Version(int major) + : major{major} + {} + + friend bool operator==(Version first, Version second) noexcept + { + return first.major == second.major && first.minor == second.minor; + } + + friend bool operator<(Version first, Version second) noexcept + { + return std::tie(first.major, first.minor) < std::tie(second.major, second.minor); + } + + explicit operator bool() const { return major && minor; } + +public: + VersionNumber major; + VersionNumber minor; +}; } // namespace QmlDesigner::Storage namespace QmlDesigner::Storage::Info { +class ExportedTypeName +{ +public: + explicit ExportedTypeName() = default; + + explicit ExportedTypeName(ModuleId moduleId, + ::Utils::SmallStringView name, + Storage::Version version = Storage::Version{}) + : name{name} + , version{version} + , moduleId{moduleId} + {} + + explicit ExportedTypeName(ModuleId moduleId, + ::Utils::SmallStringView name, + int majorVersion, + int minorVersion) + : name{name} + , version{majorVersion, minorVersion} + , moduleId{moduleId} + {} + + friend bool operator==(const ExportedTypeName &first, const ExportedTypeName &second) + { + return first.moduleId == second.moduleId && first.version == second.version + && first.name == second.name; + } + + friend bool operator<(const ExportedTypeName &first, const ExportedTypeName &second) + { + return std::tie(first.moduleId, first.name, first.version) + < std::tie(second.moduleId, second.name, second.version); + } + +public: + ::Utils::SmallString name; + Storage::Version version; + ModuleId moduleId; +}; + +using ExportedTypeNames = std::vector; + class PropertyDeclaration { public: diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h index bc6e494b2d8..f0672606162 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h @@ -26,6 +26,7 @@ public: Storage::Version version) const = 0; virtual TypeId typeId(ImportedTypeNameId typeNameId) const = 0; + virtual Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const = 0; virtual ImportId importId(const Storage::Import &import) const = 0; virtual ImportedTypeNameId importedTypeNameId(ImportId sourceId, Utils::SmallStringView typeName) = 0; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h index 699333aa209..e2e4c1bb4b1 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h @@ -15,70 +15,6 @@ namespace QmlDesigner::Storage { -class VersionNumber -{ -public: - explicit VersionNumber() = default; - explicit VersionNumber(int value) - : value{value} - {} - - explicit operator bool() const { return value >= 0; } - - friend bool operator==(VersionNumber first, VersionNumber second) noexcept - { - return first.value == second.value; - } - - friend bool operator!=(VersionNumber first, VersionNumber second) noexcept - { - return !(first == second); - } - - friend bool operator<(VersionNumber first, VersionNumber second) noexcept - { - return first.value < second.value; - } - -public: - int value = -1; -}; - -class Version -{ -public: - explicit Version() = default; - explicit Version(VersionNumber major, VersionNumber minor = VersionNumber{}) - : major{major} - , minor{minor} - {} - - explicit Version(int major, int minor) - : major{major} - , minor{minor} - {} - - explicit Version(int major) - : major{major} - {} - - friend bool operator==(Version first, Version second) noexcept - { - return first.major == second.major && first.minor == second.minor; - } - - friend bool operator<(Version first, Version second) noexcept - { - return std::tie(first.major, first.minor) < std::tie(second.major, second.minor); - } - - explicit operator bool() const { return major && minor; } - -public: - VersionNumber major; - VersionNumber minor; -}; - class Import { public: diff --git a/tests/unit/tests/matchers/CMakeLists.txt b/tests/unit/tests/matchers/CMakeLists.txt index 2c740669d48..f457c6dd0e9 100644 --- a/tests/unit/tests/matchers/CMakeLists.txt +++ b/tests/unit/tests/matchers/CMakeLists.txt @@ -5,6 +5,8 @@ add_qtc_library(TestMatchers OBJECT DEPENDS Googletest Utils QmlDesigner SOURCES + info_exportedtypenames-matcher.h import-matcher.h unittest-matchers.h + version-matcher.h ) diff --git a/tests/unit/tests/matchers/import-matcher.h b/tests/unit/tests/matchers/import-matcher.h index 1edb05788da..067f16fae55 100644 --- a/tests/unit/tests/matchers/import-matcher.h +++ b/tests/unit/tests/matchers/import-matcher.h @@ -3,36 +3,10 @@ #pragma once +#include "version-matcher.h" + #include -#include -#include - -template -auto IsVersionNumber(const Matcher &matcher) -{ - return Field(&QmlDesigner::Storage::VersionNumber::value, matcher); -} - -template -auto IsMinorVersion(const Matcher &matcher) -{ - return Field(&QmlDesigner::Storage::Version::minor, matcher); -} - -template -auto IsMajorVersion(const Matcher &matcher) -{ - return Field(&QmlDesigner::Storage::Version::major, matcher); -} - -template -auto IsVersion(const MajorMatcher &majorMatcher, const MinorMatcher &minorMatcher) -{ - return AllOf(IsMajorVersion(IsVersionNumber(majorMatcher)), - IsMinorVersion(IsVersionNumber(minorMatcher))); -} - template + +template +auto IsInfoExportTypeNames(const ModuleIdMatcher &moduleIdMatcher, + const NameMatcher &nameMatcher, + const MajorVersionMatcher &majorVersionMatcher, + const MinorVersionMatcher &minorVersionMatcher) +{ + return AllOf(Field(&QmlDesigner::Storage::Info::ExportedTypeName::moduleId, moduleIdMatcher), + Field(&QmlDesigner::Storage::Info::ExportedTypeName::name, nameMatcher), + Field(&QmlDesigner::Storage::Info::ExportedTypeName::version, + IsVersion(majorVersionMatcher, minorVersionMatcher))); +} + +template +auto IsInfoExportTypeNames(const ModuleIdMatcher &moduleIdMatcher, + const NameMatcher &nameMatcher, + const VersionMatcher &versionMatcher) +{ + return AllOf(Field(&QmlDesigner::Storage::Info::ExportedTypeName::moduleId, moduleIdMatcher), + Field(&QmlDesigner::Storage::Info::ExportedTypeName::name, nameMatcher), + Field(&QmlDesigner::Storage::Info::ExportedTypeName::version, versionMatcher)); +} diff --git a/tests/unit/tests/matchers/version-matcher.h b/tests/unit/tests/matchers/version-matcher.h new file mode 100644 index 00000000000..d4c4b1c55f8 --- /dev/null +++ b/tests/unit/tests/matchers/version-matcher.h @@ -0,0 +1,34 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include +#include + +template +auto IsVersionNumber(const Matcher &matcher) +{ + return Field(&QmlDesigner::Storage::VersionNumber::value, matcher); +} + +template +auto IsMinorVersion(const Matcher &matcher) +{ + return Field(&QmlDesigner::Storage::Version::minor, matcher); +} + +template +auto IsMajorVersion(const Matcher &matcher) +{ + return Field(&QmlDesigner::Storage::Version::major, matcher); +} + +template +auto IsVersion(const MajorMatcher &majorMatcher, const MinorMatcher &minorMatcher) +{ + return AllOf(IsMajorVersion(IsVersionNumber(majorMatcher)), + IsMinorVersion(IsVersionNumber(minorMatcher))); +} diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index b7b4428fa76..17a8beed70f 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -114,6 +114,11 @@ public: QmlDesigner::Storage::Version version), (const, override)); + MOCK_METHOD(QmlDesigner::Storage::Info::ExportedTypeNames, + exportedTypeNames, + (QmlDesigner::TypeId), + (const, override)); + MOCK_METHOD(QmlDesigner::ImportId, importId, (const QmlDesigner::Storage::Import &import), diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 4e9dedaa5a6..a8c4e17445b 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -600,6 +600,11 @@ std::ostream &operator<<(std::ostream &out, const Type &type) { return out << "(" << type.defaultPropertyId << ")"; } + +std::ostream &operator<<(std::ostream &out, const ExportedTypeName &name) +{ + return out << "(\"" << name.name << "\"," << name.moduleId << ", " << name.version << ")"; +} } // namespace Storage::Info namespace Storage::Synchronization { diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index 929396fac12..50fdec5308d 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -170,9 +170,11 @@ std::ostream &operator<<(std::ostream &out, Version version); namespace Storage::Info { class ProjectDeclaration; class Type; +class ExportedTypeName; std::ostream &operator<<(std::ostream &out, const ProjectDeclaration &declaration); std::ostream &operator<<(std::ostream &out, const Type &type); +std::ostream &operator<<(std::ostream &out, const ExportedTypeName &name); } // namespace Storage::Info diff --git a/tests/unit/tests/unittests/CMakeLists.txt b/tests/unit/tests/unittests/CMakeLists.txt index 97e1fb9c90b..5de9ef141c8 100644 --- a/tests/unit/tests/unittests/CMakeLists.txt +++ b/tests/unit/tests/unittests/CMakeLists.txt @@ -25,27 +25,6 @@ add_qtc_test(unittest GTEST unittests-main.cpp ) -function(extend_qtc_test_with_target_sources target) - cmake_parse_arguments(_arg "" "" "DEFINES;INCLUDES" ${ARGN}) - - get_target_property(${target}Sources ${target} SOURCES) - # work around issue with CMake < 3.14 where target sources can contain - # $ - list(FILTER ${target}Sources EXCLUDE REGEX "^\\$ - ${_arg_DEFINES} - INCLUDES - $ - ${_arg_INCLUDES} - ) -endfunction() - finalize_qtc_gtest(unittest EXCLUDE_SOURCES_REGEX ".c$" EXCLUDE_ALL_FROM_PRECHECK diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 903f5f9c730..acfb6cff9fa 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -3,6 +3,8 @@ #include "../utils/googletest.h" +#include + #include #include #include @@ -6943,4 +6945,29 @@ TEST_F(ProjectStorage, synchronize_document_imports_adds_import) ASSERT_TRUE(storage.importId(imports.back())); } +TEST_F(ProjectStorage, get_exported_type_names) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId2, "QObject"); + + auto exportedTypeNames = storage.exportedTypeNames(typeId); + + ASSERT_THAT(exportedTypeNames, + UnorderedElementsAre(IsInfoExportTypeNames(qmlModuleId, "Object", 2, -1), + IsInfoExportTypeNames(qmlModuleId, "Obj", 2, -1), + IsInfoExportTypeNames(qmlNativeModuleId, "QObject", -1, -1))); +} + +TEST_F(ProjectStorage, get_no_exported_type_names_if_type_id_is_invalid) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + TypeId typeId; + + auto exportedTypeNames = storage.exportedTypeNames(typeId); + + ASSERT_THAT(exportedTypeNames, IsEmpty()); +} + } // namespace