| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (C) 2018 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:48:25 +01:00
										 |  |  | #include "mockbuilddependenciesstorage.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | #include "mockmodifiedtimechecker.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-12 19:27:51 +01:00
										 |  |  | #include "mockbuilddependencygenerator.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  | #include "mocksqlitetransactionbackend.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <builddependenciesprovider.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using ClangBackEnd::BuildDependency; | 
					
						
							|  |  |  | using ClangBackEnd::BuildDependencies; | 
					
						
							|  |  |  | using ClangBackEnd::FilePathId; | 
					
						
							|  |  |  | using ClangBackEnd::FilePathIds; | 
					
						
							|  |  |  | using ClangBackEnd::SourceEntry; | 
					
						
							|  |  |  | using ClangBackEnd::SourceEntries; | 
					
						
							|  |  |  | using ClangBackEnd::SourceType; | 
					
						
							|  |  |  | using ClangBackEnd::UsedMacro; | 
					
						
							|  |  |  | using ClangBackEnd::UsedMacros; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MATCHER_P(HasSourceId, sourceId,  std::string(negation ? "hasn't" : "has") | 
					
						
							|  |  |  |           + " sourceId " + PrintToString(sourceId)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const SourceEntry & sourceEntry = arg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return sourceEntry.sourceId.filePathId == sourceId; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BuildDependenciesProvider : public testing::Test | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend; | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage; | 
					
						
							|  |  |  |     NiceMock<MockModifiedTimeChecker> mockModifiedTimeChecker; | 
					
						
							| 
									
										
										
										
											2018-11-12 19:27:51 +01:00
										 |  |  |     NiceMock<MockBuildDependencyGenerator> mockBuildDependenciesGenerator; | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     ClangBackEnd::BuildDependenciesProvider provider{mockBuildDependenciesStorage, | 
					
						
							|  |  |  |                                                      mockModifiedTimeChecker, | 
					
						
							|  |  |  |                                                      mockBuildDependenciesGenerator, | 
					
						
							|  |  |  |                                                      mockSqliteTransactionBackend}; | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1", | 
					
						
							|  |  |  |                                                         {"--yi"}, | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |                                                         {{"YI", "1"}}, | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |                                                         {"/yi"}, | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |                                                         {1}, | 
					
						
							|  |  |  |                                                         {2}}; | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2", | 
					
						
							|  |  |  |                                                         {"--er"}, | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |                                                         {{"ER", "2"}}, | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |                                                         {"/er"}, | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |                                                         {1}, | 
					
						
							|  |  |  |                                                         {2, 3, 4}}; | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     SourceEntries firstSources{{1, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                {2, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                {10, SourceType::UserInclude, 1}}; | 
					
						
							|  |  |  |     SourceEntries secondSources{{1, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                 {3, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                 {8, SourceType::UserInclude, 1}}; | 
					
						
							|  |  |  |     SourceEntries thirdSources{{4, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                {8, SourceType::UserInclude, 1}, | 
					
						
							|  |  |  |                                {10, SourceType::UserInclude, 1}}; | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |     UsedMacros firstUsedMacros{{"YI", 1}}; | 
					
						
							|  |  |  |     UsedMacros secondUsedMacros{{"LIANG", 2}, {"ER", 2}}; | 
					
						
							|  |  |  |     UsedMacros thirdUsedMacros{{"SAN", 10}}; | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     FilePathIds sourceFiles{1, 3, 8}; | 
					
						
							|  |  |  |     ClangBackEnd::SourceDependencies sourceDependencies{{1, 3}, {1, 8}}; | 
					
						
							|  |  |  |     ClangBackEnd::FileStatuses fileStatuses{{1, 21, 12, false}, | 
					
						
							|  |  |  |                                             {3, 21, 12, false}, | 
					
						
							|  |  |  |                                             {8, 21, 12, false}}; | 
					
						
							|  |  |  |     BuildDependency buildDependency{ | 
					
						
							|  |  |  |         secondSources, | 
					
						
							|  |  |  |         secondUsedMacros, | 
					
						
							|  |  |  |         sourceFiles, | 
					
						
							|  |  |  |         sourceDependencies, | 
					
						
							|  |  |  |         fileStatuses | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTimeStampsAreUpToDate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     InSequence s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, | 
					
						
							|  |  |  |                 fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))) | 
					
						
							|  |  |  |         .WillRepeatedly(Return(firstSources)); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)).Times(0); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     provider.create(projectPart1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, FetchDependSourcesFromStorage) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-07 17:48:25 +01:00
										 |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(firstSources)); | 
					
						
							|  |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(secondSources)); | 
					
						
							|  |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(thirdSources)); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto buildDependency = provider.create(projectPart2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(buildDependency.includes, ElementsAre(HasSourceId(1), HasSourceId(2), HasSourceId(3), HasSourceId(4), HasSourceId(8), HasSourceId(10))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTimeStampsAreNotUpToDate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     InSequence s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, | 
					
						
							|  |  |  |                 fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))) | 
					
						
							|  |  |  |         .WillRepeatedly(Return(firstSources)); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false)); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)) | 
					
						
							|  |  |  |         .WillOnce(Return(buildDependency)); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, updateSources(Eq(secondSources))); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatuses))); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(secondUsedMacros))); | 
					
						
							|  |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     provider.create(projectPart1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, FetchDependSourcesFromGenerator) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-07 17:48:25 +01:00
										 |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillByDefault(Return(firstSources)); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(false)); | 
					
						
							|  |  |  |     ON_CALL(mockBuildDependenciesGenerator, create(projectPart1)).WillByDefault(Return(buildDependency)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto buildDependency = provider.create(projectPart1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(buildDependency.includes, ElementsAre(HasSourceId(1), HasSourceId(3), HasSourceId(8))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeStampsAreUpToDate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     InSequence s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); | 
					
						
							| 
									
										
										
										
											2018-11-07 17:48:25 +01:00
										 |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources)); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true)); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})); | 
					
						
							|  |  |  |     EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10})); | 
					
						
							| 
									
										
										
										
											2018-11-20 16:20:41 +01:00
										 |  |  |     EXPECT_CALL(mockSqliteTransactionBackend, commit()); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     provider.create(projectPart1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(BuildDependenciesProvider, FetchUsedMacrosFromStorageIfDependSourcesAreUpToDate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-07 17:48:25 +01:00
										 |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillByDefault(Return(firstSources)); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  |     ON_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillByDefault(Return(true)); | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})).WillByDefault(Return(firstUsedMacros)); | 
					
						
							|  |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})).WillByDefault(Return(secondUsedMacros)); | 
					
						
							|  |  |  |     ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10})).WillByDefault(Return(thirdUsedMacros)); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto buildDependency = provider.create(projectPart1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-06 19:02:00 +01:00
										 |  |  |     ASSERT_THAT(buildDependency.usedMacros, ElementsAre(UsedMacro{"YI", 1}, UsedMacro{"ER", 2}, UsedMacro{"LIANG", 2}, UsedMacro{"SAN", 10})); | 
					
						
							| 
									
										
										
										
											2018-10-25 11:08:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | } |