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
15namespace clang {
16namespace doc {
17
18static std::unique_ptr<Generator> getYAMLGenerator() {
19 auto G = doc::findGeneratorByName(Format: "yaml");
20 if (!G)
21 return nullptr;
22 return std::move(G.get());
23}
24
25TEST(YAMLGeneratorTest, emitNamespaceYAML) {
26 NamespaceInfo I;
27 I.Name = "Namespace";
28 I.Path = "path/to/A";
29 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
30
31 I.Children.Namespaces.emplace_back(
32 args: EmptySID, args: "ChildNamespace", args: InfoType::IT_namespace,
33 args: "path::to::A::Namespace::ChildNamespace", args: "path/to/A/Namespace");
34 I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct", args: InfoType::IT_record,
35 args: "path::to::A::Namespace::ChildStruct",
36 args: "path/to/A/Namespace");
37 I.Children.Functions.emplace_back();
38 I.Children.Functions.back().Name = "OneFunction";
39 I.Children.Functions.back().Access = AccessSpecifier::AS_none;
40 I.Children.Enums.emplace_back();
41 I.Children.Enums.back().Name = "OneEnum";
42
43 auto G = getYAMLGenerator();
44 assert(G);
45 std::string Buffer;
46 llvm::raw_string_ostream Actual(Buffer);
47 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
48 assert(!Err);
49 std::string Expected =
50 R"raw(---
51USR: '0000000000000000000000000000000000000000'
52Name: 'Namespace'
53Path: 'path/to/A'
54Namespace:
55 - Type: Namespace
56 Name: 'A'
57 QualName: 'A'
58ChildNamespaces:
59 - Type: Namespace
60 Name: 'ChildNamespace'
61 QualName: 'path::to::A::Namespace::ChildNamespace'
62 Path: 'path/to/A/Namespace'
63ChildRecords:
64 - Type: Record
65 Name: 'ChildStruct'
66 QualName: 'path::to::A::Namespace::ChildStruct'
67 Path: 'path/to/A/Namespace'
68ChildFunctions:
69 - USR: '0000000000000000000000000000000000000000'
70 Name: 'OneFunction'
71 ReturnType: {}
72ChildEnums:
73 - USR: '0000000000000000000000000000000000000000'
74 Name: 'OneEnum'
75...
76)raw";
77 EXPECT_EQ(Expected, Actual.str());
78}
79
80TEST(YAMLGeneratorTest, emitRecordYAML) {
81 RecordInfo I;
82 I.Name = "r";
83 I.Path = "path/to/A";
84 I.IsTypeDef = true;
85 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
86
87 I.DefLoc = Location(10, 10, "test.cpp");
88 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
89
90 I.Members.emplace_back(Args: TypeInfo("int"), Args: "X", Args: AccessSpecifier::AS_private);
91
92 // Member documentation.
93 CommentInfo TopComment;
94 TopComment.Kind = CommentKind::CK_FullComment;
95 TopComment.Children.emplace_back(args: std::make_unique<CommentInfo>());
96 CommentInfo *Brief = TopComment.Children.back().get();
97 Brief->Kind = CommentKind::CK_ParagraphComment;
98 Brief->Children.emplace_back(args: std::make_unique<CommentInfo>());
99 Brief->Children.back()->Kind = CommentKind::CK_TextComment;
100 Brief->Children.back()->Name = "ParagraphComment";
101 Brief->Children.back()->Text = "Value of the thing.";
102 I.Members.back().Description.push_back(x: std::move(TopComment));
103
104 I.TagType = TagTypeKind::Class;
105 I.Bases.emplace_back(args: EmptySID, args: "F", args: "path/to/F", args: true,
106 args: AccessSpecifier::AS_public, args: true);
107 I.Bases.back().Children.Functions.emplace_back();
108 I.Bases.back().Children.Functions.back().Name = "InheritedFunctionOne";
109 I.Bases.back().Members.emplace_back(Args: TypeInfo("int"), Args: "N",
110 Args: AccessSpecifier::AS_private);
111 // F is in the global namespace
112 I.Parents.emplace_back(Args: EmptySID, Args: "F", Args: InfoType::IT_record, Args: "");
113 I.VirtualParents.emplace_back(Args: EmptySID, Args: "G", Args: InfoType::IT_record,
114 Args: "path::to::G::G", Args: "path/to/G");
115
116 I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct", args: InfoType::IT_record,
117 args: "path::to::A::r::ChildStruct", args: "path/to/A/r");
118 I.Children.Functions.emplace_back();
119 I.Children.Functions.back().Name = "OneFunction";
120 I.Children.Enums.emplace_back();
121 I.Children.Enums.back().Name = "OneEnum";
122
123 auto G = getYAMLGenerator();
124 assert(G);
125 std::string Buffer;
126 llvm::raw_string_ostream Actual(Buffer);
127 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
128 assert(!Err);
129 std::string Expected =
130 R"raw(---
131USR: '0000000000000000000000000000000000000000'
132Name: 'r'
133Path: 'path/to/A'
134Namespace:
135 - Type: Namespace
136 Name: 'A'
137 QualName: 'A'
138DefLocation:
139 LineNumber: 10
140 Filename: 'test.cpp'
141Location:
142 - LineNumber: 12
143 Filename: 'test.cpp'
144TagType: Class
145IsTypeDef: true
146Members:
147 - Type:
148 Name: 'int'
149 QualName: 'int'
150 Name: 'X'
151 Access: Private
152 Description:
153 - Kind: FullComment
154 Children:
155 - Kind: ParagraphComment
156 Children:
157 - Kind: TextComment
158 Text: 'Value of the thing.'
159 Name: 'ParagraphComment'
160Bases:
161 - USR: '0000000000000000000000000000000000000000'
162 Name: 'F'
163 Path: 'path/to/F'
164 TagType: Struct
165 Members:
166 - Type:
167 Name: 'int'
168 QualName: 'int'
169 Name: 'N'
170 Access: Private
171 ChildFunctions:
172 - USR: '0000000000000000000000000000000000000000'
173 Name: 'InheritedFunctionOne'
174 ReturnType: {}
175 Access: Public
176 IsVirtual: true
177 Access: Public
178 IsParent: true
179Parents:
180 - Type: Record
181 Name: 'F'
182VirtualParents:
183 - Type: Record
184 Name: 'G'
185 QualName: 'path::to::G::G'
186 Path: 'path/to/G'
187ChildRecords:
188 - Type: Record
189 Name: 'ChildStruct'
190 QualName: 'path::to::A::r::ChildStruct'
191 Path: 'path/to/A/r'
192ChildFunctions:
193 - USR: '0000000000000000000000000000000000000000'
194 Name: 'OneFunction'
195 ReturnType: {}
196 Access: Public
197ChildEnums:
198 - USR: '0000000000000000000000000000000000000000'
199 Name: 'OneEnum'
200...
201)raw";
202 EXPECT_EQ(Expected, Actual.str());
203}
204
205TEST(YAMLGeneratorTest, emitFunctionYAML) {
206 FunctionInfo I;
207 I.Name = "f";
208 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
209
210 I.DefLoc = Location(10, 10, "test.cpp");
211 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
212
213 I.Access = AccessSpecifier::AS_none;
214
215 I.ReturnType = TypeInfo(Reference(EmptySID, "void", InfoType::IT_default));
216 I.Params.emplace_back(Args: TypeInfo("int"), Args: "P");
217 I.Params.emplace_back(Args: TypeInfo("double"), Args: "D");
218 I.Params.back().DefaultValue = "2.0 * M_PI";
219 I.IsMethod = true;
220 I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
221
222 auto G = getYAMLGenerator();
223 assert(G);
224 std::string Buffer;
225 llvm::raw_string_ostream Actual(Buffer);
226 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
227 assert(!Err);
228 std::string Expected =
229 R"raw(---
230USR: '0000000000000000000000000000000000000000'
231Name: 'f'
232Namespace:
233 - Type: Namespace
234 Name: 'A'
235 QualName: 'A'
236DefLocation:
237 LineNumber: 10
238 Filename: 'test.cpp'
239Location:
240 - LineNumber: 12
241 Filename: 'test.cpp'
242IsMethod: true
243Parent:
244 Type: Record
245 Name: 'Parent'
246 QualName: 'Parent'
247Params:
248 - Type:
249 Name: 'int'
250 QualName: 'int'
251 Name: 'P'
252 - Type:
253 Name: 'double'
254 QualName: 'double'
255 Name: 'D'
256 DefaultValue: '2.0 * M_PI'
257ReturnType:
258 Type:
259 Name: 'void'
260 QualName: 'void'
261...
262)raw";
263 EXPECT_EQ(Expected, Actual.str());
264}
265
266// Tests the equivalent of:
267// namespace A {
268// enum e { X };
269// }
270TEST(YAMLGeneratorTest, emitSimpleEnumYAML) {
271 EnumInfo I;
272 I.Name = "e";
273 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
274
275 I.DefLoc = Location(10, 10, "test.cpp");
276 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
277
278 I.Members.emplace_back(Args: "X");
279 I.Scoped = false;
280
281 auto G = getYAMLGenerator();
282 assert(G);
283 std::string Buffer;
284 llvm::raw_string_ostream Actual(Buffer);
285 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
286 assert(!Err);
287 std::string Expected =
288 R"raw(---
289USR: '0000000000000000000000000000000000000000'
290Name: 'e'
291Namespace:
292 - Type: Namespace
293 Name: 'A'
294 QualName: 'A'
295DefLocation:
296 LineNumber: 10
297 Filename: 'test.cpp'
298Location:
299 - LineNumber: 12
300 Filename: 'test.cpp'
301Members:
302 - Name: 'X'
303 Value: '0'
304...
305)raw";
306 EXPECT_EQ(Expected, Actual.str());
307}
308
309// Tests the equivalent of:
310// enum class e : short { X = FOO_BAR + 2 };
311TEST(YAMLGeneratorTest, enumTypedScopedEnumYAML) {
312 EnumInfo I;
313 I.Name = "e";
314
315 I.Members.emplace_back(Args: "X", Args: "-9876", Args: "FOO_BAR + 2");
316 I.Scoped = true;
317 I.BaseType = TypeInfo("short");
318
319 auto G = getYAMLGenerator();
320 assert(G);
321 std::string Buffer;
322 llvm::raw_string_ostream Actual(Buffer);
323 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
324 assert(!Err);
325 std::string Expected =
326 R"raw(---
327USR: '0000000000000000000000000000000000000000'
328Name: 'e'
329Scoped: true
330BaseType:
331 Type:
332 Name: 'short'
333 QualName: 'short'
334Members:
335 - Name: 'X'
336 Value: '-9876'
337 Expr: 'FOO_BAR + 2'
338...
339)raw";
340 EXPECT_EQ(Expected, Actual.str());
341}
342
343TEST(YAMLGeneratorTest, enumTypedefYAML) {
344 TypedefInfo I;
345 I.Name = "MyUsing";
346 I.Underlying = TypeInfo("int");
347 I.IsUsing = true;
348
349 auto G = getYAMLGenerator();
350 assert(G);
351 std::string Buffer;
352 llvm::raw_string_ostream Actual(Buffer);
353 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
354 assert(!Err);
355 std::string Expected =
356 R"raw(---
357USR: '0000000000000000000000000000000000000000'
358Name: 'MyUsing'
359Underlying:
360 Name: 'int'
361 QualName: 'int'
362IsUsing: true
363...
364)raw";
365 EXPECT_EQ(Expected, Actual.str());
366}
367
368TEST(YAMLGeneratorTest, emitCommentYAML) {
369 FunctionInfo I;
370 I.Name = "f";
371 I.DefLoc = Location(10, 10, "test.cpp");
372 I.ReturnType = TypeInfo("void");
373 I.Params.emplace_back(Args: TypeInfo("int"), Args: "I");
374 I.Params.emplace_back(Args: TypeInfo("int"), Args: "J");
375 I.Access = AccessSpecifier::AS_none;
376
377 CommentInfo Top;
378 Top.Kind = CommentKind::CK_FullComment;
379
380 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
381 CommentInfo *BlankLine = Top.Children.back().get();
382 BlankLine->Kind = CommentKind::CK_ParagraphComment;
383 BlankLine->Children.emplace_back(args: std::make_unique<CommentInfo>());
384 BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
385
386 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
387 CommentInfo *Brief = Top.Children.back().get();
388 Brief->Kind = CommentKind::CK_ParagraphComment;
389 Brief->Children.emplace_back(args: std::make_unique<CommentInfo>());
390 Brief->Children.back()->Kind = CommentKind::CK_TextComment;
391 Brief->Children.back()->Name = "ParagraphComment";
392 Brief->Children.back()->Text = " Brief description.";
393
394 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
395 CommentInfo *Extended = Top.Children.back().get();
396 Extended->Kind = CommentKind::CK_ParagraphComment;
397 Extended->Children.emplace_back(args: std::make_unique<CommentInfo>());
398 Extended->Children.back()->Kind = CommentKind::CK_TextComment;
399 Extended->Children.back()->Text = " Extended description that";
400 Extended->Children.emplace_back(args: std::make_unique<CommentInfo>());
401 Extended->Children.back()->Kind = CommentKind::CK_TextComment;
402 Extended->Children.back()->Text = " continues onto the next line.";
403
404 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
405 CommentInfo *HTML = Top.Children.back().get();
406 HTML->Kind = CommentKind::CK_ParagraphComment;
407 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
408 HTML->Children.back()->Kind = CommentKind::CK_TextComment;
409 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
410 HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
411 HTML->Children.back()->Name = "ul";
412 HTML->Children.back()->AttrKeys.emplace_back(Args: "class");
413 HTML->Children.back()->AttrValues.emplace_back(Args: "test");
414 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
415 HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
416 HTML->Children.back()->Name = "li";
417 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
418 HTML->Children.back()->Kind = CommentKind::CK_TextComment;
419 HTML->Children.back()->Text = " Testing.";
420 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
421 HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
422 HTML->Children.back()->Name = "ul";
423 HTML->Children.back()->SelfClosing = true;
424
425 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
426 CommentInfo *Verbatim = Top.Children.back().get();
427 Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
428 Verbatim->Name = "verbatim";
429 Verbatim->CloseName = "endverbatim";
430 Verbatim->Children.emplace_back(args: std::make_unique<CommentInfo>());
431 Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
432 Verbatim->Children.back()->Text = " The description continues.";
433
434 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
435 CommentInfo *ParamOut = Top.Children.back().get();
436 ParamOut->Kind = CommentKind::CK_ParamCommandComment;
437 ParamOut->Direction = "[out]";
438 ParamOut->ParamName = "I";
439 ParamOut->Explicit = true;
440 ParamOut->Children.emplace_back(args: std::make_unique<CommentInfo>());
441 ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
442 ParamOut->Children.back()->Children.emplace_back(
443 args: std::make_unique<CommentInfo>());
444 ParamOut->Children.back()->Children.back()->Kind =
445 CommentKind::CK_TextComment;
446 ParamOut->Children.back()->Children.emplace_back(
447 args: std::make_unique<CommentInfo>());
448 ParamOut->Children.back()->Children.back()->Kind =
449 CommentKind::CK_TextComment;
450 ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
451
452 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
453 CommentInfo *ParamIn = Top.Children.back().get();
454 ParamIn->Kind = CommentKind::CK_ParamCommandComment;
455 ParamIn->Direction = "[in]";
456 ParamIn->ParamName = "J";
457 ParamIn->Children.emplace_back(args: std::make_unique<CommentInfo>());
458 ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
459 ParamIn->Children.back()->Children.emplace_back(
460 args: std::make_unique<CommentInfo>());
461 ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
462 ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
463 ParamIn->Children.back()->Children.emplace_back(
464 args: std::make_unique<CommentInfo>());
465 ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
466
467 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
468 CommentInfo *Return = Top.Children.back().get();
469 Return->Kind = CommentKind::CK_BlockCommandComment;
470 Return->Name = "return";
471 Return->Explicit = true;
472 Return->Children.emplace_back(args: std::make_unique<CommentInfo>());
473 Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
474 Return->Children.back()->Children.emplace_back(
475 args: std::make_unique<CommentInfo>());
476 Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
477 Return->Children.back()->Children.back()->Text = "void";
478
479 I.Description.emplace_back(args: std::move(Top));
480
481 auto G = getYAMLGenerator();
482 assert(G);
483 std::string Buffer;
484 llvm::raw_string_ostream Actual(Buffer);
485 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
486 assert(!Err);
487 std::string Expected =
488 R"raw(---
489USR: '0000000000000000000000000000000000000000'
490Name: 'f'
491Description:
492 - Kind: FullComment
493 Children:
494 - Kind: ParagraphComment
495 Children:
496 - Kind: TextComment
497 - Kind: ParagraphComment
498 Children:
499 - Kind: TextComment
500 Text: ' Brief description.'
501 Name: 'ParagraphComment'
502 - Kind: ParagraphComment
503 Children:
504 - Kind: TextComment
505 Text: ' Extended description that'
506 - Kind: TextComment
507 Text: ' continues onto the next line.'
508 - Kind: ParagraphComment
509 Children:
510 - Kind: TextComment
511 - Kind: HTMLStartTagComment
512 Name: 'ul'
513 AttrKeys:
514 - 'class'
515 AttrValues:
516 - 'test'
517 - Kind: HTMLStartTagComment
518 Name: 'li'
519 - Kind: TextComment
520 Text: ' Testing.'
521 - Kind: HTMLEndTagComment
522 Name: 'ul'
523 SelfClosing: true
524 - Kind: VerbatimBlockComment
525 Name: 'verbatim'
526 CloseName: 'endverbatim'
527 Children:
528 - Kind: VerbatimBlockLineComment
529 Text: ' The description continues.'
530 - Kind: ParamCommandComment
531 Direction: '[out]'
532 ParamName: 'I'
533 Explicit: true
534 Children:
535 - Kind: ParagraphComment
536 Children:
537 - Kind: TextComment
538 - Kind: TextComment
539 Text: ' is a parameter.'
540 - Kind: ParamCommandComment
541 Direction: '[in]'
542 ParamName: 'J'
543 Children:
544 - Kind: ParagraphComment
545 Children:
546 - Kind: TextComment
547 Text: ' is a parameter.'
548 - Kind: TextComment
549 - Kind: BlockCommandComment
550 Name: 'return'
551 Explicit: true
552 Children:
553 - Kind: ParagraphComment
554 Children:
555 - Kind: TextComment
556 Text: 'void'
557DefLocation:
558 LineNumber: 10
559 Filename: 'test.cpp'
560Params:
561 - Type:
562 Name: 'int'
563 QualName: 'int'
564 Name: 'I'
565 - Type:
566 Name: 'int'
567 QualName: 'int'
568 Name: 'J'
569ReturnType:
570 Type:
571 Name: 'void'
572 QualName: 'void'
573...
574)raw";
575
576 EXPECT_EQ(Expected, Actual.str());
577}
578
579} // namespace doc
580} // namespace clang
581

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp