diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 9f3045bc1f9..d35af311469 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -131,6 +131,23 @@ public: return moduleCache.value(moduleId); } + TypeId typeId(ModuleId moduleId, Utils::SmallStringView exportedTypeName, Storage::Version version) + { + if (version.minor) + return selectTypeIdByModuleIdAndExportedNameAndVersionStatement + .template valueWithTransaction(&moduleId, + exportedTypeName, + version.major.value, + version.minor.value); + + if (version.major) + return selectTypeIdByModuleIdAndExportedNameAndMajorVersionStatement + .template valueWithTransaction(&moduleId, exportedTypeName, version.major.value); + + return selectTypeIdByModuleIdAndExportedNameStatement + .template valueWithTransaction(&moduleId, exportedTypeName); + } + PropertyDeclarationId fetchPropertyDeclarationByTypeIdAndName(TypeId typeId, Utils::SmallStringView name) { @@ -2351,6 +2368,25 @@ public: database}; mutable ReadStatement<1, 1> selectTypeIdByExportedNameStatement{ "SELECT typeId FROM exportedTypeNames WHERE name=?1", database}; + mutable ReadStatement<1, 2> selectTypeIdByModuleIdAndExportedNameStatement{ + "SELECT typeId FROM exportedTypeNames " + "WHERE moduleId=?1 AND name=?2 " + "ORDER BY majorVersion DESC, minorVersion DESC " + "LIMIT 1", + database}; + mutable ReadStatement<1, 3> selectTypeIdByModuleIdAndExportedNameAndMajorVersionStatement{ + "SELECT typeId FROM exportedTypeNames " + "WHERE moduleId=?1 AND name=?2 AND majorVersion=?3" + "ORDER BY minorVersion DESC " + "LIMIT 1", + database}; + mutable ReadStatement<1, 4> selectTypeIdByModuleIdAndExportedNameAndVersionStatement{ + "SELECT typeId FROM exportedTypeNames " + "WHERE moduleId=?1 AND name=?2 AND majorVersion=?3 AND minorVersion<=?4" + "ORDER BY minorVersion DESC " + "LIMIT 1", + database}; + mutable ReadStatement<1, 2> selectPrototypeIdStatement{ "WITH RECURSIVE " " typeSelection(typeId) AS (" diff --git a/src/plugins/qmldesigner/qmldesignercore.cmake b/src/plugins/qmldesigner/qmldesignercore.cmake index e6031f3efbf..6b08e209009 100644 --- a/src/plugins/qmldesigner/qmldesignercore.cmake +++ b/src/plugins/qmldesigner/qmldesignercore.cmake @@ -443,3 +443,7 @@ function(extend_with_qmldesigner_core target_name) extend_qtc_target(${target_name} ${export_symbol_declaration}) endfunction() + +file(GLOB PROJECTSTORAGE_EXCLUDED_SOURCES designercore/projectstorage/*.cpp) +set_property(SOURCE ${PROJECTSTORAGE_EXCLUDED_SOURCES} PROPERTY SKIP_AUTOMOC ON) + diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt index 61c8f0802a7..41f3764e30a 100644 --- a/tests/unit/unittest/CMakeLists.txt +++ b/tests/unit/unittest/CMakeLists.txt @@ -352,3 +352,9 @@ extend_qtc_test(unittest projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h ) + +file(GLOB PROJECTSTORAGE_EXCLUDED_SOURCES ${QmlDesignerDir}/designercore/projectstorage/*.cpp) +set_property(SOURCE ${PROJECTSTORAGE_EXCLUDED_SOURCES} PROPERTY SKIP_AUTOMOC ON) + +file(GLOB UNITTEST_EXCLUDED_SOURCES *.cpp) +set_property(SOURCE ${UNITTEST_EXCLUDED_SOURCES} PROPERTY SKIP_AUTOMOC ON) diff --git a/tests/unit/unittest/projectstorage-test.cpp b/tests/unit/unittest/projectstorage-test.cpp index d9ae25bf236..b4f83ef0d1e 100644 --- a/tests/unit/unittest/projectstorage-test.cpp +++ b/tests/unit/unittest/projectstorage-test.cpp @@ -25,8 +25,6 @@ #include "googletest.h" -#include "sqlitedatabasemock.h" - #include #include #include @@ -34,6 +32,8 @@ #include #include +#include + namespace { using QmlDesigner::FileStatus; @@ -522,6 +522,15 @@ protected: return package; } + template + static void shuffle(Container &container) + { + std::random_device randomDevice; + std::mt19937 generator(randomDevice()); + + std::shuffle(container.begin(), container.end(), generator); + } + auto createSynchronizationPackageWithVersions() { SynchronizationPackage package; @@ -563,6 +572,8 @@ protected: package.updatedSourceIds.push_back(sourceId1); + shuffle(package.types); + return package; } @@ -4885,4 +4896,155 @@ TEST_F(ProjectStorage, SynchronizeTypesRemovePropertyDeclarationAndIndirectAlias TypeAccessSemantics::Reference), Field(&Storage::Type::propertyDeclarations, IsEmpty())))); } + +TEST_F(ProjectStorage, GetTypeId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{}); + + ASSERT_THAT(typeId, fetchTypeId(sourceId1, "QObject4")); +} + +TEST_F(ProjectStorage, GetNoTypeIdForNonExistingTypeName) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object2", Storage::Version{}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdForInvalidModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(ModuleId{}, "Object", Storage::Version{}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdForWrongModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qtQuick3DModuleId, "Object", Storage::Version{}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetTypeIdWithMajorVersion) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{2}); + + ASSERT_THAT(typeId, fetchTypeId(sourceId1, "QObject3")); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithMajorVersionForNonExistingTypeName) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object2", Storage::Version{2}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithMajorVersionForInvalidModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(ModuleId{}, "Object", Storage::Version{2}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithMajorVersionForWrongModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qtQuick3DModuleId, "Object", Storage::Version{2}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithMajorVersionForWrongVersion) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{4}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetTypeIdWithCompleteVersion) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{2, 0}); + + ASSERT_THAT(typeId, fetchTypeId(sourceId1, "QObject2")); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionWithHigherMinorVersion) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{2, 12}); + + ASSERT_THAT(typeId, fetchTypeId(sourceId1, "QObject3")); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionForNonExistingTypeName) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object2", Storage::Version{2, 0}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionForInvalidModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(ModuleId{}, "Object", Storage::Version{2, 0}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionForWrongModuleId) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qtQuick3DModuleId, "Object", Storage::Version{2, 0}); + + ASSERT_FALSE(typeId); +} + +TEST_F(ProjectStorage, GetNoTypeIdWithCompleteVersionForWrongMajorVersion) +{ + auto package{createSynchronizationPackageWithVersions()}; + storage.synchronize(package); + + auto typeId = storage.typeId(qmlModuleId, "Object", Storage::Version{4, 0}); + + ASSERT_FALSE(typeId); +} + } // namespace