summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp')
-rw-r--r--clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp129
1 files changed, 123 insertions, 6 deletions
diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
index 6823fc557ee..e6cc01b8a76 100644
--- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
+++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
@@ -8,10 +8,21 @@
#include "GlobalCompilationDatabase.h"
+#include "Path.h"
#include "TestFS.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include <fstream>
+#include <string>
namespace clang {
namespace clangd {
@@ -20,8 +31,10 @@ using ::testing::AllOf;
using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::EndsWith;
+using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::StartsWith;
+using ::testing::UnorderedElementsAre;
TEST(GlobalCompilationDatabaseTest, FallbackCommand) {
DirectoryBasedGlobalCompilationDatabase DB(None);
@@ -50,13 +63,9 @@ class OverlayCDBTest : public ::testing::Test {
class BaseCDB : public GlobalCompilationDatabase {
public:
llvm::Optional<tooling::CompileCommand>
- getCompileCommand(llvm::StringRef File,
- ProjectInfo *Project) const override {
- if (File == testPath("foo.cc")) {
- if (Project)
- Project->SourceRoot = testRoot();
+ getCompileCommand(llvm::StringRef File) const override {
+ if (File == testPath("foo.cc"))
return cmd(File, "-DA=1");
- }
return None;
}
@@ -64,6 +73,10 @@ class OverlayCDBTest : public ::testing::Test {
getFallbackCommand(llvm::StringRef File) const override {
return cmd(File, "-DA=2");
}
+
+ llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override {
+ return ProjectInfo{testRoot()};
+ }
};
protected:
@@ -153,6 +166,110 @@ TEST_F(OverlayCDBTest, Adjustments) {
Not(Contains("random-plugin"))));
}
+TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
+ const char *const CDBOuter =
+ R"cdb(
+ [
+ {
+ "file": "a.cc",
+ "command": "",
+ "directory": "{0}",
+ },
+ {
+ "file": "build/gen.cc",
+ "command": "",
+ "directory": "{0}",
+ },
+ {
+ "file": "build/gen2.cc",
+ "command": "",
+ "directory": "{0}",
+ }
+ ]
+ )cdb";
+ const char *const CDBInner =
+ R"cdb(
+ [
+ {
+ "file": "gen.cc",
+ "command": "",
+ "directory": "{0}/build",
+ }
+ ]
+ )cdb";
+ class CleaningFS {
+ public:
+ llvm::SmallString<128> Root;
+
+ CleaningFS() {
+ EXPECT_FALSE(
+ llvm::sys::fs::createUniqueDirectory("clangd-cdb-test", Root))
+ << "Failed to create unique directory";
+ }
+
+ ~CleaningFS() {
+ EXPECT_FALSE(llvm::sys::fs::remove_directories(Root))
+ << "Failed to cleanup " << Root;
+ }
+
+ void registerFile(PathRef RelativePath, llvm::StringRef Contents) {
+ llvm::SmallString<128> AbsPath(Root);
+ llvm::sys::path::append(AbsPath, RelativePath);
+
+ EXPECT_FALSE(llvm::sys::fs::create_directories(
+ llvm::sys::path::parent_path(AbsPath)))
+ << "Failed to create directories for: " << AbsPath;
+
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(AbsPath, EC);
+ EXPECT_FALSE(EC) << "Failed to open " << AbsPath << " for writing";
+ OS << llvm::formatv(Contents.data(),
+ llvm::sys::path::convert_to_slash(Root));
+ OS.close();
+
+ EXPECT_FALSE(OS.has_error());
+ }
+ };
+
+ CleaningFS FS;
+ FS.registerFile("compile_commands.json", CDBOuter);
+ FS.registerFile("build/compile_commands.json", CDBInner);
+
+ // Note that gen2.cc goes missing with our following model, not sure this
+ // happens in practice though.
+ {
+ DirectoryBasedGlobalCompilationDatabase DB(llvm::None);
+ std::vector<std::string> DiscoveredFiles;
+ auto Sub =
+ DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
+ DiscoveredFiles = Changes;
+ });
+ DB.getCompileCommand((FS.Root + "/a.cc").str());
+ EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(EndsWith("a.cc")));
+
+ DB.getCompileCommand((FS.Root + "/build/gen.cc").str());
+ EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(EndsWith("gen.cc")));
+ }
+
+ // With a custom compile commands dir.
+ {
+ DirectoryBasedGlobalCompilationDatabase DB(FS.Root.str().str());
+ std::vector<std::string> DiscoveredFiles;
+ auto Sub =
+ DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
+ DiscoveredFiles = Changes;
+ });
+ DB.getCompileCommand((FS.Root + "/a.cc").str());
+ EXPECT_THAT(DiscoveredFiles,
+ UnorderedElementsAre(EndsWith("a.cc"), EndsWith("gen.cc"),
+ EndsWith("gen2.cc")));
+
+ DiscoveredFiles.clear();
+ DB.getCompileCommand((FS.Root + "/build/gen.cc").str());
+ EXPECT_THAT(DiscoveredFiles, IsEmpty());
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
OpenPOWER on IntegriCloud