12 #include "clang/Tooling/CompilationDatabase.h"
13 #include "llvm/Support/ScopedPrinter.h"
14 #include "gmock/gmock.h"
15 #include "gtest/gtest.h"
18 using ::testing::AllOf;
19 using ::testing::ElementsAre;
20 using ::testing::Pair;
21 using ::testing::UnorderedElementsAre;
22 using ::testing::UnorderedElementsAreArray;
28 const char *
YAML = R
"(
38 FileURI: file:///path/foo.h
47 Documentation: 'Foo doc'
64 FileURI: file:///path/bar.h
73 CompletionSnippetSuffix: '-snippet'
80 FileURI: file:///path/foo.cc
102 URI: 'file:///path/source1.cpp'
104 Digest: EED8F5EAF25C453C
106 - 'file:///path/inc1.h'
107 - 'file:///path/inc2.h'
113 MATCHER_P2(IncludeHeaderWithRef, IncludeHeader,
References,
"") {
114 return (arg.IncludeHeader == IncludeHeader) && (arg.References ==
References);
117 TEST(SerializationTest, NoCrashOnEmptyYAML) {
121 TEST(SerializationTest, YAMLConversions) {
123 ASSERT_TRUE(
bool(ParsedYAML)) << ParsedYAML.takeError();
124 ASSERT_TRUE(
bool(ParsedYAML->Symbols));
126 *ParsedYAML->Symbols,
127 UnorderedElementsAre(ID(
"057557CEBF6E6B2D"), ID(
"057557CEBF6E6B2E")));
129 auto Sym1 = *ParsedYAML->Symbols->find(
131 auto Sym2 = *ParsedYAML->Symbols->find(
134 EXPECT_THAT(Sym1, QName(
"clang::Foo1"));
135 EXPECT_EQ(Sym1.Signature,
"");
136 EXPECT_EQ(Sym1.Documentation,
"Foo doc");
137 EXPECT_EQ(Sym1.ReturnType,
"int");
138 EXPECT_EQ(StringRef(Sym1.CanonicalDeclaration.FileURI),
"file:///path/foo.h");
139 EXPECT_EQ(Sym1.Origin, static_cast<SymbolOrigin>(1 << 7));
140 EXPECT_EQ(static_cast<uint8_t>(Sym1.Flags), 129);
143 EXPECT_THAT(Sym1.IncludeHeaders,
144 UnorderedElementsAre(IncludeHeaderWithRef(
"include1", 7u),
145 IncludeHeaderWithRef(
"include2", 3u)));
147 EXPECT_THAT(Sym2, QName(
"clang::Foo2"));
148 EXPECT_EQ(Sym2.Signature,
"-sig");
149 EXPECT_EQ(Sym2.ReturnType,
"");
150 EXPECT_EQ(llvm::StringRef(Sym2.CanonicalDeclaration.FileURI),
151 "file:///path/bar.h");
155 ASSERT_TRUE(
bool(ParsedYAML->Refs));
159 ::testing::SizeIs(1))));
160 auto Ref1 = ParsedYAML->Refs->begin()->second.front();
162 EXPECT_EQ(StringRef(Ref1.Location.FileURI),
"file:///path/foo.cc");
166 ASSERT_TRUE(
bool(ParsedYAML->Relations));
168 *ParsedYAML->Relations,
171 ASSERT_TRUE(
bool(ParsedYAML->Cmd));
172 auto &Cmd = *ParsedYAML->Cmd;
173 ASSERT_EQ(Cmd.Directory,
"testdir");
174 EXPECT_THAT(Cmd.CommandLine, ElementsAre(
"cmd1",
"cmd2"));
176 ASSERT_TRUE(
bool(ParsedYAML->Sources));
177 const auto *URI =
"file:///path/source1.cpp";
178 ASSERT_TRUE(ParsedYAML->Sources->count(URI));
179 auto IGNDeserialized = ParsedYAML->Sources->lookup(URI);
180 EXPECT_EQ(llvm::toHex(IGNDeserialized.Digest),
"EED8F5EAF25C453C");
181 EXPECT_THAT(IGNDeserialized.DirectIncludes,
182 ElementsAre(
"file:///path/inc1.h",
"file:///path/inc2.h"));
183 EXPECT_EQ(IGNDeserialized.URI, URI);
187 std::vector<std::string> YAMLFromSymbols(
const SymbolSlab &Slab) {
188 std::vector<std::string> Result;
189 for (
const auto &Sym : Slab)
190 Result.push_back(
toYAML(Sym));
193 std::vector<std::string> YAMLFromRefs(
const RefSlab &Slab) {
194 std::vector<std::string> Result;
195 for (
const auto &
Refs : Slab)
200 std::vector<std::string> YAMLFromRelations(
const RelationSlab &Slab) {
201 std::vector<std::string> Result;
202 for (
const auto &Rel : Slab)
203 Result.push_back(
toYAML(Rel));
207 TEST(SerializationTest, BinaryConversions) {
209 EXPECT_TRUE(
bool(In)) << In.takeError();
212 IndexFileOut
Out(*In);
214 std::string Serialized = llvm::to_string(
Out);
217 ASSERT_TRUE(
bool(In2)) << In.takeError();
218 ASSERT_TRUE(In2->Symbols);
219 ASSERT_TRUE(In2->Refs);
220 ASSERT_TRUE(In2->Relations);
223 EXPECT_THAT(YAMLFromSymbols(*In2->Symbols),
224 UnorderedElementsAreArray(YAMLFromSymbols(*In->Symbols)));
225 EXPECT_THAT(YAMLFromRefs(*In2->Refs),
226 UnorderedElementsAreArray(YAMLFromRefs(*In->Refs)));
227 EXPECT_THAT(YAMLFromRelations(*In2->Relations),
228 UnorderedElementsAreArray(YAMLFromRelations(*In->Relations)));
231 TEST(SerializationTest, SrcsTest) {
233 EXPECT_TRUE(
bool(In)) << In.takeError();
235 std::string TestContent(
"TestContent");
236 IncludeGraphNode IGN;
237 IGN.Digest =
digest(TestContent);
238 IGN.DirectIncludes = {
"inc1",
"inc2"};
243 Sources[IGN.URI] = IGN;
245 IndexFileOut
Out(*In);
247 Out.Sources = &Sources;
249 std::string Serialized = llvm::to_string(
Out);
252 ASSERT_TRUE(
bool(In)) << In.takeError();
253 ASSERT_TRUE(In->Symbols);
254 ASSERT_TRUE(In->Refs);
255 ASSERT_TRUE(In->Sources);
256 ASSERT_TRUE(In->Sources->count(IGN.URI));
258 EXPECT_THAT(YAMLFromSymbols(*In->Symbols),
259 UnorderedElementsAreArray(YAMLFromSymbols(*In->Symbols)));
260 EXPECT_THAT(YAMLFromRefs(*In->Refs),
261 UnorderedElementsAreArray(YAMLFromRefs(*In->Refs)));
262 auto IGNDeserialized = In->Sources->lookup(IGN.URI);
263 EXPECT_EQ(IGNDeserialized.Digest, IGN.Digest);
264 EXPECT_EQ(IGNDeserialized.DirectIncludes, IGN.DirectIncludes);
265 EXPECT_EQ(IGNDeserialized.URI, IGN.URI);
266 EXPECT_EQ(IGNDeserialized.Flags, IGN.Flags);
270 TEST(SerializationTest, CmdlTest) {
272 EXPECT_TRUE(
bool(In)) << In.takeError();
274 tooling::CompileCommand Cmd;
275 Cmd.Directory =
"testdir";
276 Cmd.CommandLine.push_back(
"cmd1");
277 Cmd.CommandLine.push_back(
"cmd2");
278 Cmd.Filename =
"ignored";
279 Cmd.Heuristic =
"ignored";
280 Cmd.Output =
"ignored";
282 IndexFileOut
Out(*In);
286 std::string Serialized = llvm::to_string(
Out);
289 ASSERT_TRUE(
bool(In)) << In.takeError();
290 ASSERT_TRUE(In->Cmd);
292 const tooling::CompileCommand &SerializedCmd = In->Cmd.getValue();
293 EXPECT_EQ(SerializedCmd.CommandLine, Cmd.CommandLine);
294 EXPECT_EQ(SerializedCmd.Directory, Cmd.Directory);
295 EXPECT_NE(SerializedCmd.Filename, Cmd.Filename);
296 EXPECT_NE(SerializedCmd.Heuristic, Cmd.Heuristic);
297 EXPECT_NE(SerializedCmd.Output, Cmd.Output);