366 lines · cpp
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-exception6//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("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(EmptySID, "A", InfoType::IT_namespace);28 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";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, Actual, ClangDocContext());43 assert(!Err);44 std::string Expected = R"raw(# namespace Namespace45 46 47 48## Namespaces49 50* [ChildNamespace](../ChildNamespace/index.md)51 52 53## Records54 55* [ChildStruct](../ChildStruct.md)56 57 58## Functions59 60### OneFunction61 62* OneFunction()*63 64 65 66## Enums67 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(EmptySID, "A", InfoType::IT_namespace);84 85 I.DefLoc = Location(10, 10, "test.cpp");86 I.Loc.emplace_back(12, 12, "test.cpp");87 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);92 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";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, Actual, ClangDocContext());104 assert(!Err);105 std::string Expected = R"raw(# class r106 107*Defined at test.cpp#10*108 109Inherits from F, G110 111 112 113## Members114 115private int X116 117 118 119## Records120 121ChildStruct122 123 124 125## Functions126 127### OneFunction128 129*public OneFunction()*130 131 132 133## Enums134 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(EmptySID, "A", InfoType::IT_namespace);151 152 I.DefLoc = Location(10, 10, "test.cpp");153 I.Loc.emplace_back(12, 12, "test.cpp");154 155 I.Access = AccessSpecifier::AS_none;156 157 I.ReturnType = TypeInfo("void");158 I.Params.emplace_back(TypeInfo("int"), "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, Actual, ClangDocContext());167 assert(!Err);168 std::string Expected = R"raw(### f169 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(EmptySID, "A", InfoType::IT_namespace);183 184 I.DefLoc = Location(10, 10, "test.cpp");185 I.Loc.emplace_back(12, 12, "test.cpp");186 187 I.Members.emplace_back("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, Actual, 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(TypeInfo("int"), "I");217 I.Params.emplace_back(TypeInfo("int"), "J");218 I.Access = AccessSpecifier::AS_none;219 220 CommentInfo Top;221 Top.Kind = CommentKind::CK_FullComment;222 223 Top.Children.emplace_back(std::make_unique<CommentInfo>());224 CommentInfo *BlankLine = Top.Children.back().get();225 BlankLine->Kind = CommentKind::CK_ParagraphComment;226 BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());227 BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;228 229 Top.Children.emplace_back(std::make_unique<CommentInfo>());230 CommentInfo *Brief = Top.Children.back().get();231 Brief->Kind = CommentKind::CK_ParagraphComment;232 Brief->Children.emplace_back(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(std::make_unique<CommentInfo>());238 CommentInfo *Extended = Top.Children.back().get();239 Extended->Kind = CommentKind::CK_ParagraphComment;240 Extended->Children.emplace_back(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(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(std::make_unique<CommentInfo>());248 CommentInfo *HTML = Top.Children.back().get();249 HTML->Kind = CommentKind::CK_ParagraphComment;250 HTML->Children.emplace_back(std::make_unique<CommentInfo>());251 HTML->Children.back()->Kind = CommentKind::CK_TextComment;252 HTML->Children.emplace_back(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("class");256 HTML->Children.back()->AttrValues.emplace_back("test");257 HTML->Children.emplace_back(std::make_unique<CommentInfo>());258 HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;259 HTML->Children.back()->Name = "li";260 HTML->Children.emplace_back(std::make_unique<CommentInfo>());261 HTML->Children.back()->Kind = CommentKind::CK_TextComment;262 HTML->Children.back()->Text = " Testing.";263 HTML->Children.emplace_back(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(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(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(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(std::make_unique<CommentInfo>());284 ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;285 ParamOut->Children.back()->Children.emplace_back(286 std::make_unique<CommentInfo>());287 ParamOut->Children.back()->Children.back()->Kind =288 CommentKind::CK_TextComment;289 ParamOut->Children.back()->Children.emplace_back(290 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(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(std::make_unique<CommentInfo>());301 ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;302 ParamIn->Children.back()->Children.emplace_back(303 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 std::make_unique<CommentInfo>());308 ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;309 310 Top.Children.emplace_back(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(std::make_unique<CommentInfo>());316 Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;317 Return->Children.back()->Children.emplace_back(318 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(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, Actual, ClangDocContext());329 assert(!Err);330 std::string Expected =331 R"raw(### f332 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**void358 359)raw";360 361 EXPECT_EQ(Expected, Actual.str());362}363 364} // namespace doc365} // namespace clang366