diff options
author | Marco Bubke <marco.bubke@qt.io> | 2019-08-22 16:10:38 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2019-08-27 11:53:45 +0000 |
commit | 9f805b7e8aad04f72203828b89f389f73a5ffcd7 (patch) | |
tree | 914959e9a44677f10be6481de659db363bd0a1e9 /tests/unit | |
parent | c174eb378a7957b8b123e2054cce0e166842a8aa (diff) | |
download | qt-creator-9f805b7e8aad04f72203828b89f389f73a5ffcd7.tar.gz |
ClangRefactoring: Improve follow symbol and usage
Change-Id: Idb42010443e4560489ef067e54d05b4e567598e9
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Diffstat (limited to 'tests/unit')
-rw-r--r-- | tests/unit/unittest/data/symbolscollector/class.cpp | 14 | ||||
-rw-r--r-- | tests/unit/unittest/filepathcache-test.cpp | 6 | ||||
-rw-r--r-- | tests/unit/unittest/gtest-creator-printing.cpp | 17 | ||||
-rw-r--r-- | tests/unit/unittest/gtest-creator-printing.h | 2 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitereadstatement.cpp | 10 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitereadstatement.h | 12 | ||||
-rw-r--r-- | tests/unit/unittest/mocksymbolquery.h | 7 | ||||
-rw-r--r-- | tests/unit/unittest/refactoringdatabaseinitializer-test.cpp | 7 | ||||
-rw-r--r-- | tests/unit/unittest/refactoringengine-test.cpp | 91 | ||||
-rw-r--r-- | tests/unit/unittest/symbolquery-test.cpp | 57 | ||||
-rw-r--r-- | tests/unit/unittest/symbolscollector-test.cpp | 40 |
11 files changed, 232 insertions, 31 deletions
diff --git a/tests/unit/unittest/data/symbolscollector/class.cpp b/tests/unit/unittest/data/symbolscollector/class.cpp new file mode 100644 index 0000000000..5f393c44cd --- /dev/null +++ b/tests/unit/unittest/data/symbolscollector/class.cpp @@ -0,0 +1,14 @@ +class Class +{ + Class(); + Class(int); + + void foo(); + + void bar() {} +}; + +void Class::foo() +{ + bar(); +} diff --git a/tests/unit/unittest/filepathcache-test.cpp b/tests/unit/unittest/filepathcache-test.cpp index 9555796116..4b43d3924c 100644 --- a/tests/unit/unittest/filepathcache-test.cpp +++ b/tests/unit/unittest/filepathcache-test.cpp @@ -453,11 +453,11 @@ TEST_F(FilePathCache, GetFileIdInAfterPopulateIfEmpty) TEST_F(FilePathCache, DontPopulateIfNotEmpty) { cacheNotFilled.filePathId("/path/to/file.cpp"); - cacheNotFilled.populateIfEmpty(); - auto id = cacheNotFilled.filePathId("/path2/to/file.cpp"); + EXPECT_CALL(mockStorageFilled, fetchAllDirectories()).Times(0); + EXPECT_CALL(mockStorageFilled, fetchAllSources()).Times(0); - ASSERT_FALSE(id.isValid()); + cacheNotFilled.populateIfEmpty(); } TEST_F(FilePathCache, GetDirectoryIdAfterPopulateIfEmpty) diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 141a926d9e..385e7e8ab9 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -37,6 +37,9 @@ #include <clangcodemodelservermessages.h> #include <clangpathwatcher.h> #include <clangrefactoringmessages.h> +#include <coreplugin/find/searchresultitem.h> +#include <coreplugin/locator/ilocatorfilter.h> +#include <cpptools/usages.h> #include <filepath.h> #include <filepathcaching.h> #include <filepathview.h> @@ -46,6 +49,8 @@ #include <pchpaths.h> #include <pchtask.h> #include <precompiledheadersupdatedmessage.h> +#include <projectexplorer/headerpath.h> +#include <projectexplorer/projectmacro.h> #include <projectpartartefact.h> #include <projectpartentry.h> #include <projectpartpch.h> @@ -58,11 +63,7 @@ #include <toolchainargumentscache.h> #include <tooltipinfo.h> #include <usedmacro.h> -#include <cpptools/usages.h> -#include <projectexplorer/projectmacro.h> -#include <projectexplorer/headerpath.h> -#include <coreplugin/find/searchresultitem.h> -#include <coreplugin/locator/ilocatorfilter.h> +#include <utils/link.h> namespace { ClangBackEnd::FilePathCaching *filePathCache = nullptr; @@ -178,6 +179,12 @@ std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn) return out << "(" << lineColumn.line << ", " << lineColumn.column << ")"; } +std::ostream &operator<<(std::ostream &out, const Link &link) +{ + return out << "(" << link.targetFileName << ", " << link.targetLine << ", " << link.targetColumn + << ", " << link.linkTextStart << ", " << link.linkTextEnd << ")"; +} + const char * toText(Utils::Language language) { using Utils::Language; diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index 624288ee98..948b2e911c 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -81,11 +81,13 @@ std::ostream &operator<<(std::ostream &out, const HeaderPath &headerPath); namespace Utils { class LineColumn; class SmallStringView; +class Link; std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn); std::ostream &operator<<(std::ostream &out, const Utils::Language &language); std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion); std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension); +std::ostream &operator<<(std::ostream &out, const Link &link); template <typename Type> std::ostream &operator<<(std::ostream &out, const Utils::optional<Type> &optional) diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp index 0a63f3c284..1a27eea50f 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.cpp +++ b/tests/unit/unittest/mocksqlitereadstatement.cpp @@ -46,6 +46,16 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>( return valuesReturnSourceUsages(reserveSize, sourceId, line, column); } +template<> +CppTools::Usages MockSqliteReadStatement::values<CppTools::Usage, 3>(std::size_t reserveSize, + const int &sourceId, + const int &line, + const int &column, + const int &locationKind) +{ + return valuesReturnSourceUsages(reserveSize, sourceId, line, column, locationKind); +} + template <> Symbols MockSqliteReadStatement::values<Symbol, 3>( diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h index 0048fd6276..04e1f8effc 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.h +++ b/tests/unit/unittest/mocksqlitereadstatement.h @@ -78,8 +78,9 @@ public: MOCK_METHOD4(valuesReturnSourceLocations, SourceLocations(std::size_t, int, int, int)); - MOCK_METHOD4(valuesReturnSourceUsages, - CppTools::Usages(std::size_t, int, int, int)); + MOCK_METHOD4(valuesReturnSourceUsages, CppTools::Usages(std::size_t, int, int, int)); + + MOCK_METHOD5(valuesReturnSourceUsages, CppTools::Usages(std::size_t, int, int, int, int)); MOCK_METHOD1(valuesReturnStdVectorDirectory, std::vector<Sources::Directory>(std::size_t)); @@ -191,6 +192,13 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>( const int &line, const int &column); +template<> +CppTools::Usages MockSqliteReadStatement::values<CppTools::Usage, 3>(std::size_t reserveSize, + const int &sourceId, + const int &line, + const int &column, + const int &locationKind); + template <> Symbols MockSqliteReadStatement::values<Symbol, 3>( diff --git a/tests/unit/unittest/mocksymbolquery.h b/tests/unit/unittest/mocksymbolquery.h index 0b3f4d5984..f8333ed7aa 100644 --- a/tests/unit/unittest/mocksymbolquery.h +++ b/tests/unit/unittest/mocksymbolquery.h @@ -40,4 +40,11 @@ public: ClangRefactoring::Symbols(const ClangBackEnd::SymbolKinds &symbolKinds, Utils::SmallStringView searchTerm)); MOCK_CONST_METHOD2(locationForSymbolId, Utils::optional<ClangRefactoring::SourceLocation>(ClangRefactoring::SymbolId symbolId, ClangBackEnd::SourceLocationKind kind)); + MOCK_CONST_METHOD4(sourceUsagesAtByLocationKind, + CppTools::Usages(ClangBackEnd::FilePathId filePathId, + int line, + int utf8Column, + ClangBackEnd::SourceLocationKind)); + MOCK_CONST_METHOD3(declarationsAt, + CppTools::Usages(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); }; diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp index 3af0fc8cfe..7af00158df 100644 --- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp +++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp @@ -60,7 +60,9 @@ TEST_F(RefactoringDatabaseInitializer, AddLocationsTable) 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 INDEX IF NOT EXISTS index_locations_symbolId ON locations(symbolId)"))); initializer.createLocationsTable(); } @@ -221,6 +223,9 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor) execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON " "locations(sourceId, locationKind)"))); EXPECT_CALL(mockDatabase, + execute(Eq( + "CREATE INDEX IF NOT EXISTS index_locations_symbolId ON locations(symbolId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, " "directoryId INTEGER, sourceName TEXT)"))); EXPECT_CALL(mockDatabase, diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 280a240942..0648cca8e0 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -65,13 +65,15 @@ protected: commandLine = Utils::SmallStringVector( optionsBuilder.build(projectFile.kind, CppTools::UsePrecompiledHeaders::No)); commandLine.push_back(qStringFilePath); + ON_CALL(mockFilePathCaching, filePathId(Eq(clangBackEndFilePath))).WillByDefault(Return(12)); + cursor.setPosition(11); } protected: NiceMock<MockFilePathCaching> mockFilePathCaching; MockRefactoringServer mockRefactoringServer; MockRefactoringClient mockRefactoringClient; - MockSymbolQuery mockSymbolQuery; + NiceMock<MockSymbolQuery> mockSymbolQuery; ClangRefactoring::RefactoringEngine engine{mockRefactoringServer, mockRefactoringClient, mockFilePathCaching, @@ -85,27 +87,96 @@ protected: SmallStringVector commandLine; ProjectExplorer::Project project; CppTools::ProjectPart::Ptr projectPart; + CppTools::Usages usages{{"/path1", 1, 3}, {"/path2", 4, 5}}; CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource}; }; -TEST_F(RefactoringEngine, ExpectSourceUsagesAtInFindUsages) +TEST_F(RefactoringEngine, FindUsages) { - cursor.setPosition(11); + ON_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5)).WillByDefault(Return(usages)); + NiceMock<MockFunction<void(const CppTools::Usages &)>> mockCallback; - EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, 2, 5)); + EXPECT_CALL(mockCallback, Call(usages)); - engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, - [](const CppTools::Usages &) {}); + engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction()); } -TEST_F(RefactoringEngine, ExpectSourceUsagesAtInGlobalRename) +TEST_F(RefactoringEngine, CallFindUsages) { - cursor.setPosition(11); + EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5)); - EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, 2, 5)); + engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, [](const CppTools::Usages &) {}); +} + +TEST_F(RefactoringEngine, FindUsagesWithInvalidCursor) +{ + EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, _, _)).Times(0); + + engine.findUsages(CppTools::CursorInEditor{{}, filePath}, [](const CppTools::Usages &) {}); +} + +TEST_F(RefactoringEngine, CallSourceUsagesInInGlobalRename) +{ + EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5)); engine.globalRename(CppTools::CursorInEditor{cursor, filePath}, - [](const CppTools::Usages &) {}, QString()); + [](const CppTools::Usages &) {}, + {}); +} + +TEST_F(RefactoringEngine, CallSourceUsagesInInGlobalRenameWithInvalidCursor) +{ + EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, _, _)).Times(0); + + engine.globalRename(CppTools::CursorInEditor{{}, filePath}, [](const CppTools::Usages &) {}, {}); +} + +TEST_F(RefactoringEngine, CallDeclarationsAtInInGlobalFollowSymbol) +{ + + EXPECT_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5)); + + engine.globalFollowSymbol( + CppTools::CursorInEditor{cursor, filePath}, [](const Utils::Link &) {}, {}, {}, {}, {}); +} + +TEST_F(RefactoringEngine, CallDeclarationsAtInInGlobalFollowSymbolWithInvalidCursor) +{ + EXPECT_CALL(mockSymbolQuery, declarationsAt(_, _, _)).Times(0); + + engine.globalFollowSymbol( + CppTools::CursorInEditor{{}, filePath}, [](const Utils::Link &) {}, {}, {}, {}, {}); +} + +TEST_F(RefactoringEngine, InGlobalFollowSymbol) +{ + using Utils::Link; + NiceMock<MockFunction<void(const Link &)>> mockCallback; + ON_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5)).WillByDefault(Return(usages)); + + EXPECT_CALL(mockCallback, + Call(AllOf(Field(&Link::targetFileName, Eq("/path1")), + Field(&Link::targetLine, Eq(1)), + Field(&Link::targetColumn, Eq(2))))); + + engine.globalFollowSymbol( + CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction(), {}, {}, {}, {}); +} + +TEST_F(RefactoringEngine, InGlobalFollowSymbolSkipCurrentFile) +{ + using Utils::Link; + NiceMock<MockFunction<void(const Link &)>> mockCallback; + CppTools::Usages usages{{clangBackEndFilePath, 1, 3}, {"/path2", 4, 5}}; + ON_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5)).WillByDefault(Return(usages)); + + EXPECT_CALL(mockCallback, + Call(AllOf(Field(&Link::targetFileName, Eq("/path2")), + Field(&Link::targetLine, Eq(4)), + Field(&Link::targetColumn, Eq(4))))); + + engine.globalFollowSymbol( + CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction(), {}, {}, {}, {}); } TEST_F(RefactoringEngine, EngineIsNotUsableForUnusableServer) diff --git a/tests/unit/unittest/symbolquery-test.cpp b/tests/unit/unittest/symbolquery-test.cpp index a2aeb41d08..8a7fad4272 100644 --- a/tests/unit/unittest/symbolquery-test.cpp +++ b/tests/unit/unittest/symbolquery-test.cpp @@ -61,12 +61,11 @@ protected: MockSqliteReadStatement &selectSymbolsForKindAndStartsWith2 = mockStatementFactory.selectSymbolsForKindAndStartsWith2; MockSqliteReadStatement &selectSymbolsForKindAndStartsWith3 = mockStatementFactory.selectSymbolsForKindAndStartsWith3; MockSqliteReadStatement &selectLocationOfSymbol = mockStatementFactory.selectLocationOfSymbol; - SourceLocations locations{{1, 1, 1}, - {1, 2, 3}, - {2, 1, 1}, - {2, 3, 1}, - {4, 1, 1}, - {4, 1, 3}}; + MockSqliteReadStatement &selectSourceUsagesOrderedForSymbolLocation = mockStatementFactory + .selectSourceUsagesOrderedForSymbolLocation; + MockSqliteReadStatement &selectSourceUsagesByLocationKindForSymbolLocation + = mockStatementFactory.selectSourceUsagesByLocationKindForSymbolLocation; + SourceLocations locations{{1, 1, 1}, {1, 2, 3}, {2, 1, 1}, {2, 3, 1}, {4, 1, 1}, {4, 1, 3}}; MockQuery query{mockStatementFactory}; }; @@ -78,8 +77,9 @@ protected: database.execute("INSERT INTO sources VALUES (1, 1, \"filename.h\")"); database.execute("INSERT INTO sources VALUES (2, 1, \"filename.cpp\")"); database.execute("INSERT INTO directories VALUES (1, \"/path/to\")"); - database.execute("INSERT INTO locations VALUES (1, 2, 3, 1, 1)"); - database.execute("INSERT INTO locations VALUES (1, 4, 6, 2, 3)"); + database.execute("INSERT INTO locations VALUES (1, 2, 3, 1, 2)"); + database.execute("INSERT INTO locations VALUES (1, 4, 6, 2, 1)"); + database.execute("INSERT INTO locations VALUES (1, 20, 36, 2, 3)"); database.execute("INSERT INTO symbols VALUES (1, \"functionusr\", \"Function\", 3, \"void function(int)\")"); database.execute("INSERT INTO symbols VALUES (2, \"classusr\", \"Class\", 2, \"class Class final\")"); database.execute("INSERT INTO symbols VALUES (3, \"enumusr\", \"Enum\", 1, \"enum Enum : char\")"); @@ -105,7 +105,8 @@ TEST_F(SymbolQuerySlowTest, LocationsAt) ASSERT_THAT(locations, UnorderedElementsAre(SourceLocation(1, 2, 3), - SourceLocation(2, 4, 6))); + SourceLocation(2, 4, 6), + SourceLocation(2, 20, 36))); } TEST_F(SymbolQuery, SourceUsagesAtCallsValues) @@ -121,7 +122,8 @@ TEST_F(SymbolQuerySlowTest, SourceUsagesAt) ASSERT_THAT(usages, UnorderedElementsAre(CppTools::Usage("/path/to/filename.h", 2, 3), - CppTools::Usage("/path/to/filename.cpp", 4, 6))); + CppTools::Usage("/path/to/filename.cpp", 4, 6), + CppTools::Usage("/path/to/filename.cpp", 20, 36))); } TEST_F(SymbolQuery, SymbolsCallsValuesWithOneKindParameter) @@ -193,4 +195,39 @@ TEST_F(SymbolQuerySlowTest, LocationForSymbolId) ASSERT_THAT(location.value(), Eq(SourceLocation(2, {4, 6}))); } +TEST_F(SymbolQuery, SourceUsagesAtByLocationKindCallsValues) +{ + EXPECT_CALL(selectSourceUsagesByLocationKindForSymbolLocation, + valuesReturnSourceUsages( + _, 42, 14, 7, static_cast<int>(ClangBackEnd::SourceLocationKind::Definition))); + + query.sourceUsagesAtByLocationKind(42, 14, 7, ClangBackEnd::SourceLocationKind::Definition); +} + +TEST_F(SymbolQuerySlowTest, SourceUsagesAtByLocationKind) +{ + auto usages = query.sourceUsagesAtByLocationKind(2, + 4, + 6, + ClangBackEnd::SourceLocationKind::Definition); + + ASSERT_THAT(usages, ElementsAre(CppTools::Usage("/path/to/filename.cpp", 4, 6))); +} + +TEST_F(SymbolQuery, DeclarationsAtCallsValues) +{ + EXPECT_CALL(selectSourceUsagesOrderedForSymbolLocation, valuesReturnSourceUsages(_, 42, 14, 7)); + + query.declarationsAt(42, 14, 7); +} + +TEST_F(SymbolQuerySlowTest, DeclarationsAt) +{ + auto usages = query.declarationsAt(2, 4, 6); + + ASSERT_THAT(usages, + ElementsAre(CppTools::Usage("/path/to/filename.cpp", 4, 6), + CppTools::Usage("/path/to/filename.h", 2, 3))); } + +} // namespace diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 675a4af6d4..4719030737 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -648,4 +648,44 @@ TEST_F(SymbolsCollector, ClearInputFilesAfterCollectingSymbols) ASSERT_TRUE(collector.isClean()); } + +TEST_F(SymbolsCollector, ClassDeclarations) +{ + collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT( + collector.sourceLocations(), + AllOf(Contains(IsSourceLocationEntry(symbolId("Class"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 1, + 7, + SourceLocationKind::Definition)), + Contains(IsSourceLocationEntry(symbolId("bar"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 8, + 8, + SourceLocationKind::Definition)), + Contains(IsSourceLocationEntry(symbolId("foo"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 11, + 13, + SourceLocationKind::Definition)), + Contains(IsSourceLocationEntry(symbolId("foo"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 6, + 8, + SourceLocationKind::Declaration)), + Contains(IsSourceLocationEntry(symbolId("Class"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 11, + 6, + SourceLocationKind::DeclarationReference)), + Contains(IsSourceLocationEntry(symbolId("bar"), + filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), + 13, + 5, + SourceLocationKind::DeclarationReference)))); +} } // namespace |