summaryrefslogtreecommitdiffstats
path: root/unittests/clangd/CodeCompleteTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/clangd/CodeCompleteTests.cpp')
-rw-r--r--unittests/clangd/CodeCompleteTests.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp
index 8ba9ebb3..4e598d35 100644
--- a/unittests/clangd/CodeCompleteTests.cpp
+++ b/unittests/clangd/CodeCompleteTests.cpp
@@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "ClangdServer.h"
#include "Compiler.h"
#include "Context.h"
@@ -13,6 +14,7 @@
#include "Protocol.h"
#include "SourceCode.h"
#include "TestFS.h"
+#include "index/MemIndex.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -83,6 +85,7 @@ StringWithPos parseTextMarker(StringRef Text) {
MATCHER_P(Named, Name, "") { return arg.insertText == Name; }
MATCHER_P(Labeled, Label, "") { return arg.label == Label; }
MATCHER_P(Kind, K, "") { return arg.kind == K; }
+MATCHER_P(Filter, F, "") { return arg.filterText == F; }
MATCHER_P(PlainText, Text, "") {
return arg.insertTextFormat == clangd::InsertTextFormat::PlainText &&
arg.insertText == Text;
@@ -457,6 +460,104 @@ TEST(SignatureHelpTest, ActiveArg) {
EXPECT_EQ(1, Results.activeParameter);
}
+std::unique_ptr<SymbolIndex> simpleIndexFromSymbols(
+ std::vector<std::pair<std::string, index::SymbolKind>> Symbols) {
+ auto I = llvm::make_unique<MemIndex>();
+ struct Snapshot {
+ SymbolSlab Slab;
+ std::vector<const Symbol *> Pointers;
+ };
+ auto Snap = std::make_shared<Snapshot>();
+ for (const auto &Pair : Symbols) {
+ Symbol Sym;
+ Sym.ID = SymbolID(Pair.first);
+ llvm::StringRef QName = Pair.first;
+ size_t Pos = QName.rfind("::");
+ if (Pos == llvm::StringRef::npos) {
+ Sym.Name = QName;
+ Sym.Scope = "";
+ } else {
+ Sym.Name = QName.substr(Pos + 2);
+ Sym.Scope = QName.substr(0, Pos);
+ }
+ Sym.SymInfo.Kind = Pair.second;
+ Snap->Slab.insert(std::move(Sym));
+ }
+ for (auto &Iter : Snap->Slab)
+ Snap->Pointers.push_back(&Iter.second);
+ auto S = std::shared_ptr<std::vector<const Symbol *>>(std::move(Snap),
+ &Snap->Pointers);
+ I->build(std::move(S));
+ return I;
+}
+
+TEST(CompletionTest, NoIndex) {
+ clangd::CodeCompleteOptions Opts;
+ Opts.Index = nullptr;
+
+ auto Results = completions(R"cpp(
+ namespace ns { class No {}; }
+ void f() { ns::^ }
+ )cpp",
+ Opts);
+ EXPECT_THAT(Results.items, Has("No"));
+}
+
+TEST(CompletionTest, SimpleIndexBased) {
+ clangd::CodeCompleteOptions Opts;
+ auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class},
+ {"nx::XYZ", index::SymbolKind::Class},
+ {"ns::foo", index::SymbolKind::Function}});
+ Opts.Index = I.get();
+
+ auto Results = completions(R"cpp(
+ namespace ns { class No {}; }
+ void f() { ns::^ }
+ )cpp",
+ Opts);
+ EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
+ EXPECT_THAT(Results.items, Has("foo", CompletionItemKind::Function));
+ EXPECT_THAT(Results.items, Not(Has("No")));
+}
+
+TEST(CompletionTest, IndexBasedWithFilter) {
+ clangd::CodeCompleteOptions Opts;
+ auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class},
+ {"ns::foo", index::SymbolKind::Function}});
+ Opts.Index = I.get();
+
+ auto Results = completions(R"cpp(
+ void f() { ns::x^ }
+ )cpp",
+ Opts);
+ EXPECT_THAT(Results.items, Contains(AllOf(Named("XYZ"), Filter("x"))));
+ EXPECT_THAT(Results.items, Not(Has("foo")));
+}
+
+TEST(CompletionTest, GlobalQualified) {
+ clangd::CodeCompleteOptions Opts;
+ auto I = simpleIndexFromSymbols({{"XYZ", index::SymbolKind::Class}});
+ Opts.Index = I.get();
+
+ auto Results = completions(R"cpp(
+ void f() { ::^ }
+ )cpp",
+ Opts);
+ EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
+}
+
+TEST(CompletionTest, FullyQualifiedScope) {
+ clangd::CodeCompleteOptions Opts;
+ auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
+ Opts.Index = I.get();
+
+ auto Results = completions(R"cpp(
+ void f() { ::ns::^ }
+ )cpp",
+ Opts);
+ EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
+}
+
} // namespace
} // namespace clangd
} // namespace clang