//
//===----------------------------------------------------------------------===//
-#include "Annotations.h"
#include "AST.h"
+#include "Annotations.h"
#include "ClangdUnit.h"
+#include "SyncAPI.h"
#include "TestFS.h"
#include "TestTU.h"
-#include "gmock/gmock.h"
#include "index/FileIndex.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Index/IndexSymbol.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CompilationDatabase.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
using testing::_;
using testing::AllOf;
+using testing::Contains;
using testing::ElementsAre;
+using testing::IsEmpty;
using testing::Pair;
using testing::UnorderedElementsAre;
Range.end.character);
}
MATCHER_P(FileURI, F, "") { return arg.Location.FileURI == F; }
+MATCHER_P(DeclURI, U, "") { return arg.CanonicalDeclaration.FileURI == U; }
+MATCHER_P(QName, N, "") { return (arg.Scope + arg.Name).str() == N; }
namespace clang {
namespace clangd {
return llvm::make_unique<RefSlab>(std::move(Slab).build());
}
-std::vector<std::string> getSymbolNames(const SymbolIndex &I,
- std::string Query = "") {
- FuzzyFindRequest Req;
- Req.Query = Query;
- std::vector<std::string> Names;
- I.fuzzyFind(Req, [&](const Symbol &S) { Names.push_back(S.Name); });
- return Names;
-}
-
RefSlab getRefs(const SymbolIndex &I, SymbolID ID) {
RefsRequest Req;
Req.IDs = {ID};
TEST(FileSymbolsTest, UpdateAndGet) {
FileSymbols FS;
- EXPECT_THAT(getSymbolNames(*FS.buildMemIndex()), UnorderedElementsAre());
+ EXPECT_THAT(runFuzzyFind(*FS.buildMemIndex(), ""), IsEmpty());
FS.update("f1", numSlab(1, 3), refSlab(SymbolID("1"), "f1.cc"));
- EXPECT_THAT(getSymbolNames(*FS.buildMemIndex()),
- UnorderedElementsAre("1", "2", "3"));
+ EXPECT_THAT(runFuzzyFind(*FS.buildMemIndex(), ""),
+ UnorderedElementsAre(QName("1"), QName("2"), QName("3")));
EXPECT_THAT(getRefs(*FS.buildMemIndex(), SymbolID("1")),
RefsAre({FileURI("f1.cc")}));
}
FileSymbols FS;
FS.update("f1", numSlab(1, 3), nullptr);
FS.update("f2", numSlab(3, 5), nullptr);
- EXPECT_THAT(getSymbolNames(*FS.buildMemIndex()),
- UnorderedElementsAre("1", "2", "3", "4", "5"));
+ EXPECT_THAT(runFuzzyFind(*FS.buildMemIndex(), ""),
+ UnorderedElementsAre(QName("1"), QName("2"), QName("3"),
+ QName("4"), QName("5")));
}
TEST(FileSymbolsTest, SnapshotAliveAfterRemove) {
FS.update("f1", numSlab(1, 3), refSlab(ID, "f1.cc"));
auto Symbols = FS.buildMemIndex();
- EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+ EXPECT_THAT(runFuzzyFind(*Symbols, ""),
+ UnorderedElementsAre(QName("1"), QName("2"), QName("3")));
EXPECT_THAT(getRefs(*Symbols, ID), RefsAre({FileURI("f1.cc")}));
FS.update("f1", nullptr, nullptr);
auto Empty = FS.buildMemIndex();
- EXPECT_THAT(getSymbolNames(*Empty), UnorderedElementsAre());
+ EXPECT_THAT(runFuzzyFind(*Empty, ""), IsEmpty());
EXPECT_THAT(getRefs(*Empty, ID), ElementsAre());
- EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+ EXPECT_THAT(runFuzzyFind(*Symbols, ""),
+ UnorderedElementsAre(QName("1"), QName("2"), QName("3")));
EXPECT_THAT(getRefs(*Symbols, ID), RefsAre({FileURI("f1.cc")}));
}
-std::vector<std::string> match(const SymbolIndex &I,
- const FuzzyFindRequest &Req) {
- std::vector<std::string> Matches;
- I.fuzzyFind(Req, [&](const Symbol &Sym) {
- Matches.push_back((Sym.Scope + Sym.Name).str());
- });
- return Matches;
-}
-
// Adds Basename.cpp, which includes Basename.h, which contains Code.
void update(FileIndex &M, llvm::StringRef Basename, llvm::StringRef Code) {
TestTU File;
FileIndex M({"unittest"});
update(M, "f", "class string {};");
- FuzzyFindRequest Req;
- Req.Query = "";
- bool SeenSymbol = false;
- M.fuzzyFind(Req, [&](const Symbol &Sym) {
- EXPECT_EQ(Sym.CanonicalDeclaration.FileURI, "unittest:///f.h");
- SeenSymbol = true;
- });
- EXPECT_TRUE(SeenSymbol);
+ EXPECT_THAT(runFuzzyFind(M, ""), ElementsAre(DeclURI("unittest:///f.h")));
}
TEST(FileIndexTest, IndexAST) {
FuzzyFindRequest Req;
Req.Query = "";
Req.Scopes = {"ns::"};
- EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns::f", "ns::X"));
+ EXPECT_THAT(runFuzzyFind(M, Req),
+ UnorderedElementsAre(QName("ns::f"), QName("ns::X")));
}
TEST(FileIndexTest, NoLocal) {
FileIndex M;
update(M, "f1", "namespace ns { void f() { int local = 0; } class X {}; }");
- FuzzyFindRequest Req;
- Req.Query = "";
- EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns", "ns::f", "ns::X"));
+ EXPECT_THAT(
+ runFuzzyFind(M, ""),
+ UnorderedElementsAre(QName("ns"), QName("ns::f"), QName("ns::X")));
}
TEST(FileIndexTest, IndexMultiASTAndDeduplicate) {
update(M, "f2", "namespace ns { void ff() {} class X {}; }");
FuzzyFindRequest Req;
- Req.Query = "";
Req.Scopes = {"ns::"};
- EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns::f", "ns::X", "ns::ff"));
+ EXPECT_THAT(
+ runFuzzyFind(M, Req),
+ UnorderedElementsAre(QName("ns::f"), QName("ns::X"), QName("ns::ff")));
}
TEST(FileIndexTest, ClassMembers) {
FileIndex M;
update(M, "f1", "class X { static int m1; int m2; static void f(); };");
- FuzzyFindRequest Req;
- Req.Query = "";
- EXPECT_THAT(match(M, Req),
- UnorderedElementsAre("X", "X::m1", "X::m2", "X::f"));
+ EXPECT_THAT(runFuzzyFind(M, ""),
+ UnorderedElementsAre(QName("X"), QName("X::m1"), QName("X::m2"),
+ QName("X::f")));
}
TEST(FileIndexTest, NoIncludeCollected) {
FileIndex M;
update(M, "f", "class string {};");
- FuzzyFindRequest Req;
- Req.Query = "";
- bool SeenSymbol = false;
- M.fuzzyFind(Req, [&](const Symbol &Sym) {
- EXPECT_TRUE(Sym.IncludeHeaders.empty());
- SeenSymbol = true;
- });
- EXPECT_TRUE(SeenSymbol);
+ auto Symbols = runFuzzyFind(M, "");
+ EXPECT_THAT(Symbols, ElementsAre(_));
+ EXPECT_THAT(Symbols.begin()->IncludeHeaders, IsEmpty());
}
TEST(FileIndexTest, TemplateParamsInLabel) {
FileIndex M;
update(M, "f", Source);
- FuzzyFindRequest Req;
- Req.Query = "";
- bool SeenVector = false;
- bool SeenMakeVector = false;
- M.fuzzyFind(Req, [&](const Symbol &Sym) {
- if (Sym.Name == "vector") {
- EXPECT_EQ(Sym.Signature, "<class Ty>");
- EXPECT_EQ(Sym.CompletionSnippetSuffix, "<${1:class Ty}>");
- SeenVector = true;
- return;
- }
+ auto Symbols = runFuzzyFind(M, "");
+ EXPECT_THAT(Symbols,
+ UnorderedElementsAre(QName("vector"), QName("make_vector")));
+ auto It = Symbols.begin();
+ Symbol Vector = *It++;
+ Symbol MakeVector = *It++;
+ if (MakeVector.Name == "vector")
+ std::swap(MakeVector, Vector);
- if (Sym.Name == "make_vector") {
- EXPECT_EQ(Sym.Signature, "<class Ty>(Arg A)");
- EXPECT_EQ(Sym.CompletionSnippetSuffix, "<${1:class Ty}>(${2:Arg A})");
- SeenMakeVector = true;
- }
- });
- EXPECT_TRUE(SeenVector);
- EXPECT_TRUE(SeenMakeVector);
+ EXPECT_EQ(Vector.Signature, "<class Ty>");
+ EXPECT_EQ(Vector.CompletionSnippetSuffix, "<${1:class Ty}>");
+
+ EXPECT_EQ(MakeVector.Signature, "<class Ty>(Arg A)");
+ EXPECT_EQ(MakeVector.CompletionSnippetSuffix, "<${1:class Ty}>(${2:Arg A})");
}
TEST(FileIndexTest, RebuildWithPreamble) {
Req.Query = "";
Req.Scopes = {"", "ns_in_header::"};
- EXPECT_THAT(
- match(Index, Req),
- UnorderedElementsAre("ns_in_header", "ns_in_header::func_in_header"));
+ EXPECT_THAT(runFuzzyFind(Index, Req),
+ UnorderedElementsAre(QName("ns_in_header"),
+ QName("ns_in_header::func_in_header")));
}
TEST(FileIndexTest, Refs) {
TEST(FileIndexTest, CollectMacros) {
FileIndex M;
update(M, "f", "#define CLANGD 1");
-
- FuzzyFindRequest Req;
- Req.Query = "";
- bool SeenSymbol = false;
- M.fuzzyFind(Req, [&](const Symbol &Sym) {
- EXPECT_EQ(Sym.Name, "CLANGD");
- EXPECT_EQ(Sym.SymInfo.Kind, index::SymbolKind::Macro);
- SeenSymbol = true;
- });
- EXPECT_TRUE(SeenSymbol);
+ EXPECT_THAT(runFuzzyFind(M, ""), Contains(QName("CLANGD")));
}
TEST(FileIndexTest, ReferencesInMainFileWithPreamble) {