1 //===-- clang-doc/MDGeneratorTest.cpp -------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ClangDocTest.h"
10 #include "Generators.h"
11 #include "Representation.h"
12 #include "gtest/gtest.h"
17 std::unique_ptr
<Generator
> getMDGenerator() {
18 auto G
= doc::findGeneratorByName("md");
21 return std::move(G
.get());
24 TEST(MDGeneratorTest
, emitNamespaceMD
) {
27 I
.Namespace
.emplace_back(EmptySID
, "A", InfoType::IT_namespace
);
29 I
.Children
.Namespaces
.emplace_back(EmptySID
, "ChildNamespace",
30 InfoType::IT_namespace
);
31 I
.Children
.Records
.emplace_back(EmptySID
, "ChildStruct", 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";
38 auto G
= getMDGenerator();
41 llvm::raw_string_ostream
Actual(Buffer
);
42 auto Err
= G
->generateDocForInfo(&I
, Actual
, ClangDocContext());
44 std::string Expected
= R
"raw(# namespace Namespace
50 * [ChildNamespace](../ChildNamespace/index.md)
55 * [ChildStruct](../ChildStruct.md)
77 EXPECT_EQ(Expected
, Actual
.str());
80 TEST(MDGeneratorTest
, emitRecordMD
) {
83 I
.Namespace
.emplace_back(EmptySID
, "A", InfoType::IT_namespace
);
85 I
.DefLoc
= Location(10, llvm::SmallString
<16>{"test.cpp"});
86 I
.Loc
.emplace_back(12, llvm::SmallString
<16>{"test.cpp"});
88 I
.Members
.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private
);
89 I
.TagType
= TagTypeKind::Class
;
90 I
.Parents
.emplace_back(EmptySID
, "F", InfoType::IT_record
);
91 I
.VirtualParents
.emplace_back(EmptySID
, "G", InfoType::IT_record
);
93 I
.Children
.Records
.emplace_back(EmptySID
, "ChildStruct", 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";
99 auto G
= getMDGenerator();
102 llvm::raw_string_ostream
Actual(Buffer
);
103 auto Err
= G
->generateDocForInfo(&I
, Actual
, ClangDocContext());
105 std::string Expected
= R
"raw(# class r
107 *Defined at test.cpp#10*
129 *public OneFunction()*
144 EXPECT_EQ(Expected
, Actual
.str());
147 TEST(MDGeneratorTest
, emitFunctionMD
) {
150 I
.Namespace
.emplace_back(EmptySID
, "A", InfoType::IT_namespace
);
152 I
.DefLoc
= Location(10, llvm::SmallString
<16>{"test.cpp"});
153 I
.Loc
.emplace_back(12, llvm::SmallString
<16>{"test.cpp"});
155 I
.Access
= AccessSpecifier::AS_none
;
157 I
.ReturnType
= TypeInfo("void");
158 I
.Params
.emplace_back(TypeInfo("int"), "P");
160 I
.Parent
= Reference(EmptySID
, "Parent", InfoType::IT_record
);
162 auto G
= getMDGenerator();
165 llvm::raw_string_ostream
Actual(Buffer
);
166 auto Err
= G
->generateDocForInfo(&I
, Actual
, ClangDocContext());
168 std::string Expected
= R
"raw(### f
172 *Defined at test.cpp#10*
176 EXPECT_EQ(Expected
, Actual
.str());
179 TEST(MDGeneratorTest
, emitEnumMD
) {
182 I
.Namespace
.emplace_back(EmptySID
, "A", InfoType::IT_namespace
);
184 I
.DefLoc
= Location(10, llvm::SmallString
<16>{"test.cpp"});
185 I
.Loc
.emplace_back(12, llvm::SmallString
<16>{"test.cpp"});
187 I
.Members
.emplace_back("X");
190 auto G
= getMDGenerator();
193 llvm::raw_string_ostream
Actual(Buffer
);
194 auto Err
= G
->generateDocForInfo(&I
, Actual
, ClangDocContext());
196 std::string Expected
= R
"raw(| enum class e |
203 *Defined at test.cpp#10*
207 EXPECT_EQ(Expected
, Actual
.str());
210 TEST(MDGeneratorTest
, emitCommentMD
) {
213 I
.DefLoc
= Location(10, llvm::SmallString
<16>{"test.cpp"});
214 I
.ReturnType
= TypeInfo("void");
215 I
.Params
.emplace_back(TypeInfo("int"), "I");
216 I
.Params
.emplace_back(TypeInfo("int"), "J");
217 I
.Access
= AccessSpecifier::AS_none
;
220 Top
.Kind
= "FullComment";
222 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
223 CommentInfo
*BlankLine
= Top
.Children
.back().get();
224 BlankLine
->Kind
= "ParagraphComment";
225 BlankLine
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
226 BlankLine
->Children
.back()->Kind
= "TextComment";
228 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
229 CommentInfo
*Brief
= Top
.Children
.back().get();
230 Brief
->Kind
= "ParagraphComment";
231 Brief
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
232 Brief
->Children
.back()->Kind
= "TextComment";
233 Brief
->Children
.back()->Name
= "ParagraphComment";
234 Brief
->Children
.back()->Text
= " Brief description.";
236 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
237 CommentInfo
*Extended
= Top
.Children
.back().get();
238 Extended
->Kind
= "ParagraphComment";
239 Extended
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
240 Extended
->Children
.back()->Kind
= "TextComment";
241 Extended
->Children
.back()->Text
= " Extended description that";
242 Extended
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
243 Extended
->Children
.back()->Kind
= "TextComment";
244 Extended
->Children
.back()->Text
= " continues onto the next line.";
246 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
247 CommentInfo
*HTML
= Top
.Children
.back().get();
248 HTML
->Kind
= "ParagraphComment";
249 HTML
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
250 HTML
->Children
.back()->Kind
= "TextComment";
251 HTML
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
252 HTML
->Children
.back()->Kind
= "HTMLStartTagComment";
253 HTML
->Children
.back()->Name
= "ul";
254 HTML
->Children
.back()->AttrKeys
.emplace_back("class");
255 HTML
->Children
.back()->AttrValues
.emplace_back("test");
256 HTML
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
257 HTML
->Children
.back()->Kind
= "HTMLStartTagComment";
258 HTML
->Children
.back()->Name
= "li";
259 HTML
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
260 HTML
->Children
.back()->Kind
= "TextComment";
261 HTML
->Children
.back()->Text
= " Testing.";
262 HTML
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
263 HTML
->Children
.back()->Kind
= "HTMLEndTagComment";
264 HTML
->Children
.back()->Name
= "ul";
265 HTML
->Children
.back()->SelfClosing
= true;
267 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
268 CommentInfo
*Verbatim
= Top
.Children
.back().get();
269 Verbatim
->Kind
= "VerbatimBlockComment";
270 Verbatim
->Name
= "verbatim";
271 Verbatim
->CloseName
= "endverbatim";
272 Verbatim
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
273 Verbatim
->Children
.back()->Kind
= "VerbatimBlockLineComment";
274 Verbatim
->Children
.back()->Text
= " The description continues.";
276 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
277 CommentInfo
*ParamOut
= Top
.Children
.back().get();
278 ParamOut
->Kind
= "ParamCommandComment";
279 ParamOut
->Direction
= "[out]";
280 ParamOut
->ParamName
= "I";
281 ParamOut
->Explicit
= true;
282 ParamOut
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
283 ParamOut
->Children
.back()->Kind
= "ParagraphComment";
284 ParamOut
->Children
.back()->Children
.emplace_back(
285 std::make_unique
<CommentInfo
>());
286 ParamOut
->Children
.back()->Children
.back()->Kind
= "TextComment";
287 ParamOut
->Children
.back()->Children
.emplace_back(
288 std::make_unique
<CommentInfo
>());
289 ParamOut
->Children
.back()->Children
.back()->Kind
= "TextComment";
290 ParamOut
->Children
.back()->Children
.back()->Text
= " is a parameter.";
292 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
293 CommentInfo
*ParamIn
= Top
.Children
.back().get();
294 ParamIn
->Kind
= "ParamCommandComment";
295 ParamIn
->Direction
= "[in]";
296 ParamIn
->ParamName
= "J";
297 ParamIn
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
298 ParamIn
->Children
.back()->Kind
= "ParagraphComment";
299 ParamIn
->Children
.back()->Children
.emplace_back(
300 std::make_unique
<CommentInfo
>());
301 ParamIn
->Children
.back()->Children
.back()->Kind
= "TextComment";
302 ParamIn
->Children
.back()->Children
.back()->Text
= " is a parameter.";
303 ParamIn
->Children
.back()->Children
.emplace_back(
304 std::make_unique
<CommentInfo
>());
305 ParamIn
->Children
.back()->Children
.back()->Kind
= "TextComment";
307 Top
.Children
.emplace_back(std::make_unique
<CommentInfo
>());
308 CommentInfo
*Return
= Top
.Children
.back().get();
309 Return
->Kind
= "BlockCommandComment";
310 Return
->Name
= "return";
311 Return
->Explicit
= true;
312 Return
->Children
.emplace_back(std::make_unique
<CommentInfo
>());
313 Return
->Children
.back()->Kind
= "ParagraphComment";
314 Return
->Children
.back()->Children
.emplace_back(
315 std::make_unique
<CommentInfo
>());
316 Return
->Children
.back()->Children
.back()->Kind
= "TextComment";
317 Return
->Children
.back()->Children
.back()->Text
= "void";
319 I
.Description
.emplace_back(std::move(Top
));
321 auto G
= getMDGenerator();
324 llvm::raw_string_ostream
Actual(Buffer
);
325 auto Err
= G
->generateDocForInfo(&I
, Actual
, ClangDocContext());
327 std::string Expected
=
330 *void f(int I, int J)*
332 *Defined at test.cpp#10*
338 Extended description that continues onto the next line.
348 The description continues.
350 **I** [out] is a parameter.
352 **J** is a parameter.
358 EXPECT_EQ(Expected
, Actual
.str());