[clang-tools-extra] aaa8b44 - [clangd] Add a TestWorkspace utility

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 24 17:15:48 PDT 2020


Author: Nathan Ridge
Date: 2020-10-24T20:15:17-04:00
New Revision: aaa8b44d19918ea1764339224cec68c27445aa8e

URL: https://github.com/llvm/llvm-project/commit/aaa8b44d19918ea1764339224cec68c27445aa8e
DIFF: https://github.com/llvm/llvm-project/commit/aaa8b44d19918ea1764339224cec68c27445aa8e.diff

LOG: [clangd] Add a TestWorkspace utility

TestWorkspace allows easily writing tests involving multiple
files that can have inclusion relationships between them.

BackgroundIndexTest.RelationsMultiFile is refactored to use
TestWorkspace, and moved to FileIndexTest as it no longer
depends on BackgroundIndex.

Differential Revision: https://reviews.llvm.org/D89297

Added: 
    clang-tools-extra/clangd/unittests/TestWorkspace.cpp
    clang-tools-extra/clangd/unittests/TestWorkspace.h

Modified: 
    clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
    clang-tools-extra/clangd/unittests/CMakeLists.txt
    clang-tools-extra/clangd/unittests/FileIndexTests.cpp
    clang-tools-extra/clangd/unittests/TestTU.cpp
    clang-tools-extra/clangd/unittests/TestTU.h
    llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
index cc0ca6f54a7f..b25d3fde0002 100644
--- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
@@ -230,49 +230,6 @@ TEST_F(BackgroundIndexTest, IndexTwoFiles) {
                        FileURI("unittest:///root/B.cc")}));
 }
 
