llvm-project/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

298 lines
7.8 KiB
C++

//===-- clang-doc/HTMLGeneratorTest.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "ClangDocTest.h"
#include "Generators.h"
#include "Representation.h"
#include "gtest/gtest.h"
namespace clang {
namespace doc {
std::unique_ptr<Generator> getHTMLGenerator() {
auto G = doc::findGeneratorByName("html");
if (!G)
return nullptr;
return std::move(G.get());
}
TEST(HTMLGeneratorTest, emitNamespaceHTML) {
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 = getHTMLGenerator();
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title>namespace Namespace</title>
<div>
<h1>namespace Namespace</h1>
<h2>Namespaces</h2>
<ul>
<li>ChildNamespace</li>
</ul>
<h2>Records</h2>
<ul>
<li>ChildStruct</li>
</ul>
<h2>Functions</h2>
<div>
<h3>OneFunction</h3>
<p>
OneFunction()
</p>
</div>
<h2>Enums</h2>
<div>
<h3>enum OneEnum</h3>
</div>
</div>
)raw";
EXPECT_EQ(Expected, Actual.str());
}
TEST(HTMLGeneratorTest, emitRecordHTML) {
RecordInfo I;
I.Name = "r";
I.Path = "X/Y/Z";
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"});
SmallString<16> PathTo;
llvm::sys::path::native("path/to", PathTo);
I.Members.emplace_back("int", "X/Y", "X", AccessSpecifier::AS_private);
I.TagType = TagTypeKind::TTK_Class;
I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, PathTo);
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 = getHTMLGenerator();
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
SmallString<16> PathToF;
llvm::sys::path::native("../../../path/to/F.html", PathToF);
SmallString<16> PathToInt;
llvm::sys::path::native("../int.html", PathToInt);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title>class r</title>
<div>
<h1>class r</h1>
<p>
Defined at line 10 of test.cpp
</p>
<p>
Inherits from
<a href=")raw" + std::string(PathToF.str()) +
R"raw(">F</a>
, G
</p>
<h2>Members</h2>
<ul>
<li>private <a href=")raw" +
std::string(PathToInt.str()) + R"raw(">int</a> X</li>
</ul>
<h2>Records</h2>
<ul>
<li>ChildStruct</li>
</ul>
<h2>Functions</h2>
<div>
<h3>OneFunction</h3>
<p>
OneFunction()
</p>
</div>
<h2>Enums</h2>
<div>
<h3>enum OneEnum</h3>
</div>
</div>
)raw";
EXPECT_EQ(Expected, Actual.str());
}
TEST(HTMLGeneratorTest, emitFunctionHTML) {
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"});
SmallString<16> PathTo;
llvm::sys::path::native("path/to", PathTo);
I.ReturnType = TypeInfo(EmptySID, "float", InfoType::IT_default, PathTo);
I.Params.emplace_back("int", PathTo, "P");
I.IsMethod = true;
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
auto G = getHTMLGenerator();
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
SmallString<16> PathToFloat;
llvm::sys::path::native("path/to/float.html", PathToFloat);
SmallString<16> PathToInt;
llvm::sys::path::native("path/to/int.html", PathToInt);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title></title>
<div>
<h3>f</h3>
<p>
<a href=")raw" + std::string(PathToFloat.str()) +
R"raw(">float</a>
f(
<a href=")raw" + std::string(PathToInt.str()) +
R"raw(">int</a>
P)
</p>
<p>
Defined at line 10 of test.cpp
</p>
</div>
)raw";
EXPECT_EQ(Expected, Actual.str());
}
TEST(HTMLGeneratorTest, emitEnumHTML) {
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 = getHTMLGenerator();
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title></title>
<div>
<h3>enum class e</h3>
<ul>
<li>X</li>
</ul>
<p>
Defined at line 10 of test.cpp
</p>
</div>
)raw";
EXPECT_EQ(Expected, Actual.str());
}
TEST(HTMLGeneratorTest, emitCommentHTML) {
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>());
CommentInfo *BlankLine = Top.Children.back().get();
BlankLine->Kind = "ParagraphComment";
BlankLine->Children.emplace_back(llvm::make_unique<CommentInfo>());
BlankLine->Children.back()->Kind = "TextComment";
Top.Children.emplace_back(llvm::make_unique<CommentInfo>());
CommentInfo *Brief = Top.Children.back().get();
Brief->Kind = "ParagraphComment";
Brief->Children.emplace_back(llvm::make_unique<CommentInfo>());
Brief->Children.back()->Kind = "TextComment";
Brief->Children.back()->Name = "ParagraphComment";
Brief->Children.back()->Text = " Brief description.";
Top.Children.emplace_back(llvm::make_unique<CommentInfo>());
CommentInfo *Extended = Top.Children.back().get();
Extended->Kind = "ParagraphComment";
Extended->Children.emplace_back(llvm::make_unique<CommentInfo>());
Extended->Children.back()->Kind = "TextComment";
Extended->Children.back()->Text = " Extended description that";
Extended->Children.emplace_back(llvm::make_unique<CommentInfo>());
Extended->Children.back()->Kind = "TextComment";
Extended->Children.back()->Text = " continues onto the next line.";
I.Description.emplace_back(std::move(Top));
auto G = getHTMLGenerator();
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title></title>
<div>
<h3>f</h3>
<p>
void f(int I, int J)
</p>
<p>
Defined at line 10 of test.cpp
</p>
<div>
<div>
<p>
Brief description.
</p>
<p>
Extended description that continues onto the next line.
</p>
</div>
</div>
</div>
)raw";
EXPECT_EQ(Expected, Actual.str());
}
} // namespace doc
} // namespace clang