15 #include "gmock/gmock.h" 16 #include "gtest/gtest.h" 22 TEST(HeaderSourceSwitchTest, FileHeuristic) {
31 Optional<Path> PathResult =
33 EXPECT_TRUE(PathResult.hasValue());
34 ASSERT_EQ(PathResult.getValue(), FooH);
37 EXPECT_TRUE(PathResult.hasValue());
38 ASSERT_EQ(PathResult.getValue(), FooCpp);
48 EXPECT_TRUE(PathResult.hasValue());
49 ASSERT_EQ(PathResult.getValue(), FooHH);
57 EXPECT_TRUE(PathResult.hasValue());
58 ASSERT_EQ(PathResult.getValue(), Foo2HH);
67 EXPECT_TRUE(PathResult.hasValue());
68 ASSERT_EQ(PathResult.getValue(), Foo3HXX);
73 EXPECT_FALSE(PathResult.hasValue());
77 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(arg))
78 if (ND->getQualifiedNameAsString() ==
Name)
83 TEST(HeaderSourceSwitchTest, GetLocalDecls) {
85 TU.HeaderCode = R
"cpp( 98 // Non-indexable symbols 105 auto AST = TU.
build();
107 testing::UnorderedElementsAre(
108 DeclNamed(
"MainF1"), DeclNamed(
"Foo"), DeclNamed(
"ns::Foo"),
109 DeclNamed(
"ns::Foo::method"), DeclNamed(
"ns::Foo::field")));
112 TEST(HeaderSourceSwitchTest, FromHeaderToSource) {
118 Testing.HeaderFilename =
"TestTU.h";
119 Testing.HeaderCode =
"void A_Sym1();";
120 Testing.Filename =
"a.cpp";
121 Testing.Code =
"void A_Sym1() {};";
122 for (
auto &Sym : Testing.headerSymbols())
123 AllSymbols.insert(Sym);
125 Testing.HeaderCode = R
"cpp( 130 Testing.Filename = "b.cpp";
131 Testing.Code = R
"cpp( 135 for (
auto &Sym : Testing.headerSymbols())
136 AllSymbols.insert(Sym);
141 llvm::StringRef HeaderCode;
142 llvm::Optional<std::string> ExpectedSource;
146 // no definition found in the index. 147 void NonDefinition(); 162 // a.cpp and b.cpp have same scope, but a.cpp because "a.cpp" < "b.cpp". 169 // We don't have definition in the index, so stay in the header. 174 for (
const auto &Case : TestCases) {
176 TU.Filename =
"TestTU.h";
177 TU.ExtraArgs.push_back(
"-xc++-header");
178 auto HeaderAST = TU.build();
179 EXPECT_EQ(Case.ExpectedSource,
185 TEST(HeaderSourceSwitchTest, FromSourceToHeader) {
198 TUForIndex.AdditionalFiles["a.h"] = R
"cpp( 201 TUForIndex.AdditionalFiles["b.h"] = R
"cpp( 205 TUForIndex.Filename = "TestTU.cpp";
206 auto Index = TUForIndex.index();
210 llvm::StringRef SourceCode;
211 llvm::Optional<std::string> ExpectedResult;
215 // symbol not in index, no header found 235 // a.h and b.h have same scope, but a.h wins because "a.h" < "b.h". 241 for (
const auto &Case : TestCases) {
243 TU.Filename =
"Test.cpp";
244 auto AST = TU.
build();
245 EXPECT_EQ(Case.ExpectedResult,
251 TEST(HeaderSourceSwitchTest, ClangdServerIntegration) {
252 class IgnoreDiagnostics :
public DiagnosticsConsumer {
254 std::vector<Diag> Diagnostics)
override {}
256 MockCompilationDatabase CDB;
257 CDB.ExtraClangFlags = {
"-I" +
261 std::string CppPath =
testPath(
"src/lib/test.cpp");
262 std::string HeaderPath =
testPath(
"src/include/test.h");
263 FS.Files[HeaderPath] =
"void foo();";
264 const std::string FileContent = R
"cpp( 268 FS.Files[CppPath] = FileContent; 270 Options.BuildDynamicSymbolIndex =
true;
273 EXPECT_EQ(HeaderPath,
llvm::StringRef PathRef
A typedef to represent a ref to file path.
static Options optsForTest()
Documents should not be synced at all.
llvm::Expected< llvm::Optional< clangd::Path > > runSwitchHeaderSource(ClangdServer &Server, PathRef File)
std::vector< const Decl * > getIndexableLocalDecls(ParsedAST &AST)
Returns all indexable decls that are present in the main file of the AST.
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
TEST(BackgroundQueueTest, Priority)
std::string testPath(PathRef File)
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
static constexpr llvm::StringLiteral Name
static TestTU withCode(llvm::StringRef Code)
CodeCompletionBuilder Builder
llvm::Optional< Path > getCorrespondingHeaderOrSource(const Path &OriginalFile, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS)
Given a header file, returns the best matching source file, and vice visa.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
IgnoreDiagnostics DiagConsumer
static llvm::Optional< ParsedAST > build(std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, const SymbolIndex *Index, const ParseOptions &Opts)
Attempts to run Clang and store parsed AST.
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags)
const SymbolIndex * Index