brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.2 KiB · 1434143 Raw
493 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ClangDocTest.h"10#include "Generators.h"11#include "Representation.h"12#include "clang/Basic/Version.h"13#include "gtest/gtest.h"14 15namespace clang {16namespace doc {17 18static const std::string ClangDocVersion =19    clang::getClangToolFullVersion("clang-doc");20 21static std::unique_ptr<Generator> getHTMLGenerator() {22  auto G = doc::findGeneratorByName("html");23  if (!G)24    return nullptr;25  return std::move(G.get());26}27 28static ClangDocContext29getClangDocContext(std::vector<std::string> UserStylesheets = {},30                   StringRef RepositoryUrl = "",31                   StringRef RepositoryLinePrefix = "", StringRef Base = "") {32  ClangDocContext CDCtx{33      {},   "test-project", {}, {}, {}, RepositoryUrl, RepositoryLinePrefix,34      Base, UserStylesheets};35  CDCtx.UserStylesheets.insert(36      CDCtx.UserStylesheets.begin(),37      "../share/clang/clang-doc-default-stylesheet.css");38  CDCtx.JsScripts.emplace_back("index.js");39  return CDCtx;40}41 42TEST(HTMLGeneratorTest, emitNamespaceHTML) {43  NamespaceInfo I;44  I.Name = "Namespace";45  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);46 47  I.Children.Namespaces.emplace_back(EmptySID, "ChildNamespace",48                                     InfoType::IT_namespace,49                                     "Namespace::ChildNamespace", "Namespace");50  I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,51                                  "Namespace::ChildStruct", "Namespace");52  I.Children.Functions.emplace_back();53  I.Children.Functions.back().Access = AccessSpecifier::AS_none;54  I.Children.Functions.back().Name = "OneFunction";55  I.Children.Enums.emplace_back();56  I.Children.Enums.back().Name = "OneEnum";57 58  auto G = getHTMLGenerator();59  assert(G);60  std::string Buffer;61  llvm::raw_string_ostream Actual(Buffer);62  ClangDocContext CDCtx = getClangDocContext({"user-provided-stylesheet.css"});63  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);64  assert(!Err);65  std::string Expected = R"raw(<!DOCTYPE html>66<meta charset="utf-8"/>67<title>namespace Namespace</title>68<link rel="stylesheet" href="../clang-doc-default-stylesheet.css"/>69<link rel="stylesheet" href="../user-provided-stylesheet.css"/>70<script src="../index_json.js"></script>71<script src="../index.js"></script>72<header id="project-title">test-project</header>73<main>74  <div id="sidebar-left" path="Namespace" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>75  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">76    <h1>namespace Namespace</h1>77    <h2 id="Namespaces">Namespaces</h2>78    <ul>79      <li>80        <a href="ChildNamespace/index.html">ChildNamespace</a>81      </li>82    </ul>83    <h2 id="Records">Records</h2>84    <ul>85      <li>86        <a href="ChildStruct.html">ChildStruct</a>87      </li>88    </ul>89    <h2 id="Functions">Functions</h2>90    <div>91      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>92      <p>OneFunction()</p>93    </div>94    <h2 id="Enums">Enums</h2>95    <div>96      <table id="0000000000000000000000000000000000000000">97        <thead>98          <tr>99            <th colspan="2">enum OneEnum</th>100          </tr>101        </thead>102      </table>103    </div>104  </div>105  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">106    <ol>107      <li>108        <span>109          <a href="#Namespaces">Namespaces</a>110        </span>111      </li>112      <li>113        <span>114          <a href="#Records">Records</a>115        </span>116      </li>117      <li>118        <span>119          <a href="#Functions">Functions</a>120        </span>121        <ul>122          <li>123            <span>124              <a href="#0000000000000000000000000000000000000000">OneFunction</a>125            </span>126          </li>127        </ul>128      </li>129      <li>130        <span>131          <a href="#Enums">Enums</a>132        </span>133        <ul>134          <li>135            <span>136              <a href="#0000000000000000000000000000000000000000">OneEnum</a>137            </span>138          </li>139        </ul>140      </li>141    </ol>142  </div>143</main>144<footer>145  <span class="no-break">)raw" +146                         ClangDocVersion + R"raw(</span>147</footer>148)raw";149 150  EXPECT_EQ(Expected, Actual.str());151}152 153TEST(HTMLGeneratorTest, emitRecordHTML) {154  RecordInfo I;155  I.Name = "r";156  I.Path = "X/Y/Z";157  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);158 159  I.DefLoc = Location(10, 10, "dir/test.cpp", true);160  I.Loc.emplace_back(12, 12, "test.cpp");161 162  SmallString<16> PathTo;163  llvm::sys::path::native("path/to", PathTo);164  I.Members.emplace_back(TypeInfo("int"), "X", AccessSpecifier::AS_private);165  I.TagType = TagTypeKind::Class;166  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record, "F", PathTo);167  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);168 169  I.Children.Records.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,170                                  "X::Y::Z::r::ChildStruct", "X/Y/Z/r");171  I.Children.Functions.emplace_back();172  I.Children.Functions.back().Name = "OneFunction";173  I.Children.Enums.emplace_back();174  I.Children.Enums.back().Name = "OneEnum";175 176  auto G = getHTMLGenerator();177  assert(G);178  std::string Buffer;179  llvm::raw_string_ostream Actual(Buffer);180  ClangDocContext CDCtx = getClangDocContext({}, "http://www.repository.com");181  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);182  assert(!Err);183  std::string Expected = R"raw(<!DOCTYPE html>184<meta charset="utf-8"/>185<title>class r</title>186<link rel="stylesheet" href="../../../clang-doc-default-stylesheet.css"/>187<script src="../../../index_json.js"></script>188<script src="../../../index.js"></script>189<header id="project-title">test-project</header>190<main>191  <div id="sidebar-left" path="X/Y/Z" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>192  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">193    <h1>class r</h1>194    <p>195      Defined at line 196      <a href="http://www.repository.com/dir/test.cpp#10">10</a>197       of file 198      <a href="http://www.repository.com/dir/test.cpp">test.cpp</a>199    </p>200    <p>201      Inherits from 202      <a href="../../../path/to/F.html">F</a>203      , G204    </p>205    <h2 id="Members">Members</h2>206    <ul>207      <li>208        <div>private int X</div>209      </li>210    </ul>211    <h2 id="Records">Records</h2>212    <ul>213      <li>214        <a href="../../../X/Y/Z/r/ChildStruct.html">ChildStruct</a>215      </li>216    </ul>217    <h2 id="Functions">Functions</h2>218    <div>219      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>220      <p>public OneFunction()</p>221    </div>222    <h2 id="Enums">Enums</h2>223    <div>224      <table id="0000000000000000000000000000000000000000">225        <thead>226          <tr>227            <th colspan="2">enum OneEnum</th>228          </tr>229        </thead>230      </table>231    </div>232  </div>233  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">234    <ol>235      <li>236        <span>237          <a href="#Members">Members</a>238        </span>239      </li>240      <li>241        <span>242          <a href="#Records">Records</a>243        </span>244      </li>245      <li>246        <span>247          <a href="#Functions">Functions</a>248        </span>249        <ul>250          <li>251            <span>252              <a href="#0000000000000000000000000000000000000000">OneFunction</a>253            </span>254          </li>255        </ul>256      </li>257      <li>258        <span>259          <a href="#Enums">Enums</a>260        </span>261        <ul>262          <li>263            <span>264              <a href="#0000000000000000000000000000000000000000">OneEnum</a>265            </span>266          </li>267        </ul>268      </li>269    </ol>270  </div>271</main>272<footer>273  <span class="no-break">)raw" +274                         ClangDocVersion + R"raw(</span>275</footer>276)raw";277 278  EXPECT_EQ(Expected, Actual.str());279}280 281TEST(HTMLGeneratorTest, emitFunctionHTML) {282  FunctionInfo I;283  I.Name = "f";284  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);285 286  I.DefLoc = Location(10, 10, "dir/test.cpp", true);287  I.Loc.emplace_back(12, 12, "test.cpp");288 289  I.Access = AccessSpecifier::AS_none;290 291  SmallString<16> PathTo;292  llvm::sys::path::native("path/to", PathTo);293  I.ReturnType = TypeInfo(294      Reference(EmptySID, "float", InfoType::IT_default, "float", PathTo));295  I.Params.emplace_back(TypeInfo("int", PathTo), "P");296  I.IsMethod = true;297  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);298 299  auto G = getHTMLGenerator();300  assert(G);301  std::string Buffer;302  llvm::raw_string_ostream Actual(Buffer);303  ClangDocContext CDCtx = getClangDocContext({}, "https://www.repository.com");304  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);305  assert(!Err);306  std::string Expected = R"raw(<!DOCTYPE html>307<meta charset="utf-8"/>308<title></title>309<link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>310<script src="index_json.js"></script>311<script src="index.js"></script>312<header id="project-title">test-project</header>313<main>314  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>315  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">316    <h3 id="0000000000000000000000000000000000000000">f</h3>317    <p>318      <a href="path/to/float.html">float</a>319       f(320      <a href="path/to/int.html">int</a>321       P)322    </p>323    <p>324      Defined at line 325      <a href="https://www.repository.com/dir/test.cpp#10">10</a>326       of file 327      <a href="https://www.repository.com/dir/test.cpp">test.cpp</a>328    </p>329  </div>330  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>331</main>332<footer>333  <span class="no-break">)raw" +334                         ClangDocVersion + R"raw(</span>335</footer>336)raw";337 338  EXPECT_EQ(Expected, Actual.str());339}340 341TEST(HTMLGeneratorTest, emitEnumHTML) {342  EnumInfo I;343  I.Name = "e";344  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);345 346  I.DefLoc = Location(10, 10, "test.cpp", true);347  I.Loc.emplace_back(12, 12, "test.cpp");348 349  I.Members.emplace_back("X");350  I.Scoped = true;351 352  auto G = getHTMLGenerator();353  assert(G);354  std::string Buffer;355  llvm::raw_string_ostream Actual(Buffer);356  ClangDocContext CDCtx = getClangDocContext({}, "www.repository.com");357  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);358  assert(!Err);359  std::string Expected = R"raw(<!DOCTYPE html>360<meta charset="utf-8"/>361<title></title>362<link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>363<script src="index_json.js"></script>364<script src="index.js"></script>365<header id="project-title">test-project</header>366<main>367  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>368  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">369    <table id="0000000000000000000000000000000000000000">370      <thead>371        <tr>372          <th colspan="2">enum class e</th>373        </tr>374      </thead>375      <tbody>376        <tr>377          <td>X</td>378          <td>0</td>379        </tr>380      </tbody>381    </table>382    <p>383      Defined at line 384      <a href="https://www.repository.com/test.cpp#10">10</a>385       of file 386      <a href="https://www.repository.com/test.cpp">test.cpp</a>387    </p>388  </div>389  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>390</main>391<footer>392  <span class="no-break">)raw" +393                         ClangDocVersion + R"raw(</span>394</footer>395)raw";396 397  EXPECT_EQ(Expected, Actual.str());398}399 400TEST(HTMLGeneratorTest, emitCommentHTML) {401  FunctionInfo I;402  I.Name = "f";403  I.DefLoc = Location(10, 10, "test.cpp", true);404  I.ReturnType = TypeInfo("void");405  I.Params.emplace_back(TypeInfo("int"), "I");406  I.Params.emplace_back(TypeInfo("int"), "J");407  I.Access = AccessSpecifier::AS_none;408 409  CommentInfo Top;410  Top.Kind = CommentKind::CK_FullComment;411 412  Top.Children.emplace_back(std::make_unique<CommentInfo>());413  CommentInfo *BlankLine = Top.Children.back().get();414  BlankLine->Kind = CommentKind::CK_ParagraphComment;415  BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());416  BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;417 418  Top.Children.emplace_back(std::make_unique<CommentInfo>());419  CommentInfo *Brief = Top.Children.back().get();420  Brief->Kind = CommentKind::CK_ParagraphComment;421  Brief->Children.emplace_back(std::make_unique<CommentInfo>());422  Brief->Children.back()->Kind = CommentKind::CK_TextComment;423  Brief->Children.back()->Name = "ParagraphComment";424  Brief->Children.back()->Text = " Brief description.";425 426  Top.Children.emplace_back(std::make_unique<CommentInfo>());427  CommentInfo *Extended = Top.Children.back().get();428  Extended->Kind = CommentKind::CK_ParagraphComment;429  Extended->Children.emplace_back(std::make_unique<CommentInfo>());430  Extended->Children.back()->Kind = CommentKind::CK_TextComment;431  Extended->Children.back()->Text = " Extended description that";432  Extended->Children.emplace_back(std::make_unique<CommentInfo>());433  Extended->Children.back()->Kind = CommentKind::CK_TextComment;434  Extended->Children.back()->Text = " continues onto the next line.";435 436  Top.Children.emplace_back(std::make_unique<CommentInfo>());437  CommentInfo *Entities = Top.Children.back().get();438  Entities->Kind = CommentKind::CK_ParagraphComment;439  Entities->Children.emplace_back(std::make_unique<CommentInfo>());440  Entities->Children.back()->Kind = CommentKind::CK_TextComment;441  Entities->Children.back()->Name = "ParagraphComment";442  Entities->Children.back()->Text =443      " Comment with html entities: &, <, >, \", \'.";444 445  I.Description.emplace_back(std::move(Top));446 447  auto G = getHTMLGenerator();448  assert(G);449  std::string Buffer;450  llvm::raw_string_ostream Actual(Buffer);451  ClangDocContext CDCtx = getClangDocContext();452  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);453  assert(!Err);454  std::string Expected = R"raw(<!DOCTYPE html>455<meta charset="utf-8"/>456<title></title>457<link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>458<script src="index_json.js"></script>459<script src="index.js"></script>460<header id="project-title">test-project</header>461<main>462  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>463  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">464    <h3 id="0000000000000000000000000000000000000000">f</h3>465    <p>void f(int I, int J)</p>466    <p>467      Defined at line 468      <a href="test.cpp#10">10</a>469       of file 470      <a href="test.cpp">test.cpp</a>471    </p>472    <div>473      <div>474        <p> Brief description.</p>475        <p> Extended description that continues onto the next line.</p>476        <p> Comment with html entities: &amp;, &lt;, &gt;, &quot;, &apos;.</p>477      </div>478    </div>479  </div>480  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>481</main>482<footer>483  <span class="no-break">)raw" +484                         ClangDocVersion + R"raw(</span>485</footer>486)raw";487 488  EXPECT_EQ(Expected, Actual.str());489}490 491} // namespace doc492} // namespace clang493