1 //===-- clang-doc/YAMLGeneratorTest.cpp
2 //------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "ClangDocTest.h"
11 #include "Generators.h"
12 #include "Representation.h"
13 #include "gtest/gtest.h"
14
15 namespace clang {
16 namespace doc {
17
getYAMLGenerator()18 std::unique_ptr<Generator> getYAMLGenerator() {
19 auto G = doc::findGeneratorByName("yaml");
20 if (!G)
21 return nullptr;
22 return std::move(G.get());
23 }
24
TEST(YAMLGeneratorTest,emitNamespaceYAML)25 TEST(YAMLGeneratorTest, emitNamespaceYAML) {
26 NamespaceInfo I;
27 I.Name = "Namespace";
28 I.Path = "path/to/A";
29 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
30
31 I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
32 InfoType::IT_namespace, "path/to/A/Namespace");
33 I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
34 "path/to/A/Namespace");
35 I.ChildFunctions.emplace_back();
36 I.ChildFunctions.back().Name = "OneFunction";
37 I.ChildFunctions.back().Access = AccessSpecifier::AS_none;
38 I.ChildEnums.emplace_back();
39 I.ChildEnums.back().Name = "OneEnum";
40
41 auto G = getYAMLGenerator();
42 assert(G);
43 std::string Buffer;
44 llvm::raw_string_ostream Actual(Buffer);
45 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
46 assert(!Err);
47 std::string Expected =
48 R"raw(---
49 USR: '0000000000000000000000000000000000000000'
50 Name: 'Namespace'
51 Path: 'path/to/A'
52 Namespace:
53 - Type: Namespace
54 Name: 'A'
55 ChildNamespaces:
56 - Type: Namespace
57 Name: 'ChildNamespace'
58 Path: 'path/to/A/Namespace'
59 ChildRecords:
60 - Type: Record
61 Name: 'ChildStruct'
62 Path: 'path/to/A/Namespace'
63 ChildFunctions:
64 - USR: '0000000000000000000000000000000000000000'
65 Name: 'OneFunction'
66 ReturnType: {}
67 ChildEnums:
68 - USR: '0000000000000000000000000000000000000000'
69 Name: 'OneEnum'
70 ...
71 )raw";
72 EXPECT_EQ(Expected, Actual.str());
73 }
74
TEST(YAMLGeneratorTest,emitRecordYAML)75 TEST(YAMLGeneratorTest, emitRecordYAML) {
76 RecordInfo I;
77 I.Name = "r";
78 I.Path = "path/to/A";
79 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
80
81 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
82 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
83
84 I.Members.emplace_back("int", "path/to/int", "X",
85 AccessSpecifier::AS_private);
86 I.TagType = TagTypeKind::TTK_Class;
87 I.Bases.emplace_back(EmptySID, "F", "path/to/F", true,
88 AccessSpecifier::AS_public, true);
89 I.Bases.back().ChildFunctions.emplace_back();
90 I.Bases.back().ChildFunctions.back().Name = "InheritedFunctionOne";
91 I.Bases.back().Members.emplace_back("int", "path/to/int", "N",
92 AccessSpecifier::AS_private);
93 // F is in the global namespace
94 I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "");
95 I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record,
96 "path/to/G");
97
98 I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
99 "path/to/A/r");
100 I.ChildFunctions.emplace_back();
101 I.ChildFunctions.back().Name = "OneFunction";
102 I.ChildEnums.emplace_back();
103 I.ChildEnums.back().Name = "OneEnum";
104
105 auto G = getYAMLGenerator();
106 assert(G);
107 std::string Buffer;
108 llvm::raw_string_ostream Actual(Buffer);
109 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
110 assert(!Err);
111 std::string Expected =
112 R"raw(---
113 USR: '0000000000000000000000000000000000000000'
114 Name: 'r'
115 Path: 'path/to/A'
116 Namespace:
117 - Type: Namespace
118 Name: 'A'
119 DefLocation:
120 LineNumber: 10
121 Filename: 'test.cpp'
122 Location:
123 - LineNumber: 12
124 Filename: 'test.cpp'
125 TagType: Class
126 Members:
127 - Type:
128 Name: 'int'
129 Path: 'path/to/int'
130 Name: 'X'
131 Access: Private
132 Bases:
133 - USR: '0000000000000000000000000000000000000000'
134 Name: 'F'
135 Path: 'path/to/F'
136 Members:
137 - Type:
138 Name: 'int'
139 Path: 'path/to/int'
140 Name: 'N'
141 Access: Private
142 ChildFunctions:
143 - USR: '0000000000000000000000000000000000000000'
144 Name: 'InheritedFunctionOne'
145 ReturnType: {}
146 Access: Public
147 IsVirtual: true
148 Access: Public
149 IsParent: true
150 Parents:
151 - Type: Record
152 Name: 'F'
153 IsInGlobalNamespace: true
154 VirtualParents:
155 - Type: Record
156 Name: 'G'
157 Path: 'path/to/G'
158 ChildRecords:
159 - Type: Record
160 Name: 'ChildStruct'
161 Path: 'path/to/A/r'
162 ChildFunctions:
163 - USR: '0000000000000000000000000000000000000000'
164 Name: 'OneFunction'
165 ReturnType: {}
166 Access: Public
167 ChildEnums:
168 - USR: '0000000000000000000000000000000000000000'
169 Name: 'OneEnum'
170 ...
171 )raw";
172 EXPECT_EQ(Expected, Actual.str());
173 }
174
TEST(YAMLGeneratorTest,emitFunctionYAML)175 TEST(YAMLGeneratorTest, emitFunctionYAML) {
176 FunctionInfo I;
177 I.Name = "f";
178 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
179
180 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
181 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
182
183 I.Access = AccessSpecifier::AS_none;
184
185 I.ReturnType =
186 TypeInfo(EmptySID, "void", InfoType::IT_default, "path/to/void");
187 I.Params.emplace_back("int", "path/to/int", "P");
188 I.IsMethod = true;
189 I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
190
191 auto G = getYAMLGenerator();
192 assert(G);
193 std::string Buffer;
194 llvm::raw_string_ostream Actual(Buffer);
195 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
196 assert(!Err);
197 std::string Expected =
198 R"raw(---
199 USR: '0000000000000000000000000000000000000000'
200 Name: 'f'
201 Namespace:
202 - Type: Namespace
203 Name: 'A'
204 DefLocation:
205 LineNumber: 10
206 Filename: 'test.cpp'
207 Location:
208 - LineNumber: 12
209 Filename: 'test.cpp'
210 IsMethod: true
211 Parent:
212 Type: Record
213 Name: 'Parent'
214 Params:
215 - Type:
216 Name: 'int'
217 Path: 'path/to/int'
218 Name: 'P'
219 ReturnType:
220 Type:
221 Name: 'void'
222 Path: 'path/to/void'
223 ...
224 )raw";
225 EXPECT_EQ(Expected, Actual.str());
226 }
227
TEST(YAMLGeneratorTest,emitEnumYAML)228 TEST(YAMLGeneratorTest, emitEnumYAML) {
229 EnumInfo I;
230 I.Name = "e";
231 I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
232
233 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
234 I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
235
236 I.Members.emplace_back("X");
237 I.Scoped = true;
238
239 auto G = getYAMLGenerator();
240 assert(G);
241 std::string Buffer;
242 llvm::raw_string_ostream Actual(Buffer);
243 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
244 assert(!Err);
245 std::string Expected =
246 R"raw(---
247 USR: '0000000000000000000000000000000000000000'
248 Name: 'e'
249 Namespace:
250 - Type: Namespace
251 Name: 'A'
252 DefLocation:
253 LineNumber: 10
254 Filename: 'test.cpp'
255 Location:
256 - LineNumber: 12
257 Filename: 'test.cpp'
258 Scoped: true
259 Members:
260 - 'X'
261 ...
262 )raw";
263 EXPECT_EQ(Expected, Actual.str());
264 }
265
TEST(YAMLGeneratorTest,emitCommentYAML)266 TEST(YAMLGeneratorTest, emitCommentYAML) {
267 FunctionInfo I;
268 I.Name = "f";
269 I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
270 I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
271 I.Params.emplace_back("int", "I");
272 I.Params.emplace_back("int", "J");
273 I.Access = AccessSpecifier::AS_none;
274
275 CommentInfo Top;
276 Top.Kind = "FullComment";
277
278 Top.Children.emplace_back(std::make_unique<CommentInfo>());
279 CommentInfo *BlankLine = Top.Children.back().get();
280 BlankLine->Kind = "ParagraphComment";
281 BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
282 BlankLine->Children.back()->Kind = "TextComment";
283
284 Top.Children.emplace_back(std::make_unique<CommentInfo>());
285 CommentInfo *Brief = Top.Children.back().get();
286 Brief->Kind = "ParagraphComment";
287 Brief->Children.emplace_back(std::make_unique<CommentInfo>());
288 Brief->Children.back()->Kind = "TextComment";
289 Brief->Children.back()->Name = "ParagraphComment";
290 Brief->Children.back()->Text = " Brief description.";
291
292 Top.Children.emplace_back(std::make_unique<CommentInfo>());
293 CommentInfo *Extended = Top.Children.back().get();
294 Extended->Kind = "ParagraphComment";
295 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
296 Extended->Children.back()->Kind = "TextComment";
297 Extended->Children.back()->Text = " Extended description that";
298 Extended->Children.emplace_back(std::make_unique<CommentInfo>());
299 Extended->Children.back()->Kind = "TextComment";
300 Extended->Children.back()->Text = " continues onto the next line.";
301
302 Top.Children.emplace_back(std::make_unique<CommentInfo>());
303 CommentInfo *HTML = Top.Children.back().get();
304 HTML->Kind = "ParagraphComment";
305 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
306 HTML->Children.back()->Kind = "TextComment";
307 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
308 HTML->Children.back()->Kind = "HTMLStartTagComment";
309 HTML->Children.back()->Name = "ul";
310 HTML->Children.back()->AttrKeys.emplace_back("class");
311 HTML->Children.back()->AttrValues.emplace_back("test");
312 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
313 HTML->Children.back()->Kind = "HTMLStartTagComment";
314 HTML->Children.back()->Name = "li";
315 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
316 HTML->Children.back()->Kind = "TextComment";
317 HTML->Children.back()->Text = " Testing.";
318 HTML->Children.emplace_back(std::make_unique<CommentInfo>());
319 HTML->Children.back()->Kind = "HTMLEndTagComment";
320 HTML->Children.back()->Name = "ul";
321 HTML->Children.back()->SelfClosing = true;
322
323 Top.Children.emplace_back(std::make_unique<CommentInfo>());
324 CommentInfo *Verbatim = Top.Children.back().get();
325 Verbatim->Kind = "VerbatimBlockComment";
326 Verbatim->Name = "verbatim";
327 Verbatim->CloseName = "endverbatim";
328 Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
329 Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
330 Verbatim->Children.back()->Text = " The description continues.";
331
332 Top.Children.emplace_back(std::make_unique<CommentInfo>());
333 CommentInfo *ParamOut = Top.Children.back().get();
334 ParamOut->Kind = "ParamCommandComment";
335 ParamOut->Direction = "[out]";
336 ParamOut->ParamName = "I";
337 ParamOut->Explicit = true;
338 ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
339 ParamOut->Children.back()->Kind = "ParagraphComment";
340 ParamOut->Children.back()->Children.emplace_back(
341 std::make_unique<CommentInfo>());
342 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
343 ParamOut->Children.back()->Children.emplace_back(
344 std::make_unique<CommentInfo>());
345 ParamOut->Children.back()->Children.back()->Kind = "TextComment";
346 ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
347
348 Top.Children.emplace_back(std::make_unique<CommentInfo>());
349 CommentInfo *ParamIn = Top.Children.back().get();
350 ParamIn->Kind = "ParamCommandComment";
351 ParamIn->Direction = "[in]";
352 ParamIn->ParamName = "J";
353 ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
354 ParamIn->Children.back()->Kind = "ParagraphComment";
355 ParamIn->Children.back()->Children.emplace_back(
356 std::make_unique<CommentInfo>());
357 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
358 ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
359 ParamIn->Children.back()->Children.emplace_back(
360 std::make_unique<CommentInfo>());
361 ParamIn->Children.back()->Children.back()->Kind = "TextComment";
362
363 Top.Children.emplace_back(std::make_unique<CommentInfo>());
364 CommentInfo *Return = Top.Children.back().get();
365 Return->Kind = "BlockCommandComment";
366 Return->Name = "return";
367 Return->Explicit = true;
368 Return->Children.emplace_back(std::make_unique<CommentInfo>());
369 Return->Children.back()->Kind = "ParagraphComment";
370 Return->Children.back()->Children.emplace_back(
371 std::make_unique<CommentInfo>());
372 Return->Children.back()->Children.back()->Kind = "TextComment";
373 Return->Children.back()->Children.back()->Text = "void";
374
375 I.Description.emplace_back(std::move(Top));
376
377 auto G = getYAMLGenerator();
378 assert(G);
379 std::string Buffer;
380 llvm::raw_string_ostream Actual(Buffer);
381 auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
382 assert(!Err);
383 std::string Expected =
384 R"raw(---
385 USR: '0000000000000000000000000000000000000000'
386 Name: 'f'
387 Description:
388 - Kind: 'FullComment'
389 Children:
390 - Kind: 'ParagraphComment'
391 Children:
392 - Kind: 'TextComment'
393 - Kind: 'ParagraphComment'
394 Children:
395 - Kind: 'TextComment'
396 Text: ' Brief description.'
397 Name: 'ParagraphComment'
398 - Kind: 'ParagraphComment'
399 Children:
400 - Kind: 'TextComment'
401 Text: ' Extended description that'
402 - Kind: 'TextComment'
403 Text: ' continues onto the next line.'
404 - Kind: 'ParagraphComment'
405 Children:
406 - Kind: 'TextComment'
407 - Kind: 'HTMLStartTagComment'
408 Name: 'ul'
409 AttrKeys:
410 - 'class'
411 AttrValues:
412 - 'test'
413 - Kind: 'HTMLStartTagComment'
414 Name: 'li'
415 - Kind: 'TextComment'
416 Text: ' Testing.'
417 - Kind: 'HTMLEndTagComment'
418 Name: 'ul'
419 SelfClosing: true
420 - Kind: 'VerbatimBlockComment'
421 Name: 'verbatim'
422 CloseName: 'endverbatim'
423 Children:
424 - Kind: 'VerbatimBlockLineComment'
425 Text: ' The description continues.'
426 - Kind: 'ParamCommandComment'
427 Direction: '[out]'
428 ParamName: 'I'
429 Explicit: true
430 Children:
431 - Kind: 'ParagraphComment'
432 Children:
433 - Kind: 'TextComment'
434 - Kind: 'TextComment'
435 Text: ' is a parameter.'
436 - Kind: 'ParamCommandComment'
437 Direction: '[in]'
438 ParamName: 'J'
439 Children:
440 - Kind: 'ParagraphComment'
441 Children:
442 - Kind: 'TextComment'
443 Text: ' is a parameter.'
444 - Kind: 'TextComment'
445 - Kind: 'BlockCommandComment'
446 Name: 'return'
447 Explicit: true
448 Children:
449 - Kind: 'ParagraphComment'
450 Children:
451 - Kind: 'TextComment'
452 Text: 'void'
453 DefLocation:
454 LineNumber: 10
455 Filename: 'test.cpp'
456 Params:
457 - Type:
458 Name: 'int'
459 Name: 'I'
460 - Type:
461 Name: 'int'
462 Name: 'J'
463 ReturnType:
464 Type:
465 Name: 'void'
466 ...
467 )raw";
468
469 EXPECT_EQ(Expected, Actual.str());
470 }
471
472 } // namespace doc
473 } // namespace clang
474