2017-08-21 12:00:27 +02:00
/****************************************************************************
* *
* * 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"
2017-09-21 11:43:59 +02:00
# include "mockfilepathcaching.h"
2018-02-20 12:43:05 +01:00
# include "mocksqlitedatabase.h"
2017-08-21 12:00:27 +02:00
# include <symbolstorage.h>
# include <sqlitedatabase.h>
2018-02-06 11:16:29 +01:00
# include <utils/optional.h>
2017-08-21 12:00:27 +02:00
namespace {
2017-09-21 11:43:59 +02:00
using ClangBackEnd : : FilePathCachingInterface ;
2018-12-17 12:06:57 +01:00
using ClangBackEnd : : FilePathId ;
using ClangBackEnd : : IncludeSearchPath ;
using ClangBackEnd : : IncludeSearchPaths ;
using ClangBackEnd : : IncludeSearchPathType ;
2017-08-21 12:00:27 +02:00
using ClangBackEnd : : SourceLocationEntries ;
using ClangBackEnd : : SourceLocationEntry ;
2018-04-09 13:30:30 +02:00
using ClangBackEnd : : SourceLocationKind ;
2018-12-17 12:06:57 +01:00
using ClangBackEnd : : SymbolEntries ;
using ClangBackEnd : : SymbolEntry ;
using ClangBackEnd : : SymbolIndex ;
2018-03-22 17:46:43 +01:00
using ClangBackEnd : : SymbolKind ;
2017-09-18 10:21:45 +02:00
using Sqlite : : Database ;
using Sqlite : : Table ;
2018-12-17 12:06:57 +01:00
using Utils : : PathString ;
2017-08-21 12:00:27 +02:00
2018-10-11 18:09:55 +02:00
using Storage = ClangBackEnd : : SymbolStorage < MockSqliteDatabase > ;
2017-08-21 12:00:27 +02:00
class SymbolStorage : public testing : : Test
{
protected :
2018-01-22 14:21:01 +01:00
NiceMock < MockSqliteDatabase > mockDatabase ;
2018-10-11 18:09:55 +02:00
Storage storage { mockDatabase } ;
MockSqliteWriteStatement & insertSymbolsToNewSymbolsStatement = storage . m_insertSymbolsToNewSymbolsStatement ;
MockSqliteWriteStatement & insertLocationsToNewLocationsStatement = storage . m_insertLocationsToNewLocationsStatement ;
MockSqliteReadStatement & selectNewSourceIdsStatement = storage . m_selectNewSourceIdsStatement ;
MockSqliteWriteStatement & addNewSymbolsToSymbolsStatement = storage . m_addNewSymbolsToSymbolsStatement ;
MockSqliteWriteStatement & syncNewSymbolsFromSymbolsStatement = storage . m_syncNewSymbolsFromSymbolsStatement ;
MockSqliteWriteStatement & syncSymbolsIntoNewLocationsStatement = storage . m_syncSymbolsIntoNewLocationsStatement ;
MockSqliteWriteStatement & deleteAllLocationsFromUpdatedFilesStatement = storage . m_deleteAllLocationsFromUpdatedFilesStatement ;
MockSqliteWriteStatement & insertNewLocationsInLocationsStatement = storage . m_insertNewLocationsInLocationsStatement ;
MockSqliteWriteStatement & deleteNewSymbolsTableStatement = storage . m_deleteNewSymbolsTableStatement ;
MockSqliteWriteStatement & deleteNewLocationsTableStatement = storage . m_deleteNewLocationsTableStatement ;
2018-12-17 12:06:57 +01:00
MockSqliteWriteStatement & insertOrUpdateProjectPartStatement = storage . m_insertOrUpdateProjectPartStatement ;
2018-10-11 18:09:55 +02:00
MockSqliteReadStatement & getProjectPartIdStatement = storage . m_getProjectPartIdStatement ;
MockSqliteReadStatement & getProjectPartArtefactsBySourceId = storage . m_getProjectPartArtefactsBySourceId ;
MockSqliteReadStatement & getProjectPartArtefactsByProjectPartName = storage . m_getProjectPartArtefactsByProjectPartName ;
2018-02-20 12:43:05 +01:00
2018-03-22 17:46:43 +01:00
SymbolEntries symbolEntries { { 1 , { " functionUSR " , " function " , SymbolKind : : Function } } ,
{ 2 , { " function2USR " , " function2 " , SymbolKind : : Function } } } ;
2018-11-06 19:02:00 +01:00
SourceLocationEntries sourceLocations { { 1 , 3 , { 42 , 23 } , SourceLocationKind : : Declaration } ,
{ 2 , 4 , { 7 , 11 } , SourceLocationKind : : Definition } } ;
2018-12-17 12:06:57 +01:00
IncludeSearchPaths systemIncludeSearchPaths {
{ " /includes " , 1 , IncludeSearchPathType : : BuiltIn } ,
{ " /other/includes " , 2 , IncludeSearchPathType : : System } } ;
IncludeSearchPaths projectIncludeSearchPaths {
{ " /project/includes " , 1 , IncludeSearchPathType : : User } ,
{ " /other/project/includes " , 2 , IncludeSearchPathType : : User } } ;
Utils : : SmallString systemIncludeSearchPathsText {
R " ([[ " / includes " ,1,2],[ " / other / includes " ,2,3]]) " } ;
Utils : : SmallString projectIncludeSearchPathsText {
R " ([[ " / project / includes " ,1,1],[ " / other / project / includes " ,2,1]]) " } ;
ClangBackEnd : : ProjectPartArtefact artefact { R " ([ " - DFOO " ]) " ,
R " ([[ " FOO " , " 1 " ,1]]) " ,
systemIncludeSearchPathsText ,
projectIncludeSearchPathsText ,
2019-01-23 14:10:58 +01:00
74 ,
Utils : : Language : : Cxx ,
Utils : : LanguageVersion : : CXX11 ,
Utils : : LanguageExtension : : None } ;
2017-08-21 12:00:27 +02:00
} ;
TEST_F ( SymbolStorage , CreateAndFillTemporaryLocationsTable )
{
InSequence sequence ;
2018-04-09 13:30:30 +02:00
EXPECT_CALL ( insertLocationsToNewLocationsStatement , write ( TypedEq < SymbolIndex > ( 1 ) , TypedEq < int > ( 42 ) , TypedEq < int > ( 23 ) , TypedEq < int > ( 3 ) , TypedEq < int > ( int ( SourceLocationKind : : Declaration ) ) ) ) ;
EXPECT_CALL ( insertLocationsToNewLocationsStatement , write ( TypedEq < SymbolIndex > ( 2 ) , TypedEq < int > ( 7 ) , TypedEq < int > ( 11 ) , TypedEq < int > ( 4 ) , TypedEq < int > ( int ( SourceLocationKind : : Definition ) ) ) ) ;
2017-08-21 12:00:27 +02:00
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 , DropNewSymbolsTable )
{
EXPECT_CALL ( deleteNewSymbolsTableStatement , execute ( ) ) ;
storage . deleteNewSymbolsTable ( ) ;
}
TEST_F ( SymbolStorage , DropNewLocationsTable )
{
EXPECT_CALL ( deleteNewLocationsTableStatement , execute ( ) ) ;
storage . deleteNewLocationsTable ( ) ;
}
TEST_F ( SymbolStorage , AddSymbolsAndSourceLocationsCallsWrite )
{
InSequence sequence ;
2018-04-05 10:58:33 +02:00
EXPECT_CALL ( insertSymbolsToNewSymbolsStatement , write ( An < uint > ( ) , An < Utils : : SmallStringView > ( ) , An < Utils : : SmallStringView > ( ) , An < uint > ( ) ) ) . Times ( 2 ) ;
2018-04-09 13:30:30 +02:00
EXPECT_CALL ( insertLocationsToNewLocationsStatement , write ( TypedEq < SymbolIndex > ( 1 ) , TypedEq < int > ( 42 ) , TypedEq < int > ( 23 ) , TypedEq < int > ( 3 ) , TypedEq < int > ( int ( SourceLocationKind : : Declaration ) ) ) ) ;
EXPECT_CALL ( insertLocationsToNewLocationsStatement , write ( TypedEq < SymbolIndex > ( 2 ) , TypedEq < int > ( 7 ) , TypedEq < int > ( 11 ) , TypedEq < int > ( 4 ) , TypedEq < int > ( int ( SourceLocationKind : : Definition ) ) ) ) ;
2017-08-21 12:00:27 +02:00
EXPECT_CALL ( addNewSymbolsToSymbolsStatement , execute ( ) ) ;
EXPECT_CALL ( syncNewSymbolsFromSymbolsStatement , execute ( ) ) ;
EXPECT_CALL ( syncSymbolsIntoNewLocationsStatement , execute ( ) ) ;
EXPECT_CALL ( deleteAllLocationsFromUpdatedFilesStatement , execute ( ) ) ;
EXPECT_CALL ( insertNewLocationsInLocationsStatement , execute ( ) ) ;
EXPECT_CALL ( deleteNewSymbolsTableStatement , execute ( ) ) ;
EXPECT_CALL ( deleteNewLocationsTableStatement , execute ( ) ) ;
storage . addSymbolsAndSourceLocations ( symbolEntries , sourceLocations ) ;
}
2018-01-22 14:21:01 +01:00
TEST_F ( SymbolStorage , ConvertStringsToJson )
{
Utils : : SmallStringVector strings { " foo " , " bar " , " foo " } ;
auto jsonText = storage . toJson ( strings ) ;
ASSERT_THAT ( jsonText , Eq ( " [ \" foo \" , \" bar \" , \" foo \" ] " ) ) ;
}
2018-12-17 12:06:57 +01:00
TEST_F ( SymbolStorage , InsertOrUpdateProjectPart )
2018-01-22 14:21:01 +01:00
{
InSequence sequence ;
2018-12-17 12:06:57 +01:00
EXPECT_CALL ( insertOrUpdateProjectPartStatement ,
2018-01-29 12:07:15 +01:00
write ( TypedEq < Utils : : SmallStringView > ( " project " ) ,
2018-12-17 12:06:57 +01:00
TypedEq < Utils : : SmallStringView > ( R " ([ " foo " ]) " ) ,
TypedEq < Utils : : SmallStringView > ( R " ([[ " FOO " , " 1 " ,1]]) " ) ,
TypedEq < Utils : : SmallStringView > ( systemIncludeSearchPathsText ) ,
2019-01-23 14:10:58 +01:00
TypedEq < Utils : : SmallStringView > ( projectIncludeSearchPathsText ) ,
1 ,
34 ,
0 ) ) ;
2018-12-17 12:06:57 +01:00
EXPECT_CALL (
getProjectPartIdStatement , valueReturnInt32 ( TypedEq < Utils : : SmallStringView > ( " project " ) ) )
. WillOnce ( Return ( 74 ) ) ;
2019-01-23 14:10:58 +01:00
storage . insertOrUpdateProjectPart ( " project " ,
{ " foo " } ,
{ { " FOO " , " 1 " , 1 } } ,
systemIncludeSearchPaths ,
projectIncludeSearchPaths ,
Utils : : Language : : Cxx ,
Utils : : LanguageVersion : : CXX11 ,
Utils : : LanguageExtension : : None ) ;
2018-01-22 14:21:01 +01:00
}
2018-02-06 19:03:14 +01:00
TEST_F ( SymbolStorage , FetchProjectPartArtefactBySourceIdCallsValueInStatement )
2018-02-06 11:16:29 +01:00
{
2018-02-08 12:48:46 +01:00
EXPECT_CALL ( getProjectPartArtefactsBySourceId , valueReturnProjectPartArtefact ( 1 ) )
2018-02-06 11:16:29 +01:00
. WillRepeatedly ( Return ( artefact ) ) ;
2018-11-06 19:02:00 +01:00
storage . fetchProjectPartArtefact ( 1 ) ;
2018-02-06 11:16:29 +01:00
}
2018-02-06 19:03:14 +01:00
TEST_F ( SymbolStorage , FetchProjectPartArtefactBySourceIdReturnArtefact )
2018-02-06 11:16:29 +01:00
{
2018-02-08 12:48:46 +01:00
EXPECT_CALL ( getProjectPartArtefactsBySourceId , valueReturnProjectPartArtefact ( 1 ) )
2018-02-06 11:16:29 +01:00
. WillRepeatedly ( Return ( artefact ) ) ;
2018-11-06 19:02:00 +01:00
auto result = storage . fetchProjectPartArtefact ( 1 ) ;
2018-02-06 11:16:29 +01:00
ASSERT_THAT ( result , Eq ( artefact ) ) ;
}
2018-02-07 16:18:16 +01:00
TEST_F ( SymbolStorage , FetchProjectPartArtefactByProjectNameCallsValueInStatement )
{
2018-02-08 12:48:46 +01:00
EXPECT_CALL ( getProjectPartArtefactsBySourceId , valueReturnProjectPartArtefact ( 1 ) )
2018-02-07 16:18:16 +01:00
. WillRepeatedly ( Return ( artefact ) ) ;
2018-11-06 19:02:00 +01:00
storage . fetchProjectPartArtefact ( 1 ) ;
2018-02-07 16:18:16 +01:00
}
TEST_F ( SymbolStorage , FetchProjectPartArtefactByProjectNameReturnArtefact )
{
2018-02-08 12:48:46 +01:00
EXPECT_CALL ( getProjectPartArtefactsBySourceId , valueReturnProjectPartArtefact ( 1 ) )
2018-02-07 16:18:16 +01:00
. WillRepeatedly ( Return ( artefact ) ) ;
2018-11-06 19:02:00 +01:00
auto result = storage . fetchProjectPartArtefact ( 1 ) ;
2018-02-07 16:18:16 +01:00
ASSERT_THAT ( result , Eq ( artefact ) ) ;
}
2018-02-08 17:49:02 +01:00
2018-10-11 18:09:55 +02:00
TEST_F ( SymbolStorage , AddNewSymbolsTable )
{
InSequence s ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT, symbolKind INTEGER) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId) " ) ) ) ;
storage . createNewSymbolsTable ( ) ;
}
2018-02-08 17:49:02 +01:00
2018-10-11 18:09:55 +02:00
TEST_F ( SymbolStorage , AddNewLocationsTable )
{
InSequence s ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, sourceId INTEGER, line INTEGER, column INTEGER, locationKind INTEGER) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE UNIQUE INDEX IF NOT EXISTS index_newLocations_sourceId_line_column ON newLocations(sourceId, line, column) " ) ) ) ;
storage . createNewLocationsTable ( ) ;
}
TEST_F ( SymbolStorage , AddTablesInConstructor )
{
InSequence s ;
EXPECT_CALL ( mockDatabase , immediateBegin ( ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT, symbolKind INTEGER) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, sourceId INTEGER, line INTEGER, column INTEGER, locationKind INTEGER) " ) ) ) ;
EXPECT_CALL ( mockDatabase , execute ( Eq ( " CREATE UNIQUE INDEX IF NOT EXISTS index_newLocations_sourceId_line_column ON newLocations(sourceId, line, column) " ) ) ) ;
EXPECT_CALL ( mockDatabase , commit ( ) ) ;
Storage storage { mockDatabase } ;
}
2018-02-08 17:49:02 +01:00
2017-08-21 12:00:27 +02:00
}