-TEST_F(BackgroundIndexTest, RelationsMultiFile) {
-  MockFS FS;
-  FS.Files[testPath("root/Base.h")] = "class Base {};";
-  FS.Files[testPath("root/A.cc")] = R"cpp(
-    #include "Base.h"
-    class A : public Base {};
-  )cpp";
-  FS.Files[testPath("root/B.cc")] = R"cpp(
-    #include "Base.h"
-    class B : public Base {};
-  )cpp";
-
-  llvm::StringMap<std::string> Storage;
-  size_t CacheHits = 0;
-  MemoryShardStorage MSS(Storage, CacheHits);
-  OverlayCDB CDB(/*Base=*/nullptr);
-  BackgroundIndex Index(FS, CDB, [&](llvm::StringRef) { return &MSS; },
-                        /*Opts=*/{});
-
-  tooling::CompileCommand Cmd;
-  Cmd.Filename = testPath("root/A.cc");
-  Cmd.Directory = testPath("root");
-  Cmd.CommandLine = {"clang++", Cmd.Filename};
-  CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
-  ASSERT_TRUE(Index.blockUntilIdleForTest());
-
-  Cmd.Filename = testPath("root/B.cc");
-  Cmd.CommandLine = {"clang++", Cmd.Filename};
-  CDB.setCompileCommand(testPath("root/B.cc"), Cmd);
-  ASSERT_TRUE(Index.blockUntilIdleForTest());
-
-  auto HeaderShard = MSS.loadShard(testPath("root/Base.h"));
-  EXPECT_NE(HeaderShard, nullptr);
-  SymbolID Base = findSymbol(*HeaderShard->Symbols, "Base").ID;
-
-  RelationsRequest Req;
-  Req.Subjects.insert(Base);
-  Req.Predicate = RelationKind::BaseOf;
-  uint32_t Results = 0;
-  Index.relations(Req, [&](const SymbolID &, const Symbol &) { ++Results; });
-  EXPECT_EQ(Results, 2u);
-}
-
 TEST_F(BackgroundIndexTest, MainFileRefs) {
   MockFS FS;
   FS.Files[testPath("root/A.h")] = R"cpp(

diff  --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt
index de8eaca6059f..bf964484bc6c 100644
--- a/clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -88,6 +88,7 @@ add_unittest(ClangdUnitTests ClangdTests
   TestFS.cpp
   TestIndex.cpp
   TestTU.cpp
+  TestWorkspace.cpp
   TypeHierarchyTests.cpp
   TweakTests.cpp
   TweakTesting.cpp

diff  --git a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
index 4abe0bf5e5dc..80c4798fc65b 100644
--- a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
@@ -14,6 +14,7 @@
 #include "SyncAPI.h"
 #include "TestFS.h"
 #include "TestTU.h"
+#include "TestWorkspace.h"
 #include "URI.h"
 #include "index/CanonicalIncludes.h"
 #include "index/FileIndex.h"
@@ -426,6 +427,33 @@ TEST(FileIndexTest, Relations) {
   EXPECT_EQ(Results, 1u);
 }
 
+TEST(FileIndexTest, RelationsMultiFile) {
+  TestWorkspace Workspace;
+  Workspace.addSource("Base.h", "class Base {};");
+  Workspace.addMainFile("A.cpp", R"cpp(
+    #include "Base.h"
+    class A : public Base {};
+  )cpp");
+  Workspace.addMainFile("B.cpp", R"cpp(
+    #include "Base.h"
+    class B : public Base {};
+  )cpp");
+
+  auto Index = Workspace.index();
+  FuzzyFindRequest FFReq;
+  FFReq.Query = "Base";
+  FFReq.AnyScope = true;
+  SymbolID Base;
+  Index->fuzzyFind(FFReq, [&](const Symbol &S) { Base = S.ID; });
+
+  RelationsRequest Req;
+  Req.Subjects.insert(Base);
+  Req.Predicate = RelationKind::BaseOf;
+  uint32_t Results = 0;
+  Index->relations(Req, [&](const SymbolID &, const Symbol &) { ++Results; });
+  EXPECT_EQ(Results, 2u);
+}
+
 TEST(FileIndexTest, ReferencesInMainFileWithPreamble) {
   TestTU TU;
   TU.HeaderCode = "class Foo{};";

diff  --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp
index 81b6b43da94b..d0f011ef5649 100644
--- a/clang-tools-extra/clangd/unittests/TestTU.cpp
+++ b/clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -80,7 +80,8 @@ void deleteModuleCache(const std::string ModuleCachePath) {
   }
 }
 
-std::shared_ptr<const PreambleData> TestTU::preamble() const {
+std::shared_ptr<const PreambleData>
+TestTU::preamble(PreambleParsedCallback PreambleCallback) const {
   MockFS FS;
   auto Inputs = inputs(FS);
   IgnoreDiagnostics Diags;
@@ -91,8 +92,7 @@ std::shared_ptr<const PreambleData> TestTU::preamble() const {
   auto ModuleCacheDeleter = llvm::make_scope_exit(
       std::bind(deleteModuleCache, CI->getHeaderSearchOpts().ModuleCachePath));
   return clang::clangd::buildPreamble(testPath(Filename), *CI, Inputs,
-                                      /*StoreInMemory=*/true,
-                                      /*PreambleCallback=*/nullptr);
+                                      /*StoreInMemory=*/true, PreambleCallback);
 }
 
 ParsedAST TestTU::build() const {

diff  --git a/clang-tools-extra/clangd/unittests/TestTU.h b/clang-tools-extra/clangd/unittests/TestTU.h
index dd0cecc406ac..f383e693408c 100644
--- a/clang-tools-extra/clangd/unittests/TestTU.h
+++ b/clang-tools-extra/clangd/unittests/TestTU.h
@@ -79,7 +79,8 @@ struct TestTU {
   // By default, build() will report Error diagnostics as GTest errors.
   // Suppress this behavior by adding an 'error-ok' comment to the code.
   ParsedAST build() const;
-  std::shared_ptr<const PreambleData> preamble() const;
+  std::shared_ptr<const PreambleData>
+  preamble(PreambleParsedCallback PreambleCallback = nullptr) const;
   ParseInputs inputs(MockFS &FS) const;
   SymbolSlab headerSymbols() const;
   RefSlab headerRefs() const;

diff  --git a/clang-tools-extra/clangd/unittests/TestWorkspace.cpp b/clang-tools-extra/clangd/unittests/TestWorkspace.cpp
new file mode 100644
index 000000000000..52cf45f5be24
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/TestWorkspace.cpp
@@ -0,0 +1,49 @@
+//===--- TestWorkspace.cpp - Utility for writing multi-file tests -*- C++-*===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestWorkspace.h"
+
+namespace clang {
+namespace clangd {
+
+std::unique_ptr<SymbolIndex> TestWorkspace::index() {
+  auto Index = std::make_unique<FileIndex>();
+  for (const auto &Input : Inputs) {
+    if (!Input.second.IsMainFile)
+      continue;
+    TU.Code = Input.second.Code;
+    TU.Filename = Input.first().str();
+    TU.preamble([&](ASTContext &Ctx, std::shared_ptr<clang::Preprocessor> PP,
+                    const CanonicalIncludes &CanonIncludes) {
+      Index->updatePreamble(testPath(Input.first()), "null", Ctx, PP,
+                            CanonIncludes);
+    });
+    ParsedAST MainAST = TU.build();
+    Index->updateMain(testPath(Input.first()), MainAST);
+  }
+  return Index;
+}
+
+Optional<ParsedAST> TestWorkspace::openFile(llvm::StringRef Filename) {
+  auto It = Inputs.find(Filename);
+  if (It == Inputs.end()) {
+    ADD_FAILURE() << "Accessing non-existing file: " << Filename;
+    return llvm::None;
+  }
+  TU.Code = It->second.Code;
+  TU.Filename = It->first().str();
+  return TU.build();
+}
+
+void TestWorkspace::addInput(llvm::StringRef Filename,
+                             const SourceFile &Input) {
+  Inputs.insert(std::make_pair(Filename, Input));
+  TU.AdditionalFiles.insert(std::make_pair(Filename, Input.Code));
+}
+} // namespace clangd
+} // namespace clang
\ No newline at end of file

diff  --git a/clang-tools-extra/clangd/unittests/TestWorkspace.h b/clang-tools-extra/clangd/unittests/TestWorkspace.h
new file mode 100644
index 000000000000..eb5112f198dd
--- /dev/null
+++ b/clang-tools-extra/clangd/unittests/TestWorkspace.h
@@ -0,0 +1,59 @@
+//===--- TestWorkspace.h - Utility for writing multi-file tests --*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// TestWorkspace builds on TestTU to provide a way to write tests involving
+// several related files with inclusion relationships between them.
+//
+// The tests can exercise both index and AST based operations.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H
+#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H
+
+#include "TestFS.h"
+#include "TestTU.h"
+#include "index/FileIndex.h"
+#include "index/Index.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace clangd {
+
+class TestWorkspace {
+public:
+  // The 
diff erence between addSource() and addMainFile() is that only main
+  // files will be indexed.
+  void addSource(llvm::StringRef Filename, llvm::StringRef Code) {
+    addInput(Filename.str(), {Code.str(), /*IsMainFile=*/false});
+  }
+  void addMainFile(llvm::StringRef Filename, llvm::StringRef Code) {
+    addInput(Filename.str(), {Code.str(), /*IsMainFile=*/true});
+  }
+
+  std::unique_ptr<SymbolIndex> index();
+
+  Optional<ParsedAST> openFile(llvm::StringRef Filename);
+
+private:
+  struct SourceFile {
+    std::string Code;
+    bool IsMainFile = false;
+  };
+  llvm::StringMap<SourceFile> Inputs;
+  TestTU TU;
+
+  void addInput(llvm::StringRef Filename, const SourceFile &Input);
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTWORKSPACE_H

diff  --git a/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
index 8872b36e4a89..4e8ac3144512 100644
--- a/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
+++ b/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
@@ -96,6 +96,7 @@ unittest("ClangdTests") {
     "TestFS.cpp",
     "TestIndex.cpp",
     "TestTU.cpp",
+    "TestWorkspace.cpp",
     "TweakTesting.cpp",
     "TweakTests.cpp",
     "TypeHierarchyTests.cpp",


        


More information about the cfe-commits mailing list