| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | /****************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (C) 2016 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 "sourcerangecontainer-matcher.h"
 | 
					
						
							|  |  |  | #include "dynamicastmatcherdiagnosticcontainer-matcher.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  | #include "filesystem-utilities.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <clangquery.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 11:12:00 +02:00
										 |  |  | #include <mutex>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | using ClangBackEnd::ClangQuery; | 
					
						
							| 
									
										
										
										
											2017-07-03 11:12:00 +02:00
										 |  |  | using ClangBackEnd::StringCache; | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  | using testing::AllOf; | 
					
						
							|  |  |  | using testing::Contains; | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | using testing::IsEmpty; | 
					
						
							|  |  |  | using testing::Not; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ClangQuery : public ::testing::Test | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     void SetUp() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2017-07-03 11:12:00 +02:00
										 |  |  |     StringCache<Utils::PathString, std::mutex> filePathCache; | 
					
						
							|  |  |  |     ::ClangQuery simpleFunctionQuery{filePathCache}; | 
					
						
							|  |  |  |     ::ClangQuery simpleClassQuery{filePathCache}; | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | using ClangQuerySlowTest = ClangQuery; | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_F(ClangQuery, NoSourceRangesForDefaultConstruction) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto sourceRanges = simpleFunctionQuery.takeSourceRanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(sourceRanges.sourceRangeWithTextContainers(), IsEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, SourceRangesForSimpleFunctionDeclarationAreNotEmpty) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleFunctionQuery.setQuery("functionDecl()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleFunctionQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(), Not(IsEmpty())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleFunctionQuery.setQuery("functionDecl()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleFunctionQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(), | 
					
						
							|  |  |  |                 Contains(IsSourceRangeWithText(1, 1, 8, 2, "int function(int* pointer, int value)\n{\n  if (pointer == nullptr) {\n    return value + 1;\n  } else {\n    return value - 1;\n  }\n}"))); | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange) | 
					
						
							| 
									
										
										
										
											2016-11-30 15:29:36 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-03 11:12:00 +02:00
										 |  |  |     ::ClangQuery query(filePathCache); | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); | 
					
						
							| 
									
										
										
										
											2016-11-30 15:29:36 +01:00
										 |  |  |     query.setQuery("functionDecl()"); | 
					
						
							|  |  |  |     ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}}; | 
					
						
							|  |  |  |     query.addUnsavedFiles({unsavedFile}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     query.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), | 
					
						
							|  |  |  |                 Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_F(ClangQuerySlowTest, FileIsNotExistingButTheUnsavedDataIsParsed) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ::ClangQuery query(filePathCache); | 
					
						
							|  |  |  |     query.addFile(TESTDATA_DIR, "foo.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/foo.cpp"), "-std=c++14"}); | 
					
						
							|  |  |  |     query.setQuery("functionDecl()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     query.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), | 
					
						
							|  |  |  |                 Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}"))); | 
					
						
							| 
									
										
										
										
											2016-11-30 15:29:36 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 14:00:32 +02:00
										 |  |  | TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-03 11:12:00 +02:00
										 |  |  |     ::ClangQuery query(filePathCache); | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); | 
					
						
							| 
									
										
										
										
											2017-06-26 14:00:32 +02:00
										 |  |  |     query.setQuery("functionDecl()"); | 
					
						
							|  |  |  |     ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}}; | 
					
						
							|  |  |  |     query.addUnsavedFiles({unsavedFile}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     query.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), | 
					
						
							|  |  |  |                 Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); | 
					
						
							| 
									
										
										
										
											2017-06-26 14:00:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFieldDeclarationRange) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleClassQuery.setQuery("fieldDecl(hasType(isInteger()))"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleClassQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0), | 
					
						
							| 
									
										
										
										
											2016-11-23 13:13:38 +01:00
										 |  |  |                 IsSourceRangeWithText(4, 5, 4, 10, "    int x;")); | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, NoSourceRangesForEmptyQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleClassQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers(), IsEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, NoSourceRangesForWrongQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleClassQuery.setQuery("wrongQuery()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleClassQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers(), IsEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, NoDiagnosticsForDefaultConstruction) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     auto diagnostics = simpleFunctionQuery.takeDiagnosticContainers(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(diagnostics, IsEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, DiagnosticsForEmptyQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleFunctionQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleFunctionQuery.takeDiagnosticContainers(), | 
					
						
							|  |  |  |                 Not(IsEmpty())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, DiagnosticsForWrongQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleClassQuery.setQuery("wrongQuery()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleClassQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleClassQuery.takeDiagnosticContainers(), | 
					
						
							|  |  |  |                 Not(IsEmpty())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, NoDiagnosticsForAccurateQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleFunctionQuery.setQuery("functionDecl()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleFunctionQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleFunctionQuery.takeDiagnosticContainers(), | 
					
						
							|  |  |  |                 IsEmpty()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, DiagnosticForWrongQuery) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleClassQuery.setQuery("wrongQuery()"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleClassQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleClassQuery.takeDiagnosticContainers(), | 
					
						
							|  |  |  |                 HasDiagnosticMessage("RegistryMatcherNotFound", 1, 1, 1, 11)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 11:39:17 +01:00
										 |  |  | TEST_F(ClangQuerySlowTest, DiagnosticForWrongArgumenType) | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     simpleFunctionQuery.setQuery("functionDecl(1)"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     simpleFunctionQuery.findLocations(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ASSERT_THAT(simpleFunctionQuery.takeDiagnosticContainers(), | 
					
						
							|  |  |  |                 AllOf(HasDiagnosticMessage("RegistryWrongArgType", 1, 14, 1, 15), | 
					
						
							|  |  |  |                       HasDiagnosticContext("MatcherConstruct", 1, 1, 1, 13))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClangQuery::SetUp() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-03 12:35:58 +02:00
										 |  |  |     simpleFunctionQuery.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); | 
					
						
							| 
									
										
										
										
											2016-11-15 15:38:12 +01:00
										 |  |  |     simpleClassQuery.addFile(TESTDATA_DIR, "query_simpleclass.cpp", "", {"cc", "query_simpleclass.cpp", "-std=c++14"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | } |