xref: /llvm-project/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp (revision 2c1c9a240776e5ccfb29b8a22bb32bb7e87ac2dd)
1 //===-- clang-doc/HTMLGeneratorTest.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ClangDocTest.h"
10 #include "Generators.h"
11 #include "Representation.h"
12 #include "gtest/gtest.h"
13 
14 namespace clang {
15 namespace doc {
16 
17 std::unique_ptr<Generator> getHTMLGenerator() {
18   auto G = doc::findGeneratorByName("html");
19   if (!G)
20     return nullptr;
21   return std::move(G.get());
22 }
23 
24 TEST(HTMLGeneratorTest, emitNamespaceHTML) {
25   NamespaceInfo I;
26   I.Name = "Namespace";
27   I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
28 
29   I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
30                                  InfoType::IT_namespace);
31   I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
32   I.ChildFunctions.emplace_back();
33   I.ChildFunctions.back().Name = "OneFunction";
34   I.ChildEnums.emplace_back();
35   I.ChildEnums.back().Name = "OneEnum";
36 
37   auto G = getHTMLGenerator();
38   assert(G);
39   std::string Buffer;
40   llvm::raw_string_ostream Actual(Buffer);
41   auto Err = G->generateDocForInfo(&I, Actual);
42   assert(!Err);
43   std::string Expected = R"raw(<!DOCTYPE html>
44 <meta charset="utf-8"/>
45 <title>namespace Namespace</title>
46 <div>
47   <h1>namespace Namespace</h1>
48   <h2>Namespaces</h2>
49   <ul>
50     <li>ChildNamespace</li>
51   </ul>
52   <h2>Records</h2>
53   <ul>
54     <li>ChildStruct</li>
55   </ul>
56   <h2>Functions</h2>
57   <div>
58     <h3>OneFunction</h3>
59     <p>
60       OneFunction()
61     </p>
62   </div>
63   <h2>Enums</h2>
64   <div>
65     <h3>enum OneEnum</h3>
66   </div>
67 </div>
68 )raw";
69 
70   EXPECT_EQ(Expected, Actual.str());
71 }
72 
73 TEST(HTMLGeneratorTest, emitRecordHTML) {
74   RecordInfo I;
75   I.Name = "r";
76   I.Path = "X/Y/Z";
77   I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
78 
79   I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
80   I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
81 
82   I.Members.emplace_back("int", "X/Y", "X", AccessSpecifier::AS_private);
83   I.TagType = TagTypeKind::TTK_Class;
84   I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record,
85                          llvm::SmallString<128>("path/to"));
86   I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
87 
88   I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
89   I.ChildFunctions.emplace_back();
90   I.ChildFunctions.back().Name = "OneFunction";
91   I.ChildEnums.emplace_back();
92   I.ChildEnums.back().Name = "OneEnum";
93 
94   auto G = getHTMLGenerator();
95   assert(G);
96   std::string Buffer;
97   llvm::raw_string_ostream Actual(Buffer);
98   auto Err = G->generateDocForInfo(&I, Actual);
99   assert(!Err);
100   std::string Expected = R"raw(<!DOCTYPE html>
101 <meta charset="utf-8"/>
102 <title>class r</title>
103 <div>
104   <h1>class r</h1>
105   <p>
106     Defined at line 10 of test.cpp
107   </p>
108   <p>
109     Inherits from
110     <a href="../../../path/to/F.html">F</a>
111     , G
112   </p>
113   <h2>Members</h2>
114   <ul>
115     <li>private <a href="../int.html">int</a> X</li>
116   </ul>
117   <h2>Records</h2>
118   <ul>
119     <li>ChildStruct</li>
120   </ul>
121   <h2>Functions</h2>
122   <div>
123     <h3>OneFunction</h3>
124     <p>
125       OneFunction()
126     </p>
127   </div>
128   <h2>Enums</h2>
129   <div>
130     <h3>enum OneEnum</h3>
131   </div>
132 </div>
133 )raw";
134 
135   EXPECT_EQ(Expected, Actual.str());
136 }
137 
138 TEST(HTMLGeneratorTest, emitFunctionHTML) {
139   FunctionInfo I;
140   I.Name = "f";
141   I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
142 
143   I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
144   I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
145 
146   I.ReturnType = TypeInfo(EmptySID, "float", InfoType::IT_default, "path/to");
147   I.Params.emplace_back("int", "path/to", "P");
148   I.IsMethod = true;
149   I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
150 
151   auto G = getHTMLGenerator();
152   assert(G);
153   std::string Buffer;
154   llvm::raw_string_ostream Actual(Buffer);
155   auto Err = G->generateDocForInfo(&I, Actual);
156   assert(!Err);
157   std::string Expected = R"raw(<!DOCTYPE html>
158 <meta charset="utf-8"/>
159 <title></title>
160 <div>
161   <h3>f</h3>
162   <p>
163     <a href="path/to/float.html">float</a>
164      f(
165     <a href="path/to/int.html">int</a>
166      P)
167   </p>
168   <p>
169     Defined at line 10 of test.cpp
170   </p>
171 </div>
172 )raw";
173 
174   EXPECT_EQ(Expected, Actual.str());
175 }
176 
177 TEST(HTMLGeneratorTest, emitEnumHTML) {
178   EnumInfo I;
179   I.Name = "e";
180   I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
181 
182   I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
183   I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
184 
185   I.Members.emplace_back("X");
186   I.Scoped = true;
187 
188   auto G = getHTMLGenerator();
189   assert(G);
190   std::string Buffer;
191   llvm::raw_string_ostream Actual(Buffer);
192   auto Err = G->generateDocForInfo(&I, Actual);
193   assert(!Err);
194   std::string Expected = R"raw(<!DOCTYPE html>
195 <meta charset="utf-8"/>
196 <title></title>
197 <div>
198   <h3>enum class e</h3>
199   <ul>
200     <li>X</li>
201   </ul>
202   <p>
203     Defined at line 10 of test.cpp
204   </p>
205 </div>
206 )raw";
207 
208   EXPECT_EQ(Expected, Actual.str());
209 }
210 
211 TEST(HTMLGeneratorTest, emitCommentHTML) {
212   FunctionInfo I;
213   I.Name = "f";
214   I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
215   I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
216   I.Params.emplace_back("int", "I");
217   I.Params.emplace_back("int", "J");
218 
219   CommentInfo Top;
220   Top.Kind = "FullComment";
221 
222   Top.Children.emplace_back(llvm::make_unique<CommentInfo>());
223   CommentInfo *BlankLine = Top.Children.back().get();
224   BlankLine->Kind = "ParagraphComment";
225   BlankLine->Children.emplace_back(llvm::make_unique<CommentInfo>());
226   BlankLine->Children.back()->Kind = "TextComment";
227 
228   Top.Children.emplace_back(llvm::make_unique<CommentInfo>());
229   CommentInfo *Brief = Top.Children.back().get();
230   Brief->Kind = "ParagraphComment";
231   Brief->Children.emplace_back(llvm::make_unique<CommentInfo>());
232   Brief->Children.back()->Kind = "TextComment";
233   Brief->Children.back()->Name = "ParagraphComment";
234   Brief->Children.back()->Text = " Brief description.";
235 
236   Top.Children.emplace_back(llvm::make_unique<CommentInfo>());
237   CommentInfo *Extended = Top.Children.back().get();
238   Extended->Kind = "ParagraphComment";
239   Extended->Children.emplace_back(llvm::make_unique<CommentInfo>());
240   Extended->Children.back()->Kind = "TextComment";
241   Extended->Children.back()->Text = " Extended description that";
242   Extended->Children.emplace_back(llvm::make_unique<CommentInfo>());
243   Extended->Children.back()->Kind = "TextComment";
244   Extended->Children.back()->Text = " continues onto the next line.";
245 
246   I.Description.emplace_back(std::move(Top));
247 
248   auto G = getHTMLGenerator();
249   assert(G);
250   std::string Buffer;
251   llvm::raw_string_ostream Actual(Buffer);
252   auto Err = G->generateDocForInfo(&I, Actual);
253   assert(!Err);
254   std::string Expected = R"raw(<!DOCTYPE html>
255 <meta charset="utf-8"/>
256 <title></title>
257 <div>
258   <h3>f</h3>
259   <p>
260     void f(int I, int J)
261   </p>
262   <p>
263     Defined at line 10 of test.cpp
264   </p>
265   <div>
266     <div>
267       <p>
268          Brief description.
269       </p>
270       <p>
271          Extended description that continues onto the next line.
272       </p>
273     </div>
274   </div>
275 </div>
276 )raw";
277 
278   EXPECT_EQ(Expected, Actual.str());
279 }
280 
281 } // namespace doc
282 } // namespace clang
283