diff options
author | Marco Bubke <marco.bubke@qt.io> | 2017-08-21 12:00:27 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2017-08-29 16:37:24 +0000 |
commit | f49a1d721c8be7d49bc0831ffa7316f2ec4f383f (patch) | |
tree | 8fdb264206b2d5d58f16185e616bc56a7eea5e09 /tests | |
parent | 81d43b8a11e39ca7165213945b0bb0e6ef5d7980 (diff) | |
download | qt-creator-f49a1d721c8be7d49bc0831ffa7316f2ec4f383f.tar.gz |
Clang: Add symbol storage
Extend file path cache to 64 bit integer.
Change-Id: I5627f13d59a3214f389087038482cbcc8d0eb484
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/unittest/clangpathwatcher-test.cpp | 7 | ||||
-rw-r--r-- | tests/unit/unittest/clangquery-test.cpp | 4 | ||||
-rw-r--r-- | tests/unit/unittest/clangquerygatherer-test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/unittest/includecollector-test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitedatabase.h | 41 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitereadstatement.cpp | 76 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitereadstatement.h | 92 | ||||
-rw-r--r-- | tests/unit/unittest/mocksqlitewritestatement.h | 59 | ||||
-rw-r--r-- | tests/unit/unittest/pchcreator-test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/unittest/pchmanagerserver-test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/unittest/sourcerangeextractor-test.cpp | 2 | ||||
-rw-r--r-- | tests/unit/unittest/sqlitestatement-test.cpp | 1 | ||||
-rw-r--r-- | tests/unit/unittest/storagesqlitestatementfactory-test.cpp | 186 | ||||
-rw-r--r-- | tests/unit/unittest/stringcache-test.cpp | 49 | ||||
-rw-r--r-- | tests/unit/unittest/symbolscollector-test.cpp | 5 | ||||
-rw-r--r-- | tests/unit/unittest/symbolstorage-test.cpp | 203 | ||||
-rw-r--r-- | tests/unit/unittest/unittest.pro | 11 |
17 files changed, 706 insertions, 38 deletions
diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp index ebe57c3a3d..4bbadca3a3 100644 --- a/tests/unit/unittest/clangpathwatcher-test.cpp +++ b/tests/unit/unittest/clangpathwatcher-test.cpp @@ -42,11 +42,12 @@ using testing::NiceMock; using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>, FakeTimer>; using ClangBackEnd::WatcherEntry; +using ClangBackEnd::FilePathIndices; class ClangPathWatcher : public testing::Test { protected: - ClangBackEnd::StringCache<Utils::PathString> pathCache; + ClangBackEnd::FilePathCache<> pathCache; NiceMock<MockClangPathWatcherNotifier> notifier; Watcher watcher{pathCache, ¬ifier}; NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher(); @@ -55,8 +56,8 @@ protected: Utils::SmallString id3{"id3"}; Utils::PathString path1{"/path/path1"}; Utils::PathString path2{"/path/path2"}; - std::vector<uint> paths = watcher.pathCache().stringIds({path1, path2}); - std::vector<uint> ids = watcher.idCache().stringIds({id1, id2, id3}); + FilePathIndices paths{watcher.pathCache().stringIds({path1, path2})}; + FilePathIndices ids{watcher.idCache().stringIds({id1, id2, id3})}; WatcherEntry watcherEntry1{ids[0], paths[0]}; WatcherEntry watcherEntry2{ids[1], paths[0]}; WatcherEntry watcherEntry3{ids[0], paths[1]}; diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp index 3b1a196e94..792c234570 100644 --- a/tests/unit/unittest/clangquery-test.cpp +++ b/tests/unit/unittest/clangquery-test.cpp @@ -33,7 +33,7 @@ #include <mutex> using ClangBackEnd::ClangQuery; -using ClangBackEnd::StringCache; +using ClangBackEnd::FilePathCache; using testing::AllOf; using testing::Contains; @@ -48,7 +48,7 @@ protected: void SetUp() override; protected: - StringCache<Utils::PathString, std::mutex> filePathCache; + FilePathCache<std::mutex> filePathCache; ::ClangQuery simpleFunctionQuery{filePathCache}; ::ClangQuery simpleClassQuery{filePathCache}; }; diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp index 47719f031d..a9a191383c 100644 --- a/tests/unit/unittest/clangquerygatherer-test.cpp +++ b/tests/unit/unittest/clangquerygatherer-test.cpp @@ -75,7 +75,7 @@ protected: void SetUp() override; protected: - ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache; + ClangBackEnd::FilePathCache<std::mutex> filePathCache; Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"}; FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp index d2c0d06b71..ad405e55d7 100644 --- a/tests/unit/unittest/includecollector-test.cpp +++ b/tests/unit/unittest/includecollector-test.cpp @@ -43,7 +43,7 @@ protected: uint id(const Utils::SmallString &path); protected: - ClangBackEnd::StringCache<Utils::PathString> filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; ClangBackEnd::IncludeCollector collector{filePathCache}; ClangBackEnd::IncludeCollector emptyCollector{filePathCache}; Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.h", diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h new file mode 100644 index 0000000000..55c06cb81e --- /dev/null +++ b/tests/unit/unittest/mocksqlitedatabase.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include <sqlitetable.h> + +#include <utils/smallstringview.h> + +class MockSqliteDatabase +{ +public: + MOCK_METHOD1(execute, + void (Utils::SmallStringView sqlStatement)); + +}; + diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp new file mode 100644 index 0000000000..a1813b52c7 --- /dev/null +++ b/tests/unit/unittest/mocksqlitereadstatement.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "mocksqlitereadstatement.h" + +template <typename ResultType, + typename... QueryType> +std::vector<ResultType> values(std::size_t, QueryType...) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template <typename... ResultType> +std::vector<std::tuple<ResultType...>> values(std::size_t, + Utils::SmallStringView, + uint, + uint) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template <typename... ResultType, + template <typename...> class ContainerType, + typename ElementType> +std::vector<std::tuple<ResultType...>> tupleValues(std::size_t, + const ContainerType<ElementType> &) +{ + FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload."; +} + +template <> +std::vector<FilePathIndex> MockSqliteReadStatement::values<FilePathIndex>(std::size_t reserveSize) +{ + return valuesReturnStdVectorInt(reserveSize); +} + +template <> +std::vector<std::tuple<int64_t, int64_t, int64_t>> +MockSqliteReadStatement::tupleValues<int64_t, int64_t, int64_t>( + std::size_t reserveSize, + const Utils::PathString &sourcePath, + const uint &line, + const uint &column) +{ + return valuesReturnStdVectorTupleInt64Int64Int64(reserveSize, sourcePath, line, column); +} + +template <> +std::vector<std::tuple<int64_t, Utils::PathString>> +MockSqliteReadStatement::tupleValues<int64_t, Utils::PathString>(std::size_t reserveSize, + const std::vector<int64_t> &sourceIds) +{ + return valuesReturnStdVectorTupleInt64PathString(reserveSize, sourceIds); +} diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h new file mode 100644 index 0000000000..7e45bd3952 --- /dev/null +++ b/tests/unit/unittest/mocksqlitereadstatement.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <stringcachefwd.h> + +#include "mocksqlitedatabase.h" + +#include <utils/smallstring.h> + +#include <cstdint> +#include <tuple> +#include <vector> + +using std::int64_t; +using ClangBackEnd::FilePathIndex; + +class MockSqliteReadStatement +{ +public: + MockSqliteReadStatement() = default; + MockSqliteReadStatement(Utils::SmallStringView sqlStatement, MockSqliteDatabase &) + : sqlStatement(sqlStatement) + {} + + MOCK_CONST_METHOD1(valuesReturnStdVectorInt, + std::vector<FilePathIndex>(std::size_t)); + + MOCK_CONST_METHOD4(valuesReturnStdVectorTupleInt64Int64Int64, + std::vector<std::tuple<int64_t, int64_t, int64_t>>(std::size_t, Utils::SmallStringView, int64_t, int64_t)); + + MOCK_CONST_METHOD2(valuesReturnStdVectorTupleInt64PathString, + std::vector<std::tuple<int64_t, Utils::PathString>>(std::size_t, const std::vector<int64_t> &)); + + template <typename ResultType, + typename... QueryType> + std::vector<ResultType> values(std::size_t, QueryType...); + + template <typename... ResultType, + typename... QueryType> + std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const QueryType&... queryValues); + + template <typename... ResultType, + template <typename...> class ContainerType, + typename ElementType> + std::vector<std::tuple<ResultType...>> tupleValues(std::size_t reserveSize, const ContainerType<ElementType> &queryValues); + + +public: + Utils::SmallString sqlStatement; +}; + +template <> +std::vector<int> MockSqliteReadStatement::values<int>(std::size_t reserveSize); + +template <> +std::vector<std::tuple<int64_t, int64_t, int64_t>> +MockSqliteReadStatement::tupleValues<int64_t, int64_t, int64_t>( + std::size_t reserveSize, + const Utils::PathString &sourcePath, + const uint &line, + const uint &column); + +template <> +std::vector<std::tuple<int64_t, Utils::PathString>> +MockSqliteReadStatement::tupleValues<int64_t, Utils::PathString>(std::size_t reserveSize, + const std::vector<int64_t> &); + + diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h new file mode 100644 index 0000000000..98ea4e7e24 --- /dev/null +++ b/tests/unit/unittest/mocksqlitewritestatement.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "mocksqlitedatabase.h" + +#include <utils/smallstring.h> + +class MockSqliteWriteStatement +{ +public: + MockSqliteWriteStatement() = default; + MockSqliteWriteStatement(Utils::SmallStringView sqlStatement, MockSqliteDatabase &) + : sqlStatement(sqlStatement) + {} + + MOCK_METHOD0(execute, + void ()); + + MOCK_METHOD2(bind, + void (int index, Utils::SmallStringView value)); + + MOCK_METHOD2(bindValues, + void (Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD3(write, + void (uint, Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD4(write, + void (uint, uint, uint, uint)); + + MOCK_METHOD2(write, + void (uint, Utils::SmallStringView)); + + Utils::SmallString sqlStatement; +}; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 12cd50b8e5..f03b0cd25e 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -68,7 +68,7 @@ protected: uint id(const Utils::PathString &path); protected: - ClangBackEnd::StringCache<Utils::PathString> filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp"; PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp"; PathString header1Path = TESTDATA_DIR "/includecollector_header1.h"; diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 8ac039b16a..b9b170e3dc 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -59,7 +59,7 @@ protected: NiceMock<MockPchCreator> mockPchCreator; NiceMock<MockClangPathWatcher> mockClangPathWatcher; NiceMock<MockProjectParts> mockProjectParts; - ClangBackEnd::StringCache<Utils::PathString> filePathCache; + ClangBackEnd::FilePathCache<> filePathCache; ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts}; NiceMock<MockPchManagerClient> mockPchManagerClient; SmallString projectPartId1 = "project1"; diff --git a/tests/unit/unittest/sourcerangeextractor-test.cpp b/tests/unit/unittest/sourcerangeextractor-test.cpp index 42f2f0f724..d20cd9bb93 100644 --- a/tests/unit/unittest/sourcerangeextractor-test.cpp +++ b/tests/unit/unittest/sourcerangeextractor-test.cpp @@ -54,7 +54,7 @@ protected: TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}}; ClangBackEnd::SourceRangesContainer sourceRangesContainer; const clang::SourceManager &sourceManager{clangTool.sourceManager()}; - ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache; + ClangBackEnd::FilePathCache<std::mutex> filePathCache; ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer}; clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()); clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4); diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index b3523bdc77..c052367a8b 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -340,7 +340,6 @@ TEST_F(SqliteStatement, GetStructValuesWithoutArguments) Output{"poo", "40", 3})); } - TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes) { SqliteReadStatement statement("SELECT name FROM test WHERE number=?", database); diff --git a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp new file mode 100644 index 0000000000..98c99d908e --- /dev/null +++ b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" + +#include "mocksqlitedatabase.h" +#include "mocksqlitereadstatement.h" +#include "mocksqlitewritestatement.h" + +#include <storagesqlitestatementfactory.h> + +namespace { + +using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>, + MockSqliteReadStatement, + MockSqliteWriteStatement>; + +using Sqlite::SqliteTable; + +class StorageSqliteStatementFactory : public testing::Test +{ +protected: + NiceMock<MockSqliteDatabase> mockDatabase; + StatementFactory factory{mockDatabase}; +}; + +TEST_F(StorageSqliteStatementFactory, AddSymbolsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createSymbolsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddLocationsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createLocationsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddSourcesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createSourcesTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddNewSymbolsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createNewSymbolsTable(); +} + + +TEST_F(StorageSqliteStatementFactory, AddNewLocationsTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + factory.createNewLocationsTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor) +{ + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))).Times(5); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))).Times(5); + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); + + StatementFactory factory{mockDatabase}; +} + +TEST_F(StorageSqliteStatementFactory, InsertNewSymbolsStatement) +{ + ASSERT_THAT(factory.insertSymbolsToNewSymbolsStatement.sqlStatement, + Eq("INSERT INTO newSymbols(temporarySymbolId, usr, symbolName) VALUES(?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertNewLocationsToLocations) +{ + ASSERT_THAT(factory.insertLocationsToNewLocationsStatement.sqlStatement, + Eq("INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement) +{ + ASSERT_THAT(factory.selectNewSourceIdsStatement.sqlStatement, + Eq("SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)")); +} + +TEST_F(StorageSqliteStatementFactory, AddNewSymbolsToSymbolsStatement) +{ + ASSERT_THAT(factory.addNewSymbolsToSymbolsStatement.sqlStatement, + Eq("INSERT INTO symbols(usr, symbolname) SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE usr == newsymbols.usr)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertSourcesStatement) +{ + ASSERT_THAT(factory.insertSourcesStatement.sqlStatement, + Eq("INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncNewSymbolsFromSymbolsStatement) +{ + ASSERT_THAT(factory.syncNewSymbolsFromSymbolsStatement.sqlStatement, + Eq("UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncSymbolsIntoNewLocations) +{ + ASSERT_THAT(factory.syncSymbolsIntoNewLocationsStatement.sqlStatement, + Eq("UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteAllLocationsFromUpdatedFiles) +{ + ASSERT_THAT(factory.deleteAllLocationsFromUpdatedFilesStatement.sqlStatement, + Eq("DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertNewLocationsInLocations) +{ + ASSERT_THAT(factory.insertNewLocationsInLocationsStatement.sqlStatement, + Eq("INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteNewSymbolsTableStatement) +{ + ASSERT_THAT(factory.deleteNewSymbolsTableStatement.sqlStatement, + Eq("DELETE FROM newSymbols")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteNewLocationsTableStatement) +{ + ASSERT_THAT(factory.deleteNewLocationsTableStatement.sqlStatement, + Eq("DELETE FROM newLocations")); +} + +} + diff --git a/tests/unit/unittest/stringcache-test.cpp b/tests/unit/unittest/stringcache-test.cpp index 265555f35c..a4f989ba02 100644 --- a/tests/unit/unittest/stringcache-test.cpp +++ b/tests/unit/unittest/stringcache-test.cpp @@ -31,13 +31,16 @@ namespace { -using ClangBackEnd::StringCacheEntries; using ClangBackEnd::StringCacheException; +using uint64 = unsigned long long; + +using CacheEntries = ClangBackEnd::FileCacheCacheEntries; + class StringCache : public testing::Test { protected: - ClangBackEnd::StringCache<Utils::PathString> cache; + ClangBackEnd::FilePathCache<> cache; Utils::PathString filePath1{"/file/pathOne"}; Utils::PathString filePath2{"/file/pathTwo"}; Utils::PathString filePath3{"/file/pathThree"}; @@ -144,7 +147,7 @@ TEST_F(StringCache, IsNotEmpty) TEST_F(StringCache, PopulateWithEmptyVector) { - StringCacheEntries<Utils::PathString> entries; + CacheEntries entries; cache.uncheckedPopulate(std::move(entries)); @@ -153,10 +156,10 @@ TEST_F(StringCache, PopulateWithEmptyVector) TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries) { - StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; cache.uncheckedPopulate(std::move(entries)); @@ -165,10 +168,10 @@ TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries) TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries) { - StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; cache.uncheckedPopulate(std::move(entries)); auto string = cache.string(2); @@ -178,30 +181,30 @@ TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries) TEST_F(StringCache, EntriesHaveUniqueIds) { - StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 2}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 2}}; ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException); } TEST_F(StringCache, IdsAreHigherLowerEntriesSize) { - StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0}, - {filePath2.clone(), 1}, - {filePath3.clone(), 4}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath2.clone(), 1}, + {filePath3.clone(), 4}, + {filePath4.clone(), 3}}; ASSERT_THROW(cache.populate(std::move(entries)), std::out_of_range); } TEST_F(StringCache, MultipleEntries) { - StringCacheEntries<Utils::PathString> entries{{filePath1.clone(), 0}, - {filePath1.clone(), 1}, - {filePath3.clone(), 2}, - {filePath4.clone(), 3}}; + CacheEntries entries{{filePath1.clone(), 0}, + {filePath1.clone(), 1}, + {filePath3.clone(), 2}, + {filePath4.clone(), 3}}; ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException); } diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 15e15ba5f1..4543c61e44 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -42,6 +42,7 @@ using testing::_; using ClangBackEnd::SourceLocationEntry; using ClangBackEnd::SymbolEntry; using ClangBackEnd::SymbolType; +using ClangBackEnd::SymbolIndex; namespace { @@ -53,7 +54,7 @@ protected: return filePathCache.stringId(string); } - uint symbolIdForSymbolName(const Utils::SmallString &symbolName); + SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName); protected: ClangBackEnd::FilePathCache<> filePathCache; @@ -149,7 +150,7 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation) Field(&SourceLocationEntry::column, 5)))); } -uint SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName) +SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName) { for (const auto &entry : collector.symbols()) { if (entry.second.symbolName == symbolName) diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp new file mode 100644 index 0000000000..ec30b9289d --- /dev/null +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" + +#include "mocksqlitereadstatement.h" +#include "mocksqlitewritestatement.h" + +#include <storagesqlitestatementfactory.h> +#include <symbolstorage.h> +#include <sqlitedatabase.h> + +#include <storagesqlitestatementfactory.h> + +namespace { + +using Utils::PathString; +using ClangBackEnd::FilePathCache; +using ClangBackEnd::SymbolEntries; +using ClangBackEnd::SymbolEntry; +using ClangBackEnd::SourceLocationEntries; +using ClangBackEnd::SourceLocationEntry; +using ClangBackEnd::StorageSqliteStatementFactory; +using ClangBackEnd::SymbolType; +using Sqlite::SqliteDatabase; +using Sqlite::SqliteTable; + +using StatementFactory = StorageSqliteStatementFactory<MockSqliteDatabase, + MockSqliteReadStatement, + MockSqliteWriteStatement>; +using Storage = ClangBackEnd::SymbolStorage<StatementFactory>; + +class SymbolStorage : public testing::Test +{ +protected: + void SetUp(); + +protected: + FilePathCache<> filePathCache; + NiceMock<MockSqliteDatabase> mockDatabase; + StatementFactory statementFactory{mockDatabase}; + + MockSqliteWriteStatement &insertSymbolsToNewSymbolsStatement = statementFactory.insertSymbolsToNewSymbolsStatement; + MockSqliteWriteStatement &insertLocationsToNewLocationsStatement = statementFactory.insertLocationsToNewLocationsStatement; + MockSqliteWriteStatement &insertSourcesStatement = statementFactory.insertSourcesStatement; + MockSqliteReadStatement &selectNewSourceIdsStatement = statementFactory.selectNewSourceIdsStatement; + MockSqliteWriteStatement &addNewSymbolsToSymbolsStatement = statementFactory.addNewSymbolsToSymbolsStatement; + MockSqliteWriteStatement &syncNewSymbolsFromSymbolsStatement = statementFactory.syncNewSymbolsFromSymbolsStatement; + MockSqliteWriteStatement &syncSymbolsIntoNewLocationsStatement = statementFactory.syncSymbolsIntoNewLocationsStatement; + MockSqliteWriteStatement &deleteAllLocationsFromUpdatedFilesStatement = statementFactory.deleteAllLocationsFromUpdatedFilesStatement; + MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = statementFactory.insertNewLocationsInLocationsStatement; + MockSqliteWriteStatement &deleteNewSymbolsTableStatement = statementFactory.deleteNewSymbolsTableStatement; + MockSqliteWriteStatement &deleteNewLocationsTableStatement = statementFactory.deleteNewLocationsTableStatement; + SymbolEntries symbolEntries{{1, {"functionUSR", "function"}}, + {2, {"function2USR", "function2"}}}; + SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SymbolType::Declaration}, + {2, 4, {7, 11}, SymbolType::Declaration}}; + Storage storage{statementFactory, filePathCache}; +}; + +TEST_F(SymbolStorage, CreateAndFillTemporaryLocationsTable) +{ + InSequence sequence; + + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + + storage.fillTemporaryLocationsTable(sourceLocations); +} + +TEST_F(SymbolStorage, AddNewSymbolsToSymbols) +{ + EXPECT_CALL(addNewSymbolsToSymbolsStatement, execute()); + + storage.addNewSymbolsToSymbols(); +} + +TEST_F(SymbolStorage, SyncNewSymbolsFromSymbols) +{ + EXPECT_CALL(syncNewSymbolsFromSymbolsStatement, execute()); + + storage.syncNewSymbolsFromSymbols(); +} + +TEST_F(SymbolStorage, SyncSymbolsIntoNewLocations) +{ + EXPECT_CALL(syncSymbolsIntoNewLocationsStatement, execute()); + + storage.syncSymbolsIntoNewLocations(); +} + +TEST_F(SymbolStorage, DeleteAllLocationsFromUpdatedFiles) +{ + EXPECT_CALL(deleteAllLocationsFromUpdatedFilesStatement, execute()); + + storage.deleteAllLocationsFromUpdatedFiles(); +} + +TEST_F(SymbolStorage, InsertNewLocationsInLocations) +{ + EXPECT_CALL(insertNewLocationsInLocationsStatement, execute()); + + storage.insertNewLocationsInLocations(); +} + +TEST_F(SymbolStorage, SelectNewSourceIdsCalls) +{ + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + storage.selectNewSourceIds(); +} + +TEST_F(SymbolStorage, SelectNewSourceIds) +{ + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + auto sourceIds = storage.selectNewSourceIds(); + + ASSERT_THAT(sourceIds, ElementsAre(0, 1, 2)); +} + +TEST_F(SymbolStorage, InserNewSources) +{ + InSequence sequence; + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + + EXPECT_CALL(insertSourcesStatement, write(0, Eq("/path/to/source1"))); + EXPECT_CALL(insertSourcesStatement, write(1, Eq("/path/to/source2"))); + EXPECT_CALL(insertSourcesStatement, write(2, Eq("/path/to/source3"))); + + storage.insertNewSources(); +} + + +TEST_F(SymbolStorage, DropNewSymbolsTable) +{ + EXPECT_CALL(deleteNewSymbolsTableStatement, execute()); + + storage.deleteNewSymbolsTable(); +} + +TEST_F(SymbolStorage, DropNewLocationsTable) +{ + EXPECT_CALL(deleteNewLocationsTableStatement, execute()); + + storage.deleteNewLocationsTable(); +} + +TEST_F(SymbolStorage, AddSymbolsAndSourceLocationsCallsWrite) +{ + InSequence sequence; + + EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); + EXPECT_CALL(insertSymbolsToNewSymbolsStatement, write(_, _, _)).Times(2); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + EXPECT_CALL(addNewSymbolsToSymbolsStatement, execute()); + EXPECT_CALL(syncNewSymbolsFromSymbolsStatement, execute()); + EXPECT_CALL(syncSymbolsIntoNewLocationsStatement, execute()); + EXPECT_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)); + EXPECT_CALL(insertSourcesStatement, write(0, Eq("/path/to/source1"))); + EXPECT_CALL(insertSourcesStatement, write(1, Eq("/path/to/source2"))); + EXPECT_CALL(insertSourcesStatement, write(2, Eq("/path/to/source3"))); + EXPECT_CALL(deleteAllLocationsFromUpdatedFilesStatement, execute()); + EXPECT_CALL(insertNewLocationsInLocationsStatement, execute()); + EXPECT_CALL(deleteNewSymbolsTableStatement, execute()); + EXPECT_CALL(deleteNewLocationsTableStatement, execute()); + EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + + storage.addSymbolsAndSourceLocations(symbolEntries, sourceLocations); +} + +void SymbolStorage::SetUp() +{ + ON_CALL(selectNewSourceIdsStatement, valuesReturnStdVectorInt(_)) + .WillByDefault(Return(std::vector<FilePathIndex>{0, 1, 2})); + + filePathCache.stringIds({"/path/to/source1", "/path/to/source2", "/path/to/source3"}); +} +} + diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 7c44c4f4ad..667aeaa5d7 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -69,7 +69,10 @@ SOURCES += \ symbolindexer-test.cpp \ stringcache-test.cpp \ unittests-main.cpp \ - utf8-test.cpp + utf8-test.cpp \ + symbolstorage-test.cpp \ + storagesqlitestatementfactory-test.cpp \ + mocksqlitereadstatement.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -188,7 +191,11 @@ HEADERS += \ spydummy.h \ testenvironment.h \ mocksymbolscollector.h \ - mocksymbolstorage.h + mocksymbolstorage.h \ + mocksqlitewritestatement.h \ + mocksqlitedatabase.h \ + mocksqlitereadstatement.h \ + google-using-directive.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \ |