[clang-tools-extra] r322824 - [clangd] CodeCompleteTests cleanup: naming, ordering, helpers. NFC

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 18 01:27:56 PST 2018


Author: sammccall
Date: Thu Jan 18 01:27:56 2018
New Revision: 322824

URL: http://llvm.org/viewvc/llvm-project?rev=322824&view=rev
Log:
[clangd] CodeCompleteTests cleanup: naming, ordering, helpers. NFC

Modified:
    clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp

Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=322824&r1=322823&r2=322824&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Thu Jan 18 01:27:56 2018
@@ -97,8 +97,25 @@ Matcher<const std::vector<CompletionItem
 }
 MATCHER(IsDocumented, "") { return !arg.documentation.empty(); }
 
+std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) {
+  SymbolSlab::Builder Slab;
+  for (const auto &Sym : Symbols)
+    Slab.insert(Sym);
+  return MemIndex::build(std::move(Slab).build());
+}
+
+// Builds a server and runs code completion.
+// If IndexSymbols is non-empty, an index will be built and passed to opts.
 CompletionList completions(StringRef Text,
+                           std::vector<Symbol> IndexSymbols = {},
                            clangd::CodeCompleteOptions Opts = {}) {
+  std::unique_ptr<SymbolIndex> OverrideIndex;
+  if (!IndexSymbols.empty()) {
+    assert(!Opts.Index && "both Index and IndexSymbols given!");
+    OverrideIndex = memIndex(std::move(IndexSymbols));
+    Opts.Index = OverrideIndex.get();
+  }
+
   MockFSProvider FS;
   MockCompilationDatabase CDB;
   IgnoreDiagnostics DiagConsumer;
@@ -116,6 +133,27 @@ CompletionList completions(StringRef Tex
   return CompletionList;
 }
 
+// Helpers to produce fake index symbols for memIndex() or completions().
+Symbol sym(StringRef QName, index::SymbolKind Kind) {
+  Symbol Sym;
+  Sym.ID = SymbolID(QName);
+  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.CompletionPlainInsertText = Sym.Name;
+  Sym.CompletionLabel = Sym.Name;
+  Sym.SymInfo.Kind = Kind;
+  return Sym;
+}
+Symbol func(StringRef Name) { return sym(Name, index::SymbolKind::Function); }
+Symbol cls(StringRef Name) { return sym(Name, index::SymbolKind::Class); }
+Symbol var(StringRef Name) { return sym(Name, index::SymbolKind::Variable); }
+
 TEST(CompletionTest, Limit) {
   clangd::CodeCompleteOptions Opts;
   Opts.Limit = 2;
@@ -127,7 +165,7 @@ struct ClassWithMembers {
 }
 int main() { ClassWithMembers().^ }
       )cpp",
-                             Opts);
+                             /*IndexSymbols=*/{}, Opts);
 
   EXPECT_TRUE(Results.isIncomplete);
   EXPECT_THAT(Results.items, ElementsAre(Named("AAA"), Named("BBB")));
@@ -188,7 +226,7 @@ void TestAfterDotCompletion(clangd::Code
         ClassWithMembers().^
       }
       )cpp",
-      Opts);
+      /*IndexSymbols=*/{}, Opts);
 
   // Class members. The only items that must be present in after-dot
   // completion.
@@ -233,7 +271,7 @@ void TestGlobalScopeCompletion(clangd::C
         ^
       }
       )cpp",
-      Opts);
+      /*IndexSymbols=*/{}, Opts);
 
   // Class members. Should never be present in global completions.
   EXPECT_THAT(Results.items,
@@ -355,7 +393,7 @@ TEST(CompletionTest, Snippets) {
         f.^
       }
       )cpp",
-      Opts);
+      /*IndexSymbols=*/{}, Opts);
   EXPECT_THAT(Results.items,
               HasSubsequence(Snippet("a"),
                              Snippet("f(${1:int i}, ${2:const float f})")));
@@ -375,9 +413,6 @@ TEST(CompletionTest, Kinds) {
   EXPECT_THAT(Results.items, Has("Struct", CompletionItemKind::Class));
   EXPECT_THAT(Results.items, Has("MACRO", CompletionItemKind::Text));
 
-  clangd::CodeCompleteOptions Opts;
-  Opts.EnableSnippets = true; // Needed for code patterns.
-
   Results = completions("nam^");
   EXPECT_THAT(Results.items, Has("namespace", CompletionItemKind::Snippet));
 }
@@ -406,184 +441,67 @@ TEST(CompletionTest, FuzzyRanking) {
   EXPECT_THAT(Items, ElementsAre(Named("BigBang"), Named("Babble")));
 }
 
-SignatureHelp signatures(StringRef Text) {
-  MockFSProvider FS;
-  MockCompilationDatabase CDB;
-  IgnoreDiagnostics DiagConsumer;
-  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
-                      /*StorePreamblesInMemory=*/true);
-  auto File = getVirtualTestFilePath("foo.cpp");
-  Annotations Test(Text);
-  Server.addDocument(Context::empty(), File, Test.code());
-  auto R = Server.signatureHelp(Context::empty(), File, Test.point());
-  assert(R);
-  return R.get().Value;
-}
-
-MATCHER_P(ParamsAre, P, "") {
-  if (P.size() != arg.parameters.size())
-    return false;
-  for (unsigned I = 0; I < P.size(); ++I)
-    if (P[I] != arg.parameters[I].label)
-      return false;
-  return true;
-}
-
-Matcher<SignatureInformation> Sig(std::string Label,
-                                  std::vector<std::string> Params) {
-  return AllOf(Labeled(Label), ParamsAre(Params));
-}
-
-TEST(SignatureHelpTest, Overloads) {
-  auto Results = signatures(R"cpp(
-    void foo(int x, int y);
-    void foo(int x, float y);
-    void foo(float x, int y);
-    void foo(float x, float y);
-    void bar(int x, int y = 0);
-    int main() { foo(^); }
-  )cpp");
-  EXPECT_THAT(Results.signatures,
-              UnorderedElementsAre(
-                  Sig("foo(float x, float y) -> void", {"float x", "float y"}),
-                  Sig("foo(float x, int y) -> void", {"float x", "int y"}),
-                  Sig("foo(int x, float y) -> void", {"int x", "float y"}),
-                  Sig("foo(int x, int y) -> void", {"int x", "int y"})));
-  // We always prefer the first signature.
-  EXPECT_EQ(0, Results.activeSignature);
-  EXPECT_EQ(0, Results.activeParameter);
-}
-
-TEST(SignatureHelpTest, DefaultArgs) {
-  auto Results = signatures(R"cpp(
-    void bar(int x, int y = 0);
-    void bar(float x = 0, int y = 42);
-    int main() { bar(^
-  )cpp");
-  EXPECT_THAT(Results.signatures,
-              UnorderedElementsAre(
-                  Sig("bar(int x, int y = 0) -> void", {"int x", "int y = 0"}),
-                  Sig("bar(float x = 0, int y = 42) -> void",
-                      {"float x = 0", "int y = 42"})));
-  EXPECT_EQ(0, Results.activeSignature);
-  EXPECT_EQ(0, Results.activeParameter);
-}
-
-TEST(SignatureHelpTest, ActiveArg) {
-  auto Results = signatures(R"cpp(
-    int baz(int a, int b, int c);
-    int main() { baz(baz(1,2,3), ^); }
-  )cpp");
-  EXPECT_THAT(Results.signatures,
-              ElementsAre(Sig("baz(int a, int b, int c) -> int",
-                              {"int a", "int b", "int c"})));
-  EXPECT_EQ(0, Results.activeSignature);
-  EXPECT_EQ(1, Results.activeParameter);
-}
-
-std::unique_ptr<SymbolIndex> simpleIndexFromSymbols(
-    std::vector<std::pair<std::string, index::SymbolKind>> Symbols) {
-  SymbolSlab::Builder Slab;
-  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.CompletionPlainInsertText = Sym.Name;
-    Sym.SymInfo.Kind = Pair.second;
-    Slab.insert(Sym);
-  }
-  return MemIndex::build(std::move(Slab).build());
-}
-
 TEST(CompletionTest, NoIndex) {
-  clangd::CodeCompleteOptions Opts;
-  Opts.Index = nullptr;
-
   auto Results = completions(R"cpp(
       namespace ns { class Local {}; }
       void f() { ns::^ }
-  )cpp",
-                             Opts);
+  )cpp");
   EXPECT_THAT(Results.items, Has("Local"));
 }
 
 TEST(CompletionTest, StaticAndDynamicIndex) {
   clangd::CodeCompleteOptions Opts;
-  auto StaticIdx =
-      simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
-  auto DynamicIdx =
-      simpleIndexFromSymbols({{"ns::foo", index::SymbolKind::Function}});
+  auto StaticIdx = memIndex({cls("ns::XYZ")});
+  auto DynamicIdx = memIndex({func("ns::foo")});
   auto Merge = mergeIndex(DynamicIdx.get(), StaticIdx.get());
   Opts.Index = Merge.get();
 
-  auto Results = completions(R"cpp(
-      void f() { ::ns::^ }
-  )cpp",
-                             Opts);
+  auto Results = completions(
+      R"cpp(
+          void f() { ::ns::^ }
+      )cpp",
+      /*IndexSymbols=*/{}, Opts);
   EXPECT_THAT(Results.items, Contains(Labeled("[I]XYZ")));
   EXPECT_THAT(Results.items, Contains(Labeled("[I]foo")));
 }
 
-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 { int local; }
-      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, Has("local"));
+TEST(CompletionTest, IndexScope) {
+  auto Results = completions(
+      R"cpp(
+          namespace ns { int local; }
+          void f() { ns::^ }
+      )cpp",
+      {cls("ns::XYZ"), cls("nx::XYZ"), func("ns::foo")});
+  EXPECT_THAT(Results.items,
+              UnorderedElementsAre(Named("XYZ"), Named("foo"), Named("local")));
 }
 
 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("XYZ"))));
-  EXPECT_THAT(Results.items, Not(Has("foo")));
+  auto Results = completions(
+      R"cpp(
+          void f() { ns::x^ }
+      )cpp",
+      {cls("ns::XYZ"), func("ns::foo")});
+  EXPECT_THAT(Results.items,
+              UnorderedElementsAre(AllOf(Named("XYZ"), Filter("XYZ"))));
 }
 
-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, IndexGlobalQualified) {
+  auto Results = completions(
+      R"cpp(
+          void f() { ::^ }
+      )cpp",
+      {cls("XYZ")});
+  EXPECT_THAT(Results.items, AllOf(Has("XYZ", CompletionItemKind::Class),
+                                   Has("f", CompletionItemKind::Function)));
 }
 
-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);
+TEST(CompletionTest, IndexFullyQualifiedScope) {
+  auto Results = completions(
+      R"cpp(
+          void f() { ::ns::^ }
+      )cpp",
+      {cls("ns::XYZ")});
   EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
 }
 
@@ -612,7 +530,7 @@ TEST(CompletionTest, IndexSuppressesPrea
   EXPECT_THAT(WithoutIndex.items,
               UnorderedElementsAre(Named("local"), Named("preamble")));
 
-  auto I = simpleIndexFromSymbols({{"ns::index", index::SymbolKind::Variable}});
+  auto I = memIndex({var("ns::index")});
   Opts.Index = I.get();
   auto WithIndex =
       Server.codeComplete(Context::empty(), File, Test.point(), Opts)
@@ -622,7 +540,7 @@ TEST(CompletionTest, IndexSuppressesPrea
               UnorderedElementsAre(Named("local"), Named("index")));
 }
 
-TEST(CompletionTest, ASTIndexMultiFile) {
+TEST(CompletionTest, DynamicIndexMultiFile) {
   MockFSProvider FS;
   MockCompilationDatabase CDB;
   IgnoreDiagnostics DiagConsumer;
@@ -660,6 +578,81 @@ TEST(CompletionTest, ASTIndexMultiFile)
                                             Doc("Doooc"), Detail("void"))));
 }
 
+SignatureHelp signatures(StringRef Text) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
+                      /*StorePreamblesInMemory=*/true);
+  auto File = getVirtualTestFilePath("foo.cpp");
+  Annotations Test(Text);
+  Server.addDocument(Context::empty(), File, Test.code());
+  auto R = Server.signatureHelp(Context::empty(), File, Test.point());
+  assert(R);
+  return R.get().Value;
+}
+
+MATCHER_P(ParamsAre, P, "") {
+  if (P.size() != arg.parameters.size())
+    return false;
+  for (unsigned I = 0; I < P.size(); ++I)
+    if (P[I] != arg.parameters[I].label)
+      return false;
+  return true;
+}
+
+Matcher<SignatureInformation> Sig(std::string Label,
+                                  std::vector<std::string> Params) {
+  return AllOf(Labeled(Label), ParamsAre(Params));
+}
+
+TEST(SignatureHelpTest, Overloads) {
+  auto Results = signatures(R"cpp(
+    void foo(int x, int y);
+    void foo(int x, float y);
+    void foo(float x, int y);
+    void foo(float x, float y);
+    void bar(int x, int y = 0);
+    int main() { foo(^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+              UnorderedElementsAre(
+                  Sig("foo(float x, float y) -> void", {"float x", "float y"}),
+                  Sig("foo(float x, int y) -> void", {"float x", "int y"}),
+                  Sig("foo(int x, float y) -> void", {"int x", "float y"}),
+                  Sig("foo(int x, int y) -> void", {"int x", "int y"})));
+  // We always prefer the first signature.
+  EXPECT_EQ(0, Results.activeSignature);
+  EXPECT_EQ(0, Results.activeParameter);
+}
+
+TEST(SignatureHelpTest, DefaultArgs) {
+  auto Results = signatures(R"cpp(
+    void bar(int x, int y = 0);
+    void bar(float x = 0, int y = 42);
+    int main() { bar(^
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+              UnorderedElementsAre(
+                  Sig("bar(int x, int y = 0) -> void", {"int x", "int y = 0"}),
+                  Sig("bar(float x = 0, int y = 42) -> void",
+                      {"float x = 0", "int y = 42"})));
+  EXPECT_EQ(0, Results.activeSignature);
+  EXPECT_EQ(0, Results.activeParameter);
+}
+
+TEST(SignatureHelpTest, ActiveArg) {
+  auto Results = signatures(R"cpp(
+    int baz(int a, int b, int c);
+    int main() { baz(baz(1,2,3), ^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+              ElementsAre(Sig("baz(int a, int b, int c) -> int",
+                              {"int a", "int b", "int c"})));
+  EXPECT_EQ(0, Results.activeSignature);
+  EXPECT_EQ(1, Results.activeParameter);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang




More information about the cfe-commits mailing list