QmlDesigner: Update directories without qmldir to project storage

There are qml directories without a qmldir. To identify them we use the
directory source id instead of the qmldir source id.

Task-number: QDS-9345
Change-Id: I1356ad332c091b64cbdad389a3ac505133716634
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2023-03-06 18:03:57 +01:00
parent f0fde39b0b
commit c4a51f168e
3 changed files with 305 additions and 53 deletions

View File

@@ -287,9 +287,10 @@ void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
switch (combineState(directoryState, qmldirState)) { switch (combineState(directoryState, qmldirState)) {
case FileState::Changed: { case FileState::Changed: {
QmlDirParser parser; QmlDirParser parser;
parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath})); if (qmldirState != FileState::NotExists)
parser.parse(m_fileSystem.contentAsQString(QString{qmldirSourcePath}));
if (qmldirState == FileState::Changed) if (qmldirState != FileState::NotChanged)
package.updatedSourceIds.push_back(qmlDirSourceId); package.updatedSourceIds.push_back(qmlDirSourceId);
Utils::PathString moduleName{parser.typeNamespace()}; Utils::PathString moduleName{parser.typeNamespace()};
@@ -330,7 +331,9 @@ void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
directoryId, directoryId,
package, package,
notUpdatedFileStatusSourceIds, notUpdatedFileStatusSourceIds,
watchedQmlSourceIds); notUpdatedSourceIds,
watchedQmlSourceIds,
qmldirState);
package.updatedProjectSourceIds.push_back(directorySourceId); package.updatedProjectSourceIds.push_back(directorySourceId);
break; break;
} }
@@ -343,10 +346,14 @@ void ProjectStorageUpdater::updateDirectories(const QStringList &directories,
break; break;
} }
case FileState::NotExists: { case FileState::NotExists: {
package.updatedFileStatusSourceIds.push_back(directorySourceId);
package.updatedFileStatusSourceIds.push_back(qmlDirSourceId);
package.updatedProjectSourceIds.push_back(directorySourceId);
package.updatedSourceIds.push_back(qmlDirSourceId); package.updatedSourceIds.push_back(qmlDirSourceId);
auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(directorySourceId); auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(directorySourceId);
for (const Storage::Synchronization::ProjectData &projectData : qmlProjectDatas) { for (const Storage::Synchronization::ProjectData &projectData : qmlProjectDatas) {
package.updatedSourceIds.push_back(projectData.sourceId); package.updatedSourceIds.push_back(projectData.sourceId);
package.updatedFileStatusSourceIds.push_back(projectData.sourceId);
} }
break; break;
@@ -463,7 +470,9 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
SourceId directorySourceId, SourceId directorySourceId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
SourceIds &notUpdatedFileStatusSourceIds, SourceIds &notUpdatedFileStatusSourceIds,
SourceIds &watchedQmlSourceIds) SourceIds &notUpdatedSourceIds,
SourceIds &watchedQmlSourceIds,
FileState qmldirState)
{ {
if (std::find(relativeFilePath.begin(), relativeFilePath.end(), '+') != relativeFilePath.end()) if (std::find(relativeFilePath.begin(), relativeFilePath.end(), '+') != relativeFilePath.end())
return; return;
@@ -481,6 +490,15 @@ void ProjectStorageUpdater::parseQmlComponent(Utils::SmallStringView relativeFil
switch (state) { switch (state) {
case FileState::NotChanged: case FileState::NotChanged:
if (qmldirState == FileState::NotExists) {
notUpdatedSourceIds.emplace_back(sourceId);
package.projectDatas.emplace_back(directorySourceId,
sourceId,
ModuleId{},
Storage::Synchronization::FileType::QmlDocument);
return;
}
type.changeLevel = Storage::Synchronization::ChangeLevel::Minimal; type.changeLevel = Storage::Synchronization::ChangeLevel::Minimal;
break; break;
case FileState::NotExists: case FileState::NotExists:
@@ -576,7 +594,9 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
SourceIds &notUpdatedFileStatusSourceIds, SourceIds &notUpdatedFileStatusSourceIds,
SourceIds &watchedQmlSourceIds) SourceIds &notUpdatedSourceIds,
SourceIds &watchedQmlSourceIds,
FileState qmldirState)
{ {
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) { std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
return first.fileName < second.fileName; return first.fileName < second.fileName;
@@ -593,7 +613,9 @@ void ProjectStorageUpdater::parseQmlComponents(Components components,
directorySourceId, directorySourceId,
package, package,
notUpdatedFileStatusSourceIds, notUpdatedFileStatusSourceIds,
watchedQmlSourceIds); notUpdatedSourceIds,
watchedQmlSourceIds,
qmldirState);
}; };
rangeForTheSameFileName(components, callback); rangeForTheSameFileName(components, callback);
@@ -606,18 +628,20 @@ ProjectStorageUpdater::FileState ProjectStorageUpdater::fileState(SourceId sourc
{ {
auto currentFileStatus = m_fileStatusCache.find(sourceId); auto currentFileStatus = m_fileStatusCache.find(sourceId);
if (!currentFileStatus.isValid()) if (!currentFileStatus.isValid()) {
updatedSourceIds.push_back(sourceId);
return FileState::NotExists; return FileState::NotExists;
}
auto projectStorageFileStatus = m_projectStorage.fetchFileStatus(sourceId); auto projectStorageFileStatus = m_projectStorage.fetchFileStatus(sourceId);
if (!projectStorageFileStatus.isValid() || projectStorageFileStatus != currentFileStatus) { if (!projectStorageFileStatus.isValid() || projectStorageFileStatus != currentFileStatus) {
fileStatuses.push_back(currentFileStatus); fileStatuses.push_back(currentFileStatus);
updatedSourceIds.push_back(currentFileStatus.sourceId); updatedSourceIds.push_back(sourceId);
return FileState::Changed; return FileState::Changed;
} }
notUpdatedSourceIds.push_back(currentFileStatus.sourceId); notUpdatedSourceIds.push_back(sourceId);
return FileState::NotChanged; return FileState::NotChanged;
} }

View File

@@ -135,14 +135,18 @@ private:
SourceContextId directoryId, SourceContextId directoryId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
SourceIds &notUpdatedFileStatusSourceIds, SourceIds &notUpdatedFileStatusSourceIds,
SourceIds &watchedQmlSourceIds); SourceIds &notUpdatedSourceIds,
SourceIds &watchedQmlSourceIds,
FileState qmldirState);
void parseQmlComponent(Utils::SmallStringView fileName, void parseQmlComponent(Utils::SmallStringView fileName,
Utils::SmallStringView directory, Utils::SmallStringView directory,
Storage::Synchronization::ExportedTypes exportedTypes, Storage::Synchronization::ExportedTypes exportedTypes,
SourceId directorySourceId, SourceId directorySourceId,
Storage::Synchronization::SynchronizationPackage &package, Storage::Synchronization::SynchronizationPackage &package,
SourceIds &notUpdatedFileStatusSourceIds, SourceIds &notUpdatedFileStatusSourceIds,
SourceIds &watchedQmlSourceIds); SourceIds &notUpdatedSourceIds,
SourceIds &watchedQmlSourceIds,
FileState qmldirState);
void parseQmlComponent(Utils::SmallStringView fileName, void parseQmlComponent(Utils::SmallStringView fileName,
Utils::SmallStringView filePath, Utils::SmallStringView filePath,
Utils::SmallStringView directoryPath, Utils::SmallStringView directoryPath,

View File

@@ -140,24 +140,15 @@ public:
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId))) ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421})); .WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
{ setFilesDontChanged({directoryPathSourceId,
auto sourceIds = {directoryPathSourceId, path1SourceId,
path1SourceId, path2SourceId,
path2SourceId, path3SourceId,
path3SourceId, firstSourceId,
firstSourceId, secondSourceId,
secondSourceId, thirdSourceId,
thirdSourceId, qmltypes1SourceId,
qmltypes1SourceId, qmltypes2SourceId});
qmltypes2SourceId};
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 2, 421}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 2, 421}));
}
}
ON_CALL(fileSystemMock, fileStatus(Eq(qmldir1SourceId))) ON_CALL(fileSystemMock, fileStatus(Eq(qmldir1SourceId)))
.WillByDefault(Return(FileStatus{qmldir1SourceId, 2, 421})); .WillByDefault(Return(FileStatus{qmldir1SourceId, 2, 421}));
@@ -169,8 +160,7 @@ public:
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))) ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir"))))
.WillByDefault(Return(qmldirContent)); .WillByDefault(Return(qmldirContent));
ON_CALL(fileSystemMock, qmlFileNames(Eq(QString("/path")))) setQmlFileNames(u"/path", {"First.qml", "First2.qml", "Second.qml"});
.WillByDefault(Return(QStringList{"First.qml", "First2.qml", "Second.qml"}));
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId1))) ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId1)))
.WillByDefault(Return(FileStatus{qmlDocumentSourceId1, 22, 12})); .WillByDefault(Return(FileStatus{qmlDocumentSourceId1, 22, 12}));
@@ -230,6 +220,64 @@ public:
}); });
} }
void setFilesDontChanged(const QmlDesigner::SourceIds &sourceIds)
{
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 2, 421}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 2, 421}));
}
}
void setFilesChanged(const QmlDesigner::SourceIds &sourceIds)
{
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 1, 21}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 2, 421}));
}
}
void setFilesAdded(const QmlDesigner::SourceIds &sourceIds)
{
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 1, 21}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{}));
}
}
void setFilesRemoved(const QmlDesigner::SourceIds &sourceIds)
{
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(sourceId)))
.WillByDefault(Return(FileStatus{sourceId, 1, 21}));
}
}
void setFilesDontExists(const QmlDesigner::SourceIds &sourceIds)
{
for (auto sourceId : sourceIds) {
ON_CALL(fileSystemMock, fileStatus(Eq(sourceId))).WillByDefault(Return(FileStatus{}));
}
}
void setQmlFileNames(QStringView directoryPath, const QStringList &qmlFileNames)
{
ON_CALL(fileSystemMock, qmlFileNames(Eq(directoryPath))).WillByDefault(Return(qmlFileNames));
}
void setProjectDatas(SourceId directoryPathSourceId,
const QmlDesigner::Storage::Synchronization::ProjectDatas &projectDatas)
{
ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId)))
.WillByDefault(Return(projectDatas));
}
protected: protected:
NiceMock<FileSystemMock> fileSystemMock; NiceMock<FileSystemMock> fileSystemMock;
NiceMock<ProjectStorageMock> projectStorageMock; NiceMock<ProjectStorageMock> projectStorageMock;
@@ -1015,28 +1063,6 @@ TEST_F(ProjectStorageUpdater, UpdateQmldirDocuments)
updater.pathsWithIdsChanged({}); updater.pathsWithIdsChanged({});
} }
TEST_F(ProjectStorageUpdater, AddSourceIdForForInvalidDirectoryFileStatus)
{
ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId)))
.WillByDefault(Return(QmlDesigner::Storage::Synchronization::ProjectDatas{
{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes},
{directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}));
ON_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId))).WillByDefault(Return(FileStatus{}));
EXPECT_CALL(projectStorageMock,
synchronize(AllOf(Field(&SynchronizationPackage::imports, IsEmpty()),
Field(&SynchronizationPackage::types, IsEmpty()),
Field(&SynchronizationPackage::updatedSourceIds,
UnorderedElementsAre(qmlDirPathSourceId,
qmltypesPathSourceId,
qmltypes2PathSourceId)),
Field(&SynchronizationPackage::fileStatuses, IsEmpty()),
Field(&SynchronizationPackage::updatedFileStatusSourceIds, IsEmpty()),
Field(&SynchronizationPackage::projectDatas, IsEmpty()))));
updater.update(directories, {});
}
TEST_F(ProjectStorageUpdater, SynchronizIfQmldirFileHasNotChanged) TEST_F(ProjectStorageUpdater, SynchronizIfQmldirFileHasNotChanged)
{ {
ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId))) ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId)))
@@ -1669,4 +1695,202 @@ TEST_F(ProjectStorageUpdater, UpdatePathWatcherBuiltinQmltypesFiles)
updater.update({}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, projectPartId); updater.update({}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, projectPartId);
} }
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithoutQmldir)
{
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(directoryPathSourceId)))
.WillByDefault(Return(FileStatus{}));
EXPECT_CALL(
projectStorageMock,
synchronize(AllOf(
Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2, import3)),
Field(&SynchronizationPackage::types,
UnorderedElementsAre(
AllOf(IsStorageType("First.qml",
Storage::Synchronization::ImportedType{"Object"},
TypeTraits::Reference,
qmlDocumentSourceId1,
Storage::Synchronization::ChangeLevel::Full),
Field(&Storage::Synchronization::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(pathModuleId, "First", -1, -1)))),
AllOf(IsStorageType("First2.qml",
Storage::Synchronization::ImportedType{"Object2"},
TypeTraits::Reference,
qmlDocumentSourceId2,
Storage::Synchronization::ChangeLevel::Full),
Field(&Storage::Synchronization::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(pathModuleId, "First2", -1, -1)))),
AllOf(IsStorageType("Second.qml",
Storage::Synchronization::ImportedType{"Object3"},
TypeTraits::Reference,
qmlDocumentSourceId3,
Storage::Synchronization::ChangeLevel::Full),
Field(&Storage::Synchronization::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(pathModuleId, "Second", -1, -1)))))),
Field(&SynchronizationPackage::updatedSourceIds,
UnorderedElementsAre(qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
UnorderedElementsAre(directoryPathSourceId,
qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(directoryPathSourceId, 2, 421),
IsFileStatus(qmlDocumentSourceId1, 22, 12),
IsFileStatus(qmlDocumentSourceId2, 22, 13),
IsFileStatus(qmlDocumentSourceId3, 22, 14))),
Field(&SynchronizationPackage::updatedProjectSourceIds,
UnorderedElementsAre(directoryPathSourceId)),
Field(&SynchronizationPackage::projectDatas,
UnorderedElementsAre(IsProjectData(directoryPathSourceId,
qmlDocumentSourceId1,
ModuleId{},
FileType::QmlDocument),
IsProjectData(directoryPathSourceId,
qmlDocumentSourceId2,
ModuleId{},
FileType::QmlDocument),
IsProjectData(directoryPathSourceId,
qmlDocumentSourceId3,
ModuleId{},
FileType::QmlDocument))))));
updater.update(directories, {});
}
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithoutQmldirThrowsIfQmlDocumentDoesNotExists)
{
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDocumentSourceId1))).WillByDefault(Return(FileStatus{}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(directoryPathSourceId)))
.WillByDefault(Return(FileStatus{}));
ASSERT_THROW(updater.update(directories, {}), QmlDesigner::CannotParseQmlDocumentFile);
}
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithoutQmldirThrowsIfDirectoryDoesNotExists)
{
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))).WillByDefault(Return(FileStatus{}));
ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId)))
.WillByDefault(Return(QmlDesigner::Storage::Synchronization::ProjectDatas{
{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}));
EXPECT_CALL(projectStorageMock,
synchronize(AllOf(Field(&SynchronizationPackage::imports, IsEmpty()),
Field(&SynchronizationPackage::types, IsEmpty()),
Field(&SynchronizationPackage::updatedSourceIds,
UnorderedElementsAre(qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
UnorderedElementsAre(directoryPathSourceId,
qmlDirPathSourceId,
qmlDocumentSourceId1,
qmlDocumentSourceId2,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::fileStatuses, IsEmpty()),
Field(&SynchronizationPackage::updatedProjectSourceIds,
UnorderedElementsAre(directoryPathSourceId)),
Field(&SynchronizationPackage::projectDatas, IsEmpty()))));
updater.update(directories, {});
}
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithoutQmldirAddQmlDocument)
{
setFilesDontExists({qmlDirPathSourceId});
setFilesChanged({directoryPathSourceId});
setFilesAdded({qmlDocumentSourceId3});
setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2});
setProjectDatas(directoryPathSourceId,
{{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}});
EXPECT_CALL(
projectStorageMock,
synchronize(AllOf(
Field(&SynchronizationPackage::imports, UnorderedElementsAre(import3)),
Field(&SynchronizationPackage::types,
UnorderedElementsAre(AllOf(
IsStorageType("Second.qml",
Storage::Synchronization::ImportedType{"Object3"},
TypeTraits::Reference,
qmlDocumentSourceId3,
Storage::Synchronization::ChangeLevel::Full),
Field(&Storage::Synchronization::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(pathModuleId, "Second", -1, -1)))))),
Field(&SynchronizationPackage::updatedSourceIds,
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId3)),
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
UnorderedElementsAre(directoryPathSourceId, qmlDirPathSourceId, qmlDocumentSourceId3)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(directoryPathSourceId, 1, 21),
IsFileStatus(qmlDocumentSourceId3, 1, 21))),
Field(&SynchronizationPackage::updatedProjectSourceIds,
UnorderedElementsAre(directoryPathSourceId)),
Field(&SynchronizationPackage::projectDatas,
UnorderedElementsAre(IsProjectData(directoryPathSourceId,
qmlDocumentSourceId1,
ModuleId{},
FileType::QmlDocument),
IsProjectData(directoryPathSourceId,
qmlDocumentSourceId2,
ModuleId{},
FileType::QmlDocument),
IsProjectData(directoryPathSourceId,
qmlDocumentSourceId3,
ModuleId{},
FileType::QmlDocument))))));
updater.update(directories, {});
}
TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsWithoutQmldirRemovesQmlDocument)
{
setFilesDontExists({qmlDirPathSourceId});
setFilesChanged({directoryPathSourceId});
setFilesRemoved({qmlDocumentSourceId3});
setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2});
setQmlFileNames(u"/path", {"First.qml", "First2.qml"});
setProjectDatas(directoryPathSourceId,
{{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}});
EXPECT_CALL(projectStorageMock,
synchronize(
AllOf(Field(&SynchronizationPackage::imports, IsEmpty()),
Field(&SynchronizationPackage::types, IsEmpty()),
Field(&SynchronizationPackage::updatedSourceIds,
UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId3)),
Field(&SynchronizationPackage::updatedFileStatusSourceIds,
UnorderedElementsAre(directoryPathSourceId,
qmlDirPathSourceId,
qmlDocumentSourceId3)),
Field(&SynchronizationPackage::fileStatuses,
UnorderedElementsAre(IsFileStatus(directoryPathSourceId, 1, 21))),
Field(&SynchronizationPackage::updatedProjectSourceIds,
UnorderedElementsAre(directoryPathSourceId)),
Field(&SynchronizationPackage::projectDatas,
UnorderedElementsAre(IsProjectData(directoryPathSourceId,
qmlDocumentSourceId1,
ModuleId{},
FileType::QmlDocument),
IsProjectData(directoryPathSourceId,
qmlDocumentSourceId2,
ModuleId{},
FileType::QmlDocument))))));
updater.update(directories, {});
}
} // namespace } // namespace