From 88b8d5ea6c7c100e91649ac3a083460ae6a8ed41 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 4 Apr 2025 22:39:39 +0200 Subject: [PATCH] QmlDesigner: Use size for path watcher The modified time is only saved as milliseconds. That is quite coarse. So we check if the size changed too. Change-Id: Ib94382404002b3bcf2d1e45a73b814d8aba1935c Reviewed-by: Thomas Hartmann --- .../projectstoragepathwatcher.h | 11 ++++--- .../projectstoragepathwatchertypes.h | 1 + .../projectstoragepathwatcher-test.cpp | 32 +++++++++++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index dfbb13b50b6..b00b6f6e21d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -116,10 +116,12 @@ public: ids.push_back(id); std::ranges::transform(idPath.sourceIds, std::back_inserter(entries), [&](SourceId sourceId) { + auto fileStatus = m_fileStatusCache.find(sourceId); return WatcherEntry{id, sourceId.contextId(), sourceId, - m_fileStatusCache.lastModifiedTime(sourceId)}; + fileStatus.lastModified, + fileStatus.size}; }); } @@ -290,10 +292,11 @@ public: sourceContextIds, [&](WatcherEntry &entry) { m_fileStatusCache.update(entry.sourceId); - auto currentLastModified = m_fileStatusCache.lastModifiedTime(entry.sourceId); - if (entry.lastModified < currentLastModified) { + auto fileStatus = m_fileStatusCache.find(entry.sourceId); + if (entry.lastModified < fileStatus.lastModified || entry.size != fileStatus.size) { foundEntries.push_back(entry); - entry.lastModified = currentLastModified; + entry.lastModified = fileStatus.lastModified; + entry.size = fileStatus.size; } }, {}, diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h index be7763fd3e3..3490fdd391d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h @@ -103,6 +103,7 @@ public: SourceContextId sourceContextId; SourceId sourceId; long long lastModified = -1; + long long size = -1; friend bool operator==(WatcherEntry first, WatcherEntry second) { diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 69ff6ac423f..137acfef8d2 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -378,13 +378,12 @@ TEST_F(ProjectStoragePathWatcher, two_notify_file_changes) mockQFileSytemWatcher.directoryChanged(sourceContextPath2); } -TEST_F(ProjectStoragePathWatcher, notify_for_path_changes) +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_modified_time_changes) { watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); - ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); @@ -393,6 +392,34 @@ TEST_F(ProjectStoragePathWatcher, notify_for_path_changes) mockQFileSytemWatcher.directoryChanged(sourceContextPath); } +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_bigger) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 2, 1})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 2, 1})); + + EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); + + mockQFileSytemWatcher.directoryChanged(sourceContextPath); +} + +TEST_F(ProjectStoragePathWatcher, notify_for_path_changes_if_size_get_smaller) +{ + watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}}, + {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) + .WillByDefault(Return(FileStatus{sourceIds[0], 0, 1})); + ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) + .WillByDefault(Return(FileStatus{sourceIds[3], 0, 1})); + + EXPECT_CALL(notifier, pathsChanged(ElementsAre(sourceIds[0]))); + + mockQFileSytemWatcher.directoryChanged(sourceContextPath); +} + TEST_F(ProjectStoragePathWatcher, no_notify_for_unwatched_path_changes) { watcher.updateIdPaths({{projectChunkId1, {sourceIds[3]}}, {projectChunkId2, {sourceIds[3]}}}); @@ -442,7 +469,6 @@ TEST_F(ProjectStoragePathWatcher, trigger_manual_notify_for_path_changes) {projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}}}); ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[0]))) .WillByDefault(Return(FileStatus{sourceIds[0], 1, 2})); - ON_CALL(mockFileSystem, fileStatus(Eq(sourceIds[3]))) .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2}));