Index: unittests/clang-doc/CMakeLists.txt =================================================================== --- unittests/clang-doc/CMakeLists.txt +++ unittests/clang-doc/CMakeLists.txt @@ -13,6 +13,7 @@ add_extra_unittest(ClangDocTests BitcodeTest.cpp ClangDocTest.cpp + MDGeneratorTest.cpp MergeTest.cpp SerializeTest.cpp YAMLGeneratorTest.cpp Index: unittests/clang-doc/MDGeneratorTest.cpp =================================================================== --- unittests/clang-doc/MDGeneratorTest.cpp +++ unittests/clang-doc/MDGeneratorTest.cpp @@ -0,0 +1,361 @@ +//===-- clang-doc/MDGeneratorTest.cpp -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClangDocTest.h" +#include "Generators.h" +#include "Representation.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +std::unique_ptr getMDGenerator() { + auto G = doc::findGeneratorByName("md"); + if (!G) + return nullptr; + return std::move(G.get()); +} + +TEST(MDGeneratorTest, emitNamespaceMD) { + NamespaceInfo I; + I.Name = "Namespace"; + I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + + I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace", + InfoType::IT_namespace); + I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record); + I.ChildFunctions.emplace_back(); + I.ChildFunctions.back().Name = "OneFunction"; + I.ChildEnums.emplace_back(); + I.ChildEnums.back().Name = "OneEnum"; + + auto G = getMDGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = R"raw(# namespace Namespace + + + +## Namespaces + +ChildNamespace + + + +## Records + +ChildStruct + + + +## Functions + +### OneFunction + +* OneFunction()* + + + +## Enums + +| enum OneEnum | + +-- + + + + + +)raw"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(MDGeneratorTest, emitRecordMD) { + RecordInfo I; + I.Name = "r"; + I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + + I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"}); + I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"}); + + I.Members.emplace_back("int", "X", AccessSpecifier::AS_private); + I.TagType = TagTypeKind::TTK_Class; + I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record); + I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record); + + I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record); + I.ChildFunctions.emplace_back(); + I.ChildFunctions.back().Name = "OneFunction"; + I.ChildEnums.emplace_back(); + I.ChildEnums.back().Name = "OneEnum"; + + auto G = getMDGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = R"raw(# class r + +*Defined at line 10 of test.cpp* + +Inherits from F, G + + + +## Members + +private int X + + + +## Records + +ChildStruct + + + +## Functions + +### OneFunction + +* OneFunction()* + + + +## Enums + +| enum OneEnum | + +-- + + + + + +)raw"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(MDGeneratorTest, emitFunctionMD) { + FunctionInfo I; + I.Name = "f"; + I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + + I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"}); + I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"}); + + I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); + I.Params.emplace_back("int", "P"); + I.IsMethod = true; + I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record); + + auto G = getMDGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = R"raw(### f + +*void f(int P)* + +*Defined at line 10 of test.cpp* + +)raw"; + + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(MDGeneratorTest, emitEnumMD) { + EnumInfo I; + I.Name = "e"; + I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + + I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"}); + I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"}); + + I.Members.emplace_back("X"); + I.Scoped = true; + + auto G = getMDGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = R"raw(| enum class e | + +-- + +| X | + + +*Defined at line 10 of test.cpp* + +)raw"; + + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(MDGeneratorTest, emitCommentMD) { + FunctionInfo I; + I.Name = "f"; + I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"}); + I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); + I.Params.emplace_back("int", "I"); + I.Params.emplace_back("int", "J"); + + CommentInfo Top; + Top.Kind = "FullComment"; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *BlankLine = Top.Children.back().get(); + BlankLine->Kind = "ParagraphComment"; + BlankLine->Children.emplace_back(llvm::make_unique()); + BlankLine->Children.back()->Kind = "TextComment"; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *Brief = Top.Children.back().get(); + Brief->Kind = "ParagraphComment"; + Brief->Children.emplace_back(llvm::make_unique()); + Brief->Children.back()->Kind = "TextComment"; + Brief->Children.back()->Name = "ParagraphComment"; + Brief->Children.back()->Text = " Brief description."; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *Extended = Top.Children.back().get(); + Extended->Kind = "ParagraphComment"; + Extended->Children.emplace_back(llvm::make_unique()); + Extended->Children.back()->Kind = "TextComment"; + Extended->Children.back()->Text = " Extended description that"; + Extended->Children.emplace_back(llvm::make_unique()); + Extended->Children.back()->Kind = "TextComment"; + Extended->Children.back()->Text = " continues onto the next line."; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *HTML = Top.Children.back().get(); + HTML->Kind = "ParagraphComment"; + HTML->Children.emplace_back(llvm::make_unique()); + HTML->Children.back()->Kind = "TextComment"; + HTML->Children.emplace_back(llvm::make_unique()); + HTML->Children.back()->Kind = "HTMLStartTagComment"; + HTML->Children.back()->Name = "ul"; + HTML->Children.back()->AttrKeys.emplace_back("class"); + HTML->Children.back()->AttrValues.emplace_back("test"); + HTML->Children.emplace_back(llvm::make_unique()); + HTML->Children.back()->Kind = "HTMLStartTagComment"; + HTML->Children.back()->Name = "li"; + HTML->Children.emplace_back(llvm::make_unique()); + HTML->Children.back()->Kind = "TextComment"; + HTML->Children.back()->Text = " Testing."; + HTML->Children.emplace_back(llvm::make_unique()); + HTML->Children.back()->Kind = "HTMLEndTagComment"; + HTML->Children.back()->Name = "ul"; + HTML->Children.back()->SelfClosing = true; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *Verbatim = Top.Children.back().get(); + Verbatim->Kind = "VerbatimBlockComment"; + Verbatim->Name = "verbatim"; + Verbatim->CloseName = "endverbatim"; + Verbatim->Children.emplace_back(llvm::make_unique()); + Verbatim->Children.back()->Kind = "VerbatimBlockLineComment"; + Verbatim->Children.back()->Text = " The description continues."; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *ParamOut = Top.Children.back().get(); + ParamOut->Kind = "ParamCommandComment"; + ParamOut->Direction = "[out]"; + ParamOut->ParamName = "I"; + ParamOut->Explicit = true; + ParamOut->Children.emplace_back(llvm::make_unique()); + ParamOut->Children.back()->Kind = "ParagraphComment"; + ParamOut->Children.back()->Children.emplace_back( + llvm::make_unique()); + ParamOut->Children.back()->Children.back()->Kind = "TextComment"; + ParamOut->Children.back()->Children.emplace_back( + llvm::make_unique()); + ParamOut->Children.back()->Children.back()->Kind = "TextComment"; + ParamOut->Children.back()->Children.back()->Text = " is a parameter."; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *ParamIn = Top.Children.back().get(); + ParamIn->Kind = "ParamCommandComment"; + ParamIn->Direction = "[in]"; + ParamIn->ParamName = "J"; + ParamIn->Children.emplace_back(llvm::make_unique()); + ParamIn->Children.back()->Kind = "ParagraphComment"; + ParamIn->Children.back()->Children.emplace_back( + llvm::make_unique()); + ParamIn->Children.back()->Children.back()->Kind = "TextComment"; + ParamIn->Children.back()->Children.back()->Text = " is a parameter."; + ParamIn->Children.back()->Children.emplace_back( + llvm::make_unique()); + ParamIn->Children.back()->Children.back()->Kind = "TextComment"; + + Top.Children.emplace_back(llvm::make_unique()); + CommentInfo *Return = Top.Children.back().get(); + Return->Kind = "BlockCommandComment"; + Return->Name = "return"; + Return->Explicit = true; + Return->Children.emplace_back(llvm::make_unique()); + Return->Children.back()->Kind = "ParagraphComment"; + Return->Children.back()->Children.emplace_back( + llvm::make_unique()); + Return->Children.back()->Children.back()->Kind = "TextComment"; + Return->Children.back()->Children.back()->Text = "void"; + + I.Description.emplace_back(std::move(Top)); + + auto G = getMDGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + R"raw(### f + +*void f(int I, int J)* + +*Defined at line 10 of test.cpp* + + + + Brief description. + + Extended description that continues onto the next line. + +
    + +
  • + + Testing.
+ + + + The description continues. + +**I** [out] + +**J** + +**return**void + +)raw"; + + EXPECT_EQ(Expected, Actual.str()); +} + +} // namespace doc +} // namespace clang