Index: unittests/clangd/ClangdTests.cpp =================================================================== --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -34,6 +34,7 @@ namespace clangd { using ::testing::ElementsAre; +using ::testing::Contains; using ::testing::Eq; using ::testing::Gt; using ::testing::IsEmpty; @@ -41,6 +42,8 @@ using ::testing::UnorderedElementsAre; namespace { +// FIXME: This is copied from CodeCompleteTests.cpp. Share the code instead. +MATCHER_P(Named, Name, "") { return arg.Name == Name; } bool diagsContainErrors(const std::vector &Diagnostics) { for (auto D : Diagnostics) { @@ -927,6 +930,40 @@ EXPECT_EQ(Expected, *Changed); } +TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) { + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto SourcePath = testPath("source/foo.cpp"); + auto HeaderPath = testPath("headers/foo.h"); + FS.Files[HeaderPath] = "struct X { int bar; };"; + Annotations Code(R"cpp( + #include "foo.h" + + int main() { + X().ba^ + })cpp"); + CDB.ExtraClangFlags.push_back("-xc++"); + CDB.ExtraClangFlags.push_back("-isystem" + testPath("headers")); + + runAddDocument(Server, SourcePath, Code.code()); + auto Completions = cantFail(runCodeComplete(Server, SourcePath, Code.point(), + clangd::CodeCompleteOptions())) + .Completions; + EXPECT_THAT(Completions, ElementsAre(Named("bar"))); + // Update the header and rerun addDocument to make sure we get the updated + // files. + FS.Files[HeaderPath] = "struct X { int bar; int baz; };"; + runAddDocument(Server, SourcePath, Code.code()); + Completions = cantFail(runCodeComplete(Server, SourcePath, Code.point(), + clangd::CodeCompleteOptions())) + .Completions; + // We want to make sure we see the updated version. + EXPECT_THAT(Completions, ElementsAre(Named("bar"), Named("baz"))); +} + } // namespace } // namespace clangd } // namespace clang