Index: clang-tools-extra/unittests/clang-doc/CMakeLists.txt =================================================================== --- clang-tools-extra/unittests/clang-doc/CMakeLists.txt +++ clang-tools-extra/unittests/clang-doc/CMakeLists.txt @@ -15,6 +15,7 @@ ClangDocTest.cpp MergeTest.cpp SerializeTest.cpp + YAMLGeneratorTest.cpp ) target_link_libraries(ClangDocTests Index: clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp =================================================================== --- /dev/null +++ clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp @@ -0,0 +1,422 @@ +//===-- clang-doc/YAMLGeneratorTest.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 getYAMLGenerator() { + auto G = doc::findGeneratorByName("yaml"); + if (!G) + return nullptr; + return std::move(G.get()); +} + +TEST(YAMLGeneratorTest, emitNamespaceYAML) { + 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 = getYAMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + "---\n" + "USR: '0000000000000000000000000000000000000000'\n" + "Name: 'Namespace'\n" + "Namespace: \n" + " - Type: Namespace\n" + " Name: 'A'\n" + "ChildNamespaces: \n" + " - Type: Namespace\n" + " Name: 'ChildNamespace'\n" + "ChildRecords: \n" + " - Type: Record\n" + " Name: 'ChildStruct'\n" + "ChildFunctions: \n" + " - USR: '0000000000000000000000000000000000000000'\n" + " Name: 'OneFunction'\n" + " ReturnType: \n" + "ChildEnums: \n" + " - USR: '0000000000000000000000000000000000000000'\n" + " Name: 'OneEnum'\n" + "...\n"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(YAMLGeneratorTest, emitRecordYAML) { + 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 = getYAMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + "---\n" + "USR: '0000000000000000000000000000000000000000'\n" + "Name: 'r'\n" + "Namespace: \n" + " - Type: Namespace\n" + " Name: 'A'\n" + "DefLocation: \n" + " LineNumber: 10\n" + " Filename: 'test.cpp'\n" + "Location: \n" + " - LineNumber: 12\n" + " Filename: 'test.cpp'\n" + "TagType: Class\n" + "Members: \n" + " - Type: \n" + " Name: 'int'\n" + " Name: 'X'\n" + " Access: Private\n" + "Parents: \n" + " - Type: Record\n" + " Name: 'F'\n" + "VirtualParents: \n" + " - Type: Record\n" + " Name: 'G'\n" + "ChildRecords: \n" + " - Type: Record\n" + " Name: 'ChildStruct'\n" + "ChildFunctions: \n" + " - USR: '0000000000000000000000000000000000000000'\n" + " Name: 'OneFunction'\n" + " ReturnType: \n" + "ChildEnums: \n" + " - USR: '0000000000000000000000000000000000000000'\n" + " Name: 'OneEnum'\n" + "...\n"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(YAMLGeneratorTest, emitFunctionYAML) { + 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 = getYAMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + "---\n" + "USR: '0000000000000000000000000000000000000000'\n" + "Name: 'f'\n" + "Namespace: \n" + " - Type: Namespace\n" + " Name: 'A'\n" + "DefLocation: \n" + " LineNumber: 10\n" + " Filename: 'test.cpp'\n" + "Location: \n" + " - LineNumber: 12\n" + " Filename: 'test.cpp'\n" + "IsMethod: true\n" + "Parent: \n" + " Type: Record\n" + " Name: 'Parent'\n" + "Params: \n" + " - Type: \n" + " Name: 'int'\n" + " Name: 'P'\n" + "ReturnType: \n" + " Type: \n" + " Name: 'void'\n" + "...\n"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(YAMLGeneratorTest, emitEnumYAML) { + 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 = getYAMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + "---\n" + "USR: '0000000000000000000000000000000000000000'\n" + "Name: 'e'\n" + "Namespace: \n" + " - Type: Namespace\n" + " Name: 'A'\n" + "DefLocation: \n" + " LineNumber: 10\n" + " Filename: 'test.cpp'\n" + "Location: \n" + " - LineNumber: 12\n" + " Filename: 'test.cpp'\n" + "Scoped: true\n" + "Members: \n" + " - 'X'\n" + "...\n"; + EXPECT_EQ(Expected, Actual.str()); +} + +TEST(YAMLGeneratorTest, emitCommentYAML) { + 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 = getYAMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual); + assert(!Err); + std::string Expected = + "---\n" + "USR: '0000000000000000000000000000000000000000'\n" + "Name: 'f'\n" + "Description: \n" + " - Kind: 'FullComment'\n" + " Children: \n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " Text: ' Brief description.'\n" + " Name: 'ParagraphComment'\n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " Text: ' Extended description that'\n" + " - Kind: 'TextComment'\n" + " Text: ' continues onto the next line.'\n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " - Kind: 'HTMLStartTagComment'\n" + " Name: 'ul'\n" + " AttrKeys: \n" + " - 'class'\n" + " AttrValues: \n" + " - 'test'\n" + " - Kind: 'HTMLStartTagComment'\n" + " Name: 'li'\n" + " - Kind: 'TextComment'\n" + " Text: ' Testing.'\n" + " - Kind: 'HTMLEndTagComment'\n" + " Name: 'ul'\n" + " SelfClosing: true\n" + " - Kind: 'VerbatimBlockComment'\n" + " Name: 'verbatim'\n" + " CloseName: 'endverbatim'\n" + " Children: \n" + " - Kind: 'VerbatimBlockLineComment'\n" + " Text: ' The description continues.'\n" + " - Kind: 'ParamCommandComment'\n" + " Direction: '[out]'\n" + " ParamName: 'I'\n" + " Explicit: true\n" + " Children: \n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " - Kind: 'TextComment'\n" + " Text: ' is a parameter.'\n" + " - Kind: 'ParamCommandComment'\n" + " Direction: '[in]'\n" + " ParamName: 'J'\n" + " Children: \n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " Text: ' is a parameter.'\n" + " - Kind: 'TextComment'\n" + " - Kind: 'BlockCommandComment'\n" + " Name: 'return'\n" + " Explicit: true\n" + " Children: \n" + " - Kind: 'ParagraphComment'\n" + " Children: \n" + " - Kind: 'TextComment'\n" + " Text: 'void'\n" + "DefLocation: \n" + " LineNumber: 10\n" + " Filename: 'test.cpp'\n" + "Params: \n" + " - Type: \n" + " Name: 'int'\n" + " Name: 'I'\n" + " - Type: \n" + " Name: 'int'\n" + " Name: 'J'\n" + "ReturnType: \n" + " Type: \n" + " Name: 'void'\n" + "...\n"; + + EXPECT_EQ(Expected, Actual.str()); +} + +} // namespace doc +} // namespace clang