1//===-- clang-doc/MDGeneratorTest.cpp -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ClangDocTest.h"
10#include "Generators.h"
11#include "Representation.h"
12#include "gtest/gtest.h"
13
14namespace clang {
15namespace doc {
16
17static std::unique_ptr<Generator> getMDGenerator() {
18 auto G = doc::findGeneratorByName(Format: "md");
19 if (!G)
20 return nullptr;
21 return std::move(G.get());
22}
23
24TEST(MDGeneratorTest, emitNamespaceMD) {
25 NamespaceInfo I;
26 I.Name = "Namespace";
27 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
28
29 I.Children.Namespaces.emplace_back(args: EmptySID, args: "ChildNamespace",
30 args: InfoType::IT_namespace);
31 I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct", args: InfoType::IT_record);
32 I.Children.Functions.emplace_back();
33 I.Children.Functions.back().Name = "OneFunction";
34 I.Children.Functions.back().Access = AccessSpecifier::AS_none;
35 I.Children.Enums.emplace_back();
36 I.Children.Enums.back().Name = "OneEnum";
37
38 auto G = getMDGenerator();
39 assert(G);
40 std::string Buffer;
41 llvm::raw_string_ostream Actual(Buffer);
42 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
43 assert(!Err);
44 std::string Expected = R"raw(# namespace Namespace
45
46
47
48## Namespaces
49
50* [ChildNamespace](../ChildNamespace/index.md)
51
52
53## Records
54
55* [ChildStruct](../ChildStruct.md)
56
57
58## Functions
59
60### OneFunction
61
62* OneFunction()*
63
64
65
66## Enums
67
68| enum OneEnum |
69
70--
71
72
73
74
75
76)raw";
77 EXPECT_EQ(Expected, Actual.str());
78}
79
80TEST(MDGeneratorTest, emitRecordMD) {
81 RecordInfo I;
82 I.Name = "r";
83 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
84
85 I.DefLoc = Location(10, 10, "test.cpp");
86 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
87
88 I.Members.emplace_back(Args: TypeInfo("int"), Args: "X", Args: AccessSpecifier::AS_private);
89 I.TagType = TagTypeKind::Class;
90 I.Parents.emplace_back(Args: EmptySID, Args: "F", Args: InfoType::IT_record);
91 I.VirtualParents.emplace_back(Args: EmptySID, Args: "G", Args: InfoType::IT_record);
92
93 I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct", args: InfoType::IT_record);
94 I.Children.Functions.emplace_back();
95 I.Children.Functions.back().Name = "OneFunction";
96 I.Children.Enums.emplace_back();
97 I.Children.Enums.back().Name = "OneEnum";
98
99 auto G = getMDGenerator();
100 assert(G);
101 std::string Buffer;
102 llvm::raw_string_ostream Actual(Buffer);
103 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
104 assert(!Err);
105 std::string Expected = R"raw(# class r
106
107*Defined at test.cpp#10*
108
109Inherits from F, G
110
111
112
113## Members
114
115private int X
116
117
118
119## Records
120
121ChildStruct
122
123
124
125## Functions
126
127### OneFunction
128
129*public OneFunction()*
130
131
132
133## Enums
134
135| enum OneEnum |
136
137--
138
139
140
141
142
143)raw";
144 EXPECT_EQ(Expected, Actual.str());
145}
146
147TEST(MDGeneratorTest, emitFunctionMD) {
148 FunctionInfo I;
149 I.Name = "f";
150 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
151
152 I.DefLoc = Location(10, 10, "test.cpp");
153 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
154
155 I.Access = AccessSpecifier::AS_none;
156
157 I.ReturnType = TypeInfo("void");
158 I.Params.emplace_back(Args: TypeInfo("int"), Args: "P");
159 I.IsMethod = true;
160 I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
161
162 auto G = getMDGenerator();
163 assert(G);
164 std::string Buffer;
165 llvm::raw_string_ostream Actual(Buffer);
166 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
167 assert(!Err);
168 std::string Expected = R"raw(### f
169
170*void f(int P)*
171
172*Defined at test.cpp#10*
173
174)raw";
175
176 EXPECT_EQ(Expected, Actual.str());
177}
178
179TEST(MDGeneratorTest, emitEnumMD) {
180 EnumInfo I;
181 I.Name = "e";
182 I.Namespace.emplace_back(Args: EmptySID, Args: "A", Args: InfoType::IT_namespace);
183
184 I.DefLoc = Location(10, 10, "test.cpp");
185 I.Loc.emplace_back(Args: 12, Args: 12, Args: "test.cpp");
186
187 I.Members.emplace_back(Args: "X");
188 I.Scoped = true;
189
190 auto G = getMDGenerator();
191 assert(G);
192 std::string Buffer;
193 llvm::raw_string_ostream Actual(Buffer);
194 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
195 assert(!Err);
196 std::string Expected = R"raw(| enum class e |
197
198--
199
200| X |
201
202
203*Defined at test.cpp#10*
204
205)raw";
206
207 EXPECT_EQ(Expected, Actual.str());
208}
209
210TEST(MDGeneratorTest, emitCommentMD) {
211 FunctionInfo I;
212 I.Name = "f";
213
214 I.DefLoc = Location(10, 10, "test.cpp");
215 I.ReturnType = TypeInfo("void");
216 I.Params.emplace_back(Args: TypeInfo("int"), Args: "I");
217 I.Params.emplace_back(Args: TypeInfo("int"), Args: "J");
218 I.Access = AccessSpecifier::AS_none;
219
220 CommentInfo Top;
221 Top.Kind = CommentKind::CK_FullComment;
222
223 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
224 CommentInfo *BlankLine = Top.Children.back().get();
225 BlankLine->Kind = CommentKind::CK_ParagraphComment;
226 BlankLine->Children.emplace_back(args: std::make_unique<CommentInfo>());
227 BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
228
229 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
230 CommentInfo *Brief = Top.Children.back().get();
231 Brief->Kind = CommentKind::CK_ParagraphComment;
232 Brief->Children.emplace_back(args: std::make_unique<CommentInfo>());
233 Brief->Children.back()->Kind = CommentKind::CK_TextComment;
234 Brief->Children.back()->Name = "ParagraphComment";
235 Brief->Children.back()->Text = " Brief description.";
236
237 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
238 CommentInfo *Extended = Top.Children.back().get();
239 Extended->Kind = CommentKind::CK_ParagraphComment;
240 Extended->Children.emplace_back(args: std::make_unique<CommentInfo>());
241 Extended->Children.back()->Kind = CommentKind::CK_TextComment;
242 Extended->Children.back()->Text = " Extended description that";
243 Extended->Children.emplace_back(args: std::make_unique<CommentInfo>());
244 Extended->Children.back()->Kind = CommentKind::CK_TextComment;
245 Extended->Children.back()->Text = " continues onto the next line.";
246
247 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
248 CommentInfo *HTML = Top.Children.back().get();
249 HTML->Kind = CommentKind::CK_ParagraphComment;
250 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
251 HTML->Children.back()->Kind = CommentKind::CK_TextComment;
252 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
253 HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
254 HTML->Children.back()->Name = "ul";
255 HTML->Children.back()->AttrKeys.emplace_back(Args: "class");
256 HTML->Children.back()->AttrValues.emplace_back(Args: "test");
257 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
258 HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
259 HTML->Children.back()->Name = "li";
260 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
261 HTML->Children.back()->Kind = CommentKind::CK_TextComment;
262 HTML->Children.back()->Text = " Testing.";
263 HTML->Children.emplace_back(args: std::make_unique<CommentInfo>());
264 HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
265 HTML->Children.back()->Name = "ul";
266 HTML->Children.back()->SelfClosing = true;
267
268 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
269 CommentInfo *Verbatim = Top.Children.back().get();
270 Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
271 Verbatim->Name = "verbatim";
272 Verbatim->CloseName = "endverbatim";
273 Verbatim->Children.emplace_back(args: std::make_unique<CommentInfo>());
274 Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
275 Verbatim->Children.back()->Text = " The description continues.";
276
277 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
278 CommentInfo *ParamOut = Top.Children.back().get();
279 ParamOut->Kind = CommentKind::CK_ParamCommandComment;
280 ParamOut->Direction = "[out]";
281 ParamOut->ParamName = "I";
282 ParamOut->Explicit = true;
283 ParamOut->Children.emplace_back(args: std::make_unique<CommentInfo>());
284 ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
285 ParamOut->Children.back()->Children.emplace_back(
286 args: std::make_unique<CommentInfo>());
287 ParamOut->Children.back()->Children.back()->Kind =
288 CommentKind::CK_TextComment;
289 ParamOut->Children.back()->Children.emplace_back(
290 args: std::make_unique<CommentInfo>());
291 ParamOut->Children.back()->Children.back()->Kind =
292 CommentKind::CK_TextComment;
293 ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
294
295 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
296 CommentInfo *ParamIn = Top.Children.back().get();
297 ParamIn->Kind = CommentKind::CK_ParamCommandComment;
298 ParamIn->Direction = "[in]";
299 ParamIn->ParamName = "J";
300 ParamIn->Children.emplace_back(args: std::make_unique<CommentInfo>());
301 ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
302 ParamIn->Children.back()->Children.emplace_back(
303 args: std::make_unique<CommentInfo>());
304 ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
305 ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
306 ParamIn->Children.back()->Children.emplace_back(
307 args: std::make_unique<CommentInfo>());
308 ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
309
310 Top.Children.emplace_back(args: std::make_unique<CommentInfo>());
311 CommentInfo *Return = Top.Children.back().get();
312 Return->Kind = CommentKind::CK_BlockCommandComment;
313 Return->Name = "return";
314 Return->Explicit = true;
315 Return->Children.emplace_back(args: std::make_unique<CommentInfo>());
316 Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
317 Return->Children.back()->Children.emplace_back(
318 args: std::make_unique<CommentInfo>());
319 Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
320 Return->Children.back()->Children.back()->Text = "void";
321
322 I.Description.emplace_back(args: std::move(Top));
323
324 auto G = getMDGenerator();
325 assert(G);
326 std::string Buffer;
327 llvm::raw_string_ostream Actual(Buffer);
328 auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext());
329 assert(!Err);
330 std::string Expected =
331 R"raw(### f
332
333*void f(int I, int J)*
334
335*Defined at test.cpp#10*
336
337
338
339 Brief description.
340
341 Extended description that continues onto the next line.
342
343<ul "class=test">
344
345<li>
346
347 Testing.</ul>
348
349
350
351 The description continues.
352
353**I** [out] is a parameter.
354
355**J** is a parameter.
356
357**return**void
358
359)raw";
360
361 EXPECT_EQ(Expected, Actual.str());
362}
363
364} // namespace doc
365} // namespace clang
366

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

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