diff options
Diffstat (limited to 'tests/unit/unittest')
63 files changed, 2749 insertions, 743 deletions
diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt new file mode 100644 index 0000000000..0aed2a8995 --- /dev/null +++ b/tests/unit/unittest/CMakeLists.txt @@ -0,0 +1,413 @@ +find_package(Googletest MODULE) +find_package(GoogleBenchmark MODULE) + +if (NOT Googletest_FOUND) + message(STATUS "Googletest was not found. Please set GOOGLETEST_DIR (CMake or Environment) variable.") + message(STATUS "Have a look at cmake/FindGoogletest.cmake file for more details.") + message(STATUS "unittest module will be skipped.") + return() +endif() + +add_qtc_test(unittest GTEST + INCLUDES + BEFORE "../mockup" + DEPENDS + Qt5::Core Qt5::Network Qt5::Widgets + Qt5::Xml Qt5::Concurrent Qt5::Qml Qt5::Gui + Googletest + clangrefactoringbackend_lib clangbackend_lib clangpchmanagerbackend_lib + CPlusPlus Sqlite Utils + DEFINES + QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII + QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION + UNIT_TESTS + DONT_CHECK_MESSAGE_COUNTER + QTC_RESOURCE_DIR="${CMAKE_SOURCE_DIR}/share/qtcreator" + TESTDATA_DIR="${CMAKE_CURRENT_BINARY_DIR}/data" + ECHOSERVER="$<TARGET_FILE_DIR:echo>/echo" + CPPTOOLS_JSON="${CMAKE_CURRENT_BINARY_DIR}/CppTools.json" + SOURCES + builddependenciesprovider-test.cpp + builddependenciesstorage-test.cpp + changedfilepathcompressor-test.cpp + clangpathwatcher-test.cpp + clangqueryexamplehighlightmarker-test.cpp + clangqueryhighlightmarker-test.cpp + clientserverinprocess-test.cpp + clientserveroutsideprocess-test.cpp + commandlinebuilder-test.cpp + compare-operators.h + compilationdatabaseutils-test.cpp + compileroptionsbuilder-test.cpp + conditionally-disabled-tests.h + cppprojectfilecategorizer-test.cpp + cppprojectinfogenerator-test.cpp + cppprojectpartchooser-test.cpp + dummyclangipcclient.h + dynamicastmatcherdiagnosticcontainer-matcher.h + eventspy.cpp eventspy.h + fakeprocess.cpp fakeprocess.h + filepathcache-test.cpp + filepathstoragesqlitestatementfactory-test.cpp + filepathstorage-test.cpp + filepath-test.cpp + filepathview-test.cpp + filestatuscache-test.cpp + filesystem-utilities.h + generatedfiles-test.cpp + googletest.h + google-using-declarations.h + gtest-creator-printing.cpp gtest-creator-printing.h + gtest-llvm-printing.h + gtest-qt-printing.cpp gtest-qt-printing.h + headerpathfilter-test.cpp + highlightingresultreporter-test.cpp + lineprefixer-test.cpp + locatorfilter-test.cpp + matchingtext-test.cpp + mimedatabase-utilities.cpp mimedatabase-utilities.h + mockbuilddependenciesprovider.h + mockbuilddependenciesstorage.h + mockbuilddependencygenerator.h + mockclangcodemodelclient.h + mockclangcodemodelserver.h + mockclangpathwatcher.h + mockclangpathwatchernotifier.h + mockcppmodelmanager.h + mockeditormanager.h + mockfilepathcaching.h + mockfilepathstorage.h + mockfutureinterface.h + mockgeneratedfiles.h + mockmodifiedtimechecker.h + mockmutex.h + mockpchcreator.h + mockpchmanagerclient.h + mockpchmanagernotifier.h + mockpchmanagerserver.h + mockpchtaskgenerator.h + mockpchtaskqueue.h + mockpchtasksmerger.h + mockprecompiledheaderstorage.h + mockprocessor.h + mockprocessormanager.h + mockprogressmanager.h + mockprojectpartprovider.h + mockprojectpartqueue.h + mockprojectpartsmanager.h + mockprojectpartsstorage.h + mockqfilesystemwatcher.h + mockqueue.h + mocksearch.h + mocksearchhandle.h + mocksearchresult.h + mocksqlitedatabase.h + mocksqlitereadstatement.cpp + mocksqlitereadstatement.h + mocksqlitestatement.h + mocksqlitetransactionbackend.h + mocksqlitewritestatement.h + mocksymbolindexertaskqueue.h + mocksymbolindexing.h + mocksymbolquery.h + mocksymbolscollector.h + mocksymbolstorage.h + mocksyntaxhighligher.h + mocktaskscheduler.h + mocktimer.cpp mocktimer.h + modifiedtimechecker-test.cpp + nativefilepath-test.cpp + nativefilepathview-test.cpp + pchmanagerclientserverinprocess-test.cpp + pchmanagerclient-test.cpp + pchmanagerserver-test.cpp + pchtaskgenerator-test.cpp + pchtaskqueue-test.cpp + pchtasksmerger-test.cpp + precompiledheaderstorage-test.cpp + processcreator-test.cpp + processevents-utilities.cpp processevents-utilities.h + processormanager-test.cpp + progresscounter-test.cpp + projectpartartefact-test.cpp + projectpartsmanager-test.cpp + projectpartsstorage-test.cpp + projectupdater-test.cpp + readandwritemessageblock-test.cpp + refactoringdatabaseinitializer-test.cpp + refactoringprojectupdater-test.cpp + rundocumentparse-utility.h + sizedarray-test.cpp + smallstring-test.cpp + sourcerangecontainer-matcher.h + sourcerangefilter-test.cpp + sourcesmanager-test.cpp + spydummy.cpp spydummy.h + sqliteindex-test.cpp + sqliteteststatement.h + sqlitetransaction-test.cpp + stringcache-test.cpp + symbolindexertaskqueue-test.cpp + symbolindexer-test.cpp + symbolquery-test.cpp + symbolsfindfilter-test.cpp + symbolstorage-test.cpp + taskscheduler-test.cpp + testenvironment.h + tokenprocessor-test.cpp + toolchainargumentscache-test.cpp + unittests-main.cpp + unittest-utility-functions.h + usedmacrofilter-test.cpp + utf8-test.cpp +) + +# Do not work on the source directory data +add_custom_command(TARGET unittest POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_BINARY_DIR}/data" +) + +# create fake CppTools.json for the mime type definitions +file(READ "${CMAKE_SOURCE_DIR}/src/plugins/cpptools/CppTools.json.in" plugin_json_in) +string(REPLACE "\\\"" "\"" plugin_json_in ${plugin_json_in}) +string(REPLACE "\\'" "'" plugin_json_in ${plugin_json_in}) +string(REPLACE "$$QTCREATOR_VERSION" "${IDE_VERSION}" plugin_json_in ${plugin_json_in}) +string(REPLACE "$$QTCREATOR_COMPAT_VERSION" "${IDE_VERSION_COMPAT}" plugin_json_in ${plugin_json_in}) +string(REPLACE "$$QTCREATOR_COPYRIGHT_YEAR" "${IDE_COPYRIGHT_YEAR}" plugin_json_in ${plugin_json_in}) +string(REPLACE "$$dependencyList" "\"Dependencies\" : []" plugin_json_in ${plugin_json_in}) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CppTools.json" ${plugin_json_in}}) + +if (TARGET libclang) + target_sources(unittest PRIVATE + activationsequencecontextprocessor-test.cpp + activationsequenceprocessor-test.cpp + chunksreportedmonitor.cpp + clangasyncjob-base.cpp + clangcodecompleteresults-test.cpp + clangcodemodelserver-test.cpp + clangcompletecodejob-test.cpp + clangcompletioncontextanalyzer-test.cpp + clangdiagnosticfilter-test.cpp + clangdocumentprocessors-test.cpp + clangdocumentprocessor-test.cpp + clangdocuments-test.cpp + clangdocumentsuspenderresumer-test.cpp + clangdocument-test.cpp + clangfixitoperation-test.cpp + clangfollowsymbol-test.cpp + clangisdiagnosticrelatedtolocation-test.cpp + clangjobqueue-test.cpp + clangjobs-test.cpp + clangparsesupportivetranslationunitjob-test.cpp + clangreferencescollector-test.cpp + clangrequestannotationsjob-test.cpp + clangrequestreferencesjob-test.cpp + clangresumedocumentjob-test.cpp + clangstring-test.cpp + clangsupportivetranslationunitinitializer-test.cpp + clangsuspenddocumentjob-test.cpp + clangtooltipinfo-test.cpp + clangtranslationunits-test.cpp + clangtranslationunit-test.cpp + clangupdateannotationsjob-test.cpp + codecompleter-test.cpp + codecompletionsextractor-test.cpp + completionchunkstotextconverter-test.cpp + createtablesqlstatementbuilder-test.cpp + cursor-test.cpp + diagnosticset-test.cpp + diagnostic-test.cpp + fixit-test.cpp + senddocumenttracker-test.cpp + skippedsourceranges-test.cpp + sourcelocation-test.cpp + sourcerange-test.cpp + sqlitecolumn-test.cpp + sqlitedatabasebackend-test.cpp + sqlitedatabase-test.cpp + sqlitestatement-test.cpp + sqlitetable-test.cpp + sqlstatementbuilder-test.cpp + token-test.cpp + translationunitupdater-test.cpp + unsavedfiles-test.cpp + unsavedfile-test.cpp + utf8positionfromlinecolumn-test.cpp + chunksreportedmonitor.h + clangasyncjob-base.h + clangcompareoperators.h + diagnosticcontainer-matcher.h + ) + target_include_directories(unittest PRIVATE "${CLANG_INCLUDE_DIRS}") + target_link_libraries(unittest PRIVATE libclang) +endif() + +if (TARGET clangTooling) + target_compile_definitions(unittest PRIVATE CLANG_UNIT_TESTS) + target_sources(unittest PRIVATE + gtest-llvm-printing.cpp + clangquerygatherer-test.cpp + clangqueryprojectfindfilter-test.cpp + clangquery-test.cpp + gtest-clang-printing.cpp gtest-clang-printing.h + pchcreator-test.cpp + refactoringclientserverinprocess-test.cpp + refactoringclient-test.cpp + refactoringcompilationdatabase-test.cpp + refactoringengine-test.cpp + refactoringserver-test.cpp + sourcerangeextractor-test.cpp + symbolindexing-test.cpp + symbolscollector-test.cpp + symbolfinder-test.cpp + testclangtool.cpp testclangtool.h + usedmacrocollector-test.cpp + builddependencycollector-test.cpp + mockrefactoringclient.h + mockrefactoringserver.h + ) + target_link_libraries(unittest + PRIVATE clangTooling clangIndex clangQuery clangToolingRefactor) +endif() + +if (TARGET clangFormat) + target_sources(unittest PRIVATE + clangformat-test.cpp + ) + target_link_libraries(unittest PRIVATE clangFormat) +endif() + +if (TARGET GoogleBenchmark) + target_sources(unittest PRIVATE + smallstring-benchmark.cpp + ) + target_link_libraries(unittest PRIVATE GoogleBenchmark) +endif() + +finalize_qtc_gtest(unittest) + +# Path needs to be before CppTools +target_include_directories(unittest + PRIVATE + BEFORE $<TARGET_PROPERTY:clangrefactoringbackend_lib,INTERFACE_INCLUDE_DIRECTORIES> + BEFORE $<TARGET_PROPERTY:ClangRefactoring,INTERFACE_INCLUDE_DIRECTORIES> +) + +get_target_property(ClangSupportSources ClangSupport SOURCES) +get_target_property(ClangSupportSourcesDir ClangSupport SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ClangSupportSourcesDir}" + SOURCES ${ClangSupportSources} + DEFINES + $<TARGET_PROPERTY:ClangSupport,INTERFACE_COMPILE_DEFINITIONS> + CLANGSUPPORT_BUILD_LIB + INCLUDES + $<TARGET_PROPERTY:ClangSupport,INTERFACE_INCLUDE_DIRECTORIES> +) + +get_target_property(ClangCodeModelSourcesDir ClangCodeModel SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ClangCodeModelSourcesDir}" + SOURCES + clangactivationsequencecontextprocessor.cpp clangactivationsequencecontextprocessor.h + clangactivationsequenceprocessor.cpp clangactivationsequenceprocessor.h + clangcompletionchunkstotextconverter.cpp clangcompletionchunkstotextconverter.h + clangcompletioncontextanalyzer.cpp clangcompletioncontextanalyzer.h + clangdiagnosticfilter.cpp clangdiagnosticfilter.h + clangfixitoperation.cpp clangfixitoperation.h + clanghighlightingresultreporter.cpp clanghighlightingresultreporter.h + clanguiheaderondiskmanager.cpp clanguiheaderondiskmanager.h + clangisdiagnosticrelatedtolocation.h +) + +get_target_property(CompilationDatabasePMSourcesDir CompilationDatabaseProjectManager SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${CompilationDatabasePMSourcesDir}" + SOURCES + compilationdatabaseutils.cpp compilationdatabaseutils.h +) + +get_target_property(CoreSourcesDir Core SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${CoreSourcesDir}" + DEFINES CORE_STATIC_LIBRARY + SOURCES + coreicons.cpp coreicons.h + id.cpp id.h + find/ifindfilter.cpp find/ifindfilter.h + locator/ilocatorfilter.cpp locator/ilocatorfilter.h +) + +get_target_property(CppToolsSourcesDir CppTools SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${CppToolsSourcesDir}" + DEFINES CPPTOOLS_STATIC_LIBRARY + SOURCES + cppprojectfile.cpp cppprojectfile.h + senddocumenttracker.cpp senddocumenttracker.h + projectpart.cpp projectpart.h + compileroptionsbuilder.cpp compileroptionsbuilder.h + cppprojectfilecategorizer.cpp cppprojectfilecategorizer.h + projectinfo.cpp projectinfo.h + cppprojectinfogenerator.cpp cppprojectinfogenerator.cpp + cppprojectpartchooser.cpp cppprojectpartchooser.h + headerpathfilter.cpp headerpathfilter.h +) + +get_target_property(ProjectExplorerSourcesDir ProjectExplorer SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ProjectExplorerSourcesDir}" + DEFINES PROJECTEXPLORER_STATIC_LIBRARY + SOURCES + projectmacro.cpp projectmacro.h +) + +get_target_property(ClangRefactoringSourcesDir ClangRefactoring SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ClangRefactoringSourcesDir}" + SOURCES + clangqueryexamplehighlighter.cpp clangqueryexamplehighlighter.h + clangqueryexamplehighlightmarker.h + clangqueryhighlighter.cpp clangqueryhighlighter.h + clangqueryhighlightmarker.h + clangqueryprojectsfindfilter.cpp clangqueryprojectsfindfilter.h + projectpartutilities.cpp projectpartutilities.h + refactoringclient.cpp refactoringclient.h + refactoringconnectionclient.cpp refactoringconnectionclient.h + refactoringengine.cpp refactoringengine.h + refactoringprojectupdater.cpp refactoringprojectupdater.h + searchinterface.h + searchhandle.cpp searchhandle.h + symbolsfindfilter.cpp symbolsfindfilter.h + symbolqueryinterface.h + symbol.h + projectpartproviderinterface.h + editormanagerinterface.h + locatorfilter.cpp locatorfilter.h +) + +get_target_property(ClangPchManagerSourcesDir ClangPchManager SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ClangPchManagerSourcesDir}" + DEFINES CLANGPCHMANAGER_STATIC_LIB + SOURCES + pchmanagerclient.h pchmanagerclient.cpp + pchmanagernotifierinterface.h pchmanagernotifierinterface.cpp + pchmanagerconnectionclient.h pchmanagerconnectionclient.cpp + clangpchmanager_global.h + projectupdater.h projectupdater.cpp + pchmanagerprojectupdater.h pchmanagerprojectupdater.cpp + progressmanager.h + progressmanagerinterface.h +) + +get_target_property(ClangFormatSourcesDir ClangFormat SOURCES_DIR) +extend_qtc_target(unittest + SOURCES_PREFIX "${ClangFormatSourcesDir}" + DEFINES CLANGPCHMANAGER_STATIC_LIB + SOURCES + clangformatconstants.h + clangformatbaseindenter.cpp clangformatbaseindenter.h +) diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp index 772a435a58..9983e42d8d 100644 --- a/tests/unit/unittest/builddependenciesprovider-test.cpp +++ b/tests/unit/unittest/builddependenciesprovider-test.cpp @@ -56,9 +56,17 @@ MATCHER_P(HasSourceId, sourceId, std::string(negation ? "hasn't" : "has") class BuildDependenciesProvider : public testing::Test { protected: + BuildDependenciesProvider() + { + provider.setEnsureAliveMessageIsSentCallback( + mockEnsureAliveMessageIsSentCallback.AsStdFunction()); + } + +protected: + NiceMock<MockFunction<void()>> mockEnsureAliveMessageIsSentCallback; NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend; NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage; - NiceMock<MockModifiedTimeChecker> mockModifiedTimeChecker; + NiceMock<MockSourceEntriesModifiedTimeChecker> mockModifiedTimeChecker; NiceMock<MockBuildDependencyGenerator> mockBuildDependenciesGenerator; ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, mockModifiedTimeChecker, @@ -209,4 +217,11 @@ TEST_F(BuildDependenciesProvider, FetchUsedMacrosFromStorageIfDependSourcesAreUp ASSERT_THAT(buildDependency.usedMacros, ElementsAre(UsedMacro{"YI", 1}, UsedMacro{"ER", 2}, UsedMacro{"LIANG", 2}, UsedMacro{"SAN", 10})); } + +TEST_F(BuildDependenciesProvider, CallEnsureAliveMessageIsSentCallback) +{ + EXPECT_CALL(mockEnsureAliveMessageIsSentCallback, Call()); + + provider.create(projectPart1); +} } diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp index aa82370485..052ed452f0 100644 --- a/tests/unit/unittest/builddependenciesstorage-test.cpp +++ b/tests/unit/unittest/builddependenciesstorage-test.cpp @@ -70,6 +70,7 @@ protected: MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement; MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement = storage.deleteAllProjectPartsFilesWithProjectPartNameStatement; + MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchProjectPartsFilesStatement; }; TEST_F(BuildDependenciesStorage, ConvertStringsToJson) @@ -232,5 +233,13 @@ TEST_F(BuildDependenciesStorage, FetchUsedMacros) ASSERT_THAT(usedMacros, result); } -} +TEST_F(BuildDependenciesStorage, FetchSources) +{ + ClangBackEnd::FilePathIds result{3, 5, 7}; + EXPECT_CALL(fetchProjectPartsFilesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result)); + auto sources = storage.fetchSources(22); + + ASSERT_THAT(sources, result); +} +} // namespace diff --git a/tests/unit/unittest/builddependencycollector-test.cpp b/tests/unit/unittest/builddependencycollector-test.cpp index 6c2153fe0c..0d1b9650dc 100644 --- a/tests/unit/unittest/builddependencycollector-test.cpp +++ b/tests/unit/unittest/builddependencycollector-test.cpp @@ -737,10 +737,16 @@ TEST_F(BuildDependencyCollector, Create) 1, {}, {}, - {{TESTDATA_DIR "/builddependencycollector/system", 1, IncludeSearchPathType::System}}, + {{TESTDATA_DIR "/builddependencycollector/system", + 1, + ClangBackEnd::IncludeSearchPathType::System}}, { - {TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}, - {TESTDATA_DIR "/builddependencycollector/external", 2, IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/project", + 1, + ClangBackEnd::IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/external", + 2, + ClangBackEnd::IncludeSearchPathType::User}, }, { id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), @@ -771,6 +777,7 @@ TEST_F(BuildDependencyCollector, Create) "/builddependencycollector/external/indirect_external2.h"), fileStatus(TESTDATA_DIR "/builddependencycollector/external/external2.h"), fileStatus(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + fileStatus(TESTDATA_DIR "/preincludes/system1.h"), fileStatus(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"), fileStatus(TESTDATA_DIR "/builddependencycollector/system/indirect_system2.h"), @@ -804,7 +811,7 @@ TEST_F(BuildDependencyCollector, Create) HasSource(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), SourceType::TopProjectInclude), HasSource(id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), - SourceType::TopSystemInclude), + SourceType::SystemInclude), HasSource(id(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"), SourceType::SystemInclude), HasSource(id(TESTDATA_DIR @@ -813,7 +820,8 @@ TEST_F(BuildDependencyCollector, Create) HasSource(id(TESTDATA_DIR "/builddependencycollector/project/macros.h"), SourceType::UserInclude), HasSource(id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"), - SourceType::UserInclude))), + SourceType::UserInclude), + HasSource(id(TESTDATA_DIR "/preincludes/system1.h"), SourceType::TopSystemInclude))), Field(&BuildDependency::usedMacros, UnorderedElementsAre( UsedMacro{"IFDEF", id(TESTDATA_DIR "/builddependencycollector/project/macros.h")}, @@ -830,6 +838,7 @@ TEST_F(BuildDependencyCollector, Create) id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"), id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/preincludes/system1.h"), id(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"), id(TESTDATA_DIR "/builddependencycollector/system/indirect_system2.h"), id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), @@ -854,6 +863,8 @@ TEST_F(BuildDependencyCollector, Create) id(TESTDATA_DIR "/builddependencycollector/external/external2.h")), SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), + id(TESTDATA_DIR "/preincludes/system1.h")), + SourceDependency(id(TESTDATA_DIR "/preincludes/system1.h"), id(TESTDATA_DIR "/builddependencycollector/system/system1.h")), SourceDependency(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"), id(TESTDATA_DIR "/builddependencycollector/project/macros.h")), @@ -888,10 +899,16 @@ TEST_F(BuildDependencyCollector, Clear) 1, {}, {}, - {{TESTDATA_DIR "/builddependencycollector/system", 1, IncludeSearchPathType::System}}, + {{TESTDATA_DIR "/builddependencycollector/system", + 1, + ClangBackEnd::IncludeSearchPathType::System}}, { - {TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}, - {TESTDATA_DIR "/builddependencycollector/external", 2, IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/project", + 1, + ClangBackEnd::IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/external", + 2, + ClangBackEnd::IncludeSearchPathType::User}, }, { id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), @@ -899,14 +916,76 @@ TEST_F(BuildDependencyCollector, Clear) id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), id(TESTDATA_DIR "/builddependencycollector/project/macros.h"), }, - {}, + {id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")}, Utils::Language::Cxx, Utils::LanguageVersion::CXX11, Utils::LanguageExtension::None}; collector.create(projectPart); + ClangBackEnd::ProjectPartContainer emptyProjectPart{ + 1, + {}, + {}, + {{TESTDATA_DIR "/builddependencycollector/system", + 1, + ClangBackEnd::IncludeSearchPathType::System}}, + { + {TESTDATA_DIR "/builddependencycollector/project", + 1, + ClangBackEnd::IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/external", + 2, + ClangBackEnd::IncludeSearchPathType::User}, + }, + { + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), + id(TESTDATA_DIR "/builddependencycollector/project/macros.h"), + }, + {}, + Utils::Language::Cxx, + Utils::LanguageVersion::CXX11, + Utils::LanguageExtension::None}; - auto buildDependency = collector.create(projectPart); + auto buildDependency = collector.create(emptyProjectPart); ASSERT_THAT(buildDependency.sources, IsEmpty()); } + +TEST_F(BuildDependencyCollector, PreIncludes) +{ + using ClangBackEnd::IncludeSearchPathType; + ClangBackEnd::BuildDependencyCollector collector{filePathCache, generatedFiles, environment}; + ClangBackEnd::ProjectPartContainer projectPart{ + 1, + {}, + {}, + {{TESTDATA_DIR "/builddependencycollector/system", + 1, + ClangBackEnd::IncludeSearchPathType::System}}, + { + {TESTDATA_DIR "/builddependencycollector/project", + 1, + ClangBackEnd::IncludeSearchPathType::User}, + {TESTDATA_DIR "/builddependencycollector/external", + 2, + ClangBackEnd::IncludeSearchPathType::User}, + }, + { + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"), + id(TESTDATA_DIR "/builddependencycollector/project/macros.h"), + }, + {id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")}, + Utils::Language::Cxx, + Utils::LanguageVersion::CXX11, + Utils::LanguageExtension::None}; + + auto buildDependency = collector.create(projectPart); + + ASSERT_THAT(buildDependency.sources, + Contains(HasSource(id(TESTDATA_DIR "/preincludes/system1.h"), + SourceType::TopSystemInclude))); +} } // namespace diff --git a/tests/unit/unittest/clangdocument-test.cpp b/tests/unit/unittest/clangdocument-test.cpp index 26a4ab1bfd..4978f41fd7 100644 --- a/tests/unit/unittest/clangdocument-test.cpp +++ b/tests/unit/unittest/clangdocument-test.cpp @@ -201,7 +201,7 @@ TEST_F(DocumentSlowTest, NeedsReparseAfterChangeOfMainFile) ASSERT_TRUE(document.isDirty()); } -TEST_F(DocumentSlowTest, NoNeedForReparsingForIndependendFile) +TEST_F(DocumentSlowTest, NoNeedForReparsingForIndependentFile) { document.parse(); @@ -210,7 +210,7 @@ TEST_F(DocumentSlowTest, NoNeedForReparsingForIndependendFile) ASSERT_FALSE(document.isDirty()); } -TEST_F(DocumentSlowTest, NeedsReparsingForDependendFile) +TEST_F(DocumentSlowTest, NeedsReparsingForDependentFile) { document.parse(); diff --git a/tests/unit/unittest/clangfollowsymbol-test.cpp b/tests/unit/unittest/clangfollowsymbol-test.cpp index 628aa07618..e836cc83c6 100644 --- a/tests/unit/unittest/clangfollowsymbol-test.cpp +++ b/tests/unit/unittest/clangfollowsymbol-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangsupport_global.h> #include <clangfollowsymboljob.h> @@ -113,7 +113,7 @@ public: ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Utf8StringVector compilationArguments{ - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")})}; + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")})}; Document document = {sourceFilePath, compilationArguments, {}, documents}; Document headerDocument = {headerFilePath, compilationArguments, {}, documents}; QVector<Utf8String> deps{sourceFilePath, cursorPath}; diff --git a/tests/unit/unittest/clangformat-test.cpp b/tests/unit/unittest/clangformat-test.cpp index 44217b9876..172afb64c8 100644 --- a/tests/unit/unittest/clangformat-test.cpp +++ b/tests/unit/unittest/clangformat-test.cpp @@ -65,9 +65,9 @@ class ClangFormat : public ::testing::Test protected: void SetUp() final { - indenter.setFileName(Utils::FileName::fromString(TESTDATA_DIR "/clangformat/test.cpp")); + indenter.setFileName(Utils::FilePath::fromString(TESTDATA_DIR "/clangformat/test.cpp")); extendedIndenter.setFileName( - Utils::FileName::fromString(TESTDATA_DIR "/clangformat/test.cpp")); + Utils::FilePath::fromString(TESTDATA_DIR "/clangformat/test.cpp")); } void insertLines(const std::vector<QString> &lines) diff --git a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp index 5ff87f6059..3981980902 100644 --- a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp +++ b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp @@ -37,6 +37,7 @@ #include <cpptools/compileroptionsbuilder.h> #include <cpptools/projectpart.h> +#include <projectexplorer/project.h> namespace { @@ -53,11 +54,62 @@ using testing::ByMove; using CppTools::CompilerOptionsBuilder; using ClangBackEnd::V2::FileContainer; +std::vector<Utils::SmallStringVector> createCommandLines( + const std::vector<CppTools::ProjectPart::Ptr> &projectParts) +{ + using Filter = ClangRefactoring::ClangQueryProjectsFindFilter; + + std::vector<Utils::SmallStringVector> commandLines; + + for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) { + for (const CppTools::ProjectFile &projectFile : projectPart->files) { + Utils::SmallStringVector commandLine = Filter::compilerArguments(projectPart.data(), + projectFile.kind); + commandLine.emplace_back(projectFile.path); + commandLines.push_back(commandLine); + } + } + + return commandLines; +} + class ClangQueryProjectFindFilter : public ::testing::Test { protected: - void SetUp(); - std::unique_ptr<ClangRefactoring::SearchHandle> createSearchHandle(); + void SetUp() + { + projectsParts = createProjectParts(); + commandLines = createCommandLines(projectsParts); + + findFilter.setProjectParts(projectsParts); + findFilter.setUnsavedContent({unsavedContent.clone()}); + + ON_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), findDeclQueryText)) + .WillByDefault(Return(ByMove(createSearchHandle()))); + } + std::unique_ptr<ClangRefactoring::SearchHandle> createSearchHandle() + { + auto handle = std::make_unique<NiceMock<MockSearchHandle>>(); + handle->setRefactoringServer(&mockRefactoringServer); + + return handle; + } + + std::vector<CppTools::ProjectPart::Ptr> createProjectParts() + { + auto projectPart1 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); + projectPart1->project = &project; + projectPart1->files.append({"/path/to/file1.h", CppTools::ProjectFile::CXXHeader}); + projectPart1->files.append({"/path/to/file1.cpp", CppTools::ProjectFile::CXXSource}); + + auto projectPart2 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); + projectPart2->project = &project; + projectPart2->files.append({"/path/to/file2.cpp", CppTools::ProjectFile::CXXSource}); + projectPart2->files.append({"/path/to/unsaved.cpp", CppTools::ProjectFile::CXXSource}); + projectPart2->files.append({"/path/to/cheader.h", CppTools::ProjectFile::CHeader}); + + return {projectPart1, projectPart2}; + } protected: NiceMock<MockRefactoringServer> mockRefactoringServer; @@ -73,6 +125,7 @@ protected: ClangBackEnd::V2::FileContainer unsavedContent{{"/path/to", "unsaved.cpp"}, "void f();", {}}; + ProjectExplorer::Project project; }; TEST_F(ClangQueryProjectFindFilter, SupportedFindFlags) @@ -175,60 +228,4 @@ TEST_F(ClangQueryProjectFindFilter, CallingRequestSourceRangesAndDiagnostics) findFilter.requestSourceRangesAndDiagnostics(QString(queryText), QString(exampleContent)); } -std::vector<CppTools::ProjectPart::Ptr> createProjectParts() -{ - auto projectPart1 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); - projectPart1->files.append({"/path/to/file1.h", CppTools::ProjectFile::CXXHeader}); - projectPart1->files.append({"/path/to/file1.cpp", CppTools::ProjectFile::CXXSource}); - - auto projectPart2 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); - projectPart2->files.append({"/path/to/file2.cpp", CppTools::ProjectFile::CXXSource}); - projectPart2->files.append({"/path/to/unsaved.cpp", CppTools::ProjectFile::CXXSource}); - projectPart2->files.append({"/path/to/cheader.h", CppTools::ProjectFile::CHeader}); - - - return {projectPart1, projectPart2}; -} - -std::vector<Utils::SmallStringVector> -createCommandLines(const std::vector<CppTools::ProjectPart::Ptr> &projectParts) -{ - using Filter = ClangRefactoring::ClangQueryProjectsFindFilter; - - std::vector<Utils::SmallStringVector> commandLines; - - for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) { - for (const CppTools::ProjectFile &projectFile : projectPart->files) { - Utils::SmallStringVector commandLine = Filter::compilerArguments(projectPart.data(), - projectFile.kind); - commandLine.emplace_back(projectFile.path); - commandLines.push_back(commandLine); - } - } - - return commandLines; -} - -void ClangQueryProjectFindFilter::SetUp() -{ - projectsParts = createProjectParts(); - commandLines = createCommandLines(projectsParts); - - findFilter.setProjectParts(projectsParts); - findFilter.setUnsavedContent({unsavedContent.clone()}); - - - ON_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), findDeclQueryText)) - .WillByDefault(Return(ByMove(createSearchHandle()))); - -} - -std::unique_ptr<ClangRefactoring::SearchHandle> ClangQueryProjectFindFilter::createSearchHandle() -{ - auto handle = std::make_unique<NiceMock<MockSearchHandle>>(); - handle->setRefactoringServer(&mockRefactoringServer); - - return handle; -} - } diff --git a/tests/unit/unittest/clangreferencescollector-test.cpp b/tests/unit/unittest/clangreferencescollector-test.cpp index acf7c42ac3..bb04d8c8d1 100644 --- a/tests/unit/unittest/clangreferencescollector-test.cpp +++ b/tests/unit/unittest/clangreferencescollector-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangsupport_global.h> #include <clangreferencescollector.h> @@ -59,7 +59,7 @@ struct Data { ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/references.cpp"), - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), {}, documents}; }; diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp index 807618deef..fb630e2aa3 100644 --- a/tests/unit/unittest/clangtooltipinfo-test.cpp +++ b/tests/unit/unittest/clangtooltipinfo-test.cpp @@ -153,7 +153,7 @@ TEST_F(ToolTipInfo, MemberVariable) ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("int")))); } -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_QualifiedName)) +TEST_F(ToolTipInfo, MemberFunctionCall_QualifiedName) { const ::ToolTipInfo actual = tooltip(21, 9); @@ -161,7 +161,7 @@ TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_Qualifi } // ChangeLog: Show extra specifiers. For functions e.g.: virtual, inline, explicit, const, volatile -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_ExtraSpecifiers)) +TEST_F(ToolTipInfo, MemberFunctionCall_ExtraSpecifiers) { const ::ToolTipInfo actual = tooltip(22, 9); @@ -199,7 +199,7 @@ TEST_F(ToolTipInfo, MemberFunctionCall_qdocCategory) } // TODO: Show the template parameter type, too: "template<typename T>...)" -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(TemplateFunctionCall)) +TEST_F(ToolTipInfo, TemplateFunctionCall) { const ::ToolTipInfo actual = tooltip(30, 5); @@ -548,7 +548,7 @@ TEST_F(ToolTipInfo, Function_qdocIdCandidatesAreQualified) Utf8StringLiteral("f"))); } -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_HasParameterName)) +TEST_F(ToolTipInfo, Function_HasParameterName) { const ::ToolTipInfo actual = tooltip(167, 5); @@ -621,21 +621,21 @@ TEST_F(ToolTipInfo, AutoTypeClassTemplateType) ASSERT_THAT(actual.text, Utf8StringLiteral("Zii<int>")); } -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_DefaultConstructor)) +TEST_F(ToolTipInfo, Function_DefaultConstructor) { const ::ToolTipInfo actual = tooltip(193, 5); ASSERT_THAT(actual.text, Utf8StringLiteral("inline constexpr Con::Con() noexcept")); } -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_ExplicitDefaultConstructor)) +TEST_F(ToolTipInfo, Function_ExplicitDefaultConstructor) { const ::ToolTipInfo actual = tooltip(194, 5); ASSERT_THAT(actual.text, Utf8StringLiteral("ExplicitCon::ExplicitCon() noexcept = default")); } -TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_CustomConstructor)) +TEST_F(ToolTipInfo, Function_CustomConstructor) { const ::ToolTipInfo actual = tooltip(195, 5); diff --git a/tests/unit/unittest/clangupdateannotationsjob-test.cpp b/tests/unit/unittest/clangupdateannotationsjob-test.cpp index 0bcd5a67c0..79623619c1 100644 --- a/tests/unit/unittest/clangupdateannotationsjob-test.cpp +++ b/tests/unit/unittest/clangupdateannotationsjob-test.cpp @@ -97,16 +97,16 @@ TEST_F(UpdateAnnotationsJobSlowTest, DontSendAnnotationsIfDocumentRevisionChange ASSERT_TRUE(waitUntilJobFinished(job)); } -TEST_F(UpdateAnnotationsJobSlowTest, UpdatesDependendFilePaths) +TEST_F(UpdateAnnotationsJobSlowTest, UpdatesDependentFilePaths) { - const QSet<Utf8String> dependendOnFilesBefore = document.dependedFilePaths(); + const QSet<Utf8String> dependentOnFilesBefore = document.dependedFilePaths(); job.setContext(jobContext); job.prepareAsyncRun(); job.runAsync(); ASSERT_TRUE(waitUntilJobFinished(job)); - ASSERT_THAT(dependendOnFilesBefore, Not(document.dependedFilePaths())); + ASSERT_THAT(dependentOnFilesBefore, Not(document.dependedFilePaths())); } TEST_F(UpdateAnnotationsJobSlowTest, UpdatesUnresolvedFilePaths) diff --git a/tests/unit/unittest/codecompletionsextractor-test.cpp b/tests/unit/unittest/codecompletionsextractor-test.cpp index ae7559ce78..509dfd49dc 100644 --- a/tests/unit/unittest/codecompletionsextractor-test.cpp +++ b/tests/unit/unittest/codecompletionsextractor-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangcodecompleteresults.h> #include <clangdocument.h> @@ -148,7 +148,7 @@ protected: protected: ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; - Utf8StringVector compilationArguments{TestEnvironment::addPlatformArguments()}; + Utf8StringVector compilationArguments{UnitTest::addPlatformArguments()}; Document functionDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), compilationArguments, {}, documents}; Document functionOverloadDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_functionoverload.cpp"), compilationArguments, {}, documents}; Document variableDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), compilationArguments, {}, documents}; diff --git a/tests/unit/unittest/commandlinebuilder-test.cpp b/tests/unit/unittest/commandlinebuilder-test.cpp index 8979cebca8..c5765037dc 100644 --- a/tests/unit/unittest/commandlinebuilder-test.cpp +++ b/tests/unit/unittest/commandlinebuilder-test.cpp @@ -36,6 +36,7 @@ namespace { template<typename ProjectInfo> using Builder = ClangBackEnd::CommandLineBuilder<ProjectInfo>; +using ClangBackEnd::FilePath; using ClangBackEnd::IncludeSearchPathType; using ClangBackEnd::InputFileType; @@ -48,10 +49,7 @@ template <> class CommandLineBuilder<ClangBackEnd::PchTask> : public testing::Test { public: - CommandLineBuilder() - { - cppProjectInfo.language = Utils::Language::Cxx; - } + CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; } public: ClangBackEnd::PchTask emptyProjectInfo{0, {}, {}, {}, {}, {}, {}, {}}; @@ -62,10 +60,7 @@ template <> class CommandLineBuilder<ClangBackEnd::ProjectPartContainer> : public testing::Test { public: - CommandLineBuilder() - { - cppProjectInfo.language = Utils::Language::Cxx; - } + CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; } public: ClangBackEnd::ProjectPartContainer emptyProjectInfo{0, @@ -94,10 +89,7 @@ template <> class CommandLineBuilder<ClangBackEnd::ProjectPartArtefact> : public testing::Test { public: - CommandLineBuilder() - { - cppProjectInfo.language = Utils::Language::Cxx; - } + CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; } public: ClangBackEnd::ProjectPartArtefact emptyProjectInfo{{}, @@ -502,7 +494,13 @@ TYPED_TEST(CommandLineBuilder, IncludesOrder) {"/system/foo", 3, IncludeSearchPathType::Framework}, {"/builtin/bar", 2, IncludeSearchPathType::BuiltIn}, {"/builtin/foo", 1, IncludeSearchPathType::BuiltIn}}; - Builder<TypeParam> builder{this->emptyProjectInfo, {}, InputFileType::Header, "/source/file.cpp"}; + Builder<TypeParam> builder{this->emptyProjectInfo, + {}, + InputFileType::Header, + "/source/file.cpp", + {}, + {}, + ClangBackEnd::NativeFilePath{FilePath{"/resource/path"}}}; ASSERT_THAT(builder.commandLine, ElementsAre("clang++", @@ -513,6 +511,8 @@ TYPED_TEST(CommandLineBuilder, IncludesOrder) "-std=c++11", "-nostdinc", "-nostdinc++", + "-isystem", + toNativePath("/resource/path"), "-I", toNativePath("/include/foo"), "-I", @@ -598,6 +598,19 @@ TYPED_TEST(CommandLineBuilder, OutputFile) toNativePath("/source/file.cpp"))); } +TYPED_TEST(CommandLineBuilder, PreIncludeSearchPath) +{ + Builder<TypeParam> builder{this->emptyProjectInfo, + {}, + {}, + {}, + {}, + {}, + ClangBackEnd::NativeFilePath{FilePath{"/resource/path"}}}; + + ASSERT_THAT(builder.commandLine, Contains(toNativePath("/resource/path"))); +} + TYPED_TEST(CommandLineBuilder, IncludePchPath) { Builder<TypeParam> builder{this->emptyProjectInfo, diff --git a/tests/unit/unittest/compilationdatabaseutils-test.cpp b/tests/unit/unittest/compilationdatabaseutils-test.cpp index 252ab2ffd6..cae74fa807 100644 --- a/tests/unit/unittest/compilationdatabaseutils-test.cpp +++ b/tests/unit/unittest/compilationdatabaseutils-test.cpp @@ -29,26 +29,35 @@ #include <projectexplorer/headerpath.h> #include <projectexplorer/projectmacro.h> #include <utils/fileutils.h> +#include <utils/hostosinfo.h> using namespace ProjectExplorer; using namespace CompilationDatabaseProjectManager; +using namespace CompilationDatabaseProjectManager::Internal; namespace { class CompilationDatabaseUtils : public ::testing::Test { protected: + QStringList splitCommandLine(const QString &commandLine) + { + QSet<QString> flagsCache; + return CompilationDatabaseProjectManager::Internal::splitCommandLine(commandLine, flagsCache); + } + HeaderPaths headerPaths; Macros macros; CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::Unclassified; QStringList flags; QString fileName; QString workingDir; + QString sysRoot; }; TEST_F(CompilationDatabaseUtils, FilterEmptyFlags) { - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); ASSERT_THAT(flags.isEmpty(), true); } @@ -62,77 +71,89 @@ TEST_F(CompilationDatabaseUtils, FilterFromFilename) TEST_F(CompilationDatabaseUtils, FilterArguments) { + using Utils::HostOsInfo; + const char winPath1[] = "C:\\Qt\\5.9.2\\mingw53_32\\include"; + const char otherPath1[] = "/Qt/5.9.2/mingw53_32/include"; + const char winPath2[] = "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtWidgets"; + const char otherPath2[] = "/Qt/5.9.2/mingw53_32/include/QtWidgets"; fileName = "compileroptionsbuilder.cpp"; workingDir = "C:/build-qtcreator-MinGW_32bit-Debug"; - flags = filterFromFileName(QStringList { - "clang++", - "-c", - "-m32", - "-target", - "i686-w64-mingw32", - "-std=gnu++14", - "-fcxx-exceptions", - "-fexceptions", - "-DUNICODE", - "-DRELATIVE_PLUGIN_PATH=\"../lib/qtcreator/plugins\"", - "-DQT_CREATOR", - "-fPIC", - "-I", - "C:\\Qt\\5.9.2\\mingw53_32\\include", - "-I", - "C:\\Qt\\5.9.2\\mingw53_32\\include\\QtWidgets", - "-x", - "c++", - "C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp" - }, "compileroptionsbuilder"); - - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); - - ASSERT_THAT(flags, Eq(QStringList{"-m32", - "-target", - "i686-w64-mingw32", - "-std=gnu++14", - "-fcxx-exceptions", - "-fexceptions"})); - ASSERT_THAT(headerPaths, Eq(HeaderPaths{ - {"C:\\Qt\\5.9.2\\mingw53_32\\include", HeaderPathType::User}, - {"C:\\Qt\\5.9.2\\mingw53_32\\include\\QtWidgets", HeaderPathType::User} - })); - ASSERT_THAT(macros, Eq(Macros{ - {"UNICODE", "1"}, - {"RELATIVE_PLUGIN_PATH", "\"../lib/qtcreator/plugins\""}, - {"QT_CREATOR", "1"} - })); + flags = filterFromFileName( + QStringList{"clang++", + "-c", + "-m32", + "-target", + "i686-w64-mingw32", + "-std=gnu++14", + "-fcxx-exceptions", + "-fexceptions", + "-DUNICODE", + "-DRELATIVE_PLUGIN_PATH=\"../lib/qtcreator/plugins\"", + "-DQT_CREATOR", + "-fPIC", + "-I", + QString::fromUtf8(HostOsInfo::isWindowsHost() ? winPath1 : otherPath1), + "-I", + QString::fromUtf8(HostOsInfo::isWindowsHost() ? winPath2 : otherPath2), + "-x", + "c++", + QString("--sysroot=") + (HostOsInfo::isWindowsHost() + ? "C:\\sysroot\\embedded" : "/opt/sysroot/embedded"), + "C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"}, + "compileroptionsbuilder"); + + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); + + ASSERT_THAT(flags, + Eq(QStringList{"-m32", + "-target", + "i686-w64-mingw32", + "-std=gnu++14", + "-fcxx-exceptions", + "-fexceptions"})); + ASSERT_THAT(headerPaths, + Eq(HeaderPaths{{QString::fromUtf8(HostOsInfo::isWindowsHost() ? winPath1 : otherPath1), + HeaderPathType::User}, + {QString::fromUtf8(HostOsInfo::isWindowsHost() ? winPath2 : otherPath2), + HeaderPathType::User}})); + ASSERT_THAT(macros, + Eq(Macros{{"UNICODE", "1"}, + {"RELATIVE_PLUGIN_PATH", "\"../lib/qtcreator/plugins\""}, + {"QT_CREATOR", "1"}})); ASSERT_THAT(fileKind, CppTools::ProjectFile::Kind::CXXSource); + ASSERT_THAT(sysRoot, HostOsInfo::isWindowsHost() ? QString("C:\\sysroot\\embedded") + : QString("/opt/sysroot/embedded")); } -static QString kCmakeCommand = "C:\\PROGRA~2\\MICROS~2\\2017\\COMMUN~1\\VC\\Tools\\MSVC\\1415~1.267\\bin\\HostX64\\x64\\cl.exe " - "/nologo " - "/TP " - "-DUNICODE " - "-D_HAS_EXCEPTIONS=0 " - "-Itools\\clang\\lib\\Sema " - "/DWIN32 " - "/D_WINDOWS " - "/Zc:inline " - "/Zc:strictStrings " - "/Oi " - "/Zc:rvalueCast " - "/W4 " - "-wd4141 " - "-wd4146 " - "/MDd " - "/Zi " - "/Ob0 " - "/Od " - "/RTC1 " - "/EHs-c- " - "/GR " - "/Fotools\\clang\\lib\\Sema\\CMakeFiles\\clangSema.dir\\SemaCodeComplete.cpp.obj " - "/FdTARGET_COMPILE_PDB " - "/FS " - "-c " - "C:\\qt_llvm\\tools\\clang\\lib\\Sema\\SemaCodeComplete.cpp"; +static QString kCmakeCommand + = "C:\\PROGRA~2\\MICROS~2\\2017\\COMMUN~1\\VC\\Tools\\MSVC\\1415~1.267\\bin\\HostX64\\x64\\cl." + "exe " + "/nologo " + "/TP " + "-DUNICODE " + "-D_HAS_EXCEPTIONS=0 " + "-Itools\\clang\\lib\\Sema " + "/DWIN32 " + "/D_WINDOWS " + "/Zc:inline " + "/Zc:strictStrings " + "/Oi " + "/Zc:rvalueCast " + "/W4 " + "-wd4141 " + "-wd4146 " + "/MDd " + "/Zi " + "/Ob0 " + "/Od " + "/RTC1 " + "/EHs-c- " + "/GR " + "/Fotools\\clang\\lib\\Sema\\CMakeFiles\\clangSema.dir\\SemaCodeComplete.cpp.obj " + "/FdTARGET_COMPILE_PDB " + "/FS " + "-c " + "C:\\qt_llvm\\tools\\clang\\lib\\Sema\\SemaCodeComplete.cpp"; TEST_F(CompilationDatabaseUtils, SplitFlags) { @@ -155,21 +176,14 @@ TEST_F(CompilationDatabaseUtils, FilterCommand) workingDir = "C:/build-qt_llvm-msvc2017_64bit-Debug"; flags = filterFromFileName(splitCommandLine(kCmakeCommand), "SemaCodeComplete"); - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); - - ASSERT_THAT(flags, Eq(QStringList{"/Zc:inline", - "/Zc:strictStrings", - "/Zc:rvalueCast", - "/Zi"})); - ASSERT_THAT(headerPaths, Eq(HeaderPaths{ - {"tools\\clang\\lib\\Sema", HeaderPathType::User} - })); - ASSERT_THAT(macros, Eq(Macros{ - {"UNICODE", "1"}, - {"_HAS_EXCEPTIONS", "0"}, - {"WIN32", "1"}, - {"_WINDOWS", "1"} - })); + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); + + ASSERT_THAT(flags, Eq(QStringList{"/Zc:inline", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zi"})); + ASSERT_THAT(headerPaths, + Eq(HeaderPaths{{"C:/build-qt_llvm-msvc2017_64bit-Debug/tools\\clang\\lib\\Sema", + HeaderPathType::User}})); + ASSERT_THAT(macros, + Eq(Macros{{"UNICODE", "1"}, {"_HAS_EXCEPTIONS", "0"}, {"WIN32", "1"}, {"_WINDOWS", "1"}})); ASSERT_THAT(fileKind, CppTools::ProjectFile::Kind::CXXSource); } @@ -178,7 +192,7 @@ TEST_F(CompilationDatabaseUtils, FileKindDifferentFromExtension) fileName = "foo.c"; flags = QStringList{"-xc++"}; - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); ASSERT_THAT(fileKind, CppTools::ProjectFile::Kind::CXXSource); } @@ -186,9 +200,9 @@ TEST_F(CompilationDatabaseUtils, FileKindDifferentFromExtension) TEST_F(CompilationDatabaseUtils, FileKindDifferentFromExtension2) { fileName = "foo.cpp"; - flags = QStringList{"-x", "c"}; + flags = QStringList{"-x", "c"}; - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); ASSERT_THAT(fileKind, CppTools::ProjectFile::Kind::CSource); } @@ -197,9 +211,9 @@ TEST_F(CompilationDatabaseUtils, SkipOutputFiles) { flags = filterFromFileName(QStringList{"-o", "foo.o"}, "foo"); - filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind); + filteredFlags(fileName, workingDir, flags, headerPaths, macros, fileKind, sysRoot); ASSERT_THAT(flags.isEmpty(), true); } -} +} // namespace diff --git a/tests/unit/unittest/conditionally-disabled-tests.h b/tests/unit/unittest/conditionally-disabled-tests.h index 0b6f279975..c88a844b96 100644 --- a/tests/unit/unittest/conditionally-disabled-tests.h +++ b/tests/unit/unittest/conditionally-disabled-tests.h @@ -39,15 +39,3 @@ #else # define DISABLED_ON_NON_WINDOWS(x) x #endif - -#ifdef IS_PRETTY_DECL_SUPPORTED -# define DISABLED_WITHOUT_PRETTYDECL_PATCH(x) x -#else -# define DISABLED_WITHOUT_PRETTYDECL_PATCH(x) DISABLED_##x -#endif - -#ifdef IS_INVALIDDECL_SUPPORTED -# define DISABLED_WITHOUT_INVALIDDECL_PATCH(x) x -#else -# define DISABLED_WITHOUT_INVALIDDECL_PATCH(x) DISABLED_##x -#endif diff --git a/tests/unit/unittest/cppprojectinfogenerator-test.cpp b/tests/unit/unittest/cppprojectinfogenerator-test.cpp index 9d39b8eada..7db9f0e439 100644 --- a/tests/unit/unittest/cppprojectinfogenerator-test.cpp +++ b/tests/unit/unittest/cppprojectinfogenerator-test.cpp @@ -164,8 +164,11 @@ void ProjectInfoGenerator::SetUp() ProjectInfo ProjectInfoGenerator::generate() { QFutureInterface<void> fi; + ProjectExplorer::ConcreteToolChain aToolChain; projectUpdateInfo.rawProjectParts += rawProjectPart; + projectUpdateInfo.cxxToolChain = &aToolChain; + projectUpdateInfo.cToolChain = &aToolChain; ::ProjectInfoGenerator generator(fi, projectUpdateInfo); return generator.generate(); diff --git a/tests/unit/unittest/cursor-test.cpp b/tests/unit/unittest/cursor-test.cpp index e55668d420..2fa4bff709 100644 --- a/tests/unit/unittest/cursor-test.cpp +++ b/tests/unit/unittest/cursor-test.cpp @@ -26,7 +26,7 @@ #include "googletest.h" #include "clangcompareoperators.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangdocument.h> #include <clangdocuments.h> @@ -63,7 +63,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp")}; Document document{filePath, - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), {}, documents}; TranslationUnit translationUnit{filePath, diff --git a/tests/unit/unittest/data/preincludes/system1.h b/tests/unit/unittest/data/preincludes/system1.h new file mode 100644 index 0000000000..005a65916e --- /dev/null +++ b/tests/unit/unittest/data/preincludes/system1.h @@ -0,0 +1 @@ +#include_next <system1.h> diff --git a/tests/unit/unittest/diagnostic-test.cpp b/tests/unit/unittest/diagnostic-test.cpp index fac44162cd..3ab382c46b 100644 --- a/tests/unit/unittest/diagnostic-test.cpp +++ b/tests/unit/unittest/diagnostic-test.cpp @@ -23,10 +23,10 @@ ** ****************************************************************************/ -#include "googletest.h" #include "diagnosticcontainer-matcher.h" +#include "googletest.h" #include "rundocumentparse-utility.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <diagnostic.h> #include <diagnosticcontainer.h> @@ -87,7 +87,7 @@ protected: ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnostic.cpp"), - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), {}, documents}; UnitTest::RunDocumentParse _1{document}; diff --git a/tests/unit/unittest/diagnosticset-test.cpp b/tests/unit/unittest/diagnosticset-test.cpp index f37d00e13f..b59325e0e7 100644 --- a/tests/unit/unittest/diagnosticset-test.cpp +++ b/tests/unit/unittest/diagnosticset-test.cpp @@ -23,9 +23,9 @@ ** ****************************************************************************/ -#include "googletest.h" #include "diagnosticcontainer-matcher.h" -#include "testenvironment.h" +#include "googletest.h" +#include "unittest-utility-functions.h" #include <clangsupport_global.h> #include <clangdocument.h> @@ -64,7 +64,7 @@ protected: ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Utf8StringVector compilationArguments{ - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-pedantic")})}; + UnitTest::addPlatformArguments({Utf8StringLiteral("-pedantic")})}; Document document{Utf8StringLiteral(TESTDATA_DIR "/diagnostic_diagnosticset.cpp"), compilationArguments, {}, diff --git a/tests/unit/unittest/filesystem-utilities.h b/tests/unit/unittest/filesystem-utilities.h index fa75f06ad1..7238cfab75 100644 --- a/tests/unit/unittest/filesystem-utilities.h +++ b/tests/unit/unittest/filesystem-utilities.h @@ -29,6 +29,9 @@ #include <nativefilepath.h> +#include <QCoreApplication> +#include <QDir> + template<std::size_t Size> ClangBackEnd::NativeFilePath toNativePath(const char (&text)[Size]) { @@ -50,3 +53,9 @@ inline Utils::PathString toNativePath(Utils::SmallStringView text) return ClangBackEnd::NativeFilePath{path}.path(); } + +inline QString resourcePath() +{ + return QDir::cleanPath(QCoreApplication::applicationDirPath() + '/' + RELATIVE_DATA_PATH + + "/indexing_preincludes"); +} diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 3cb7e45def..7ac4a676e3 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -39,27 +39,28 @@ #include <clangpathwatcher.h> #include <clangrefactoringmessages.h> #include <clangreferencescollector.h> -#include <filestatus.h> #include <filepath.h> #include <filepathcaching.h> +#include <filepathview.h> +#include <filestatus.h> #include <fulltokeninfo.h> #include <includesearchpath.h> #include <nativefilepath.h> +#include <pchpaths.h> #include <pchtask.h> #include <precompiledheadersupdatedmessage.h> #include <projectpartartefact.h> -#include <projectpartid.h> +#include <projectpartentry.h> +#include <projectpartpch.h> #include <sourcedependency.h> #include <sourcelocationentry.h> #include <sourcelocationscontainer.h> -#include <tokenprocessor.h> -#include <filepathview.h> +#include <symbol.h> #include <symbolentry.h> #include <symbolindexertaskqueue.h> -#include <symbol.h> -#include <tooltipinfo.h> +#include <tokenprocessor.h> #include <toolchainargumentscache.h> -#include <projectpartentry.h> +#include <tooltipinfo.h> #include <usedmacro.h> #include <cpptools/usages.h> @@ -193,6 +194,8 @@ const char * toText(Utils::Language language) return "C"; case Language::Cxx: return "Cxx"; + case Language::None: + return "None"; } return ""; @@ -228,6 +231,8 @@ const char * toText(Utils::LanguageVersion languageVersion) return "CXX2a"; case LanguageVersion::CXX98: return "CXX98"; + case LanguageVersion::None: + return "None"; } return ""; @@ -714,18 +719,14 @@ std::ostream &operator<<(std::ostream &out, const NativeFilePath &filePath) std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message) { - out << "(" - << message.projectPartPchs - << ")"; + out << "(" << message.projectPartIds << ")"; return out; } std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch) { - out << "(" - << projectPartPch.projectPartId << ", " - << projectPartPch.pchPath << ", " + out << "(" << projectPartPch.projectPartId << ", " << projectPartPch.pchPath << ", " << projectPartPch.lastModified << ")"; return out; @@ -1226,6 +1227,16 @@ std::ostream &operator<<(std::ostream &out, const SourceEntry &entry) << typeToString(entry.hasMissingIncludes) << ")"; } +std::ostream &operator<<(std::ostream &out, const SourceTimeStamp &sourceTimeStamp) +{ + return out << "(" << sourceTimeStamp.sourceId << ", " << sourceTimeStamp.timeStamp << ")"; +} + +std::ostream &operator<<(std::ostream &out, const TimeStamp &timeStamp) +{ + return out << timeStamp.value; +} + const char *typeToString(IncludeSearchPathType type) { switch (type) { @@ -1275,6 +1286,10 @@ std::ostream &operator<<(std::ostream &out, const ProjectPartId &projectPathId) return out << projectPathId.projectPathId; } +std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths) +{ + return out << "(" << pchPaths.projectPchPath << ", " << pchPaths.systemPchPath << ")"; +} void PrintTo(const FilePath &filePath, ::std::ostream *os) { *os << filePath; diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index 9e2c5632f5..b874fc90e4 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -49,7 +49,7 @@ std::ostream &operator<<(std::ostream &out, const CompileCommand &command); } // namespace clang namespace Core { -class LocatorFilterEntry; +struct LocatorFilterEntry; std::ostream &operator<<(std::ostream &out, const LocatorFilterEntry &entry); @@ -165,7 +165,7 @@ class UpdateProjectPartsMessage; class DocumentsChangedMessage; class DocumentVisibilityChangedMessage; class FilePath; -template <char WindowsSlash> +template<char WindowsSlash> class AbstractFilePathView; using FilePathView = AbstractFilePathView<'/'>; using NativeFilePathView = AbstractFilePathView<'\\'>; @@ -190,6 +190,8 @@ class PchTask; class PchTaskSet; class BuildDependency; class SourceEntry; +class SourceTimeStamp; +class TimeStamp; class FilePathCaching; struct SlotUsage; class IncludeSearchPath; @@ -197,6 +199,7 @@ enum class IncludeSearchPathType : unsigned char; struct ArgumentsEntry; class ProjectPartContainer; class ProjectPartId; +class PchPaths; std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); @@ -281,12 +284,15 @@ std::ostream &operator<<(std::ostream &out, const PchTask &task); std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet); std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency); std::ostream &operator<<(std::ostream &out, const SourceEntry &entry); +std::ostream &operator<<(std::ostream &out, const SourceTimeStamp &sourceTimeStamp); +std::ostream &operator<<(std::ostream &out, const TimeStamp &timeStamp); std::ostream &operator<<(std::ostream &out, const SlotUsage &slotUsage); std::ostream &operator<<(std::ostream &out, const IncludeSearchPathType &pathType); std::ostream &operator<<(std::ostream &out, const IncludeSearchPath &path); std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry); std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container); std::ostream &operator<<(std::ostream &out, const ProjectPartId &projectPathId); +std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths); void PrintTo(const FilePath &filePath, ::std::ostream *os); void PrintTo(const FilePathView &filePathView, ::std::ostream *os); diff --git a/tests/unit/unittest/headerpathfilter-test.cpp b/tests/unit/unittest/headerpathfilter-test.cpp index 9a75399443..79091e0a0b 100644 --- a/tests/unit/unittest/headerpathfilter-test.cpp +++ b/tests/unit/unittest/headerpathfilter-test.cpp @@ -26,6 +26,7 @@ #include "googletest.h" #include <cpptools/headerpathfilter.h> +#include <projectexplorer/project.h> namespace { @@ -37,7 +38,7 @@ MATCHER_P(HasBuiltIn, std::string(negation ? "isn't " : "is ") + PrintToString(HeaderPath{QString::fromUtf8(path), HeaderPathType::BuiltIn})) { - return arg.path == path && arg.type == HeaderPathType::BuiltIn; + return arg.path == QString::fromUtf8(path) && arg.type == HeaderPathType::BuiltIn; } MATCHER_P(HasSystem, @@ -45,7 +46,7 @@ MATCHER_P(HasSystem, std::string(negation ? "isn't " : "is ") + PrintToString(HeaderPath{QString::fromUtf8(path), HeaderPathType::System})) { - return arg.path == path && arg.type == HeaderPathType::System; + return arg.path == QString::fromUtf8(path) && arg.type == HeaderPathType::System; } MATCHER_P(HasFramework, @@ -53,7 +54,7 @@ MATCHER_P(HasFramework, std::string(negation ? "isn't " : "is ") + PrintToString(HeaderPath{QString::fromUtf8(path), HeaderPathType::Framework})) { - return arg.path == path && arg.type == HeaderPathType::Framework; + return arg.path == QString::fromUtf8(path) && arg.type == HeaderPathType::Framework; } MATCHER_P(HasUser, @@ -61,7 +62,7 @@ MATCHER_P(HasUser, std::string(negation ? "isn't " : "is ") + PrintToString(HeaderPath{QString::fromUtf8(path), HeaderPathType::User})) { - return arg.path == path && arg.type == HeaderPathType::User; + return arg.path == QString::fromUtf8(path) && arg.type == HeaderPathType::User; } class HeaderPathFilter : public testing::Test @@ -80,9 +81,11 @@ protected: HeaderPath{"/project/user_path", HeaderPathType::User}}; projectPart.headerPaths = headerPaths; + projectPart.project = &project; } protected: + ProjectExplorer::Project project; CppTools::ProjectPart projectPart; CppTools::HeaderPathFilter filter{ projectPart, CppTools::UseTweakedHeaderPaths::No, {}, {}, "/project", "/build"}; @@ -100,7 +103,8 @@ TEST_F(HeaderPathFilter, System) filter.process(); ASSERT_THAT(filter.systemHeaderPaths, - ElementsAre(HasSystem("/system_path"), + ElementsAre(HasSystem("/project/.pre_includes"), + HasSystem("/system_path"), HasFramework("/framework_path"), HasUser("/outside_project_user_path"), HasUser("/buildb/user_path"), @@ -137,7 +141,8 @@ TEST_F(HeaderPathFilter, DontAddInvalidPath) AllOf(Field(&CppTools::HeaderPathFilter::builtInHeaderPaths, ElementsAre(HasBuiltIn("/builtin_path"))), Field(&CppTools::HeaderPathFilter::systemHeaderPaths, - ElementsAre(HasSystem("/system_path"), + ElementsAre(HasSystem("/project/.pre_includes"), + HasSystem("/system_path"), HasFramework("/framework_path"), HasUser("/outside_project_user_path"), HasUser("/buildb/user_path"), diff --git a/tests/unit/unittest/highlightingresultreporter-test.cpp b/tests/unit/unittest/highlightingresultreporter-test.cpp index dfe8dfbd2e..dd2001e02f 100644 --- a/tests/unit/unittest/highlightingresultreporter-test.cpp +++ b/tests/unit/unittest/highlightingresultreporter-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <chunksreportedmonitor.h> #include <clangdocument.h> @@ -51,7 +51,7 @@ struct Data { UnsavedFiles unsavedFiles; Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR "/highlightingmarks.cpp"), - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), Utf8StringVector(), documents}; }; diff --git a/tests/unit/unittest/matchingtext-test.cpp b/tests/unit/unittest/matchingtext-test.cpp index 081e356764..b49731d3e6 100644 --- a/tests/unit/unittest/matchingtext-test.cpp +++ b/tests/unit/unittest/matchingtext-test.cpp @@ -221,6 +221,41 @@ TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotInTheMiddle) ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); } +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotAfterControlFlow_WhileAndFriends) +{ + const Document document("while (true) @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotAfterControlFlow_DoAndFriends) +{ + const Document document("do @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_InvalidCode_UnbalancedParens) +{ + const Document document(") @"); + + ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_InvalidCode_UnbalancedParens2) +{ + const Document document("while true) @"); + + ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_InvalidCode_OnlyBalancedParens) +{ + const Document document("() @"); + + ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeNamedNamespace) { const Document document("namespace X @"); diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h index 46c201de55..a4d34e481d 100644 --- a/tests/unit/unittest/mockbuilddependenciesstorage.h +++ b/tests/unit/unittest/mockbuilddependenciesstorage.h @@ -51,5 +51,7 @@ public: ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName)); MOCK_METHOD2(updatePchCreationTimeStamp, void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId)); + MOCK_CONST_METHOD1(fetchSources, + ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId)); }; diff --git a/tests/unit/unittest/mockmodifiedtimechecker.h b/tests/unit/unittest/mockmodifiedtimechecker.h index 5f0559f682..bf101988b1 100644 --- a/tests/unit/unittest/mockmodifiedtimechecker.h +++ b/tests/unit/unittest/mockmodifiedtimechecker.h @@ -29,9 +29,17 @@ #include <modifiedtimecheckerinterface.h> -class MockModifiedTimeChecker : public ClangBackEnd::ModifiedTimeCheckerInterface +class MockSourceEntriesModifiedTimeChecker + : public ClangBackEnd::ModifiedTimeCheckerInterface<ClangBackEnd::SourceEntries> { public: MOCK_CONST_METHOD1(isUpToDate, bool (const ClangBackEnd::SourceEntries &sourceEntries)); }; + +class MockSourceTimeStampsModifiedTimeChecker + : public ClangBackEnd::ModifiedTimeCheckerInterface<ClangBackEnd::SourceTimeStamps> +{ +public: + MOCK_CONST_METHOD1(isUpToDate, bool(const ClangBackEnd::SourceTimeStamps &sourceTimeStamps)); +}; diff --git a/tests/unit/unittest/mockpchmanagernotifier.h b/tests/unit/unittest/mockpchmanagernotifier.h index 600b37bd2e..8db9a63c40 100644 --- a/tests/unit/unittest/mockpchmanagernotifier.h +++ b/tests/unit/unittest/mockpchmanagernotifier.h @@ -36,9 +36,6 @@ public: : ClangPchManager::PchManagerNotifierInterface(pchManagerClient) {} - MOCK_METHOD3(precompiledHeaderUpdated, - void(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified)); + MOCK_METHOD1(precompiledHeaderUpdated, void(ClangBackEnd::ProjectPartId projectPartId)); MOCK_METHOD1(precompiledHeaderRemoved, void(ClangBackEnd::ProjectPartId projectPartId)); }; diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h index 31c38affda..84caea55be 100644 --- a/tests/unit/unittest/mockprecompiledheaderstorage.h +++ b/tests/unit/unittest/mockprecompiledheaderstorage.h @@ -37,6 +37,8 @@ public: Utils::SmallStringView pchPath, long long pchBuildTime)); MOCK_METHOD1(deleteProjectPrecompiledHeader, void(ClangBackEnd::ProjectPartId projectPartId)); + MOCK_METHOD1(deleteProjectPrecompiledHeaders, + void(const ClangBackEnd::ProjectPartIds &projectPartIds)); MOCK_METHOD3(insertSystemPrecompiledHeaders, void(const ClangBackEnd::ProjectPartIds &projectPartIds, Utils::SmallStringView pchPath, @@ -45,7 +47,8 @@ public: void(const ClangBackEnd::ProjectPartIds &projectPartIds)); MOCK_METHOD1(fetchSystemPrecompiledHeaderPath, ClangBackEnd::FilePath(ClangBackEnd::ProjectPartId projectPartId)); - MOCK_CONST_METHOD1( - fetchPrecompiledHeader, - Utils::optional<ClangBackEnd::ProjectPartPch>(ClangBackEnd::ProjectPartId projectPartId)); + MOCK_CONST_METHOD1(fetchPrecompiledHeader, + ClangBackEnd::FilePath(ClangBackEnd::ProjectPartId projectPartId)); + MOCK_CONST_METHOD1(fetchPrecompiledHeaders, + ClangBackEnd::PchPaths(ClangBackEnd::ProjectPartId projectPartId)); }; diff --git a/tests/unit/unittest/mockprojectpartsmanager.h b/tests/unit/unittest/mockprojectpartsmanager.h index b2cab59060..613faf7dfc 100644 --- a/tests/unit/unittest/mockprojectpartsmanager.h +++ b/tests/unit/unittest/mockprojectpartsmanager.h @@ -33,7 +33,7 @@ class MockProjectPartsManager : public ClangBackEnd::ProjectPartsManagerInterfac { public: MOCK_METHOD1(update, - ClangBackEnd::ProjectPartContainers( + ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts( const ClangBackEnd::ProjectPartContainers &projectsParts)); MOCK_METHOD1(remove, void(const ClangBackEnd::ProjectPartIds &projectPartIds)); MOCK_CONST_METHOD1( @@ -42,7 +42,8 @@ public: MOCK_METHOD1(updateDeferred, void(const ClangBackEnd::ProjectPartContainers &projectsParts)); MOCK_METHOD0(deferredUpdates, ClangBackEnd::ProjectPartContainers()); - ClangBackEnd::ProjectPartContainers update(ClangBackEnd::ProjectPartContainers &&projectsParts) override + ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts update( + ClangBackEnd::ProjectPartContainers &&projectsParts) override { return update(projectsParts); } diff --git a/tests/unit/unittest/mockprojectpartsstorage.h b/tests/unit/unittest/mockprojectpartsstorage.h index 114a7fab0e..e8dcbc94b2 100644 --- a/tests/unit/unittest/mockprojectpartsstorage.h +++ b/tests/unit/unittest/mockprojectpartsstorage.h @@ -56,5 +56,7 @@ public: MOCK_CONST_METHOD1(fetchProjectPartArtefact, Utils::optional<ClangBackEnd::ProjectPartArtefact>( ClangBackEnd::ProjectPartId projectPartId)); + MOCK_METHOD1(resetIndexingTimeStamps, + void(const ClangBackEnd::ProjectPartContainers &projectsParts)); MOCK_METHOD0(transactionBackend, Sqlite::TransactionInterface &()); }; diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h index 5bef2ba8c5..05f6f4e958 100644 --- a/tests/unit/unittest/mocksqlitedatabase.h +++ b/tests/unit/unittest/mocksqlitedatabase.h @@ -31,12 +31,13 @@ #include "mocksqlitetransactionbackend.h" #include "mocksqlitewritestatement.h" +#include <sqlitedatabaseinterface.h> #include <sqlitetable.h> #include <sqlitetransaction.h> #include <utils/smallstringview.h> -class MockSqliteDatabase : public MockSqliteTransactionBackend +class MockSqliteDatabase : public MockSqliteTransactionBackend, public Sqlite::DatabaseInterface { public: using ReadStatement = NiceMock<MockSqliteReadStatement>; @@ -56,5 +57,7 @@ public: MOCK_METHOD1(setIsInitialized, void (bool)); + + MOCK_METHOD0(walCheckpointFull, void()); }; diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp index c12d40b9ea..b0df1ab75d 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.cpp +++ b/tests/unit/unittest/mocksqlitereadstatement.cpp @@ -200,9 +200,15 @@ MockSqliteReadStatement::value<ClangBackEnd::ProjectPartPch, 3>(const int &proje return valueReturnProjectPartPch(projectPartId); } -template <> -Utils::optional<Utils::SmallString> -MockSqliteReadStatement::value<Utils::SmallString>(const int &sourceId) +template<> +Utils::optional<ClangBackEnd::PchPaths> MockSqliteReadStatement::value<ClangBackEnd::PchPaths, 2>( + const int &projectPartId) +{ + return valueReturnPchPaths(projectPartId); +} + +template<> +Utils::optional<Utils::SmallString> MockSqliteReadStatement::value<Utils::SmallString>(const int &sourceId) { return valueReturnSmallString(sourceId); } @@ -222,6 +228,19 @@ SourceEntries MockSqliteReadStatement::values<SourceEntry, 4>(std::size_t reserv return valuesReturnSourceEntries(reserveSize, filePathId, projectPartId); } +template<> +SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t reserveSize) +{ + return valuesReturnSourceTimeStamps(reserveSize); +} + +template<> +SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t reserveSize, + const int &sourcePathId) +{ + return valuesReturnSourceTimeStamps(reserveSize, sourcePathId); +} + template <> Utils::optional<Sources::SourceNameAndDirectoryId> MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int &id) diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h index e3ab740b6e..d952c90dec 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.h +++ b/tests/unit/unittest/mocksqlitereadstatement.h @@ -30,6 +30,7 @@ #include <sourcelocations.h> #include <filepathstoragesources.h> +#include <pchpaths.h> #include <projectpartartefact.h> #include <projectpartcontainer.h> #include <projectpartpch.h> @@ -50,6 +51,8 @@ using ClangBackEnd::FilePathIds; using ClangBackEnd::SourceEntries; using ClangBackEnd::SourceEntry; +using ClangBackEnd::SourceTimeStamp; +using ClangBackEnd::SourceTimeStamps; using ClangRefactoring::SourceLocation; using ClangRefactoring::SourceLocations; using std::int64_t; @@ -118,11 +121,11 @@ public: MOCK_METHOD1(valueReturnProjectPartContainer, Utils::optional<ClangBackEnd::ProjectPartContainer>(int)); MOCK_METHOD1(valuesReturnProjectPartContainers, ClangBackEnd::ProjectPartContainers(std::size_t)); - MOCK_METHOD1(valueReturnProjectPartPch, - Utils::optional<ClangBackEnd::ProjectPartPch>(int)); + MOCK_METHOD1(valueReturnProjectPartPch, Utils::optional<ClangBackEnd::ProjectPartPch>(int)); - MOCK_METHOD3(valuesReturnSymbols, - Symbols(std::size_t, int, Utils::SmallStringView)); + MOCK_METHOD1(valueReturnPchPaths, Utils::optional<ClangBackEnd::PchPaths>(int)); + + MOCK_METHOD3(valuesReturnSymbols, Symbols(std::size_t, int, Utils::SmallStringView)); MOCK_METHOD4(valuesReturnSymbols, Symbols(std::size_t, int, int, Utils::SmallStringView)); @@ -136,6 +139,9 @@ public: MOCK_METHOD1(valueReturnProjectPartId, Utils::optional<ClangBackEnd::ProjectPartId>(Utils::SmallStringView)); + MOCK_METHOD1(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t)); + MOCK_METHOD2(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t, int sourcePathId)); + template <typename ResultType, int ResultTypeCount = 1, typename... QueryType> @@ -263,6 +269,10 @@ Utils::optional<ClangBackEnd::ProjectPartContainer> MockSqliteReadStatement::value<ClangBackEnd::ProjectPartContainer, 8>(const int &); template<> +Utils::optional<ClangBackEnd::PchPaths> MockSqliteReadStatement::value<ClangBackEnd::PchPaths, 2>( + const int &); + +template<> ClangBackEnd::ProjectPartContainers MockSqliteReadStatement::values<ClangBackEnd::ProjectPartContainer, 8>(std::size_t reserveSize); @@ -283,6 +293,13 @@ SourceEntries MockSqliteReadStatement::values<SourceEntry, 4>(std::size_t reserv const int &, const int &); +template<> +SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t reserveSize); + +template<> +SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t reserveSize, + const int &sourcePathId); + template <> Utils::optional<Sources::SourceNameAndDirectoryId> MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int&); diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h index a174389735..7b77868e8a 100644 --- a/tests/unit/unittest/mocksymbolstorage.h +++ b/tests/unit/unittest/mocksymbolstorage.h @@ -37,4 +37,11 @@ public: MOCK_METHOD2(addSymbolsAndSourceLocations, void(const ClangBackEnd::SymbolEntries &symbolEentries, const ClangBackEnd::SourceLocationEntries &sourceLocations)); + MOCK_METHOD2(insertOrUpdateIndexingTimeStamps, + void(const FilePathIds &filePathIds, ClangBackEnd::TimeStamp indexingTimeStamp)); + MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &)); + MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps()); + MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps, + ClangBackEnd::SourceTimeStamps(ClangBackEnd::FilePathId sourcePathId)); + MOCK_CONST_METHOD1(fetchDependentSourceIds, FilePathIds(const FilePathIds &sourcePathIds)); }; diff --git a/tests/unit/unittest/modifiedtimechecker-test.cpp b/tests/unit/unittest/modifiedtimechecker-test.cpp index 8e0c881b38..ff0c3c66d8 100644 --- a/tests/unit/unittest/modifiedtimechecker-test.cpp +++ b/tests/unit/unittest/modifiedtimechecker-test.cpp @@ -57,7 +57,7 @@ protected: ClangBackEnd::FilePathCaching filePathCache{database}; decltype(getModifiedTimeCallback.AsStdFunction()) callback = getModifiedTimeCallback .AsStdFunction(); - ClangBackEnd::ModifiedTimeChecker checker{callback, filePathCache}; + ClangBackEnd::ModifiedTimeChecker<> checker{callback, filePathCache}; SourceEntries upToDateEntries = {{id("/path1"), SourceType::UserInclude, 100}, {id("/path2"), SourceType::SystemInclude, 30}}; SourceEntries notUpToDateEntries = {{id("/path1"), SourceType::UserInclude, 50}, diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index b057795a3a..0cf84a983d 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -27,6 +27,7 @@ #include "fakeprocess.h" #include "filesystem-utilities.h" +#include "testenvironment.h" #include "mockbuilddependenciesstorage.h" #include "mockclangpathwatcher.h" @@ -79,7 +80,11 @@ MATCHER_P2(HasIdAndType, class PchCreator: public ::testing::Test { protected: - PchCreator() { creator.setUnsavedFiles({generatedFile}); } + PchCreator() + { + creator.setUnsavedFiles({generatedFile}); + pchTask1.preIncludeSearchPath = testEnvironment.preIncludeSearchPath(); + } ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path) { @@ -121,6 +126,7 @@ protected: {TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}}, {{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}}, }; + TestEnvironment testEnvironment; }; using PchCreatorSlowTest = PchCreator; using PchCreatorVerySlowTest = PchCreator; @@ -148,6 +154,8 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArguments) "-std=c++98", "-nostdinc", "-nostdinc++", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath(TESTDATA_DIR "/builddependencycollector/project"), "-isystem", @@ -173,6 +181,8 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch) "-std=c++98", "-nostdinc", "-nostdinc++", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath(TESTDATA_DIR "/builddependencycollector/project"), "-isystem", @@ -193,8 +203,8 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient) EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated( - Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartPchs, - ElementsAre(Eq(creator.projectPartPch()))))); + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(creator.projectPartPch().projectPartId))))); creator.doInMainThreadAfterFinished(); } @@ -239,6 +249,15 @@ TEST_F(PchCreatorVerySlowTest, PchCreationTimeStampsAreUpdated) creator.doInMainThreadAfterFinished(); } +TEST_F(PchCreator, DoNothingInTheMainThreadIfGenerateWasNotCalled) +{ + EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(_, _)).Times(0); + EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0); + EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(_)).Times(0); + + creator.doInMainThreadAfterFinished(); +} + TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask) { creator.generatePch(std::move(pchTask1)); @@ -296,6 +315,36 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask Field(&ProjectPartPch::lastModified, Gt(0)))); } +TEST_F(PchCreatorSlowTest, NoIncludes) +{ + pchTask1.includes = {}; + + creator.generatePch(std::move(pchTask1)); + + ASSERT_THAT(creator.projectPartPch(), + AllOf(Field(&ProjectPartPch::projectPartId, Eq(pchTask1.projectPartId())), + Field(&ProjectPartPch::pchPath, IsEmpty()), + Field(&ProjectPartPch::lastModified, Gt(0)))); +} + +TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls) +{ + pchTask1.includes = {}; + creator.generatePch(std::move(pchTask1)); + + EXPECT_CALL(mockPchManagerClient, + precompiledHeadersUpdated( + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(creator.projectPartPch().projectPartId))))); + EXPECT_CALL(mockClangPathWatcher, + updateIdPaths( + ElementsAre(AllOf(Field(&ClangBackEnd::IdPaths::id, 1), + Field(&ClangBackEnd::IdPaths::filePathIds, IsEmpty()))))); + EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1))); + + creator.doInMainThreadAfterFinished(); +} + TEST_F(PchCreatorVerySlowTest, GeneratedFile) { creator.clear(); diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp index 6c74143e4d..18a61d7038 100644 --- a/tests/unit/unittest/pchmanagerclient-test.cpp +++ b/tests/unit/unittest/pchmanagerclient-test.cpp @@ -65,11 +65,9 @@ protected: filePathCache, mockProjectPartsStorage}; ClangBackEnd::ProjectPartId projectPartId{1}; - ClangBackEnd::FilePath pchFilePath{"/path/to/pch"}; - PrecompiledHeadersUpdatedMessage message{{{projectPartId, pchFilePath.clone(), 1}}}; + PrecompiledHeadersUpdatedMessage message{{projectPartId}}; ClangBackEnd::ProjectPartId projectPartId2{2}; - ClangBackEnd::FilePath pchFilePath2{"/path/to/pch2"}; - PrecompiledHeadersUpdatedMessage message2{{{projectPartId2, pchFilePath2.clone(), 1}}}; + PrecompiledHeadersUpdatedMessage message2{{projectPartId2}}; }; TEST_F(PchManagerClient, NotifierAttached) @@ -93,8 +91,7 @@ TEST_F(PchManagerClient, NotifierDetached) TEST_F(PchManagerClient, Update) { - EXPECT_CALL(mockPchManagerNotifier, - precompiledHeaderUpdated(projectPartId, pchFilePath.toQString(), Eq(1))); + EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId)); client.precompiledHeadersUpdated(message.clone()); } @@ -106,58 +103,6 @@ TEST_F(PchManagerClient, Remove) projectUpdater.removeProjectParts({projectPartId, projectPartId}); } -TEST_F(PchManagerClient, GetNoProjectPartPchForWrongProjectPartId) -{ - auto optional = client.projectPartPch(23); - - ASSERT_FALSE(optional); -} - -TEST_F(PchManagerClient, GetProjectPartPchForProjectPartId) -{ - client.precompiledHeadersUpdated(std::move(message)); - - auto optional = client.projectPartPch(projectPartId); - - ASSERT_TRUE(optional); -} - -TEST_F(PchManagerClient, ProjectPartPchRemoved) -{ - client.precompiledHeadersUpdated(std::move(message)); - - client.precompiledHeaderRemoved(projectPartId); - - ASSERT_FALSE(client.projectPartPch(projectPartId)); -} - -TEST_F(PchManagerClient, ProjectPartPchHasNoDublicateEntries) -{ - client.precompiledHeadersUpdated(message.clone()); - client.precompiledHeadersUpdated(message2.clone()); - - client.precompiledHeadersUpdated(message.clone()); - - ASSERT_THAT(client.projectPartPchs(), SizeIs(2)); -} - -TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdLastModified) -{ - client.precompiledHeadersUpdated(std::move(message)); - - ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 1); -} - -TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated) -{ - client.precompiledHeadersUpdated(message.clone()); - PrecompiledHeadersUpdatedMessage updateMessage{{{projectPartId, pchFilePath.clone(), 42}}}; - - client.precompiledHeadersUpdated(updateMessage.clone()); - - ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 42); -} - TEST_F(PchManagerClient, SetPchCreationProgress) { EXPECT_CALL(mockPchCreationProgressManager, setProgress(10, 20)); diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp index e55b71f860..194f52afd3 100644 --- a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp +++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp @@ -148,7 +148,7 @@ TEST_F(PchManagerClientServerInProcess, SendRemoveGeneratedFilesMessage) TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage) { - PrecompiledHeadersUpdatedMessage message{{{1, "/path/to/pch", 1}}}; + PrecompiledHeadersUpdatedMessage message{1}; EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(message)); diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 502b51bc8c..47b7d987ab 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -48,6 +48,7 @@ using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::FileContainers; using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainers; +using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts; class PchManagerServer : public ::testing::Test { @@ -55,7 +56,8 @@ class PchManagerServer : public ::testing::Test { server.setClient(&mockPchManagerClient); - ON_CALL(mockProjectPartsManager, update(projectParts)).WillByDefault(Return(projectParts)); + ON_CALL(mockProjectPartsManager, update(projectParts)) + .WillByDefault(Return(UpToDataProjectParts{{}, projectParts})); ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(true)); } @@ -107,7 +109,8 @@ protected: Utils::LanguageVersion::C11, Utils::LanguageExtension::All}; std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2}; - std::vector<ProjectPartContainer> projectParts2{projectPart2}; + std::vector<ProjectPartContainer> projectParts1{projectPart1}; + std::vector<ProjectPartContainer> projectParts2{projectPart2}; FileContainer generatedFile{{"/path/to/", "file"}, "content", {}}; ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{ Utils::clone(projectParts), {"toolChainArgument"}}; @@ -120,7 +123,7 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts)) - .WillOnce(Return(projectParts2)); + .WillOnce(Return(UpToDataProjectParts{{}, projectParts2})); EXPECT_CALL( mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument"))); @@ -219,7 +222,7 @@ TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1))) - .WillOnce(Return(ProjectPartContainers{projectPart1})); + .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}})); EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false)); EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0); EXPECT_CALL(mockProjectPartsManager, updateDeferred(ElementsAre(projectPart1))); @@ -233,7 +236,7 @@ TEST_F(PchManagerServer, GeneratePchIfGeneratedFilesAreValid) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1))) - .WillOnce(Return(ProjectPartContainers{projectPart1})); + .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}})); EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true)); EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)); EXPECT_CALL(mockProjectPartsManager, updateDeferred(_)).Times(0); @@ -276,4 +279,19 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreStillInvalidSoNoPchsGener server.updateGeneratedFiles(updateGeneratedFilesMessage.clone()); } +TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts)) + .WillOnce(Return(UpToDataProjectParts{projectParts1, projectParts2})); + EXPECT_CALL(mockPchTaskGenerator, + addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument"))); + EXPECT_CALL(mockPchManagerClient, + precompiledHeadersUpdated( + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(projectPart1.projectPartId))))); + + server.updateProjectParts(updateProjectPartsMessage.clone()); } +} // namespace diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp index 3e0bba1bc8..1754cea562 100644 --- a/tests/unit/unittest/pchtaskqueue-test.cpp +++ b/tests/unit/unittest/pchtaskqueue-test.cpp @@ -29,6 +29,7 @@ #include "mockprecompiledheaderstorage.h" #include "mocksqlitetransactionbackend.h" #include "mocktaskscheduler.h" +#include "testenvironment.h" #include <pchtaskqueue.h> #include <progresscounter.h> @@ -50,11 +51,13 @@ protected: MockSqliteTransactionBackend mockSqliteTransactionBackend; NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback; ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()}; + TestEnvironment testEnvironment; ClangBackEnd::PchTaskQueue queue{mockSytemPchTaskScheduler, mockProjectPchTaskScheduler, progressCounter, mockPrecompiledHeaderStorage, - mockSqliteTransactionBackend}; + mockSqliteTransactionBackend, + testEnvironment}; IncludeSearchPaths systemIncludeSearchPaths{ {"/includes", 1, IncludeSearchPathType::BuiltIn}, {"/other/includes", 2, IncludeSearchPathType::System}}; @@ -297,6 +300,7 @@ TEST_F(PchTaskQueue, CreateProjectTaskFromPchTask) auto tasks = queue.createProjectTasks({projectTask1}); auto projectTask = projectTask1; projectTask.systemPchPath = "/path/to/pch"; + projectTask.preIncludeSearchPath = testEnvironment.preIncludeSearchPath(); EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq(1))) .WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"})); @@ -316,6 +320,7 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated) auto tasks = queue.createProjectTasks({projectTask1}); auto projectTask = projectTask1; projectTask.systemPchPath = "/path/to/pch"; + projectTask.preIncludeSearchPath = testEnvironment.preIncludeSearchPath(); EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq(1))) .WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"})); @@ -339,8 +344,10 @@ TEST_F(PchTaskQueue, CreateSystemTaskFromPchTask) MockPchCreator mockPchCreator; ClangBackEnd::ProjectPartPch projectPartPch{{}, "/path/to/pch", 99}; auto tasks = queue.createSystemTasks({systemTask4}); + auto systemTask = systemTask4; + systemTask.preIncludeSearchPath = testEnvironment.preIncludeSearchPath(); - EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4))); + EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask))); EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch)); EXPECT_CALL(mockPrecompiledHeaderStorage, insertSystemPrecompiledHeaders(UnorderedElementsAre(1, 3), Eq("/path/to/pch"), 99)); @@ -354,12 +361,15 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated) MockPchCreator mockPchCreator; ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0}; auto tasks = queue.createSystemTasks({systemTask4}); + auto systemTask = systemTask4; + systemTask.preIncludeSearchPath = testEnvironment.preIncludeSearchPath(); - EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4))); + EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask))); EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch)); EXPECT_CALL(mockPrecompiledHeaderStorage, deleteSystemPrecompiledHeaders(UnorderedElementsAre(1, 3))); tasks.front()(mockPchCreator); } + } // namespace diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp index 13fca71fdc..9fb161d0eb 100644 --- a/tests/unit/unittest/precompiledheaderstorage-test.cpp +++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp @@ -47,7 +47,8 @@ protected: MockSqliteWriteStatement &insertSystemPrecompiledHeaderStatement = storage.insertSystemPrecompiledHeaderStatement; MockSqliteWriteStatement &deleteSystemPrecompiledHeaderStatement = storage.deleteSystemPrecompiledHeaderStatement; MockSqliteReadStatement &fetchSystemPrecompiledHeaderPathStatement = storage.fetchSystemPrecompiledHeaderPathStatement; - MockSqliteReadStatement &getPrecompiledHeader = storage.getPrecompiledHeader; + MockSqliteReadStatement &fetchPrecompiledHeaderStatement = storage.fetchPrecompiledHeaderStatement; + MockSqliteReadStatement &fetchPrecompiledHeadersStatement = storage.fetchPrecompiledHeadersStatement; }; TEST_F(PrecompiledHeaderStorage, UseTransaction) @@ -112,6 +113,31 @@ TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaderStatementIsBusy) storage.deleteProjectPrecompiledHeader(1); } +TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaders) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(1))); + EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(2))); + EXPECT_CALL(database, commit()); + + storage.deleteProjectPrecompiledHeaders({1, 2}); +} + +TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeadersStatementIsBusy) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(1))); + EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(2))); + EXPECT_CALL(database, commit()); + + storage.deleteProjectPrecompiledHeaders({1, 2}); +} + TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaders) { InSequence s; @@ -225,18 +251,88 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsNullOptional TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCallsValueInStatement) { - EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))); + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeaderStatement, valueReturnFilePath(Eq(25))); + EXPECT_CALL(database, commit()); + + storage.fetchPrecompiledHeader(25); +} + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderIsBusy) +{ + InSequence s; + + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeaderStatement, valueReturnFilePath(Eq(25))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(database, rollback()); + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeaderStatement, valueReturnFilePath(Eq(25))); + EXPECT_CALL(database, commit()); storage.fetchPrecompiledHeader(25); } TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeader) { - ClangBackEnd::ProjectPartPch pch{{}, "/path/to/pch", 131}; - EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))).WillRepeatedly(Return(pch)); + ClangBackEnd::FilePath pchFilePath{"/path/to/pch"}; + ON_CALL(fetchPrecompiledHeaderStatement, valueReturnFilePath(Eq(25))) + .WillByDefault(Return(pchFilePath)); + + auto path = storage.fetchPrecompiledHeader(25); + + ASSERT_THAT(path, Eq(pchFilePath)); +} + +TEST_F(PrecompiledHeaderStorage, FetchEmptyPrecompiledHeader) +{ + auto path = storage.fetchPrecompiledHeader(25); + + ASSERT_THAT(path, IsEmpty()); +} + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCalls) +{ + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeadersStatement, valueReturnPchPaths(Eq(25))); + EXPECT_CALL(database, commit()); + + storage.fetchPrecompiledHeaders(25); +} + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeadersIsBusy) +{ + InSequence s; - auto precompiledHeader = storage.fetchPrecompiledHeader(25); + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeadersStatement, valueReturnPchPaths(Eq(25))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(database, rollback()); + EXPECT_CALL(database, deferredBegin()); + EXPECT_CALL(fetchPrecompiledHeadersStatement, valueReturnPchPaths(Eq(25))); + EXPECT_CALL(database, commit()); - ASSERT_THAT(precompiledHeader.value(), Eq(pch)); + storage.fetchPrecompiledHeaders(25); } + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaders) +{ + ClangBackEnd::PchPaths pchFilePaths{"/project/pch", "/system/pch"}; + ON_CALL(fetchPrecompiledHeadersStatement, valueReturnPchPaths(Eq(25))) + .WillByDefault(Return(pchFilePaths)); + + auto paths = storage.fetchPrecompiledHeaders(25); + + ASSERT_THAT(paths, Eq(pchFilePaths)); } + +TEST_F(PrecompiledHeaderStorage, FetchEmptyPrecompiledHeaders) +{ + auto paths = storage.fetchPrecompiledHeaders(25); + + ASSERT_THAT(paths, + AllOf(Field(&ClangBackEnd::PchPaths::projectPchPath, IsEmpty()), + Field(&ClangBackEnd::PchPaths::systemPchPath, IsEmpty()))); +} + +} // namespace diff --git a/tests/unit/unittest/projectpartsmanager-test.cpp b/tests/unit/unittest/projectpartsmanager-test.cpp index b2b2fbc263..d86543e9c2 100644 --- a/tests/unit/unittest/projectpartsmanager-test.cpp +++ b/tests/unit/unittest/projectpartsmanager-test.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "googletest.h" +#include "mockprecompiledheaderstorage.h" #include "mockprojectpartsstorage.h" #include <projectpartsmanager.h> @@ -35,12 +36,19 @@ namespace { using ClangBackEnd::FilePathId; using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainers; +using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts; class ProjectPartsManager : public testing::Test { protected: + ProjectPartsManager() + { + projectPartContainerWithoutPrecompiledHeader1.hasPrecompiledHeader = false; + } NiceMock<MockProjectPartsStorage> mockProjectPartsStorage; - ClangBackEnd::ProjectPartsManager manager{mockProjectPartsStorage}; + NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage; + + ClangBackEnd::ProjectPartsManager manager{mockProjectPartsStorage, mockPrecompiledHeaderStorage}; FilePathId firstHeader{1}; FilePathId secondHeader{2}; FilePathId firstSource{11}; @@ -68,6 +76,27 @@ protected: Utils::Language::C, Utils::LanguageVersion::C11, Utils::LanguageExtension::All}; + ProjectPartContainer nullProjectPartContainer1{1, + {}, + {}, + {}, + {}, + {}, + {}, + Utils::Language::C, + Utils::LanguageVersion::C89, + Utils::LanguageExtension::None}; + ProjectPartContainer projectPartContainerWithoutPrecompiledHeader1{ + 1, + {"-DUNIX", "-O2"}, + {{"DEFINE", "1", 1}}, + {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}}, + {firstHeader, secondHeader}, + {firstSource, secondSource}, + Utils::Language::C, + Utils::LanguageVersion::C11, + Utils::LanguageExtension::All}; ProjectPartContainer projectPartContainer2{ 2, {"-DUNIX", "-O2"}, @@ -83,16 +112,20 @@ protected: TEST_F(ProjectPartsManager, GetNoProjectPartsForAddingEmptyProjectParts) { - auto updatedProjectParts = manager.update({}); + auto projectParts = manager.update({}); - ASSERT_THAT(updatedProjectParts, IsEmpty()); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, IsEmpty()))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPart) { - auto updatedProjectParts = manager.update({projectPartContainer1}); + auto projectParts = manager.update({projectPartContainer1}); - ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1)))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlreadyInTheDatabase) @@ -100,9 +133,11 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlr ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) .WillByDefault(Return(ProjectPartContainers{projectPartContainer1})); - auto updatedProjectParts = manager.update({projectPartContainer1, projectPartContainer2}); + auto projectParts = manager.update({projectPartContainer1, projectPartContainer2}); - ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer2)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer2)))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPartAlreadyInTheDatabase) @@ -110,9 +145,12 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPa ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) .WillByDefault(Return(ProjectPartContainers{projectPartContainer1})); - auto updatedProjectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2}); + auto projectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2}); - ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1, projectPartContainer2)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, + ElementsAre(updatedProjectPartContainer1, projectPartContainer2)))); } TEST_F(ProjectPartsManager, ProjectPartAdded) @@ -156,9 +194,11 @@ TEST_F(ProjectPartsManager, DoNotUpdateNotNewProjectPart) { manager.update({projectPartContainer1}); - auto updatedProjectParts = manager.update({projectPartContainer1}); + auto projectParts = manager.update({projectPartContainer1}); - ASSERT_THAT(updatedProjectParts, IsEmpty()); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)), + Field(&UpToDataProjectParts::notUpToDate, IsEmpty()))); } TEST_F(ProjectPartsManager, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart) @@ -188,8 +228,8 @@ TEST_F(ProjectPartsManager, MergeProjectMultipleTimesParts) TEST_F(ProjectPartsManager, GetNewProjectParts) { - auto newProjectParts = manager.filterNewProjectParts({projectPartContainer1, projectPartContainer2}, - {projectPartContainer2}); + auto newProjectParts = manager.filterProjectParts({projectPartContainer1, projectPartContainer2}, + {projectPartContainer2}); ASSERT_THAT(newProjectParts, ElementsAre(projectPartContainer1)); } @@ -198,9 +238,12 @@ TEST_F(ProjectPartsManager, GetUpdatedProjectPart) { manager.update({projectPartContainer1, projectPartContainer2}); - auto updatedProjectParts = manager.update({updatedProjectPartContainer1}); + auto projectParts = manager.update({updatedProjectPartContainer1}); - ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, + ElementsAre(updatedProjectPartContainer1)))); } TEST_F(ProjectPartsManager, ProjectPartIsReplacedWithUpdatedProjectPart) @@ -252,14 +295,14 @@ TEST_F(ProjectPartsManager, UpdateDeferred) TEST_F(ProjectPartsManager, NotUpdateDeferred) { - auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2}); + manager.update({projectPartContainer1, projectPartContainer2}); ASSERT_THAT(manager.deferredUpdates(), IsEmpty()); } TEST_F(ProjectPartsManager, UpdateDeferredCleansDeferredUpdates) { - auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2}); + manager.update({projectPartContainer1, projectPartContainer2}); manager.updateDeferred({projectPartContainer1}); manager.deferredUpdates(); @@ -272,6 +315,9 @@ TEST_F(ProjectPartsManager, UpdateCallsIfNewProjectPartIsAdded) EXPECT_CALL(mockProjectPartsStorage, fetchProjectParts(ElementsAre(Eq(projectPartContainer1.projectPartId)))); EXPECT_CALL(mockProjectPartsStorage, updateProjectParts(ElementsAre(projectPartContainer1))); + EXPECT_CALL(mockPrecompiledHeaderStorage, + deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId))); + EXPECT_CALL(mockProjectPartsStorage, resetIndexingTimeStamps(ElementsAre(projectPartContainer1))); manager.update({projectPartContainer1}); } @@ -296,12 +342,38 @@ TEST_F(ProjectPartsManager, UpdateCallsNotFetchProjectPartsInStorageIfNoNewerPro manager.update({projectPartContainer1}); } +TEST_F(ProjectPartsManager, UpdateCallsNotDeleteProjectPrecompiledHeadersIfNoNewerProjectPartsExists) +{ + manager.update({projectPartContainer1}); + + EXPECT_CALL(mockPrecompiledHeaderStorage, + deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId))) + .Times(0); + + manager.update({projectPartContainer1}); +} + +TEST_F(ProjectPartsManager, UpdateCallsNotResetIndexingTimeStampsIfNoNewerProjectPartsExists) +{ + manager.update({projectPartContainer1}); + + EXPECT_CALL(mockProjectPartsStorage, resetIndexingTimeStamps(ElementsAre(projectPartContainer1))) + .Times(0); + + manager.update({projectPartContainer1}); +} + TEST_F(ProjectPartsManager, UpdateCallsIfOldProjectPartIsAdded) { EXPECT_CALL(mockProjectPartsStorage, fetchProjectParts(ElementsAre(Eq(projectPartContainer1.projectPartId)))) .WillRepeatedly(Return(ProjectPartContainers{projectPartContainer1})); EXPECT_CALL(mockProjectPartsStorage, updateProjectParts(ElementsAre(projectPartContainer1))).Times(0); + EXPECT_CALL(mockPrecompiledHeaderStorage, + deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId))) + .Times(0); + EXPECT_CALL(mockProjectPartsStorage, resetIndexingTimeStamps(ElementsAre(projectPartContainer1))) + .Times(0); manager.update({projectPartContainer1}); } @@ -315,7 +387,35 @@ TEST_F(ProjectPartsManager, UpdateCallsIfUpdatedProjectPartIsAdded) .WillRepeatedly(Return(ProjectPartContainers{projectPartContainer1})); EXPECT_CALL(mockProjectPartsStorage, updateProjectParts(ElementsAre(updatedProjectPartContainer1))); + EXPECT_CALL(mockPrecompiledHeaderStorage, + deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId))); + EXPECT_CALL(mockProjectPartsStorage, + resetIndexingTimeStamps(ElementsAre(updatedProjectPartContainer1))); manager.update({updatedProjectPartContainer1}); } + +TEST_F(ProjectPartsManager, + GetProjectPartForAddingProjectPartWithProjectPartAlreadyInTheDatabaseButNoPrecompiledHeader) +{ + ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) + .WillByDefault(Return(ProjectPartContainers{projectPartContainerWithoutPrecompiledHeader1})); + + auto projectParts = manager.update({projectPartContainer1}); + + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1)))); +} + +TEST_F(ProjectPartsManager, ProjectPartAddedWithProjectPartAlreadyInTheDatabaseButWithoutEntries) +{ + ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) + .WillByDefault(Return(ProjectPartContainers{nullProjectPartContainer1})); + + manager.update({projectPartContainer1}); + + ASSERT_THAT(manager.projectParts(), ElementsAre(projectPartContainer1)); +} + } // namespace diff --git a/tests/unit/unittest/projectpartsstorage-test.cpp b/tests/unit/unittest/projectpartsstorage-test.cpp index ad78b0b833..3c13f33ad6 100644 --- a/tests/unit/unittest/projectpartsstorage-test.cpp +++ b/tests/unit/unittest/projectpartsstorage-test.cpp @@ -27,12 +27,13 @@ #include "mocksqlitedatabase.h" +#include <builddependenciesstorage.h> #include <projectpartsstorage.h> #include <refactoringdatabaseinitializer.h> #include <sqlitedatabase.h> #include <sqlitereadstatement.h> #include <sqlitewritestatement.h> - +#include <symbolstorage.h> namespace { using ClangBackEnd::FilePathId; @@ -103,6 +104,8 @@ protected: MockSqliteWriteStatement &insertProjectPartsSourcesStatement = storage.insertProjectPartsSourcesStatement; MockSqliteReadStatement &fetchProjectPartsHeadersByIdStatement = storage.fetchProjectPartsHeadersByIdStatement; MockSqliteReadStatement &fetchProjectPartsSourcesByIdStatement = storage.fetchProjectPartsSourcesByIdStatement; + MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderPathStatement; + MockSqliteWriteStatement &resetDependentIndexingTimeStampsStatement = storage.resetDependentIndexingTimeStampsStatement; IncludeSearchPaths systemIncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn}, {"/other/includes", 2, IncludeSearchPathType::System}}; IncludeSearchPaths projectIncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User}, @@ -252,7 +255,13 @@ TEST_F(ProjectPartsStorage, FetchProjectPartsByIds) EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1))); + EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(1))); + EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(1))); + EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1))); EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2))); + EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(2))); + EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(2))); + EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(2))); EXPECT_CALL(mockDatabase, commit()); storage.fetchProjectParts({1, 2}); @@ -275,6 +284,36 @@ TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsIsBusy) storage.fetchProjectParts({1, 2}); } +TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledNullOptional) +{ + ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1))) + .WillByDefault(Return(Utils::optional<Utils::SmallString>{})); + + auto projectParts = storage.fetchProjectParts({1}); + + ASSERT_FALSE(projectParts.front().hasPrecompiledHeader); +} + +TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledEmptyString) +{ + ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1))) + .WillByDefault(Return(Utils::optional<Utils::SmallString>{""})); + + auto projectParts = storage.fetchProjectParts({1}); + + ASSERT_FALSE(projectParts.front().hasPrecompiledHeader); +} + +TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledStringWithContent) +{ + ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1))) + .WillByDefault(Return(Utils::optional<Utils::SmallString>{"/some/path"})); + + auto projectParts = storage.fetchProjectParts({1}); + + ASSERT_TRUE(projectParts.front().hasPrecompiledHeader); +} + TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasMissingId) { auto projectParts = storage.fetchProjectParts({1, 2, 3}); @@ -302,7 +341,7 @@ TEST_F(ProjectPartsStorage, UpdateProjectParts) TypedEq<Utils::SmallStringView>(R"([["FOO","1",1]])"), TypedEq<Utils::SmallStringView>(R"([["/include",1,3]])"), TypedEq<Utils::SmallStringView>(R"([["/home/yi",2,1]])"), - 1, + 2, 35, 2)); EXPECT_CALL(deleteProjectPartsHeadersByIdStatement, write(TypedEq<int>(1))); @@ -317,8 +356,8 @@ TEST_F(ProjectPartsStorage, UpdateProjectParts) TypedEq<Utils::SmallStringView>(R"([["BAR","2",1]])"), TypedEq<Utils::SmallStringView>(R"([["/usr/include",1,3]])"), TypedEq<Utils::SmallStringView>(R"([["/home/er",2,1]])"), - 0, - 2, + 1, + 3, 1)); EXPECT_CALL(deleteProjectPartsHeadersByIdStatement, write(TypedEq<int>(2))); EXPECT_CALL(insertProjectPartsHeadersStatement, write(TypedEq<int>(2), TypedEq<int>(5))); @@ -343,7 +382,7 @@ TEST_F(ProjectPartsStorage, UpdateProjectPartsIsBusy) TypedEq<Utils::SmallStringView>(R"([["FOO","1",1]])"), TypedEq<Utils::SmallStringView>(R"([["/include",1,3]])"), TypedEq<Utils::SmallStringView>(R"([["/home/yi",2,1]])"), - 1, + 2, 35, 2)); EXPECT_CALL(mockDatabase, commit()); @@ -387,6 +426,35 @@ TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdReturnArtefac ASSERT_THAT(result, Eq(artefact)); } +TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStamps) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(3))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(4))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(7))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(8))); + EXPECT_CALL(mockDatabase, commit()); + + storage.resetIndexingTimeStamps({projectPart1, projectPart2}); +} + +TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(3))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(4))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(7))); + EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(8))); + EXPECT_CALL(mockDatabase, commit()); + + storage.resetIndexingTimeStamps({projectPart1, projectPart2}); +} + class ProjectPartsStorageSlow : public testing::Test, public Data { using Storage = ClangBackEnd::ProjectPartsStorage<Sqlite::Database>; @@ -395,6 +463,8 @@ protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; Storage storage{database}; + ClangBackEnd::SymbolStorage<> symbolStorage{database}; + ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database}; }; TEST_F(ProjectPartsStorageSlow, FetchProjectPartName) @@ -432,4 +502,26 @@ TEST_F(ProjectPartsStorageSlow, FetchProjectParts) ASSERT_THAT(projectParts, ElementsAre(projectPart1, projectPart2)); } + +TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps) +{ + symbolStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34); + buildDependenciesStorage.insertOrUpdateSourceDependencies( + {{3, 1}, {4, 1}, {1, 2}, {7, 5}, {8, 6}, {6, 5}, {9, 10}}); + + storage.resetIndexingTimeStamps({projectPart1, projectPart2}); + + ASSERT_THAT(symbolStorage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 0}, + SourceTimeStamp{2, 0}, + SourceTimeStamp{3, 0}, + SourceTimeStamp{4, 0}, + SourceTimeStamp{5, 0}, + SourceTimeStamp{6, 0}, + SourceTimeStamp{7, 0}, + SourceTimeStamp{8, 0}, + SourceTimeStamp{9, 34}, + SourceTimeStamp{10, 34})); +} + } // namespace diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp index 028a6161c9..ea1c14dc35 100644 --- a/tests/unit/unittest/projectupdater-test.cpp +++ b/tests/unit/unittest/projectupdater-test.cpp @@ -46,9 +46,10 @@ #include <updategeneratedfilesmessage.h> #include <updateprojectpartsmessage.h> -#include <projectexplorer/projectexplorerconstants.h> #include <cpptools/compileroptionsbuilder.h> #include <cpptools/projectpart.h> +#include <projectexplorer/project.h> +#include <projectexplorer/projectexplorerconstants.h> #include <utils/algorithm.h> @@ -85,6 +86,8 @@ protected: void SetUp() override { + project.rootProjectDirectoryPath = Utils::FilePath::fromString("project"); + projectPart.project = &project; projectPart.files.push_back(header1ProjectFile); projectPart.files.push_back(header2ProjectFile); projectPart.files.push_back(source1ProjectFile); @@ -94,6 +97,7 @@ protected: projectPart.projectMacros = {{"FOO", "2"}, {"BAR", "1"}}; projectPartId = projectPartsStorage.fetchProjectPartId(Utils::SmallString{projectPart.id()}); + projectPart2.project = &project; projectPart2.files.push_back(header2ProjectFile); projectPart2.files.push_back(header1ProjectFile); projectPart2.files.push_back(source2ProjectFile); @@ -115,7 +119,8 @@ protected: expectedContainer = {projectPartId, arguments.clone(), Utils::clone(compilerMacros), - {{CLANG_RESOURCE_DIR, 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"project/.pre_includes", 1, ClangBackEnd::IncludeSearchPathType::System}, + {CLANG_RESOURCE_DIR, 2, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, {}, {filePathId(headerPaths[1])}, {filePathIds(sourcePaths)}, @@ -125,7 +130,8 @@ protected: expectedContainer2 = {projectPartId2, arguments2.clone(), Utils::clone(compilerMacros), - {{CLANG_RESOURCE_DIR, 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"project/.pre_includes", 1, ClangBackEnd::IncludeSearchPathType::System}, + {CLANG_RESOURCE_DIR, 2, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, {}, {filePathId(headerPaths[1])}, {filePathIds(sourcePaths)}, @@ -159,6 +165,7 @@ protected: CppTools::ProjectFile cannotBuildSourceProjectFile{QString("/cannot/build"), CppTools::ProjectFile::CXXSource}; CppTools::ProjectFile nonActiveProjectFile{QString("/foo"), CppTools::ProjectFile::CXXSource, false}; + ProjectExplorer::Project project; CppTools::ProjectPart projectPart; CppTools::ProjectPart projectPart2; CppTools::ProjectPart nonBuildingProjectPart; @@ -269,6 +276,7 @@ TEST_F(ProjectUpdater, CallStorageInsideTransaction) { InSequence s; CppTools::ProjectPart projectPart; + projectPart.project = &project; projectPart.displayName = "project"; Utils::SmallString projectPartName = projectPart.id(); MockSqliteTransactionBackend mockSqliteTransactionBackend; @@ -302,9 +310,18 @@ TEST_F(ProjectUpdater, CreateSortedCompilerMacros) CompilerMacro{"DEFINE", "1", 3})); } +TEST_F(ProjectUpdater, FilterCompilerMacros) +{ + auto paths = updater.createCompilerMacros( + {{"DEFINE", "1"}, {"QT_TESTCASE_BUILDDIR", "2"}, {"BAR", "1"}}); + + ASSERT_THAT(paths, ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"DEFINE", "1", 3})); +} + TEST_F(ProjectUpdater, CreateSortedIncludeSearchPaths) { CppTools::ProjectPart projectPart; + projectPart.project = &project; ProjectExplorer::HeaderPath includePath{"/to/path1", ProjectExplorer::HeaderPathType::User}; ProjectExplorer::HeaderPath includePath2{"/to/path2", ProjectExplorer::HeaderPathType::User}; ProjectExplorer::HeaderPath invalidPath; @@ -317,13 +334,15 @@ TEST_F(ProjectUpdater, CreateSortedIncludeSearchPaths) auto paths = updater.createIncludeSearchPaths(projectPart); - ASSERT_THAT(paths.system, - ElementsAre(Eq(IncludeSearchPath{systemPath.path, 1, IncludeSearchPathType::System}), - Eq(IncludeSearchPath{builtInPath.path, 4, IncludeSearchPathType::BuiltIn}), - Eq(IncludeSearchPath{frameworkPath.path, 2, IncludeSearchPathType::Framework}), - Eq(IncludeSearchPath{CLANG_RESOURCE_DIR, - 3, - ClangBackEnd::IncludeSearchPathType::BuiltIn}))); + ASSERT_THAT( + paths.system, + ElementsAre(Eq(IncludeSearchPath{systemPath.path, 2, IncludeSearchPathType::System}), + Eq(IncludeSearchPath{builtInPath.path, 5, IncludeSearchPathType::BuiltIn}), + Eq(IncludeSearchPath{frameworkPath.path, 3, IncludeSearchPathType::Framework}), + Eq(IncludeSearchPath{"project/.pre_includes", 1, IncludeSearchPathType::System}), + Eq(IncludeSearchPath{CLANG_RESOURCE_DIR, + 4, + ClangBackEnd::IncludeSearchPathType::BuiltIn}))); ASSERT_THAT(paths.project, ElementsAre(Eq(IncludeSearchPath{includePath.path, 2, IncludeSearchPathType::User}), Eq(IncludeSearchPath{includePath2.path, 1, IncludeSearchPathType::User}))); @@ -339,7 +358,10 @@ TEST_F(ProjectUpdater, ToolChainArguments) auto arguments = updater.toolChainArguments(&projectPart); ASSERT_THAT(arguments, - ElementsAre("-m32", "-fPIC", "--target=target", "extraflags", "-include", "config.h")); + ElementsAre(QString{"-m32"}, + QString{"extraflags"}, + QString{"-include"}, + QString{"config.h"})); } TEST_F(ProjectUpdater, ToolChainArgumentsMSVC) @@ -352,61 +374,61 @@ TEST_F(ProjectUpdater, ToolChainArgumentsMSVC) auto arguments = updater.toolChainArguments(&projectPart); ASSERT_THAT(arguments, - ElementsAre("-m32", - "--target=target", - "extraflags", - "-U__clang__", - "-U__clang_major__", - "-U__clang_minor__", - "-U__clang_patchlevel__", - "-U__clang_version__", - "-U__cpp_aggregate_bases", - "-U__cpp_aggregate_nsdmi", - "-U__cpp_alias_templates", - "-U__cpp_aligned_new", - "-U__cpp_attributes", - "-U__cpp_binary_literals", - "-U__cpp_capture_star_this", - "-U__cpp_constexpr", - "-U__cpp_decltype", - "-U__cpp_decltype_auto", - "-U__cpp_deduction_guides", - "-U__cpp_delegating_constructors", - "-U__cpp_digit_separators", - "-U__cpp_enumerator_attributes", - "-U__cpp_exceptions", - "-U__cpp_fold_expressions", - "-U__cpp_generic_lambdas", - "-U__cpp_guaranteed_copy_elision", - "-U__cpp_hex_float", - "-U__cpp_if_constexpr", - "-U__cpp_inheriting_constructors", - "-U__cpp_init_captures", - "-U__cpp_initializer_lists", - "-U__cpp_inline_variables", - "-U__cpp_lambdas", - "-U__cpp_namespace_attributes", - "-U__cpp_nested_namespace_definitions", - "-U__cpp_noexcept_function_type", - "-U__cpp_nontype_template_args", - "-U__cpp_nontype_template_parameter_auto", - "-U__cpp_nsdmi", - "-U__cpp_range_based_for", - "-U__cpp_raw_strings", - "-U__cpp_ref_qualifiers", - "-U__cpp_return_type_deduction", - "-U__cpp_rtti", - "-U__cpp_rvalue_references", - "-U__cpp_static_assert", - "-U__cpp_structured_bindings", - "-U__cpp_template_auto", - "-U__cpp_threadsafe_static_init", - "-U__cpp_unicode_characters", - "-U__cpp_unicode_literals", - "-U__cpp_user_defined_literals", - "-U__cpp_variable_templates", - "-U__cpp_variadic_templates", - "-U__cpp_variadic_using")); + ElementsAre(QString{"-m32"}, + QString{"extraflags"}, + QString{"-U__clang__"}, + QString{"-U__clang_major__"}, + QString{"-U__clang_minor__"}, + QString{"-U__clang_patchlevel__"}, + QString{"-U__clang_version__"}, + QString{"-U__cpp_aggregate_bases"}, + QString{"-U__cpp_aggregate_nsdmi"}, + QString{"-U__cpp_alias_templates"}, + QString{"-U__cpp_aligned_new"}, + QString{"-U__cpp_attributes"}, + QString{"-U__cpp_binary_literals"}, + QString{"-U__cpp_capture_star_this"}, + QString{"-U__cpp_constexpr"}, + QString{"-U__cpp_decltype"}, + QString{"-U__cpp_decltype_auto"}, + QString{"-U__cpp_deduction_guides"}, + QString{"-U__cpp_delegating_constructors"}, + QString{"-U__cpp_digit_separators"}, + QString{"-U__cpp_enumerator_attributes"}, + QString{"-U__cpp_exceptions"}, + QString{"-U__cpp_fold_expressions"}, + QString{"-U__cpp_generic_lambdas"}, + QString{"-U__cpp_guaranteed_copy_elision"}, + QString{"-U__cpp_hex_float"}, + QString{"-U__cpp_if_constexpr"}, + QString{"-U__cpp_impl_destroying_delete"}, + QString{"-U__cpp_inheriting_constructors"}, + QString{"-U__cpp_init_captures"}, + QString{"-U__cpp_initializer_lists"}, + QString{"-U__cpp_inline_variables"}, + QString{"-U__cpp_lambdas"}, + QString{"-U__cpp_namespace_attributes"}, + QString{"-U__cpp_nested_namespace_definitions"}, + QString{"-U__cpp_noexcept_function_type"}, + QString{"-U__cpp_nontype_template_args"}, + QString{"-U__cpp_nontype_template_parameter_auto"}, + QString{"-U__cpp_nsdmi"}, + QString{"-U__cpp_range_based_for"}, + QString{"-U__cpp_raw_strings"}, + QString{"-U__cpp_ref_qualifiers"}, + QString{"-U__cpp_return_type_deduction"}, + QString{"-U__cpp_rtti"}, + QString{"-U__cpp_rvalue_references"}, + QString{"-U__cpp_static_assert"}, + QString{"-U__cpp_structured_bindings"}, + QString{"-U__cpp_template_auto"}, + QString{"-U__cpp_threadsafe_static_init"}, + QString{"-U__cpp_unicode_characters"}, + QString{"-U__cpp_unicode_literals"}, + QString{"-U__cpp_user_defined_literals"}, + QString{"-U__cpp_variable_templates"}, + QString{"-U__cpp_variadic_templates"}, + QString{"-U__cpp_variadic_using"})); } TEST_F(ProjectUpdater, FetchProjectPartName) @@ -415,7 +437,7 @@ TEST_F(ProjectUpdater, FetchProjectPartName) auto projectPartName = updater.fetchProjectPartName(1); - ASSERT_THAT(projectPartName, Eq(" projectb")); + ASSERT_THAT(projectPartName, Eq(QString{" projectb"})); } // test for update many time and get the same id diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 37b6e2a744..00a390dd14 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -38,6 +38,7 @@ #include <cpptools/compileroptionsbuilder.h> #include <cpptools/projectpart.h> +#include <projectexplorer/project.h> #include <utils/smallstringvector.h> @@ -63,7 +64,26 @@ using Utils::SmallStringVector; class RefactoringClient : public ::testing::Test { - void SetUp(); + void SetUp() + { + using Filter = ClangRefactoring::ClangQueryProjectsFindFilter; + + client.setRefactoringEngine(&engine); + + projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); + projectPart->project = &project; + projectPart->files.push_back(projectFile); + + commandLine = Filter::compilerArguments(projectPart.data(), projectFile.kind); + + client.setSearchHandle(&mockSearchHandle); + client.setExpectedResultCount(1); + + ON_CALL(mockFilePathCaching, filePath(Eq(FilePathId{1}))) + .WillByDefault(Return(FilePath(PathString("/path/to/file")))); + ON_CALL(mockFilePathCaching, filePath(Eq(FilePathId{42}))) + .WillByDefault(Return(clangBackEndFilePath)); + } protected: NiceMock<MockFilePathCaching> mockFilePathCaching; @@ -81,9 +101,10 @@ protected: QTextDocument textDocument{fileContent}; QTextCursor cursor{&textDocument}; QString qStringFilePath{QStringLiteral("/home/user/file.cpp")}; - Utils::FileName filePath{Utils::FileName::fromString(qStringFilePath)}; + Utils::FilePath filePath{Utils::FilePath::fromString(qStringFilePath)}; ClangBackEnd::FilePath clangBackEndFilePath{qStringFilePath}; SmallStringVector commandLine; + ProjectExplorer::Project project; CppTools::ProjectPart::Ptr projectPart; CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource}; SourceLocationsForRenamingMessage renameMessage{"symbol", @@ -228,25 +249,4 @@ TEST_F(RefactoringClient, SetProgress) client.progress({ClangBackEnd::ProgressType::Indexing, 10, 20}); } - -void RefactoringClient::SetUp() -{ - using Filter = ClangRefactoring::ClangQueryProjectsFindFilter; - - client.setRefactoringEngine(&engine); - - projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); - projectPart->files.push_back(projectFile); - - commandLine = Filter::compilerArguments(projectPart.data(), projectFile.kind); - - client.setSearchHandle(&mockSearchHandle); - client.setExpectedResultCount(1); - - ON_CALL(mockFilePathCaching, filePath(Eq(FilePathId{1}))) - .WillByDefault(Return(FilePath(PathString("/path/to/file")))); - ON_CALL(mockFilePathCaching, filePath(Eq(FilePathId{42}))) - .WillByDefault(Return(clangBackEndFilePath)); -} - } diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp index 4865e2ebff..7177060311 100644 --- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp +++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp @@ -131,7 +131,7 @@ TEST_F(RefactoringDatabaseInitializer, AddFileStatusesTable) mockDatabase, execute(Eq( "CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, " - "lastModified INTEGER)"))); + "lastModified INTEGER, indexingTimeStamp INTEGER)"))); initializer.createFileStatusesTable(); } @@ -140,8 +140,19 @@ TEST_F(RefactoringDatabaseInitializer, AddSourceDependenciesTable) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, " + "dependencySourceId INTEGER)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON " + "sourceDependencies(sourceId, dependencySourceId)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_dependencySourceId_sourceId ON " + "sourceDependencies(dependencySourceId, sourceId)"))); initializer.createSourceDependenciesTable(); } @@ -189,40 +200,88 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor) EXPECT_CALL(mockDatabase, isInitialized()).WillOnce(Return(false)); EXPECT_CALL(mockDatabase, exclusiveBegin()); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT, symbolKind INTEGER, signature TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_symbolKind_symbolName ON symbols(symbolKind, symbolName)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER, locationKind INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON locations(sourceId, locationKind)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, directoryId INTEGER, sourceName TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_sources_directoryId_sourceName ON sources(directoryId, sourceName)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS directories(directoryId INTEGER PRIMARY KEY, directoryPath TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr " + "TEXT, symbolName TEXT, symbolKind INTEGER, signature TEXT)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_symbolKind_symbolName ON " + "symbols(symbolKind, symbolName)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, " + "column INTEGER, sourceId INTEGER, locationKind INTEGER)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_locations_sourceId_line_column " + "ON locations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON " + "locations(sourceId, locationKind)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, " + "directoryId INTEGER, sourceName TEXT)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_sources_directoryId_sourceName " + "ON sources(directoryId, sourceName)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS directories(directoryId INTEGER PRIMARY " + "KEY, directoryPath TEXT)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_directories_directoryPath ON " + "directories(directoryPath)"))); EXPECT_CALL(mockDatabase, execute( Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY " "KEY, projectPartName TEXT, toolChainArguments TEXT, compilerMacros " "TEXT, systemIncludeSearchPaths TEXT, projectIncludeSearchPaths TEXT, " "language INTEGER, languageVersion INTEGER, languageExtension INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName " + "ON projectParts(projectPartName)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsFiles(projectPartId INTEGER, " "sourceId INTEGER, sourceType INTEGER, pchCreationTimeStamp INTEGER, " "hasMissingIncludes INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsFiles_sourceId_projectPartId ON projectPartsFiles(sourceId, projectPartId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId ON projectPartsFiles(projectPartId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, sourceId INTEGER, macroName TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON usedMacros(sourceId, macroName)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsFiles_sourceId_projectPartId " + "ON projectPartsFiles(sourceId, projectPartId)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId ON " + "projectPartsFiles(projectPartId)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, " + "sourceId INTEGER, macroName TEXT)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON " + "usedMacros(sourceId, macroName)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))); EXPECT_CALL( mockDatabase, execute(Eq( "CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, " - "lastModified INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER PRIMARY KEY, projectPchPath TEXT, projectPchBuildTime INTEGER, systemPchPath TEXT, systemPchBuildTime INTEGER)"))); + "lastModified INTEGER, indexingTimeStamp INTEGER)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, " + "dependencySourceId INTEGER)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON " + "sourceDependencies(sourceId, dependencySourceId)"))); + EXPECT_CALL( + mockDatabase, + execute( + Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_dependencySourceId_sourceId ON " + "sourceDependencies(dependencySourceId, sourceId)"))); + EXPECT_CALL(mockDatabase, + execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER " + "PRIMARY KEY, projectPchPath TEXT, projectPchBuildTime INTEGER, " + "systemPchPath TEXT, systemPchBuildTime INTEGER)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsHeaders(projectPartId INTEGER, " "sourceId INTEGER)"))); @@ -271,7 +330,7 @@ TEST_F(RefactoringDatabaseInitializer, DontCreateIfAlreadyInitialized) EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))).Times(0); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, " - "size INTEGER, lastModified INTEGER, isInPrecompiledHeader INTEGER)"))) + "size INTEGER, lastModified INTEGER, indexingTimeStamp INTEGER)"))) .Times(0); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))).Times(0); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))).Times(0); diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 747c930090..3cf5961dd1 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -36,6 +36,7 @@ #include <cpptools/compileroptionsbuilder.h> #include <cpptools/projectpart.h> +#include <projectexplorer/project.h> #include <utils/smallstringvector.h> @@ -56,7 +57,17 @@ using Utils::SmallStringVector; class RefactoringEngine : public ::testing::Test { protected: - void SetUp(); + void SetUp() + { + projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); + projectPart->project = &project; + projectPart->files.push_back(projectFile); + + CompilerOptionsBuilder optionsBuilder(*projectPart); + commandLine = Utils::SmallStringVector( + optionsBuilder.build(projectFile.kind, CppTools::UsePrecompiledHeaders::No)); + commandLine.push_back(qStringFilePath); + } protected: NiceMock<MockFilePathCaching> mockFilePathCaching; @@ -71,9 +82,10 @@ protected: QTextDocument textDocument{fileContent}; QTextCursor cursor{&textDocument}; QString qStringFilePath{QStringLiteral("/home/user/file.cpp")}; - Utils::FileName filePath{Utils::FileName::fromString(qStringFilePath)}; + Utils::FilePath filePath{Utils::FilePath::fromString(qStringFilePath)}; ClangBackEnd::FilePath clangBackEndFilePath{qStringFilePath}; SmallStringVector commandLine; + ProjectExplorer::Project project; CppTools::ProjectPart::Ptr projectPart; CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource}; }; @@ -143,17 +155,5 @@ TEST_F(RefactoringEngine, ServerIsUsableForUsableEngine) ASSERT_TRUE(mockRefactoringServer.isAvailable()); } - -void RefactoringEngine::SetUp() -{ - projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart); - projectPart->files.push_back(projectFile); - - CompilerOptionsBuilder optionsBuilder(*projectPart); - commandLine = Utils::SmallStringVector( - optionsBuilder.build(projectFile.kind, CppTools::UsePrecompiledHeaders::No)); - commandLine.push_back(qStringFilePath); -} - } diff --git a/tests/unit/unittest/refactoringprojectupdater-test.cpp b/tests/unit/unittest/refactoringprojectupdater-test.cpp index 028edc0f7f..6913d1a16f 100644 --- a/tests/unit/unittest/refactoringprojectupdater-test.cpp +++ b/tests/unit/unittest/refactoringprojectupdater-test.cpp @@ -41,6 +41,8 @@ #include <refactoringprojectupdater.h> +#include <projectexplorer/project.h> + #include <memory> namespace { @@ -64,6 +66,7 @@ protected: ProjectPart::Ptr createProjectPart(const char *name) { ProjectPart::Ptr projectPart{new ProjectPart}; + projectPart->project = &project; projectPart->displayName = QString::fromUtf8(name, std::strlen(name)); projectPartId = projectPart->id(); return projectPart; @@ -80,6 +83,7 @@ protected: ClangPchManager::PchManagerClient pchManagerClient{mockPchCreationProgressManager, mockDependencyCreationProgressManager}; MockCppModelManager mockCppModelManager; + ProjectExplorer::Project project; ClangRefactoring::RefactoringProjectUpdater updater{mockRefactoringServer, pchManagerClient, mockCppModelManager, @@ -97,7 +101,7 @@ TEST_F(RefactoringProjectUpdater, DontUpdateProjectPartIfNoProjectPartExistsForI EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString("project1")))); EXPECT_CALL(mockRefactoringServer, updateProjectParts(_)).Times(0); - pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}}); + pchManagerClient.precompiledHeadersUpdated({3}); } TEST_F(RefactoringProjectUpdater, UpdateProjectPart) @@ -114,7 +118,7 @@ TEST_F(RefactoringProjectUpdater, UpdateProjectPart) updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts, ElementsAre(IsProjectPartContainer(3))))); - pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}}); + pchManagerClient.precompiledHeadersUpdated({3}); } TEST_F(RefactoringProjectUpdater, RemoveProjectPart) diff --git a/tests/unit/unittest/skippedsourceranges-test.cpp b/tests/unit/unittest/skippedsourceranges-test.cpp index 083f795ec9..fd95dc4779 100644 --- a/tests/unit/unittest/skippedsourceranges-test.cpp +++ b/tests/unit/unittest/skippedsourceranges-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <cursor.h> #include <clangdocument.h> @@ -89,7 +89,7 @@ struct Data { ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/skippedsourceranges.cpp"); - Utf8StringVector compilationArguments{TestEnvironment::addPlatformArguments( + Utf8StringVector compilationArguments{UnitTest::addPlatformArguments( {Utf8StringLiteral("-std=c++11"), {}, Utf8StringLiteral("-DBLAH")})}; Document document{filePath, compilationArguments, {}, documents}; TranslationUnit translationUnit{filePath, diff --git a/tests/unit/unittest/sourcerange-test.cpp b/tests/unit/unittest/sourcerange-test.cpp index c66b9854db..1b2b44a8f9 100644 --- a/tests/unit/unittest/sourcerange-test.cpp +++ b/tests/unit/unittest/sourcerange-test.cpp @@ -25,7 +25,7 @@ #include "googletest.h" #include "rundocumentparse-utility.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangtranslationunit.h> #include <diagnostic.h> @@ -75,7 +75,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_source_range.cpp")}; Document document{filePath, - {TestEnvironment::addPlatformArguments({Utf8StringLiteral("-pedantic")})}, + {UnitTest::addPlatformArguments({Utf8StringLiteral("-pedantic")})}, {}, documents}; UnitTest::RunDocumentParse _1{document}; diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index edfcb286ad..2db11dc5fb 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -28,11 +28,13 @@ #include "mockbuilddependenciesstorage.h" #include "mockclangpathwatcher.h" #include "mockfilepathcaching.h" +#include "mockmodifiedtimechecker.h" #include "mockprecompiledheaderstorage.h" #include "mockprojectpartsstorage.h" #include "mocksqlitetransactionbackend.h" #include "mocksymbolscollector.h" #include "mocksymbolstorage.h" +#include "testenvironment.h" #include <filepathcaching.h> #include <filestatuscache.h> @@ -113,7 +115,12 @@ protected: .WillByDefault(Return(artefact)); ON_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillByDefault(Return(-1)); ON_CALL(mockCollector, collectSymbols()).WillByDefault(Return(true)); - + ON_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds)) + .WillByDefault(Return(sourceFileIds)); + ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(sourceFileIds[0]))) + .WillByDefault(Return(FilePathIds{sourceFileIds[0]})); + ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(main1PathId))) + .WillByDefault(Return(FilePathIds{main1PathId})); mockCollector.setIsUsed(false); generatedFiles.update(unsaved); @@ -230,8 +237,12 @@ protected: Utils::Language::Cxx, Utils::LanguageVersion::CXX14, Utils::LanguageExtension::None}; + ClangBackEnd::SourceTimeStamps dependentSourceTimeStamps1{{1, 32}}; + ClangBackEnd::SourceTimeStamps dependentSourceTimeStamps2{{2, 35}}; + ClangBackEnd::FileStatuses fileStatuses1{{1, 0, 32}}; + ClangBackEnd::FileStatuses fileStatuses2{{2, 0, 35}}; Utils::optional<ClangBackEnd::ProjectPartArtefact > nullArtefact; - ClangBackEnd::ProjectPartPch projectPartPch{74, "/path/to/pch", 4}; + ClangBackEnd::PchPaths pchPaths{"/project/pch", "/system/pch"}; NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend; NiceMock<MockSymbolStorage> mockSymbolStorage; NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage; @@ -243,6 +254,8 @@ protected: Manager collectorManger{generatedFiles}; NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback; ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()}; + NiceMock<MockSourceTimeStampsModifiedTimeChecker> mockModifiedTimeChecker; + TestEnvironment testEnvironment; ClangBackEnd::SymbolIndexer indexer{indexerQueue, mockSymbolStorage, mockBuildDependenciesStorage, @@ -251,8 +264,11 @@ protected: filePathCache, fileStatusCache, mockSqliteTransactionBackend, - mockProjectPartsStorage}; - SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter}; + mockProjectPartsStorage, + mockModifiedTimeChecker, + testEnvironment}; + NiceMock<MockSqliteDatabase> mockSqliteDatabase; + SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter, mockSqliteDatabase}; Scheduler indexerScheduler{collectorManger, indexerQueue, progressCounter, @@ -278,6 +294,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector) "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -294,8 +312,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector) TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInCollector) { - ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(projectPart1.projectPartId))) - .WillByDefault(Return(projectPartPch)); + ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillByDefault(Return(pchPaths)); EXPECT_CALL(mockCollector, setFile(main1PathId, @@ -310,6 +328,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInColl "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -323,7 +343,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInColl "-Xclang", "-include-pch", "-Xclang", - toNativePath("/path/to/pch")))); + toNativePath("/project/pch")))); indexer.updateProjectParts({projectPart1}); } @@ -346,6 +366,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithoutPrecompiledHeaderInC "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -384,7 +406,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEv TEST_F(SymbolIndexer, UpdateProjectPartsCallscollectSymbolsInCollector) { - EXPECT_CALL(mockCollector, collectSymbols()).Times(2);; + EXPECT_CALL(mockCollector, collectSymbols()).Times(2); indexer.updateProjectParts({projectPart1, projectPart2}); } @@ -421,9 +443,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) { InSequence s; - EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(projectPart1.projectPartId))); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))); EXPECT_CALL(mockCollector, setFile(main1PathId, ElementsAre("clang++", @@ -437,6 +457,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -455,13 +477,258 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) indexer.updateProjectParts({projectPart1}); } -TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingSymbols) +TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsProjectAndSystemPchPathsAndHasNoError) { InSequence s; - EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(projectPart1.projectPartId))); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectPch) +{ + InSequence s; + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, + UpdateProjectPartsCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectAndSystemPch) +{ + InSequence s; + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsProjectAndSystemPchPathsAndHasOnlyError) +{ + InSequence s; + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); EXPECT_CALL(mockCollector, setFile(main1PathId, ElementsAre("clang++", @@ -475,6 +742,39 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingS "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -486,9 +786,153 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingS "-isystem", toNativePath("/includes")))); EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsSystemPchPathsAndHasErrorWithProjectPch) +{ + InSequence s; + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{{}, "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsNoPchPathsAndHasErrors) +{ + InSequence s; + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(projectPart1.projectPartId))); + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-Wno-pragma-once-outside-header", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps) +{ + InSequence s; + ProjectPartContainer projectPart{1, + {"-Wno-pragma-once-outside-header"}, + {{"BAR", "1", 1}, {"FOO", "1", 2}}, + Utils::clone(systemIncludeSearchPaths), + Utils::clone(projectIncludeSearchPaths), + {header1PathId}, + {main1PathId, main2PathId}, + Utils::Language::Cxx, + Utils::LanguageVersion::CXX14, + Utils::LanguageExtension::None}; + + EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId))) + .WillOnce(Return(dependentSourceTimeStamps1)); + EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps1)); + EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId))) + .WillOnce(Return(dependentSourceTimeStamps2)); + EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps2)); + EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1)); + EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1)); + EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses2)); + EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2)); + + indexer.updateProjectParts({projectPart}); +} + +TEST_F(SymbolIndexer, DependentSourceAreNotUpToDate) +{ + InSequence s; + + EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillOnce(Return(false)); + EXPECT_CALL(mockCollector, setFile(main1PathId, _)); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, DependentSourceAreUpToDate) +{ + InSequence s; + + EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillOnce(Return(true)); + EXPECT_CALL(mockCollector, setFile(main1PathId, _)).Times(0); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, SourcesAreWatched) +{ + using ClangBackEnd::IdPaths; + InSequence s; + FilePathIds sourcePathIds{4, 6, 8}; + + EXPECT_CALL(mockBuildDependenciesStorage, fetchSources(projectPart1.projectPartId)) + .WillOnce(Return(sourcePathIds)); + EXPECT_CALL(mockPathWatcher, + updateIdPaths(ElementsAre(AllOf(Field(&IdPaths::id, projectPart1.projectPartId), + Field(&IdPaths::filePathIds, sourcePathIds))))); indexer.updateProjectParts({projectPart1}); } @@ -505,7 +949,9 @@ TEST_F(SymbolIndexer, CallSetNotifier) filePathCache, fileStatusCache, mockSqliteTransactionBackend, - mockProjectPartsStorage}; + mockProjectPartsStorage, + mockModifiedTimeChecker, + testEnvironment}; } TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage) @@ -516,6 +962,54 @@ TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage) indexer.pathsChanged(sourceFileIds); } +TEST_F(SymbolIndexer, PathChangedCallsFetchSourcePathIds) +{ + InSequence s; + + EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds)) + .WillOnce(Return(FilePathIds{2, 6, 5})); + EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{2})); + EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{6})); + EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{5})); + + indexer.pathsChanged(sourceFileIds); +} + +TEST_F(SymbolIndexer, PathChangedFetchIncludedIndexingTimeStamps) +{ + InSequence s; + ProjectPartContainer projectPart{1, + {"-Wno-pragma-once-outside-header"}, + {{"BAR", "1", 1}, {"FOO", "1", 2}}, + Utils::clone(systemIncludeSearchPaths), + Utils::clone(projectIncludeSearchPaths), + {header1PathId}, + {main1PathId, main2PathId}, + Utils::Language::Cxx, + Utils::LanguageVersion::CXX14, + Utils::LanguageExtension::None}; + + EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillOnce(Return(FilePathIds{1, 2})); + EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(1))) + .WillOnce(Return(dependentSourceTimeStamps1)); + EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(2))) + .WillOnce(Return(dependentSourceTimeStamps2)); + EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses1)); + EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1)); + EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses2)); + EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2)); + + indexer.pathsChanged({1, 3}); +} + +TEST_F(SymbolIndexer, PathChangedFetchesDependentSourceIdsFromStorage) +{ + EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0])); + EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[1])); + + indexer.pathsChanged(sourceFileIds); +} + TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) { InSequence s; @@ -524,8 +1018,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))); EXPECT_CALL(mockCollector, setFile(Eq(sourceFileIds[0]), ElementsAre("clang++", @@ -539,6 +1033,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -564,8 +1060,8 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0])) .WillOnce(Return(nullArtefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(_)).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(_)).Times(0); EXPECT_CALL(mockCollector, setFile(_, _)).Times(0); EXPECT_CALL(mockCollector, collectSymbols()).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); @@ -575,18 +1071,271 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) indexer.pathsChanged({sourceFileIds[0]}); } -TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSymbols) +TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasNoError) { InSequence s; - EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); EXPECT_CALL(mockCollector, - setFile(Eq(sourceFileIds[0]), + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.pathsChanged({sourceFileIds[0]}); +} + +TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectPch) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsStorage, + fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillOnce(Return(artefact)); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.pathsChanged({sourceFileIds[0]}); +} + +TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectAndSystemPch) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsStorage, + fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillOnce(Return(artefact)); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + + indexer.pathsChanged({sourceFileIds[0]}); +} + +TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasOnlyError) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsStorage, + fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillOnce(Return(artefact)); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/project/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], ElementsAre("clang++", "-w", "-DFOO", @@ -598,6 +1347,39 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSy "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -609,9 +1391,92 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSy "-isystem", toNativePath("/includes")))); EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + + indexer.pathsChanged({sourceFileIds[0]}); +} + +TEST_F(SymbolIndexer, PathsChangedCallsGetsSystemPchPathsAndHasErrorWithProjectPch) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsStorage, + fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillOnce(Return(artefact)); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillOnce(Return(ClangBackEnd::PchPaths{{}, "/system/pch"})); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes"), + "-Xclang", + "-include-pch", + "-Xclang", + toNativePath("/system/pch")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + + indexer.pathsChanged({sourceFileIds[0]}); +} + +TEST_F(SymbolIndexer, PathsChangedCallsGetsNoPchPathsAndHasErrors) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsStorage, + fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillOnce(Return(artefact)); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))); + EXPECT_CALL(mockCollector, + setFile(sourceFileIds[0], + ElementsAre("clang++", + "-w", + "-DFOO", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); + EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); indexer.pathsChanged({sourceFileIds[0]}); } @@ -620,8 +1485,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) { ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) .WillByDefault(Return(artefact)); - ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))) - .WillByDefault(Return(projectPartPch)); + ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) + .WillByDefault(Return(pchPaths)); std::vector<SymbolIndexerTask> symbolIndexerTask; EXPECT_CALL(mockCollector, @@ -637,6 +1502,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -650,7 +1517,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) "-Xclang", "-include-pch", "-Xclang", - toNativePath("/path/to/pch")))); + toNativePath("/project/pch")))); indexer.pathsChanged({sourceFileIds[0]}); } @@ -674,6 +1541,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists) "-nostdinc++", "-DBAR=1", "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), "-I", toNativePath("/project/includes"), "-I", @@ -797,6 +1666,7 @@ TEST_F(SymbolIndexer, PathsChangedUpdatesFileStatusCache) auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp"); auto oldLastModified = fileStatusCache.lastModifiedTime(sourceId); touchFile(sourceId); + ON_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillByDefault(Return(FilePathIds{sourceId})); indexer.pathsChanged({sourceId}); @@ -889,4 +1759,68 @@ TEST_F(SymbolIndexer, DISABLED_UpToDateFilesAreNotParsedInUpdateProjectParts) indexer.updateProjectParts({projectPart1}); } +TEST_F(SymbolIndexer, MultipleSourceFiles) +{ + ProjectPartContainer projectPart{0, + {}, + {{"BAR", "1", 1}, {"FOO", "1", 2}}, + Utils::clone(systemIncludeSearchPaths), + Utils::clone(projectIncludeSearchPaths), + {header1PathId, header2PathId}, + {main1PathId, main2PathId}, + Utils::Language::Cxx, + Utils::LanguageVersion::CXX14, + Utils::LanguageExtension::None}; + + EXPECT_CALL(mockCollector, + setFile(main1PathId, + ElementsAre("clang++", + "-w", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + EXPECT_CALL(mockCollector, + setFile(main2PathId, + ElementsAre("clang++", + "-w", + "-DNOMINMAX", + "-x", + "c++", + "-std=c++14", + "-nostdinc", + "-nostdinc++", + "-DBAR=1", + "-DFOO=1", + "-isystem", + toNativePath(TESTDATA_DIR "/preincludes"), + "-I", + toNativePath("/project/includes"), + "-I", + toNativePath("/other/project/includes"), + "-isystem", + toNativePath(TESTDATA_DIR), + "-isystem", + toNativePath("/other/includes"), + "-isystem", + toNativePath("/includes")))); + + indexer.updateProjectParts({projectPart}); } +} // namespace diff --git a/tests/unit/unittest/symbolindexertaskqueue-test.cpp b/tests/unit/unittest/symbolindexertaskqueue-test.cpp index 2932310eb0..1364091161 100644 --- a/tests/unit/unittest/symbolindexertaskqueue-test.cpp +++ b/tests/unit/unittest/symbolindexertaskqueue-test.cpp @@ -25,6 +25,7 @@ #include "googletest.h" +#include "mocksqlitedatabase.h" #include "mocktaskscheduler.h" #include <symbolindexertaskqueue.h> @@ -54,7 +55,8 @@ protected: NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback; ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()}; NiceMock<MockTaskScheduler<Callable>> mockTaskScheduler; - ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler, progressCounter}; + NiceMock<MockSqliteDatabase> mockSqliteDatabase; + ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler, progressCounter, mockSqliteDatabase}; }; TEST_F(SymbolIndexerTaskQueue, AddTasks) @@ -208,4 +210,35 @@ TEST_F(SymbolIndexerTaskQueue, ProcessTasksRemovesProcessedTasks) ASSERT_THAT(queue.tasks(), SizeIs(1)); } + +TEST_F(SymbolIndexerTaskQueue, + ProcessTasksWritesBackTheDatabaseLogIfTheQueueIsEmptyAndTheIndexerHasNothingToDo) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()); + + queue.processEntries(); +} + +TEST_F(SymbolIndexerTaskQueue, ProcessTasksDoesNotWritesBackTheDatabaseLogIfTheIndexerHasSomethingToDo) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{1, 1})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()).Times(0); + + queue.processEntries(); +} + +TEST_F(SymbolIndexerTaskQueue, HandleExeptionInWalCheckPoint) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()).WillOnce(Throw(Sqlite::DatabaseIsBusy{""})); + + queue.processEntries(); } +} // namespace diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp index 6e094951f3..67411efd37 100644 --- a/tests/unit/unittest/symbolindexing-test.cpp +++ b/tests/unit/unittest/symbolindexing-test.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "googletest.h" +#include "testenvironment.h" #include <symbolindexing.h> #include <symbolquery.h> @@ -85,7 +86,12 @@ protected: ClangBackEnd::GeneratedFiles generatedFiles; NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback; ClangBackEnd::ProjectPartsStorage<Sqlite::Database> projectPartStorage{database}; - ClangBackEnd::SymbolIndexing indexing{database, filePathCache, generatedFiles, mockSetProgressCallback.AsStdFunction()}; + TestEnvironment testEnvironment; + ClangBackEnd::SymbolIndexing indexing{database, + filePathCache, + generatedFiles, + mockSetProgressCallback.AsStdFunction(), + testEnvironment}; StatementFactory queryFactory{database}; Query query{queryFactory}; PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp"; diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 48e4420dc1..f0080a5d2c 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -271,56 +271,6 @@ TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile)) Contains(HasSymbolName("function"))); } -TEST_F(SymbolsCollector, SourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), - UnorderedElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), - filePathId(TESTDATA_DIR "/symbolscollector/header1.h"), - filePathId(TESTDATA_DIR "/symbolscollector/header2.h"))); -} - -TEST_F(SymbolsCollector, MainFileInSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - ASSERT_THAT(collector.sourceFiles(), - ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"))); -} - -TEST_F(SymbolsCollector, ResetMainFileInSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - ASSERT_THAT(collector.sourceFiles(), - ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"))); -} - -TEST_F(SymbolsCollector, DontDuplicateSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - collector.collectSymbols(); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), - UnorderedElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), - filePathId(TESTDATA_DIR "/symbolscollector/header1.h"), - filePathId(TESTDATA_DIR "/symbolscollector/header2.h"))); -} - -TEST_F(SymbolsCollector, ClearSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - - ASSERT_THAT(collector.sourceFiles(), IsEmpty()); -} - TEST_F(SymbolsCollector, ClearSymbols) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -351,27 +301,6 @@ TEST_F(SymbolsCollector, ClearFileStatus) ASSERT_THAT(collector.fileStatuses(), IsEmpty()); } -TEST_F(SymbolsCollector, ClearUsedMacros) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/defines.h"), {"cc"}); - collector.collectSymbols(); - - collector.clear(); - - ASSERT_THAT(collector.usedMacros(), IsEmpty()); -} - -TEST_F(SymbolsCollector, ClearSourceDependencies) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main2.cpp"), - {"cc", "-I" TESTDATA_DIR}); - collector.collectSymbols(); - - collector.clear(); - - ASSERT_THAT(collector.sourceDependencies(), IsEmpty()); -} - TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -382,16 +311,6 @@ TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) ASSERT_THAT(collector.symbols(), IsEmpty()); } -TEST_F(SymbolsCollector, DontCollectSourceFilesAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), IsEmpty()); -} - TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -402,82 +321,6 @@ TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared) ASSERT_THAT(collector.fileStatuses(), IsEmpty()); } -TEST_F(SymbolsCollector, DontCollectUsedMacrosAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), IsEmpty()); -} - -TEST_F(SymbolsCollector, DontCollectSourceDependenciesAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceDependencies(), IsEmpty()); -} - -TEST_F(SymbolsCollector, CollectUsedMacrosWithExternalDefine) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(SymbolsCollector, CollectUsedMacrosWithoutExternalDefine) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(SymbolsCollector, DontCollectHeaderGuards) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - Not(Contains(Eq(UsedMacro{"SYMBOLSCOLLECTOR_DEFINES_H", fileId})))); -} - -TEST_F(SymbolsCollector, DISABLED_DontCollectDynamicLibraryExports) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - Not(Contains(Eq(UsedMacro{"CLASS_EXPORT", fileId})))); -} - TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); @@ -489,7 +332,7 @@ TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 4, 9, SourceLocationKind::MacroDefinition))); } -TEST_F(SymbolsCollector, CollectMacroUsageInIfNotDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInIfNotDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -500,7 +343,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageInIfNotDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 6, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectSecondMacroUsageInIfNotDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectSecondMacroUsageInIfNotDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -511,7 +354,7 @@ TEST_F(SymbolsCollector, CollectSecondMacroUsageInIfNotDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 9, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageCompilerArgumentSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageCompilerArgumentSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -522,7 +365,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageCompilerArgumentSourceLocation) Contains(IsSourceLocationEntry(symbolId("COMPILER_ARGUMENT"), fileId, 12, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageInIfDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInIfDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -533,7 +376,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageInIfDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_DEFINE"), fileId, 17, 8, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageInDefinedSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInDefinedSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -566,7 +409,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageUndefSourceLocation) Contains(IsSourceLocationEntry(symbolId("UN_DEFINE"), fileId, 34, 8, SourceLocationKind::MacroUndefinition))); } -TEST_F(SymbolsCollector, CollectMacroUsageBuiltInSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageBuiltInSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -588,7 +431,7 @@ TEST_F(SymbolsCollector, CollectMacroDefinitionSymbols) Contains(AllOf(HasSymbolName("IF_NOT_DEFINE"), HasSymbolKind(SymbolKind::Macro)))); } -TEST_F(SymbolsCollector, CollectMacroBuiltInSymbols) +TEST_F(SymbolsCollector, DISABLED_CollectMacroBuiltInSymbols) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc"}); @@ -599,7 +442,7 @@ TEST_F(SymbolsCollector, CollectMacroBuiltInSymbols) Contains(AllOf(HasSymbolName("__clang__"), HasSymbolKind(SymbolKind::Macro)))); } -TEST_F(SymbolsCollector, CollectMacroCompilerArgumentSymbols) +TEST_F(SymbolsCollector, DISABLED_CollectMacroCompilerArgumentSymbols) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -623,23 +466,6 @@ TEST_F(SymbolsCollector, CollectFileStatuses) fileStatus(TESTDATA_DIR "/symbolscollector/header2.h"))); } -TEST_F(SymbolsCollector, CollectSourceDependencies) -{ - auto mainFileId = filePathId(TESTDATA_DIR "/symbolscollector/main2.cpp"); - auto header1FileId = filePathId(TESTDATA_DIR "/symbolscollector/header1.h"); - auto header2FileId = filePathId(TESTDATA_DIR "/symbolscollector/header2.h"); - auto header3FileId = filePathId(TESTDATA_DIR "/symbolscollector/header3.h"); - collector.setFile(mainFileId, {"cc", "-I" TESTDATA_DIR}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceDependencies(), - UnorderedElementsAre(SourceDependency(mainFileId, header1FileId), - SourceDependency(mainFileId, header3FileId), - SourceDependency(header3FileId, header2FileId), - SourceDependency(header1FileId, header2FileId))); -} - TEST_F(SymbolsCollector, IsClassSymbol) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/symbolkind.cpp"), {"cc"}); @@ -770,13 +596,13 @@ TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtSecondRun) collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - AllOf( - Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), - Not(Contains(HasSymbolName("MemberReference"))), - Not(Contains(HasSymbolName("HeaderFunctionReference"))), - Not(Contains(HasSymbolName("HeaderFunction"))), - Not(Contains(HasSymbolName("Class"))), - Not(Contains(HasSymbolName("Member"))))); + AllOf(Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), + Not(Contains(HasSymbolName("MemberReference"))), + Not(Contains(HasSymbolName("HeaderFunctionReference"))), + Not(Contains(HasSymbolName("HeaderFunction"))), + Not(Contains(HasSymbolName("Class"))), + Not(Contains(HasSymbolName("Member"))), + Not(Contains(HasSymbolName("HEADER_DEFINE"))))); } TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtTouchHeader) @@ -792,13 +618,14 @@ TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtTouchHeader) collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - AllOf( - Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), - Not(Contains(HasSymbolName("MemberReference"))), - Not(Contains(HasSymbolName("HeaderFunctionReference"))), - Not(Contains(HasSymbolName("HeaderFunction"))), - Not(Contains(HasSymbolName("Class"))), - Not(Contains(HasSymbolName("Member"))))); + AllOf(Contains(HasSymbolName("TouchHeaderFunction")), + Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), + Not(Contains(HasSymbolName("MemberReference"))), + Not(Contains(HasSymbolName("HeaderFunctionReference"))), + Not(Contains(HasSymbolName("HeaderFunction"))), + Not(Contains(HasSymbolName("Class"))), + Not(Contains(HasSymbolName("Member"))), + Not(Contains(HasSymbolName("HEADER_DEFINE"))))); } TEST_F(SymbolsCollector, DontIndexSystemIncudes) diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp index 059b1a3c0f..a29b7f92aa 100644 --- a/tests/unit/unittest/symbolstorage-test.cpp +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -28,17 +28,22 @@ #include "mockfilepathcaching.h" #include "mocksqlitedatabase.h" -#include <symbolstorage.h> +#include <builddependenciesstorage.h> +#include <refactoringdatabaseinitializer.h> #include <sqlitedatabase.h> +#include <sqlitereadstatement.h> +#include <sqlitewritestatement.h> +#include <symbolstorage.h> #include <utils/optional.h> namespace { - using ClangBackEnd::FilePathCachingInterface; +using ClangBackEnd::FilePathId; using ClangBackEnd::SourceLocationEntries; using ClangBackEnd::SourceLocationEntry; using ClangBackEnd::SourceLocationKind; +using ClangBackEnd::SourceTimeStamp; using ClangBackEnd::SymbolEntries; using ClangBackEnd::SymbolEntry; using ClangBackEnd::SymbolIndex; @@ -64,6 +69,10 @@ protected: MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = storage.insertNewLocationsInLocationsStatement; MockSqliteWriteStatement &deleteNewSymbolsTableStatement = storage.deleteNewSymbolsTableStatement; MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.deleteNewLocationsTableStatement; + MockSqliteWriteStatement &inserOrUpdateIndexingTimesStampStatement = storage.inserOrUpdateIndexingTimesStampStatement; + MockSqliteReadStatement &fetchIndexingTimeStampsStatement = storage.fetchIndexingTimeStampsStatement; + MockSqliteReadStatement &fetchIncludedIndexingTimeStampsStatement = storage.fetchIncludedIndexingTimeStampsStatement; + MockSqliteReadStatement &fetchDependentSourceIdsStatement = storage.fetchDependentSourceIdsStatement; SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}}, {2, {"function2USR", "function2", SymbolKind::Function}}}; SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SourceLocationKind::Declaration}, @@ -183,5 +192,145 @@ TEST_F(SymbolStorage, AddTablesInConstructor) Storage storage{mockDatabase}; } +TEST_F(SymbolStorage, FetchIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchIndexingTimeStamps(); +} + +TEST_F(SymbolStorage, InsertIndexingTimeStamp) +{ + ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}}; + + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37))); + + storage.insertOrUpdateIndexingTimeStamps(fileStatuses); +} + +TEST_F(SymbolStorage, InsertIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34))); + EXPECT_CALL(mockDatabase, commit()); + + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); +} + +TEST_F(SymbolStorage, FetchIncludedIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, + valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, + valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchIncludedIndexingTimeStamps(1); +} + +TEST_F(SymbolStorage, FetchDependentSourceIdsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(7))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchDependentSourceIds({3, 2, 7}); +} + +class SymbolStorageSlow : public testing::Test +{ +protected: + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::SymbolStorage<> storage{database}; + ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database}; +}; + +TEST_F(SymbolStorageSlow, InsertIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 34})); +} + +TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); + + storage.insertOrUpdateIndexingTimeStamps({1}, 37); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34})); } +TEST_F(SymbolStorageSlow, InsertIndexingTimeStamp) +{ + storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}}); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); +} + +TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamp) +{ + storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}}); + + storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}}); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); +} + +TEST_F(SymbolStorageSlow, FetchIncludedIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5}, 34); + buildDependenciesStorage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {3, 4}, {5, 3}}); + + auto timeStamps = storage.fetchIncludedIndexingTimeStamps(1); + + ASSERT_THAT(timeStamps, + ElementsAre(SourceTimeStamp{1, 34}, + SourceTimeStamp{2, 34}, + SourceTimeStamp{3, 34}, + SourceTimeStamp{4, 34})); +} + +TEST_F(SymbolStorageSlow, FetchDependentSourceIds) +{ + buildDependenciesStorage.insertOrUpdateSourceDependencies( + {{1, 2}, {1, 3}, {2, 3}, {4, 2}, {5, 6}, {7, 6}}); + + auto sourceIds = storage.fetchDependentSourceIds({3, 2, 7}); + + ASSERT_THAT(sourceIds, ElementsAre(FilePathId{1}, FilePathId{4}, FilePathId{7})); +} +} // namespace diff --git a/tests/unit/unittest/testenvironment.h b/tests/unit/unittest/testenvironment.h index a9529c58d5..1e6c7da862 100644 --- a/tests/unit/unittest/testenvironment.h +++ b/tests/unit/unittest/testenvironment.h @@ -27,36 +27,24 @@ #include <environment.h> -#include <utf8string.h> -#include <utils/hostosinfo.h> +#include <filepath.h> #include <QTemporaryDir> -#include <QVector> class TestEnvironment final : public ClangBackEnd::Environment { public: - TestEnvironment() { - temporaryDirectory.setAutoRemove(true); - } - QString pchBuildDirectory() const override - { - return temporaryDirectory.path(); - } - - uint hardwareConcurrency() const - { - return 2; - } + TestEnvironment() { temporaryDirectory.setAutoRemove(true); } - static QVector<Utf8String> addPlatformArguments(std::initializer_list<Utf8String> arguments = {}) + Utils::PathString pchBuildDirectory() const override { return temporaryDirectory.path(); } + uint hardwareConcurrency() const { return 2; } + ClangBackEnd::NativeFilePathView preIncludeSearchPath() const override { - QVector<Utf8String> result{arguments}; - if (Utils::HostOsInfo::isWindowsHost()) - result.append(Utf8StringLiteral("-fno-delayed-template-parsing")); - return result; + return includeSearchPath; } private: QTemporaryDir temporaryDirectory; + ClangBackEnd::NativeFilePath includeSearchPath{ + ClangBackEnd::FilePath{TESTDATA_DIR "/preincludes"}}; }; diff --git a/tests/unit/unittest/token-test.cpp b/tests/unit/unittest/token-test.cpp index 3f7c39ea5f..f5f8a36e3a 100644 --- a/tests/unit/unittest/token-test.cpp +++ b/tests/unit/unittest/token-test.cpp @@ -25,7 +25,7 @@ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangdocument.h> #include <clangdocuments.h> @@ -55,7 +55,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/token.cpp")}; Utf8StringVector compilationArguments{ - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")})}; + UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")})}; Document document{filePath, compilationArguments, {}, documents}; TranslationUnit translationUnit{filePath, filePath, diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp index 8d79bc95cb..285c6d3446 100644 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "googletest.h" -#include "testenvironment.h" +#include "unittest-utility-functions.h" #include <clangdocument.h> #include <clangdocuments.h> @@ -128,7 +128,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/highlightingmarks.cpp")}; Document document{filePath, - TestEnvironment::addPlatformArguments( + UnitTest::addPlatformArguments( {Utf8StringLiteral("-std=c++14"), Utf8StringLiteral("-I" TESTDATA_DIR)}), {}, @@ -1552,14 +1552,14 @@ TEST_F(TokenProcessor, NamespaceTypeSpelling) ASSERT_THAT(container.extraInfo.semanticParentTypeSpelling, Utf8StringLiteral("NFoo::NBar::NTest")); } -TEST_F(TokenProcessor, DISABLED_WITHOUT_INVALIDDECL_PATCH(TypeNameOfInvalidDeclarationIsInvalid)) +TEST_F(TokenProcessor, TypeNameOfInvalidDeclarationIsInvalid) { const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Invalid)); } -TEST_F(TokenProcessor, DISABLED_WITHOUT_INVALIDDECL_PATCH(VariableNameOfInvalidDeclarationIsInvalid)) +TEST_F(TokenProcessor, VariableNameOfInvalidDeclarationIsInvalid) { const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); diff --git a/tests/unit/unittest/translationunitupdater-test.cpp b/tests/unit/unittest/translationunitupdater-test.cpp index b491018956..eecc06b8a7 100644 --- a/tests/unit/unittest/translationunitupdater-test.cpp +++ b/tests/unit/unittest/translationunitupdater-test.cpp @@ -113,7 +113,7 @@ TEST_F(TranslationUnitUpdaterSlowTest, NotUpdatingParseTimePointForReparseOnly) ASSERT_FALSE(result.hasParsed()); } -TEST_F(TranslationUnitUpdaterSlowTest, UpdatesDependendOnFilesOnParse) +TEST_F(TranslationUnitUpdaterSlowTest, UpdatesDependentOnFilesOnParse) { ::TranslationUnitUpdater updater = createUpdater(createInput()); diff --git a/tests/unit/unittest/unittest-utility-functions.h b/tests/unit/unittest/unittest-utility-functions.h index 6d68c1adfc..5102769e78 100644 --- a/tests/unit/unittest/unittest-utility-functions.h +++ b/tests/unit/unittest/unittest-utility-functions.h @@ -25,10 +25,12 @@ #pragma once +#include <utils/hostosinfo.h> #include <utils/smallstring.h> - #include <utils/temporarydirectory.h> +#include <utf8stringvector.h> + inline bool operator==(const QString &first, const char *second) { @@ -42,4 +44,12 @@ Utils::PathString temporaryDirPath() { return Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath()); } + +inline QVector<Utf8String> addPlatformArguments(std::initializer_list<Utf8String> arguments = {}) +{ + QVector<Utf8String> result{arguments}; + if (Utils::HostOsInfo::isWindowsHost()) + result.append(Utf8StringLiteral("-fno-delayed-template-parsing")); + return result; +} } // namespace UnitTest diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 4fbba5b413..63980ab055 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -26,6 +26,9 @@ msvc: QMAKE_CXXFLAGS_WARN_ON -= -w34100 # 'unreferenced formal parameter' in MAT win32:DEFINES += ECHOSERVER=\"R\\\"xxx($$OUT_PWD/../echo)xxx\\\"\" unix: DEFINES += ECHOSERVER=\"R\\\"xxx($$OUT_PWD/../echoserver/echo)xxx\\\"\" +RELATIVE_DATA_PATH = ../../../share/qtcreator +DEFINES += $$shell_quote(RELATIVE_DATA_PATH=\"$$RELATIVE_DATA_PATH\") + linux { QMAKE_LFLAGS_RELEASE = #disable optimization QMAKE_LFLAGS += -fno-merge-debug-strings -fuse-ld=gold @@ -33,7 +36,7 @@ CONFIG(release, debug|release):QMAKE_LFLAGS += -Wl,--strip-debug } gcc:!clang: QMAKE_CXXFLAGS += -Wno-noexcept-type -msvc: QMAKE_CXXFLAGS += /bigobj +msvc: QMAKE_CXXFLAGS += /bigobj /wd4267 /wd4141 /wd4146 # create fake CppTools.json for the mime type definitions dependencyList = "\"Dependencies\" : []" |