logic: refresh info generator fixes and tests
* fixed case where "to-index" state of a file has changed and thus the file needs to be re-indexed * clear and re-index files that depend on changed non-indexed files * clear and re-index files referenced by unchanged but cleared (due to referencing a changed file) files * fixed: updated files with changed timestamp that do not have content in the db will now count as changed * refined refresh info generator tests * updated checklists for manual project setup tests
This commit is contained in:
@@ -344,18 +344,13 @@ void PersistentStorage::clearFileElements(const std::vector<FilePath>& filePaths
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<FileInfo> PersistentStorage::getFileInfoForAllIndexedFiles() const
|
std::vector<FileInfo> PersistentStorage::getFileInfoForAllFiles() const
|
||||||
{
|
{
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
std::vector<FileInfo> fileInfos;
|
std::vector<FileInfo> fileInfos;
|
||||||
for (StorageFile file : m_sqliteIndexStorage.getAll<StorageFile>())
|
for (StorageFile file : m_sqliteIndexStorage.getAll<StorageFile>())
|
||||||
{
|
{
|
||||||
if (!file.indexed)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::posix_time::ptime modificationTime = boost::posix_time::not_a_date_time;
|
boost::posix_time::ptime modificationTime = boost::posix_time::not_a_date_time;
|
||||||
if (file.modificationTime != "not-a-date-time")
|
if (file.modificationTime != "not-a-date-time")
|
||||||
{
|
{
|
||||||
@@ -1471,7 +1466,22 @@ std::shared_ptr<TextAccess> PersistentStorage::getFileContent(const FilePath& fi
|
|||||||
{
|
{
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
return m_sqliteIndexStorage.getFileContentByPath(filePath.wstr());
|
std::shared_ptr<TextAccess> fileContent = m_sqliteIndexStorage.getFileContentByPath(filePath.wstr());
|
||||||
|
if (fileContent->getLineCount() > 0)
|
||||||
|
{
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
return TextAccess::createFromFile(FilePath(filePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PersistentStorage::hasContentForFile(const FilePath& filePath) const
|
||||||
|
{
|
||||||
|
std::shared_ptr<TextAccess> fileContent = m_sqliteIndexStorage.getFileContentByPath(filePath.wstr());
|
||||||
|
if (fileContent->getLineCount() > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo PersistentStorage::getFileInfoForFileId(Id id) const
|
FileInfo PersistentStorage::getFileInfoForFileId(Id id) const
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public:
|
|||||||
void clearAllErrors();
|
void clearAllErrors();
|
||||||
void clearFileElements(const std::vector<FilePath>& filePaths, std::function<void(int)> updateStatusCallback);
|
void clearFileElements(const std::vector<FilePath>& filePaths, std::function<void(int)> updateStatusCallback);
|
||||||
|
|
||||||
std::vector<FileInfo> getFileInfoForAllIndexedFiles() const;
|
std::vector<FileInfo> getFileInfoForAllFiles() const;
|
||||||
std::set<FilePath> getIncompleteFiles() const;
|
std::set<FilePath> getIncompleteFiles() const;
|
||||||
bool getFilePathIndexed(const FilePath& path) const;
|
bool getFilePathIndexed(const FilePath& path) const;
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ public:
|
|||||||
std::shared_ptr<SourceLocationFile> getCommentLocationsInFile(const FilePath& filePath) const override;
|
std::shared_ptr<SourceLocationFile> getCommentLocationsInFile(const FilePath& filePath) const override;
|
||||||
|
|
||||||
std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const override;
|
std::shared_ptr<TextAccess> getFileContent(const FilePath& filePath) const override;
|
||||||
|
bool hasContentForFile(const FilePath& filePath) const;
|
||||||
|
|
||||||
FileInfo getFileInfoForFileId(Id id) const override;
|
FileInfo getFileInfoForFileId(Id id) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -811,7 +811,7 @@ std::shared_ptr<TextAccess> SqliteIndexStorage::getFileContentByPath(const std::
|
|||||||
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
LOG_ERROR(std::to_string(e.errorCode()) + ": " + e.errorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextAccess::createFromFile(FilePath(filePath));
|
return TextAccess::createFromString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqliteIndexStorage::setFileIndexed(Id fileId, bool indexed)
|
void SqliteIndexStorage::setFileIndexed(Id fileId, bool indexed)
|
||||||
|
|||||||
@@ -12,15 +12,15 @@
|
|||||||
RefreshInfo RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(
|
RefreshInfo RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(
|
||||||
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups, std::shared_ptr<const PersistentStorage> storage)
|
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups, std::shared_ptr<const PersistentStorage> storage)
|
||||||
{
|
{
|
||||||
const std::set<FilePath> allSourceFilePathsFromSourcegroups = getAllSourceFilePaths(sourceGroups);
|
// 1) Divide filepaths that are already known by the storage to "unchanged and indexed", "unchanged and non-indexed" and "changed"
|
||||||
|
std::set<FilePath> unchangedIndexedFilePaths;
|
||||||
std::set<FilePath> unchangedFilePaths;
|
std::set<FilePath> unchangedNonindexedFilePaths;
|
||||||
std::set<FilePath> changedFilePaths;
|
std::set<FilePath> changedFilePaths;
|
||||||
|
|
||||||
{
|
{
|
||||||
const std::vector<FileInfo> fileInfosFromStorage = storage->getFileInfoForAllIndexedFiles();
|
const std::vector<FileInfo> fileInfosFromStorage = storage->getFileInfoForAllFiles();
|
||||||
|
|
||||||
std::set<FilePath> alreadyIndexedPaths;
|
std::set<FilePath> alreadyKnownPaths;
|
||||||
{
|
{
|
||||||
const std::set<FilePath> filePathsFromStorage = utility::toSet(utility::convert<FileInfo, FilePath>(
|
const std::set<FilePath> filePathsFromStorage = utility::toSet(utility::convert<FileInfo, FilePath>(
|
||||||
fileInfosFromStorage, [](const FileInfo& info) { return info.path; }
|
fileInfosFromStorage, [](const FileInfo& info) { return info.path; }
|
||||||
@@ -28,24 +28,35 @@ RefreshInfo RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(
|
|||||||
|
|
||||||
for (std::shared_ptr<SourceGroup> sourceGroup : sourceGroups)
|
for (std::shared_ptr<SourceGroup> sourceGroup : sourceGroups)
|
||||||
{
|
{
|
||||||
utility::append(alreadyIndexedPaths, sourceGroup->filterToContainedFilePaths(filePathsFromStorage));
|
utility::append(alreadyKnownPaths, sourceGroup->filterToContainedFilePaths(filePathsFromStorage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checking source and header files
|
// checking source and header files
|
||||||
for (const FileInfo& info : fileInfosFromStorage)
|
for (const FileInfo& info : fileInfosFromStorage)
|
||||||
{
|
{
|
||||||
if (alreadyIndexedPaths.find(info.path) != alreadyIndexedPaths.end() && info.path.exists())
|
if (alreadyKnownPaths.find(info.path) != alreadyKnownPaths.end() && info.path.exists())
|
||||||
{
|
{
|
||||||
if (didFileChange(info, storage))
|
if (storage->getFilePathIndexed(info.path))
|
||||||
{
|
{
|
||||||
changedFilePaths.insert(info.path);
|
if (didFileChange(info, storage))
|
||||||
|
{
|
||||||
|
changedFilePaths.insert(info.path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unchangedIndexedFilePaths.insert(info.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unchangedFilePaths.insert(info.path);
|
changedFilePaths.insert(info.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!storage->getFilePathIndexed(info.path) && !didFileChange(info, storage))
|
||||||
|
{
|
||||||
|
unchangedNonindexedFilePaths.insert(info.path);
|
||||||
|
}
|
||||||
else // file has been removed
|
else // file has been removed
|
||||||
{
|
{
|
||||||
changedFilePaths.insert(info.path);
|
changedFilePaths.insert(info.path);
|
||||||
@@ -53,56 +64,68 @@ RefreshInfo RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::set<FilePath> allSourceFilePathsFromSourcegroups = getAllSourceFilePaths(sourceGroups);
|
||||||
|
|
||||||
|
// 2) Figure out which files need to be cleared
|
||||||
|
// 2.1) Add all changed files
|
||||||
std::set<FilePath> filesToClear = changedFilePaths;
|
std::set<FilePath> filesToClear = changedFilePaths;
|
||||||
|
|
||||||
// handle referencing paths
|
// 2.2) Add files that are reference the changed files
|
||||||
utility::append(filesToClear, storage->getReferencing(changedFilePaths));
|
utility::append(filesToClear, storage->getReferencing(changedFilePaths));
|
||||||
|
|
||||||
// handle referenced paths
|
// 2.3) Handle files that are referenced by the files that will be cleared. These will be re-indexed on the fly. However, we do not
|
||||||
|
// need to clear files that are also referenced by unchanged source files, because otherwise we will lose these connections.
|
||||||
|
// 2.3.1) Get all source file paths that will not be cleared.
|
||||||
|
// - Initially this list contains all source file paths the project would index right now.
|
||||||
|
// - Then we remove all source files that will be cleared
|
||||||
|
// - NOTE: Source files that are new to the project will part of this list, but won't result in any referenced
|
||||||
|
// paths because they are not part of the DB. Source files that are new to the project but are already in the
|
||||||
|
// DB will be removed from this list if they have changed or reference changed files.
|
||||||
std::set<FilePath> staticSourceFiles = allSourceFilePathsFromSourcegroups;
|
std::set<FilePath> staticSourceFiles = allSourceFilePathsFromSourcegroups;
|
||||||
for (const FilePath& path : changedFilePaths)
|
for (const FilePath& path : filesToClear)
|
||||||
{
|
{
|
||||||
staticSourceFiles.erase(path);
|
staticSourceFiles.erase(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2.3.2) Get sets of referenced files
|
||||||
const std::set<FilePath> staticReferencedFilePaths = storage->getReferenced(staticSourceFiles);
|
const std::set<FilePath> staticReferencedFilePaths = storage->getReferenced(staticSourceFiles);
|
||||||
const std::set<FilePath> dynamicReferencedFilePaths = storage->getReferenced(changedFilePaths);
|
const std::set<FilePath> dynamicReferencedFilePaths = storage->getReferenced(filesToClear);
|
||||||
|
|
||||||
|
// 2.3.3) Add "dynamicReferencedFilePaths" to "filesToClear" that are not refenced by static paths, because these files may not be
|
||||||
|
// referenced anymore. If they still are, they will be re-added when encountered during re-indexing.
|
||||||
for (const FilePath& path : dynamicReferencedFilePaths)
|
for (const FilePath& path : dynamicReferencedFilePaths)
|
||||||
{
|
{
|
||||||
if (staticReferencedFilePaths.find(path) == staticReferencedFilePaths.end() &&
|
if (staticReferencedFilePaths.find(path) == staticReferencedFilePaths.end() &&
|
||||||
staticSourceFiles.find(path) == staticSourceFiles.end())
|
staticSourceFiles.find(path) == staticSourceFiles.end())
|
||||||
{
|
{
|
||||||
// file may not be referenced anymore and will be reindexed if still needed
|
|
||||||
filesToClear.insert(path);
|
filesToClear.insert(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const FilePath& path : unchangedFilePaths)
|
// 3) Figure out which files need to be indexed
|
||||||
{
|
std::set<FilePath> filesToIndex;
|
||||||
staticSourceFiles.erase(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::set<FilePath> filesToAdd = staticSourceFiles;
|
|
||||||
|
|
||||||
std::set<FilePath> staticSourceFilePaths;
|
|
||||||
for (const FilePath& path : allSourceFilePathsFromSourcegroups)
|
for (const FilePath& path : allSourceFilePathsFromSourcegroups)
|
||||||
{
|
{
|
||||||
if (filesToClear.find(path) == filesToClear.end() && filesToAdd.find(path) == filesToAdd.end())
|
if (filesToClear.find(path) != filesToClear.end() || // file will be cleared
|
||||||
|
unchangedIndexedFilePaths.find(path) == unchangedIndexedFilePaths.end()) // file has been changed or added
|
||||||
{
|
{
|
||||||
staticSourceFilePaths.insert(path);
|
filesToIndex.insert(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4) Store and return this information
|
||||||
RefreshInfo info;
|
RefreshInfo info;
|
||||||
info.mode = REFRESH_UPDATED_FILES;
|
info.mode = REFRESH_UPDATED_FILES;
|
||||||
info.filesToClear = filesToClear;
|
info.filesToIndex = filesToIndex;
|
||||||
|
for (const FilePath fileToClear : filesToClear)
|
||||||
for (const std::shared_ptr<SourceGroup>& sourceGroup : sourceGroups)
|
|
||||||
{
|
{
|
||||||
if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED)
|
if (storage->getFilePathIndexed(fileToClear))
|
||||||
{
|
{
|
||||||
utility::append(info.filesToIndex, sourceGroup->filterToContainedSourceFilePath(staticSourceFilePaths));
|
info.filesToClear.insert(fileToClear);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.nonIndexedFilesToClear.insert(fileToClear);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,11 +138,14 @@ RefreshInfo RefreshInfoGenerator::getRefreshInfoForIncompleteFiles(const std::ve
|
|||||||
info.mode = REFRESH_UPDATED_AND_INCOMPLETE_FILES;
|
info.mode = REFRESH_UPDATED_AND_INCOMPLETE_FILES;
|
||||||
|
|
||||||
std::set<FilePath> incompleteFiles;
|
std::set<FilePath> incompleteFiles;
|
||||||
for (const FilePath& path : storage->getIncompleteFiles())
|
|
||||||
{
|
{
|
||||||
if (info.filesToClear.find(path) == info.filesToClear.end())
|
const std::set<FilePath> filesToClear = utility::concat(info.filesToClear, info.nonIndexedFilesToClear);
|
||||||
|
for (const FilePath& path : storage->getIncompleteFiles())
|
||||||
{
|
{
|
||||||
incompleteFiles.insert(path);
|
if (filesToClear.find(path) == filesToClear.end())
|
||||||
|
{
|
||||||
|
incompleteFiles.insert(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,24 +214,30 @@ bool RefreshInfoGenerator::didFileChange(const FileInfo& info, std::shared_ptr<c
|
|||||||
FileInfo diskFileInfo = FileSystem::getFileInfoForPath(info.path);
|
FileInfo diskFileInfo = FileSystem::getFileInfoForPath(info.path);
|
||||||
if (diskFileInfo.lastWriteTime > info.lastWriteTime)
|
if (diskFileInfo.lastWriteTime > info.lastWriteTime)
|
||||||
{
|
{
|
||||||
|
if (!storage->hasContentForFile(info.path))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextAccess> storedFileContent = storage->getFileContent(info.path);
|
std::shared_ptr<TextAccess> storedFileContent = storage->getFileContent(info.path);
|
||||||
std::shared_ptr<TextAccess> diskFileContent = TextAccess::createFromFile(diskFileInfo.path);
|
std::shared_ptr<TextAccess> diskFileContent = TextAccess::createFromFile(diskFileInfo.path);
|
||||||
|
|
||||||
const std::vector<std::string>& diskFileLines = diskFileContent->getAllLines();
|
const std::vector<std::string>& diskFileLines = diskFileContent->getAllLines();
|
||||||
const std::vector<std::string>& storedFileLines = storedFileContent->getAllLines();
|
const std::vector<std::string>& storedFileLines = storedFileContent->getAllLines();
|
||||||
|
|
||||||
if (diskFileLines.size() == storedFileLines.size())
|
if (diskFileLines.size() != storedFileLines.size())
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < diskFileLines.size(); i++)
|
return true;
|
||||||
{
|
|
||||||
if (diskFileLines[i] != storedFileLines[i])
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
for (size_t i = 0; i < diskFileLines.size(); i++)
|
||||||
|
{
|
||||||
|
if (diskFileLines[i] != storedFileLines[i])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ class RefreshInfoGenerator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static RefreshInfo getRefreshInfoForUpdatedFiles(
|
static RefreshInfo getRefreshInfoForUpdatedFiles(
|
||||||
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups,
|
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups,
|
||||||
std::shared_ptr<const PersistentStorage> storage
|
std::shared_ptr<const PersistentStorage> storage
|
||||||
);
|
);
|
||||||
|
|
||||||
static RefreshInfo getRefreshInfoForIncompleteFiles(
|
static RefreshInfo getRefreshInfoForIncompleteFiles(
|
||||||
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups,
|
const std::vector<std::shared_ptr<SourceGroup>>& sourceGroups,
|
||||||
std::shared_ptr<const PersistentStorage> storage
|
std::shared_ptr<const PersistentStorage> storage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public:
|
|||||||
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_all_files_has_nothing_to_clear_and_specified_source_files_for_basic_sourcegroup()
|
void test_refresh_info_for_all_files_clears_nothing_and_indexes_previously_unknown_source_file()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
|
|
||||||
TS_ASSERT(utility::containsElement<FilePath>(
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
utility::toVector(refreshInfo.filesToIndex), sourceFilePath
|
utility::toVector(refreshInfo.filesToIndex), sourceFilePath
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
@@ -79,14 +79,58 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_indexes_previously_unknown_file()
|
// Now we will test how the refresh info generator reacts to different situations when generating refresh info for updated
|
||||||
|
// files. A file can have different states in the following dimensions:
|
||||||
|
// file may be known by the storage unknown / nonindexed / indexed
|
||||||
|
// file may be changed unchanged / changed
|
||||||
|
// file may be a source file sourcefile / headerfile
|
||||||
|
// file may now be indexed by the source group nottoindex / toindex
|
||||||
|
//
|
||||||
|
// We now wite a test case that checks for the expected result for every possible combination.
|
||||||
|
// Example: test_unknown_unchanged_sourcefile_that_is_nottoindex
|
||||||
|
|
||||||
|
enum KnownState
|
||||||
{
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
NON_INDEXED,
|
||||||
|
INDEXED
|
||||||
|
};
|
||||||
|
enum ChangedState
|
||||||
|
{
|
||||||
|
UNCHANGED,
|
||||||
|
CHANGED
|
||||||
|
};
|
||||||
|
enum FileState
|
||||||
|
{
|
||||||
|
SOURCE_FILE,
|
||||||
|
HEADER_FILE
|
||||||
|
};
|
||||||
|
enum IndexingState
|
||||||
|
{
|
||||||
|
NOT_TO_INDEX,
|
||||||
|
TO_INDEX
|
||||||
|
};
|
||||||
|
|
||||||
|
RefreshInfo getRefreshInfo(KnownState knownState, ChangedState changedState, FileState fileState, IndexingState indexingState)
|
||||||
|
{
|
||||||
|
RefreshInfo refreshInfo;
|
||||||
cleanup();
|
cleanup();
|
||||||
{
|
{
|
||||||
const FilePath unknownSourceFilePath = m_sourceFolder.getConcatenated(L"unknown_file.cpp");
|
const FilePath filePath = m_sourceFolder.getConcatenated(L"file.extension");
|
||||||
|
|
||||||
|
const std::set<FilePath> sourceFilePaths = ((fileState == SOURCE_FILE) ? std::set<FilePath>({ filePath }) : std::set<FilePath>({}));
|
||||||
|
const std::set<FilePath> allFilePaths = { filePath };
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({ unknownSourceFilePath })));
|
if (indexingState == NOT_TO_INDEX)
|
||||||
|
{
|
||||||
|
// a file is "not existing" if the source group does not care about it
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({}, {})));
|
||||||
|
}
|
||||||
|
else // if (indexingState == TO_INDEX)
|
||||||
|
{
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest(sourceFilePaths, allFilePaths)));
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
m_indexDbPath,
|
m_indexDbPath,
|
||||||
@@ -94,123 +138,263 @@ public:
|
|||||||
);
|
);
|
||||||
storage->setup();
|
storage->setup();
|
||||||
|
|
||||||
|
if (knownState == UNKNOWN)
|
||||||
|
{
|
||||||
|
// do not add anything to storage
|
||||||
|
}
|
||||||
|
else if (knownState == NON_INDEXED)
|
||||||
|
{
|
||||||
|
if (changedState == UNCHANGED)
|
||||||
|
{
|
||||||
|
addVeryNewFileToStorage(filePath, false, true, storage);
|
||||||
|
}
|
||||||
|
else // if (changedState == CHANGED)
|
||||||
|
{
|
||||||
|
addVeryOldFileToStorage(filePath, false, true, storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // if (knownState == INDEXED)
|
||||||
|
{
|
||||||
|
if (changedState == UNCHANGED)
|
||||||
|
{
|
||||||
|
addVeryNewFileToStorage(filePath, true, true, storage);
|
||||||
|
}
|
||||||
|
else // if (changedState == CHANGED)
|
||||||
|
{
|
||||||
|
addVeryOldFileToStorage(filePath, true, true, storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addFileToFileSystem(filePath);
|
||||||
|
|
||||||
storage->buildCaches();
|
storage->buildCaches();
|
||||||
|
|
||||||
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
||||||
|
|
||||||
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
|
||||||
|
|
||||||
TS_ASSERT(utility::containsElement<FilePath>(
|
|
||||||
utility::toVector(refreshInfo.filesToIndex), unknownSourceFilePath
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
return refreshInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_clears_non_existing_file()
|
void test_unknown_unchanged_sourcefile_that_is_nottoindex()
|
||||||
{
|
{
|
||||||
cleanup();
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, UNCHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
{
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
const FilePath nonexistingSourceFilePath = m_sourceFolder.getConcatenated(L"non_existing_file.cpp");
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({})));
|
|
||||||
|
|
||||||
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
|
||||||
m_indexDbPath,
|
|
||||||
m_bookmarkDbPath
|
|
||||||
);
|
|
||||||
storage->setup();
|
|
||||||
|
|
||||||
addVeryOldFileToStorage(nonexistingSourceFilePath, true, true, storage);
|
|
||||||
|
|
||||||
storage->buildCaches();
|
|
||||||
|
|
||||||
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
|
||||||
|
|
||||||
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
|
||||||
|
|
||||||
TS_ASSERT(utility::containsElement<FilePath>(
|
|
||||||
utility::toVector(refreshInfo.filesToClear), nonexistingSourceFilePath
|
|
||||||
));
|
|
||||||
}
|
|
||||||
cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_clears_and_indexes_outdated_file()
|
void test_unknown_unchanged_sourcefile_that_is_toindex()
|
||||||
{
|
{
|
||||||
cleanup();
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, UNCHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
{
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
const FilePath outdatedSourceFilePath = m_sourceFolder.getConcatenated(L"outdated_file.cpp");
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({ outdatedSourceFilePath })));
|
|
||||||
|
|
||||||
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
|
||||||
m_indexDbPath,
|
|
||||||
m_bookmarkDbPath
|
|
||||||
);
|
|
||||||
storage->setup();
|
|
||||||
|
|
||||||
addVeryOldFileToStorage(outdatedSourceFilePath, true, true, storage);
|
|
||||||
addFileToFileSystem(outdatedSourceFilePath);
|
|
||||||
|
|
||||||
storage->buildCaches();
|
|
||||||
|
|
||||||
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
|
||||||
|
|
||||||
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
|
||||||
|
|
||||||
TS_ASSERT(utility::containsElement<FilePath>(
|
|
||||||
utility::toVector(refreshInfo.filesToClear), outdatedSourceFilePath
|
|
||||||
));
|
|
||||||
TS_ASSERT(utility::containsElement<FilePath>(
|
|
||||||
utility::toVector(refreshInfo.filesToIndex), outdatedSourceFilePath
|
|
||||||
));
|
|
||||||
}
|
|
||||||
cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_keeps_up_to_date_file()
|
void test_unknown_unchanged_headerfile_that_is_nottoindex()
|
||||||
{
|
{
|
||||||
cleanup();
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, UNCHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
{
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
const FilePath upToDateSourceFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.cpp");
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({ upToDateSourceFilePath })));
|
|
||||||
|
|
||||||
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
|
||||||
m_indexDbPath,
|
|
||||||
m_bookmarkDbPath
|
|
||||||
);
|
|
||||||
storage->setup();
|
|
||||||
|
|
||||||
addVeryNewFileToStorage(upToDateSourceFilePath, true, true, storage);
|
|
||||||
addFileToFileSystem(upToDateSourceFilePath);
|
|
||||||
|
|
||||||
storage->buildCaches();
|
|
||||||
|
|
||||||
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
|
||||||
|
|
||||||
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
|
||||||
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
|
||||||
}
|
|
||||||
cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_clears_and_reindexes_outdated_file_and_referencing_source_file()
|
void test_unknown_unchanged_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, UNCHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size()); // the header file will only be indexed on demand
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unknown_changed_sourcefile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, CHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unknown_changed_sourcefile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, CHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unknown_changed_headerfile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, CHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unknown_changed_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(UNKNOWN, CHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size()); // the header file will only be indexed on demand
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_unchanged_sourcefile_that_is_nottoindex() // this test does not really make sense
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, UNCHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_unchanged_sourcefile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, UNCHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_unchanged_headerfile_that_is_nottoindex() // this test does not make much sense without source files
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, UNCHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_unchanged_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, UNCHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size()); // the header file will only be indexed on demand
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_changed_sourcefile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, CHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_changed_sourcefile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, CHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_changed_headerfile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, CHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size()); // must be cleard here and will be re-indexed on demand
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nonindexed_changed_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(NON_INDEXED, CHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size()); // the header file will only be indexed on demand
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_unchanged_sourcefile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, UNCHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_unchanged_sourcefile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, UNCHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_unchanged_headerfile_that_is_nottoindex() // TODO: check if depending source file gets reindexed
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, UNCHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_unchanged_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, UNCHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_changed_sourcefile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, CHANGED, SOURCE_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_changed_sourcefile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, CHANGED, SOURCE_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_changed_headerfile_that_is_nottoindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, CHANGED, HEADER_FILE, NOT_TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indexed_changed_headerfile_that_is_toindex()
|
||||||
|
{
|
||||||
|
const RefreshInfo refreshInfo = getRefreshInfo(INDEXED, CHANGED, HEADER_FILE, TO_INDEX);
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size()); // the header file will only be indexed on demand
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we test some referencing stuff
|
||||||
|
|
||||||
|
void test_refresh_info_for_updated_files_clears_and_reindexes_known_outdated_file_and_referencing_source_file()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
{
|
{
|
||||||
@@ -261,7 +445,7 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_clears_outdated_header_file_and_reindexes_referencing_source()
|
void test_refresh_info_for_updated_files_clears_known_outdated_header_file_and_reindexes_referencing_source_file()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
{
|
{
|
||||||
@@ -269,13 +453,15 @@ public:
|
|||||||
const FilePath outdatedHeaderFilePath = m_sourceFolder.getConcatenated(L"outdated_file.h");
|
const FilePath outdatedHeaderFilePath = m_sourceFolder.getConcatenated(L"outdated_file.h");
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest(
|
||||||
upToDateSourceFilePath
|
{
|
||||||
},
|
upToDateSourceFilePath
|
||||||
{
|
},
|
||||||
upToDateSourceFilePath,
|
{
|
||||||
outdatedHeaderFilePath
|
upToDateSourceFilePath,
|
||||||
})));
|
outdatedHeaderFilePath
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
|
||||||
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
m_indexDbPath,
|
m_indexDbPath,
|
||||||
@@ -312,6 +498,92 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_refresh_info_for_updated_files_clears_unknown_outdated_header_file_and_reindexes_referencing_source()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
{
|
||||||
|
const FilePath upToDateSourceFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.cpp");
|
||||||
|
const FilePath outdatedHeaderFilePath = m_sourceFolder.getConcatenated(L"outdated_file.h");
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({
|
||||||
|
upToDateSourceFilePath
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
|
m_indexDbPath,
|
||||||
|
m_bookmarkDbPath
|
||||||
|
);
|
||||||
|
storage->setup();
|
||||||
|
|
||||||
|
const Id upToDateSourceFileId = addVeryNewFileToStorage(upToDateSourceFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(upToDateSourceFilePath);
|
||||||
|
const Id outdatedHeaderFileId = addVeryOldFileToStorage(outdatedHeaderFilePath, false, true, storage);
|
||||||
|
addFileToFileSystem(outdatedHeaderFilePath);
|
||||||
|
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, outdatedHeaderFileId));
|
||||||
|
|
||||||
|
storage->buildCaches();
|
||||||
|
|
||||||
|
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToClear), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.nonIndexedFilesToClear), outdatedHeaderFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToIndex), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_refresh_info_for_updated_files_does_not_clear_unknown_uptodate_header_file()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
{
|
||||||
|
const FilePath upToDateSourceFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.cpp");
|
||||||
|
const FilePath upToDateHeaderFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.h");
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest(
|
||||||
|
{
|
||||||
|
upToDateSourceFilePath
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
|
||||||
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
|
m_indexDbPath,
|
||||||
|
m_bookmarkDbPath
|
||||||
|
);
|
||||||
|
storage->setup();
|
||||||
|
|
||||||
|
const Id upToDateSourceFileId = addVeryNewFileToStorage(upToDateSourceFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(upToDateSourceFilePath);
|
||||||
|
const Id upToDateHeaderFileId = addVeryNewFileToStorage(upToDateHeaderFilePath, false, true, storage);
|
||||||
|
addFileToFileSystem(upToDateHeaderFilePath);
|
||||||
|
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, upToDateHeaderFileId));
|
||||||
|
|
||||||
|
storage->buildCaches();
|
||||||
|
|
||||||
|
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(0, refreshInfo.filesToIndex.size());
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
void test_refresh_info_for_updated_files_clears_outdated_source_file_and_referened_uptodate_header_file()
|
void test_refresh_info_for_updated_files_clears_outdated_source_file_and_referened_uptodate_header_file()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
@@ -417,6 +689,122 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_clears_unchanged_files_referenced_by_unchanged_file_that_referenced_changed_indexed_file()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
{
|
||||||
|
const FilePath upToDateSourceFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.cpp");
|
||||||
|
const FilePath upToDateHeaderFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.h");
|
||||||
|
const FilePath outOfDateHeaderFilePath = m_sourceFolder.getConcatenated(L"out_of_date_file.h");
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({
|
||||||
|
upToDateSourceFilePath
|
||||||
|
},
|
||||||
|
{
|
||||||
|
upToDateSourceFilePath,
|
||||||
|
outOfDateHeaderFilePath,
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
|
m_indexDbPath,
|
||||||
|
m_bookmarkDbPath
|
||||||
|
);
|
||||||
|
storage->setup();
|
||||||
|
|
||||||
|
const Id upToDateSourceFileId = addVeryNewFileToStorage(upToDateSourceFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(upToDateSourceFilePath);
|
||||||
|
const Id upToDateHeaderFileId = addVeryNewFileToStorage(upToDateHeaderFilePath, false, true, storage);
|
||||||
|
addFileToFileSystem(upToDateHeaderFilePath);
|
||||||
|
const Id outOfDateHeaderFileId = addVeryOldFileToStorage(outOfDateHeaderFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(outOfDateHeaderFilePath);
|
||||||
|
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, upToDateHeaderFileId));
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, outOfDateHeaderFileId));
|
||||||
|
|
||||||
|
storage->buildCaches();
|
||||||
|
|
||||||
|
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(2, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.nonIndexedFilesToClear), upToDateHeaderFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToClear), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToClear), outOfDateHeaderFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToIndex), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_clears_unchanged_files_referenced_by_unchanged_file_that_referenced_changed_nonindexed_file()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
{
|
||||||
|
const FilePath upToDateSourceFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.cpp");
|
||||||
|
const FilePath upToDateHeaderFilePath = m_sourceFolder.getConcatenated(L"up_to_date_file.h");
|
||||||
|
const FilePath outOfDateHeaderFilePath = m_sourceFolder.getConcatenated(L"out_of_date_file.h");
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<SourceGroup>> sourceGroups;
|
||||||
|
sourceGroups.push_back(std::shared_ptr<SourceGroupTest>(new SourceGroupTest({
|
||||||
|
upToDateSourceFilePath
|
||||||
|
},
|
||||||
|
{
|
||||||
|
upToDateSourceFilePath,
|
||||||
|
upToDateHeaderFilePath,
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::shared_ptr<PersistentStorage> storage = std::make_shared<PersistentStorage>(
|
||||||
|
m_indexDbPath,
|
||||||
|
m_bookmarkDbPath
|
||||||
|
);
|
||||||
|
storage->setup();
|
||||||
|
|
||||||
|
const Id upToDateSourceFileId = addVeryNewFileToStorage(upToDateSourceFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(upToDateSourceFilePath);
|
||||||
|
const Id upToDateHeaderFileId = addVeryNewFileToStorage(upToDateHeaderFilePath, true, true, storage);
|
||||||
|
addFileToFileSystem(upToDateHeaderFilePath);
|
||||||
|
const Id outOfDateHeaderFileId = addVeryOldFileToStorage(outOfDateHeaderFilePath, false, true, storage);
|
||||||
|
addFileToFileSystem(outOfDateHeaderFilePath);
|
||||||
|
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, upToDateHeaderFileId));
|
||||||
|
storage->addEdge(StorageEdgeData(Edge::EDGE_INCLUDE, upToDateSourceFileId, outOfDateHeaderFileId));
|
||||||
|
|
||||||
|
storage->buildCaches();
|
||||||
|
|
||||||
|
const RefreshInfo refreshInfo = RefreshInfoGenerator::getRefreshInfoForUpdatedFiles(sourceGroups, storage);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(REFRESH_UPDATED_FILES, refreshInfo.mode);
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.nonIndexedFilesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(2, refreshInfo.filesToClear.size());
|
||||||
|
TS_ASSERT_EQUALS(1, refreshInfo.filesToIndex.size());
|
||||||
|
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.nonIndexedFilesToClear), outOfDateHeaderFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToClear), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToClear), upToDateHeaderFilePath
|
||||||
|
));
|
||||||
|
TS_ASSERT(utility::containsElement<FilePath>(
|
||||||
|
utility::toVector(refreshInfo.filesToIndex), upToDateSourceFilePath
|
||||||
|
));
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class SourceGroupSettingsTest : public SourceGroupSettings
|
class SourceGroupSettingsTest : public SourceGroupSettings
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
* Click "Cancel"
|
* Click "Cancel"
|
||||||
* Run "2_update.sh"
|
* Run "2_update.sh"
|
||||||
* Press "Refresh" button
|
* Press "Refresh" button
|
||||||
* Validate "Files to clear" shows "2"
|
* Validate "Files to clear" shows "3"
|
||||||
* Validate "source files to index" shows "1"
|
* Validate "source files to index" shows "1"
|
||||||
* Click "Start"
|
* Click "Start"
|
||||||
* Validate Project indexed without error
|
* Validate Project indexed without error
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
* Click "Cancel"
|
* Click "Cancel"
|
||||||
* Run "2_update.sh"
|
* Run "2_update.sh"
|
||||||
* Press "Refresh" button
|
* Press "Refresh" button
|
||||||
* Validate "Files to clear" shows "2"
|
* Validate "Files to clear" shows "3"
|
||||||
* Validate "source files to index" shows "1"
|
* Validate "source files to index" shows "1"
|
||||||
* Click "Start"
|
* Click "Start"
|
||||||
* Validate Project indexed without error
|
* Validate Project indexed without error
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
* Click "Cancel"
|
* Click "Cancel"
|
||||||
* Run "2_update.sh"
|
* Run "2_update.sh"
|
||||||
* Press "Refresh" button
|
* Press "Refresh" button
|
||||||
* Validate "Files to clear" shows "2"
|
* Validate "Files to clear" shows "3"
|
||||||
* Validate "source files to index" shows "1"
|
* Validate "source files to index" shows "1"
|
||||||
* Click "Start"
|
* Click "Start"
|
||||||
* Validate Project indexed without error
|
* Validate Project indexed without error
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
* Click "Cancel"
|
* Click "Cancel"
|
||||||
* Run "2_update.sh"
|
* Run "2_update.sh"
|
||||||
* Press "Refresh" button
|
* Press "Refresh" button
|
||||||
* Validate "Files to clear" shows "2"
|
* Validate "Files to clear" shows "3"
|
||||||
* Validate "source files to index" shows "1"
|
* Validate "source files to index" shows "1"
|
||||||
* Click "Start"
|
* Click "Start"
|
||||||
* Validate Project indexed without error
|
* Validate Project indexed without error
|
||||||
|
|||||||
Reference in New Issue
Block a user