[clang-tools-extra] [clang-doc] Add basic e2e test (PR #93928)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 6 22:49:51 PDT 2024


https://github.com/PeterChou1 updated https://github.com/llvm/llvm-project/pull/93928

>From 219df1820de43696dd51268f1aa22c397846c0a6 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Fri, 7 Jun 2024 01:47:15 -0400
Subject: [PATCH] [clang-doc] add basic e2e test

---
 .../Inputs/clang-doc-default-stylesheet.css   | 969 ++++++++++++++++++
 .../Inputs/clang-doc-project1/Calculator.cpp  |  21 +
 .../Inputs/clang-doc-project1/Calculator.h    |  46 +
 .../Inputs/clang-doc-project1/Circle.cpp      |  11 +
 .../Inputs/clang-doc-project1/Circle.h        |  35 +
 .../Inputs/clang-doc-project1/Rectangle.cpp   |  12 +
 .../Inputs/clang-doc-project1/Rectangle.h     |  37 +
 .../Inputs/clang-doc-project1/Shape.h         |  30 +
 .../clang-doc-project1/database_template.json |  17 +
 .../test/clang-doc/Inputs/index.js            |  87 ++
 .../test/clang-doc/clang-doc-project1.cpp     | 361 +++++++
 11 files changed, 1626 insertions(+)
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-default-stylesheet.css
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.cpp
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.h
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.cpp
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.h
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.cpp
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.h
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Shape.h
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/database_template.json
 create mode 100644 clang-tools-extra/test/clang-doc/Inputs/index.js
 create mode 100644 clang-tools-extra/test/clang-doc/clang-doc-project1.cpp

diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-default-stylesheet.css b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-default-stylesheet.css
new file mode 100644
index 0000000000000..8b335232b8048
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-default-stylesheet.css
@@ -0,0 +1,969 @@
+.dark-primary-color    { background: #1976D2; }
+.default-primary-color { background: #2196F3; }
+.light-primary-color   { background: #BBDEFB; }
+.text-primary-color    { color: #FFFFFF; }
+.accent-color          { background: #00BCD4; }
+.primary-text-color    { color: #212121; }
+.secondary-text-color  { color: #727272; }
+.divider-color         { border-color: #B6B6B6; }
+
+/* for layout */
+html,
+body {
+  margin: 0;
+  padding: 0;
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+  box-sizing: border-box;
+}
+
+*, *:before, *:after {
+  box-sizing: inherit;
+}
+
+body {
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+}
+
+header {
+  flex: 0 0 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding-left: 30px;
+}
+
+header ol {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+header ol li {
+  display: inline;
+}
+
+header form {
+  display: flex;
+  flex: 1;
+  justify-content: flex-end;
+  padding-right: 30px;
+}
+
+header#header-search-sidebar {
+  height: 50px;
+  margin-bottom: 25px;
+}
+
+footer {
+  flex: 0 0 16px;
+  text-align: center;
+  padding: 16px 20px;
+}
+
+main {
+  flex: 1;
+  display: flex;
+  flex-direction: row;
+  padding: 20px;
+  min-height: 0;
+}
+
+.sidebar-offcanvas-left {
+  flex: 0 1 230px;
+  overflow-y: scroll;
+  padding: 20px 0 15px 30px;
+  margin: 5px 20px 0 0;
+  visibility: visible; /* shown by Javascript after scroll position restore */
+}
+
+::-webkit-scrollbar-button{ display: none; height: 13px; border-radius: 0px; background-color: #AAA; }
+::-webkit-scrollbar-button:hover{ background-color: #AAA; }
+::-webkit-scrollbar-thumb{ background-color: #CCC; }
+::-webkit-scrollbar-thumb:hover{ background-color: #CCC; }
+::-webkit-scrollbar{ width: 4px; }
+/* ::-webkit-overflow-scrolling: touch; */
+
+.main-content::-webkit-scrollbar{ width: 8px; }
+
+.main-content {
+  flex: 1;
+  overflow-y: scroll;
+  padding: 10px 20px 0 20px;
+  visibility: visible; /* shown by Javascript after scroll position restore */
+}
+
+.sidebar-offcanvas-right {
+  flex: 0 1 12em;
+  overflow-y: scroll;
+  padding: 20px 15px 15px 15px;
+  margin-top: 5px;
+  margin-right: 20px;
+  visibility: visible; /* shown by Javascript after scroll position restore */
+}
+/* end for layout */
+
+body {
+  -webkit-text-size-adjust: 100%;
+  overflow-x: hidden;
+  font-family: Roboto, sans-serif;
+  font-size: 16px;
+  line-height: 1.42857143;
+  color: #111111;
+  background-color: #fff;
+}
+
+/* some of this is to reset bootstrap */
+nav.navbar {
+  background-color: inherit;
+  min-height: 50px;
+  border: 0;
+}
+
+ at media (max-width: 768px) {
+  .hidden-xs {
+    display: none !important;
+  }
+}
+
+ at media (min-width: 769px) {
+  .hidden-l {
+    display: none !important;
+  }
+}
+
+nav.navbar .row {
+  padding-top: 8px;
+}
+
+nav .container {
+  white-space: nowrap;
+}
+
+header {
+  background-color: #eeeeee;
+  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
+}
+
+header#project-title {
+  background-color: #fff;
+  font-size: 200%;
+  padding-top: 0.25em;
+  padding-bottom: 0.25em;
+  /* padding: 0em; */
+}
+
+header.header-fixed nav.navbar-fixed-top {
+  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
+}
+
+header.container-fluid {
+  padding: 0;
+}
+
+header .masthead {
+  padding-top: 64px;
+}
+
+header .contents {
+  padding: 0;
+}
+
+ at media screen and (max-width:768px) {
+  header .contents {
+    padding-left: 15px;
+    padding-right: 15px;
+  }
+}
+
+a {
+  text-decoration: none;
+}
+
+.body {
+  margin-top: 90px;
+}
+
+section {
+  margin-bottom: 36px;
+}
+
+dl {
+  margin: 0;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-family: Roboto, sans-serif;
+  font-weight: 400;
+  margin-top: 1.5em;
+  color: #111111;
+}
+
+h1.title {
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+h1 {
+  font-size: 37px;
+  margin-top: 0;
+  margin-bottom: 0.67em;
+}
+
+h2 {
+  font-size: 28px;
+}
+
+h5 {
+  font-size: 16px;
+}
+
+.subtitle {
+  font-size: 17px;
+  min-height: 1.4em;
+}
+
+.title-description .subtitle {
+  white-space: nowrap;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+}
+
+p {
+  margin-bottom: 1em;
+  margin-top: 0;
+}
+
+a {
+  color: #0175C2;
+}
+
+a:hover {
+  color: #13B9FD;
+}
+
+pre.prettyprint {
+  font-family: 'Source Code Pro', Menlo, monospace;
+  color: black;
+  border-radius: 0;
+  font-size: 15px;
+  word-wrap: normal;
+  line-height: 1.4;
+  border: 0;
+  margin: 16px 0 16px 0;
+  padding: 8px;
+}
+
+pre code {
+  white-space: pre;
+  word-wrap: initial;
+  font-size: 100%
+}
+
+.fixed {
+  white-space: pre;
+}
+
+pre {
+  border: 1px solid #ddd;
+  background-color: #eee;
+  font-size: 14px;
+}
+
+code {
+  font-family: 'Source Code Pro', Menlo, monospace;
+  /* overriding bootstrap */
+  color: inherit;
+  padding: 0.2em 0.4em;
+  font-size: 85%;
+  background-color: rgba(27,31,35,0.05);
+  border-radius: 3px;
+}
+
+ at media(max-width: 768px) {
+  nav .container {
+    width: 100%
+  }
+
+  h1 {
+    font-size: 24px;
+  }
+
+  pre {
+    margin: 16px 0;
+  }
+}
+
+ at media (min-width: 768px) {
+  ul.subnav li {
+    font-size: 17px;
+  }
+}
+
+header h1 {
+  font-weight: 400;
+  margin-bottom: 16px;
+}
+
+header a,
+header p,
+header li {
+  color: #111111;
+}
+
+header a:hover {
+  color: #0175C2;
+}
+
+header h1 .kind {
+  color: #555;
+}
+
+dt {
+  font-weight: normal;
+}
+
+dd {
+  color: #212121;
+  margin-bottom: 1em;
+  margin-left: 0;
+}
+
+dd.callable, dd.constant, dd.property {
+  margin-bottom: 24px;
+}
+
+dd p {
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  margin-bottom: 0;
+}
+
+/* indents wrapped lines */
+section.summary dt {
+  margin-left: 24px;
+  text-indent: -24px;
+}
+
+.dl-horizontal dd {
+  margin-left: initial;
+}
+
+dl.dl-horizontal dt {
+  font-style: normal;
+  text-align: left;
+  color: #727272;
+  margin-right: 20px;
+  width: initial;
+}
+
+dt .name {
+  font-weight: 500;
+}
+
+dl dt.callable .name {
+  float: none;
+  width: auto;
+}
+
+.parameter {
+  white-space: nowrap;
+}
+
+.type-parameter {
+  white-space: nowrap;
+}
+
+.multi-line-signature .type-parameter .parameter {
+  margin-left: 0px;
+  display: unset;
+}
+
+.signature {
+  color: #727272;
+}
+
+.signature a {
+  /* 50% mix of default-primary-color and primary-text-color. */
+  color: #4674a2;
+}
+
+.optional {
+  font-style: italic;
+}
+
+.undocumented {
+  font-style: italic;
+}
+
+.is-const {
+  font-style: italic;
+}
+
+.deprecated {
+  text-decoration: line-through;
+}
+
+.category.linked {
+  font-weight: bold;
+  opacity: 1;
+}
+
+/* Colors for category based on categoryOrder in dartdoc_options.config. */
+.category.cp-0 {
+  background-color: #54b7c4
+}
+
+.category.cp-1 {
+  background-color: #54c47f
+}
+
+.category.cp-2 {
+  background-color: #c4c254
+}
+
+.category.cp-3 {
+  background-color: #c49f54
+}
+
+.category.cp-4 {
+  background-color: #c45465
+}
+
+.category.cp-5 {
+  background-color: #c454c4
+}
+
+.category a {
+  color: white;
+}
+
+.category {
+  padding: 2px 4px;
+  font-size: 12px;
+  border-radius: 4px;
+  background-color: #999;
+  text-transform: uppercase;
+  color: white;
+  opacity: .5;
+}
+
+h1 .category {
+  vertical-align: middle;
+}
+
+.source-link {
+  padding: 18px 4px;
+  vertical-align: middle;
+}
+
+.source-link .material-icons {
+  font-size: 18px;
+}
+
+ at media (max-width: 768px) {
+  .source-link {
+    padding: 7px 2px;
+    font-size: 10px;
+  }
+}
+
+#external-links {
+  float: right;
+}
+
+.btn-group {
+  position: relative;
+  display: inline-flex;
+  vertical-align: middle;
+}
+
+p.firstline {
+  font-weight: bold;
+}
+
+footer {
+  color: #fff;
+  background-color: #111111;
+  width: 100%;
+}
+
+footer p {
+  margin: 0;
+}
+
+footer .no-break {
+  white-space: nowrap;
+}
+
+footer .container,
+footer .container-fluid {
+  padding-left: 0;
+  padding-right: 0;
+}
+
+footer a, footer a:hover {
+  color: #fff;
+}
+
+.markdown.desc {
+  max-width: 700px;
+}
+
+.markdown h1 {
+  font-size: 24px;
+  margin-bottom: 8px;
+}
+
+.markdown h2 {
+  font-size: 20px;
+  margin-top: 24px;
+  margin-bottom: 8px;
+}
+
+.markdown h3 {
+  font-size: 18px;
+  margin-bottom: 8px;
+}
+
+.markdown h4 {
+  font-size: 16px;
+  margin-bottom: 0;
+}
+
+.markdown li p {
+  margin: 0;
+}
+
+.gt-separated {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+.gt-separated li {
+  display: inline-block;
+}
+
+.gt-separated li:before {
+  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='%23DDDDDD' d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
+  background-position: center;
+  content: "\00a0";
+  margin: 0 6px 0 4px;
+  padding: 0 3px 0 0;
+}
+
+.gt-separated.dark li:before {
+  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='%23727272' d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
+}
+
+.gt-separated li:first-child:before {
+  background-image: none;
+  content: "";
+  margin: 0;
+}
+
+/* The slug line under a declaration for things like "const", "read-only", etc. */
+.features {
+  font-style: italic;
+  color: #727272;
+}
+
+.multi-line-signature {
+  font-size: 17px;
+  color: #727272;
+}
+
+.multi-line-signature .parameter {
+  margin-left: 24px;
+  display: block;
+}
+
+.breadcrumbs {
+  padding: 0;
+  margin: 8px 0 8px 0;
+  white-space: nowrap;
+  line-height: 1;
+}
+
+ at media screen and (min-width: 768px) {
+  nav ol.breadcrumbs {
+    float: left;
+  }
+}
+
+ at media screen and (max-width: 768px) {
+  .breadcrumbs {
+    margin: 0 0 24px 0;
+    overflow-x: hidden;
+  }
+}
+
+.self-crumb {
+  color: #555;
+}
+
+.self-name {
+  color: #555;
+  display: none;
+}
+
+.annotation-list {
+  list-style: none;
+  padding: 0;
+  display: inline;
+}
+
+.comma-separated {
+  list-style: none;
+  padding: 0;
+  display: inline;
+}
+
+.comma-separated li {
+  display: inline;
+}
+
+.comma-separated li:after {
+  content: ", ";
+}
+
+.comma-separated li:last-child:after {
+  content: "";
+}
+
+.end-with-period li:last-child:after {
+  content: ".";
+}
+
+.container > section:first-child {
+  border: 0;
+}
+
+.constructor-modifier {
+  font-style: italic;
+}
+
+section.multi-line-signature div.parameters {
+  margin-left: 24px;
+}
+
+/* subnav styles */
+
+ul.subnav {
+  overflow: auto;
+  white-space: nowrap;
+  padding-left: 0;
+  min-height: 25px;
+}
+
+ul.subnav::-webkit-scrollbar {
+  display: none;
+}
+
+ul.subnav li {
+  display: inline-block;
+  text-transform: uppercase;
+}
+
+ul.subnav li a {
+  color: #111;
+}
+
+ul.subnav li {
+  margin-right: 24px;
+}
+
+ul.subnav li:last-of-type {
+  margin-right: 0;
+}
+
+ at media(max-width: 768px) {
+  ul.subnav li {
+    margin-right: 16px;
+  }
+}
+
+/* sidebar styles */
+
+.sidebar ol {
+  list-style: none;
+  line-height: 22px;
+  margin-top: 0;
+  margin-bottom: 0;
+  padding: 0 0 15px 0;
+}
+
+.sidebar h5 a,
+.sidebar h5 a:hover {
+  color: #727272;
+}
+
+.sidebar h5,
+.sidebar ol li {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  padding: 3px 0;
+}
+
+.sidebar h5 {
+  color: #727272;
+  font-size: 18px;
+  margin: 0 0 25px 0;
+  padding-top: 0;
+}
+
+.sidebar ol li.section-title {
+  font-size: 18px;
+  font-weight: normal;
+  text-transform: uppercase;
+  padding-top: 25px;
+}
+
+.sidebar ol li.section-subtitle a {
+  color: inherit;
+}
+
+.sidebar ol li.section-subtitle {
+  font-weight: 400;
+  text-transform: uppercase;
+}
+
+.sidebar ol li.section-subitem {
+  margin-left: 12px;
+}
+
+.sidebar ol li:first-child {
+  padding-top: 0;
+  margin-top: 0;
+}
+
+button {
+  padding: 0;
+}
+
+#sidenav-left-toggle {
+  display: none;
+  vertical-align: text-bottom;
+  padding: 0;
+}
+
+/* left-nav disappears, and can transition in from the left */
+ at media screen and (max-width:768px) {
+  #sidenav-left-toggle {
+    display: inline;
+    background: no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path fill='%23111' d='M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z'/></svg>");
+    background-position: center;
+    width: 24px;
+    height: 24px;
+    border: none;
+    margin-right: 24px;
+  }
+
+  #overlay-under-drawer.active {
+    opacity: 0.4;
+    height: 100%;
+    z-index: 1999;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: black;
+    display: block;
+  }
+
+  .sidebar-offcanvas-left {
+    left: -100%;
+    position: fixed;
+    -webkit-transition:all .25s ease-out;
+    -o-transition:all .25s ease-out;
+    transition:all .25s ease-out;
+    z-index: 2000;
+    top: 0;
+    width: 280px; /* works all the way down to an iphone 4 */
+    height: 90%;
+    background-color: white;
+    overflow-y: scroll; /* TODO: how to hide scroll bars? */
+    padding: 10px;
+    margin: 10px 10px;
+    box-shadow: 5px 5px 5px 5px #444444;
+    visibility: hidden; /* shown by Javascript after scroll position restore */
+  }
+
+  ol#sidebar-nav {
+    font-size: 18px;
+    white-space: pre-line;
+  }
+
+  .sidebar-offcanvas-left.active {
+    left: 0; /* this animates our drawer into the page */
+  }
+
+  .self-name {
+    display: inline-block;
+  }
+}
+
+.sidebar-offcanvas-left h5 {
+  margin-bottom: 10px;
+}
+
+.sidebar-offcanvas-left h5:last-of-type {
+  border: 0;
+  margin-bottom: 25px;
+}
+
+/* the right nav disappears out of view when the window shrinks */
+ at media screen and (max-width: 992px) {
+  .sidebar-offcanvas-right {
+     display: none;
+   }
+}
+
+#overlay-under-drawer {
+  display: none;
+}
+
+/* find-as-you-type search box */
+
+/* override bootstrap defaults */
+.form-control {
+  border-radius: 0;
+  border: 0;
+}
+
+ at media screen and (max-width: 768px) {
+  form.search {
+    display: none;
+  }
+}
+
+.typeahead,
+.tt-query,
+.tt-hint {
+  width: 200px;
+  height: 20px;
+  padding: 2px 7px 1px 7px;
+  line-height: 20px;
+  outline: none;
+}
+
+.typeahead {
+  background-color: #fff;
+  border-radius: 2px;
+}
+
+.tt-query {
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.tt-hint {
+  color: #999
+}
+
+.navbar-right .tt-menu {
+  right:0;
+  left: inherit !important;
+  width: 422px;
+  max-height: 250px;
+  overflow-y: scroll;
+}
+
+.tt-menu {
+  font-size: 14px;
+  margin: 0;
+  padding: 8px 0;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+          box-shadow: 0 5px 10px rgba(0,0,0,.2);
+}
+
+.tt-suggestion {
+  padding: 3px 20px;
+  color: #212121;
+}
+
+.tt-suggestion:hover {
+  cursor: pointer;
+  color: #fff;
+  background-color: #0097cf;
+}
+
+.tt-suggestion:hover .search-from-lib {
+  color: #ddd;
+}
+
+.tt-suggestion.tt-cursor {
+  color: #fff;
+  background-color: #0097cf;
+}
+
+.tt-suggestion.tt-cursor .search-from-lib {
+  color: #ddd;
+}
+
+.tt-suggestion p {
+  margin: 0;
+}
+
+.search-from-lib {
+  font-style: italic;
+  color: gray;
+}
+
+#search-box {
+  background-color: #ffffff;
+}
+
+.search-body {
+  border: 1px solid #7f7f7f;
+  max-width: 400px;
+  box-shadow: 3px 3px 5px rgba(0,0,0,0.1);
+}
+
+section#setter {
+  border-top: 1px solid #ddd;
+  padding-top: 36px;
+}
+
+li.inherited a {
+  opacity: 0.65;
+  font-style: italic;
+}
+
+#instance-methods dt.inherited .name,
+#instance-properties dt.inherited .name,
+#operators dt.inherited .name {
+  font-weight: 300;
+  font-style: italic;
+}
+
+#instance-methods dt.inherited .signature,
+#instance-properties dt.inherited .signature,
+#operators dt.inherited .signature {
+  font-weight: 300;
+}
+
+ at media print {
+  .subnav, .sidebar {
+    display:none;
+  }
+
+  a[href]:after {
+   content:"" !important;
+  }
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.cpp b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.cpp
new file mode 100644
index 0000000000000..df1778c3b9d55
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.cpp
@@ -0,0 +1,21 @@
+#include "Calculator.h"
+#include <stdexcept>
+
+int Calculator::add(int a, int b) {
+    return a + b;
+}
+
+int Calculator::subtract(int a, int b) {
+    return a - b;
+}
+
+int Calculator::multiply(int a, int b) {
+    return a * b;
+}
+
+double Calculator::divide(int a, int b) {
+    if (b == 0) {
+        throw std::invalid_argument("Division by zero");
+    }
+    return static_cast<double>(a) / b;
+}
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.h b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.h
new file mode 100644
index 0000000000000..6811834bc0159
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Calculator.h
@@ -0,0 +1,46 @@
+#pragma once
+
+/**
+ * @brief A simple calculator class.
+ *
+ * Provides basic arithmetic operations.
+ */
+class Calculator {
+public:
+    /**
+     * @brief Adds two integers.
+     *
+     * @param a First integer.
+     * @param b Second integer.
+     * @return int The sum of a and b.
+     */
+    int add(int a, int b);
+
+    /**
+     * @brief Subtracts the second integer from the first.
+     *
+     * @param a First integer.
+     * @param b Second integer.
+     * @return int The result of a - b.
+     */
+    int subtract(int a, int b);
+
+    /**
+     * @brief Multiplies two integers.
+     *
+     * @param a First integer.
+     * @param b Second integer.
+     * @return int The product of a and b.
+     */
+    int multiply(int a, int b);
+
+    /**
+     * @brief Divides the first integer by the second.
+     *
+     * @param a First integer.
+     * @param b Second integer.
+     * @return double The result of a / b.
+     * @throw std::invalid_argument if b is zero.
+     */
+    double divide(int a, int b);
+};
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.cpp b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.cpp
new file mode 100644
index 0000000000000..823384a4d97e8
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.cpp
@@ -0,0 +1,11 @@
+#include "Circle.h"
+
+Circle::Circle(double radius) : radius_(radius) {}
+
+double Circle::area() const {
+    return 3.141 * radius_ * radius_;
+}
+
+double Circle::perimeter() const {
+    return 3.141 * radius_;
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.h b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.h
new file mode 100644
index 0000000000000..7bee3ffa92539
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Circle.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "Shape.h"
+
+/**
+ * @brief Circle class derived from Shape.
+ *
+ * Represents a circle with a given radius.
+ */
+class Circle : public Shape {
+public:
+    /**
+     * @brief Constructs a new Circle object.
+     *
+     * @param radius Radius of the circle.
+     */
+    Circle(double radius);
+
+    /**
+     * @brief Calculates the area of the circle.
+     *
+     * @return double The area of the circle.
+     */
+    double area() const override;
+
+    /**
+     * @brief Calculates the perimeter of the circle.
+     *
+     * @return double The perimeter of the circle.
+     */
+    double perimeter() const override;
+
+private:
+    double radius_; ///< Radius of the circle.
+};
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.cpp b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.cpp
new file mode 100644
index 0000000000000..7ffc769157ebc
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.cpp
@@ -0,0 +1,12 @@
+#include "Rectangle.h"
+
+Rectangle::Rectangle(double width, double height)
+        : width_(width), height_(height) {}
+
+double Rectangle::area() const {
+    return width_ * height_;
+}
+
+double Rectangle::perimeter() const {
+    return 2 * (width_ + height_);
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.h b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.h
new file mode 100644
index 0000000000000..8c6223a4f6180
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Rectangle.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "Shape.h"
+
+/**
+ * @brief Rectangle class derived from Shape.
+ *
+ * Represents a rectangle with a given width and height.
+ */
+class Rectangle : public Shape {
+public:
+    /**
+     * @brief Constructs a new Rectangle object.
+     *
+     * @param width Width of the rectangle.
+     * @param height Height of the rectangle.
+     */
+    Rectangle(double width, double height);
+
+    /**
+     * @brief Calculates the area of the rectangle.
+     *
+     * @return double The area of the rectangle.
+     */
+    double area() const override;
+
+    /**
+     * @brief Calculates the perimeter of the rectangle.
+     *
+     * @return double The perimeter of the rectangle.
+     */
+    double perimeter() const override;
+
+private:
+    double width_; ///< Width of the rectangle.
+    double height_; ///< Height of the rectangle.
+};
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Shape.h b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Shape.h
new file mode 100644
index 0000000000000..e5c5d4c9e4412
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/Shape.h
@@ -0,0 +1,30 @@
+#pragma once
+
+/**
+ * @brief Abstract base class for shapes.
+ *
+ * Provides a common interface for different types of shapes.
+ */
+class Shape {
+public:
+    /**
+     * @brief Virtual destructor.
+     */
+    virtual ~Shape() {}
+
+    /**
+     * @brief Calculates the area of the shape.
+     *
+     * @return double The area of the shape.
+     */
+    virtual double area() const = 0;
+
+    /**
+     * @brief Calculates the perimeter of the shape.
+     *
+     * @return double The perimeter of the shape.
+     */
+    virtual double perimeter() const = 0;
+};
+
+
diff --git a/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/database_template.json b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/database_template.json
new file mode 100644
index 0000000000000..ae1bc6f128677
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/clang-doc-project1/database_template.json
@@ -0,0 +1,17 @@
+[
+  {
+    "directory": "$test_dir/build",
+    "command": "clang++ -o Calculator.o -I../include $test_dir/src/Calculator.cpp",
+    "file": "$test_dir/src/Calculator.cpp"
+  },
+  {
+    "directory": "$test_dir/build",
+    "command": "clang++ -o Circle.o -I../include $test_dir/src/Circle.cpp",
+    "file": "$test_dir/src/Circle.cpp"
+  },
+  {
+    "directory": "$test_dir/build",
+    "command": "clang++ -o Rectangle.o -I../include $test_dir/src/Rectangle.cpp",
+    "file": "$test_dir/src/Rectangle.cpp"
+  }
+]
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-doc/Inputs/index.js b/clang-tools-extra/test/clang-doc/Inputs/index.js
new file mode 100644
index 0000000000000..a5ac90f2e06e7
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/Inputs/index.js
@@ -0,0 +1,87 @@
+// Append using posix-style a file name or directory to Base
+function append(Base, New) {
+  if (!New)
+    return Base;
+  if (Base)
+    Base += "/";
+  Base += New;
+  return Base;
+}
+
+// Get relative path to access FilePath from CurrentDirectory
+function computeRelativePath(FilePath, CurrentDirectory) {
+  var Path = FilePath;
+  while (Path) {
+    if (CurrentDirectory == Path)
+      return FilePath.substring(Path.length + 1);
+    Path = Path.substring(0, Path.lastIndexOf("/"));
+  }
+
+  var Dir = CurrentDirectory;
+  var Result = "";
+  while (Dir) {
+    if (Dir == FilePath)
+      break;
+    Dir = Dir.substring(0, Dir.lastIndexOf("/"));
+    Result = append(Result, "..")
+  }
+  Result = append(Result, FilePath.substring(Dir.length))
+  return Result;
+}
+
+function genLink(Ref, CurrentDirectory) {
+  var Path = computeRelativePath(Ref.Path, CurrentDirectory);
+  if (Ref.RefType == "namespace")
+    Path = append(Path, "index.html");
+  else
+    Path = append(Path, Ref.Name + ".html")
+
+    ANode = document.createElement("a");
+  ANode.setAttribute("href", Path);
+  var TextNode = document.createTextNode(Ref.Name);
+  ANode.appendChild(TextNode);
+  return ANode;
+}
+
+function genHTMLOfIndex(Index, CurrentDirectory, IsOutermostList) {
+  // Out will store the HTML elements that Index requires to be generated
+  var Out = [];
+  if (Index.Name) {
+    var SpanNode = document.createElement("span");
+    var TextNode = document.createTextNode(Index.Name);
+    SpanNode.appendChild(genLink(Index, CurrentDirectory));
+    Out.push(SpanNode);
+  }
+  if (Index.Children.length == 0)
+    return Out;
+  // Only the outermost list should use ol, the others should use ul
+  var ListNodeName = IsOutermostList ? "ol" : "ul";
+  var ListNode = document.createElement(ListNodeName);
+  for (Child of Index.Children) {
+    var LiNode = document.createElement("li");
+    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory, false);
+    for (Node of ChildNodes)
+      LiNode.appendChild(Node);
+    ListNode.appendChild(LiNode);
+  }
+  Out.push(ListNode);
+  return Out;
+}
+
+function createIndex(Index) {
+  // Get the DOM element where the index will be created
+  var IndexDiv = document.getElementById("sidebar-left");
+  // Get the relative path of this file
+  CurrentDirectory = IndexDiv.getAttribute("path");
+  var IndexNodes = genHTMLOfIndex(Index, CurrentDirectory, true);
+  for (Node of IndexNodes)
+    IndexDiv.appendChild(Node);
+}
+
+// Runs after DOM loads
+document.addEventListener("DOMContentLoaded", function() {
+  // JsonIndex is a variable from another file that contains the index
+  // in JSON format
+  var Index = JSON.parse(JsonIndex);
+  createIndex(Index);
+});
diff --git a/clang-tools-extra/test/clang-doc/clang-doc-project1.cpp b/clang-tools-extra/test/clang-doc/clang-doc-project1.cpp
new file mode 100644
index 0000000000000..59bf781385b40
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/clang-doc-project1.cpp
@@ -0,0 +1,361 @@
+// RUN: rm -rf %t && mkdir -p %t/build %t/include %t/src %t/docs
+// RUN: sed 's|$test_dir|%/t|g' %S/Inputs/clang-doc-project1/database_template.json > %t/build/compile_commands.json
+// RUN: cp %S/Inputs/clang-doc-project1/*.h  %t/include
+// RUN: cp %S/Inputs/clang-doc-project1/*.cpp %t/src
+// RUN: cd %t
+// RUN: clang-doc --format=html --executor=all-TUs --asset=%S/Inputs ./build/compile_commands.json
+// RUN: FileCheck %s -input-file=%t/docs/index_json.js -check-prefix=CHECK-JSON-INDEX
+// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Shape.html -check-prefix=CHECK-HTML-SHAPE
+// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=CHECK-HTML-CALC
+// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Rectangle.html -check-prefix=CHECK-HTML-RECTANGLE
+// RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Circle.html -check-prefix=CHECK-HTML-CIRCLE
+
+// CHECK-JSON-INDEX: var JsonIndex = `
+// CHECK-JSON-INDEX-NEXT: {
+// CHECK-JSON-INDEX-NEXT:   "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:   "Name": "",
+// CHECK-JSON-INDEX-NEXT:   "RefType": "default",
+// CHECK-JSON-INDEX-NEXT:   "Path": "",
+// CHECK-JSON-INDEX-NEXT:   "Children": [
+// CHECK-JSON-INDEX-NEXT:     {
+// CHECK-JSON-INDEX-NEXT:       "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:       "Name": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:       "RefType": "namespace",
+// CHECK-JSON-INDEX-NEXT:       "Path": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:       "Children": [
+// CHECK-JSON-INDEX-NEXT:         {
+// CHECK-JSON-INDEX-NEXT:           "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:           "Name": "Calculator",
+// CHECK-JSON-INDEX-NEXT:           "RefType": "record",
+// CHECK-JSON-INDEX-NEXT:           "Path": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:           "Children": []
+// CHECK-JSON-INDEX-NEXT:         },
+// CHECK-JSON-INDEX-NEXT:         {
+// CHECK-JSON-INDEX-NEXT:           "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:           "Name": "Circle",
+// CHECK-JSON-INDEX-NEXT:           "RefType": "record",
+// CHECK-JSON-INDEX-NEXT:           "Path": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:           "Children": []
+// CHECK-JSON-INDEX-NEXT:         },
+// CHECK-JSON-INDEX-NEXT:         {
+// CHECK-JSON-INDEX-NEXT:           "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:           "Name": "Rectangle",
+// CHECK-JSON-INDEX-NEXT:           "RefType": "record",
+// CHECK-JSON-INDEX-NEXT:           "Path": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:           "Children": []
+// CHECK-JSON-INDEX-NEXT:         },
+// CHECK-JSON-INDEX-NEXT:         {
+// CHECK-JSON-INDEX-NEXT:           "USR": "{{([0-9A-F]{40})}}",
+// CHECK-JSON-INDEX-NEXT:           "Name": "Shape",
+// CHECK-JSON-INDEX-NEXT:           "RefType": "record",
+// CHECK-JSON-INDEX-NEXT:           "Path": "GlobalNamespace",
+// CHECK-JSON-INDEX-NEXT:           "Children": []
+// CHECK-JSON-INDEX-NEXT:         }
+// CHECK-JSON-INDEX-NEXT:       ]
+// CHECK-JSON-INDEX-NEXT:     }
+// CHECK-JSON-INDEX-NEXT:   ]
+// CHECK-JSON-INDEX-NEXT: }`;
+
+// CHECK-HTML-SHAPE: <!DOCTYPE html>
+// CHECK-HTML-SHAPE-NEXT: <meta charset="utf-8"/>
+// CHECK-HTML-SHAPE-NEXT: <title>class Shape</title>
+// CHECK-HTML-SHAPE-NEXT: <link rel="stylesheet" href="../clang-doc-default-stylesheet.css"/>
+// CHECK-HTML-SHAPE-NEXT: <script src="../index.js"></script>
+// CHECK-HTML-SHAPE-NEXT: <script src="../index_json.js"></script>
+// CHECK-HTML-SHAPE-NEXT: <header id="project-title"></header>
+// CHECK-HTML-SHAPE-NEXT: <main>
+// CHECK-HTML-SHAPE-NEXT:   <div id="sidebar-left" path="GlobalNamespace" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+// CHECK-HTML-SHAPE-NEXT:   <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+// CHECK-HTML-SHAPE-NEXT:     <h1>class Shape</h1>
+// CHECK-HTML-SHAPE-NEXT:     <p>Defined at line 8 of file {{.*}}Shape.h</p>
+// CHECK-HTML-SHAPE-NEXT:     <div>
+// CHECK-HTML-SHAPE-NEXT:       <div>
+// CHECK-HTML-SHAPE-NEXT:         <p> Provides a common interface for different types of shapes.</p>
+// CHECK-HTML-SHAPE-NEXT:       </div>
+// CHECK-HTML-SHAPE-NEXT:     </div>
+// CHECK-HTML-SHAPE-NEXT:     <h2 id="Functions">Functions</h2>
+// CHECK-HTML-SHAPE-NEXT:     <div>
+// CHECK-HTML-SHAPE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">~Shape</h3>
+// CHECK-HTML-SHAPE-NEXT:       <p>public void ~Shape()</p>
+// CHECK-HTML-SHAPE-NEXT:       <p>Defined at line 13 of file {{.*}}Shape.h</p>
+// CHECK-HTML-SHAPE-NEXT:       <div>
+// CHECK-HTML-SHAPE-NEXT:         <div></div>
+// CHECK-HTML-SHAPE-NEXT:       </div>
+// CHECK-HTML-SHAPE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">area</h3>
+// CHECK-HTML-SHAPE-NEXT:       <p>public double area()</p>
+// CHECK-HTML-SHAPE-NEXT:       <div>
+// CHECK-HTML-SHAPE-NEXT:         <div></div>
+// CHECK-HTML-SHAPE-NEXT:       </div>
+// CHECK-HTML-SHAPE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
+// CHECK-HTML-SHAPE-NEXT:       <p>public double perimeter()</p>
+// CHECK-HTML-SHAPE-NEXT:       <div>
+// CHECK-HTML-SHAPE-NEXT:         <div></div>
+// CHECK-HTML-SHAPE-NEXT:       </div>
+// CHECK-HTML-SHAPE-NEXT:     </div>
+// CHECK-HTML-SHAPE-NEXT:   </div>
+// CHECK-HTML-SHAPE-NEXT:   <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+// CHECK-HTML-SHAPE-NEXT:     <ol>
+// CHECK-HTML-SHAPE-NEXT:       <li>
+// CHECK-HTML-SHAPE-NEXT:         <span>
+// CHECK-HTML-SHAPE-NEXT:           <a href="#Functions">Functions</a>
+// CHECK-HTML-SHAPE-NEXT:         </span>
+// CHECK-HTML-SHAPE-NEXT:         <ul>
+// CHECK-HTML-SHAPE-NEXT:           <li>
+// CHECK-HTML-SHAPE-NEXT:             <span>
+// CHECK-HTML-SHAPE-NEXT:               <a href="#{{([0-9A-F]{40})}}">~Shape</a>
+// CHECK-HTML-SHAPE-NEXT:             </span>
+// CHECK-HTML-SHAPE-NEXT:           </li>
+// CHECK-HTML-SHAPE-NEXT:           <li>
+// CHECK-HTML-SHAPE-NEXT:             <span>
+// CHECK-HTML-SHAPE-NEXT:               <a href="#{{([0-9A-F]{40})}}">area</a>
+// CHECK-HTML-SHAPE-NEXT:             </span>
+// CHECK-HTML-SHAPE-NEXT:           </li>
+// CHECK-HTML-SHAPE-NEXT:           <li>
+// CHECK-HTML-SHAPE-NEXT:             <span>
+// CHECK-HTML-SHAPE-NEXT:               <a href="#{{([0-9A-F]{40})}}">perimeter</a>
+// CHECK-HTML-SHAPE-NEXT:             </span>
+// CHECK-HTML-SHAPE-NEXT:           </li>
+// CHECK-HTML-SHAPE-NEXT:         </ul>
+// CHECK-HTML-SHAPE-NEXT:       </li>
+// CHECK-HTML-SHAPE-NEXT:     </ol>
+// CHECK-HTML-SHAPE-NEXT:   </div>
+// CHECK-HTML-SHAPE-NEXT: </main>
+
+// CHECK-HTML-CALC: <!DOCTYPE html>
+// CHECK-HTML-CALC-NEXT: <meta charset="utf-8"/>
+// CHECK-HTML-CALC-NEXT: <title>class Calculator</title>
+// CHECK-HTML-CALC-NEXT: <link rel="stylesheet" href="{{.*}}clang-doc-default-stylesheet.css"/>
+// CHECK-HTML-CALC-NEXT: <script src="{{.*}}index.js"></script>
+// CHECK-HTML-CALC-NEXT: <script src="{{.*}}index_json.js"></script>
+// CHECK-HTML-CALC-NEXT: <header id="project-title"></header>
+// CHECK-HTML-CALC-NEXT: <main>
+// CHECK-HTML-CALC-NEXT:   <div id="sidebar-left" path="GlobalNamespace" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+// CHECK-HTML-CALC-NEXT:   <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+// CHECK-HTML-CALC-NEXT:     <h1>class Calculator</h1>
+// CHECK-HTML-CALC-NEXT:     <p>Defined at line 8 of file {{.*}}Calculator.h</p>
+// CHECK-HTML-CALC-NEXT:     <div>
+// CHECK-HTML-CALC-NEXT:       <div>
+// CHECK-HTML-CALC-NEXT:         <p> Provides basic arithmetic operations.</p>
+// CHECK-HTML-CALC-NEXT:       </div>
+// CHECK-HTML-CALC-NEXT:     </div>
+// CHECK-HTML-CALC-NEXT:     <h2 id="Functions">Functions</h2>
+// CHECK-HTML-CALC-NEXT:     <div>
+// CHECK-HTML-CALC-NEXT:       <h3 id="{{([0-9A-F]{40})}}">add</h3>
+// CHECK-HTML-CALC-NEXT:       <p>public int add(int a, int b)</p>
+// CHECK-HTML-CALC-NEXT:       <p>Defined at line 4 of file {{.*}}Calculator.cpp</p>
+// CHECK-HTML-CALC-NEXT:       <div>
+// CHECK-HTML-CALC-NEXT:         <div></div>
+// CHECK-HTML-CALC-NEXT:       </div>
+// CHECK-HTML-CALC-NEXT:       <h3 id="{{([0-9A-F]{40})}}">subtract</h3>
+// CHECK-HTML-CALC-NEXT:       <p>public int subtract(int a, int b)</p>
+// CHECK-HTML-CALC-NEXT:       <p>Defined at line 8 of file {{.*}}Calculator.cpp</p>
+// CHECK-HTML-CALC-NEXT:       <div>
+// CHECK-HTML-CALC-NEXT:         <div></div>
+// CHECK-HTML-CALC-NEXT:       </div>
+// CHECK-HTML-CALC-NEXT:       <h3 id="{{([0-9A-F]{40})}}">multiply</h3>
+// CHECK-HTML-CALC-NEXT:       <p>public int multiply(int a, int b)</p>
+// CHECK-HTML-CALC-NEXT:       <p>Defined at line 12 of file {{.*}}Calculator.cpp</p>
+// CHECK-HTML-CALC-NEXT:       <div>
+// CHECK-HTML-CALC-NEXT:         <div></div>
+// CHECK-HTML-CALC-NEXT:       </div>
+// CHECK-HTML-CALC-NEXT:       <h3 id="{{([0-9A-F]{40})}}">divide</h3>
+// CHECK-HTML-CALC-NEXT:       <p>public double divide(int a, int b)</p>
+// CHECK-HTML-CALC-NEXT:       <p>Defined at line 16 of file {{.*}}Calculator.cpp</p>
+// CHECK-HTML-CALC-NEXT:       <div>
+// CHECK-HTML-CALC-NEXT:         <div></div>
+// CHECK-HTML-CALC-NEXT:       </div>
+// CHECK-HTML-CALC-NEXT:     </div>
+// CHECK-HTML-CALC-NEXT:   </div>
+// CHECK-HTML-CALC-NEXT:   <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+// CHECK-HTML-CALC-NEXT:     <ol>
+// CHECK-HTML-CALC-NEXT:       <li>
+// CHECK-HTML-CALC-NEXT:         <span>
+// CHECK-HTML-CALC-NEXT:           <a href="#Functions">Functions</a>
+// CHECK-HTML-CALC-NEXT:         </span>
+// CHECK-HTML-CALC-NEXT:         <ul>
+// CHECK-HTML-CALC-NEXT:           <li>
+// CHECK-HTML-CALC-NEXT:             <span>
+// CHECK-HTML-CALC-NEXT:               <a href="#{{([0-9A-F]{40})}}">add</a>
+// CHECK-HTML-CALC-NEXT:             </span>
+// CHECK-HTML-CALC-NEXT:           </li>
+// CHECK-HTML-CALC-NEXT:           <li>
+// CHECK-HTML-CALC-NEXT:             <span>
+// CHECK-HTML-CALC-NEXT:               <a href="#{{([0-9A-F]{40})}}">subtract</a>
+// CHECK-HTML-CALC-NEXT:             </span>
+// CHECK-HTML-CALC-NEXT:           </li>
+// CHECK-HTML-CALC-NEXT:           <li>
+// CHECK-HTML-CALC-NEXT:             <span>
+// CHECK-HTML-CALC-NEXT:               <a href="#{{([0-9A-F]{40})}}">multiply</a>
+// CHECK-HTML-CALC-NEXT:             </span>
+// CHECK-HTML-CALC-NEXT:           </li>
+// CHECK-HTML-CALC-NEXT:           <li>
+// CHECK-HTML-CALC-NEXT:             <span>
+// CHECK-HTML-CALC-NEXT:               <a href="#{{([0-9A-F]{40})}}">divide</a>
+// CHECK-HTML-CALC-NEXT:             </span>
+// CHECK-HTML-CALC-NEXT:           </li>
+// CHECK-HTML-CALC-NEXT:         </ul>
+// CHECK-HTML-CALC-NEXT:       </li>
+// CHECK-HTML-CALC-NEXT:     </ol>
+// CHECK-HTML-CALC-NEXT:   </div>
+// CHECK-HTML-CALC-NEXT: </main>
+
+// CHECK-HTML-RECTANGLE: <!DOCTYPE html>
+// CHECK-HTML-RECTANGLE-NEXT: <meta charset="utf-8"/>
+// CHECK-HTML-RECTANGLE-NEXT: <title>class Rectangle</title>
+// CHECK-HTML-RECTANGLE-NEXT: <link rel="stylesheet" href="{{.*}}clang-doc-default-stylesheet.css"/>
+// CHECK-HTML-RECTANGLE-NEXT: <script src="{{.*}}index.js"></script>
+// CHECK-HTML-RECTANGLE-NEXT: <script src="{{.*}}index_json.js"></script>
+// CHECK-HTML-RECTANGLE-NEXT: <header id="project-title"></header>
+// CHECK-HTML-RECTANGLE-NEXT: <main>
+// CHECK-HTML-RECTANGLE-NEXT:   <div id="sidebar-left" path="GlobalNamespace" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+// CHECK-HTML-RECTANGLE-NEXT:   <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+// CHECK-HTML-RECTANGLE-NEXT:     <h1>class Rectangle</h1>
+// CHECK-HTML-RECTANGLE-NEXT:     <p>Defined at line 10 of file {{.*}}Rectangle.h</p>
+// CHECK-HTML-RECTANGLE-NEXT:     <div>
+// CHECK-HTML-RECTANGLE-NEXT:       <div>
+// CHECK-HTML-RECTANGLE-NEXT:         <p> Represents a rectangle with a given width and height.</p>
+// CHECK-HTML-RECTANGLE-NEXT:       </div>
+// CHECK-HTML-RECTANGLE-NEXT:     </div>
+// CHECK-HTML-RECTANGLE-NEXT:     <p>
+// CHECK-HTML-RECTANGLE-NEXT:       Inherits from
+// CHECK-HTML-RECTANGLE-NEXT:       <a href="Shape.html">Shape</a>
+// CHECK-HTML-RECTANGLE-NEXT:     </p>
+// CHECK-HTML-RECTANGLE-NEXT:     <h2 id="Members">Members</h2>
+// CHECK-HTML-RECTANGLE-NEXT:     <ul>
+// CHECK-HTML-RECTANGLE-NEXT:       <li>private double width_</li>
+// CHECK-HTML-RECTANGLE-NEXT:       <li>private double height_</li>
+// CHECK-HTML-RECTANGLE-NEXT:     </ul>
+// CHECK-HTML-RECTANGLE-NEXT:     <h2 id="Functions">Functions</h2>
+// CHECK-HTML-RECTANGLE-NEXT:     <div>
+// CHECK-HTML-RECTANGLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">Rectangle</h3>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>public void Rectangle(double width, double height)</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>Defined at line 3 of file {{.*}}Rectangle.cpp</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <div>
+// CHECK-HTML-RECTANGLE-NEXT:         <div></div>
+// CHECK-HTML-RECTANGLE-NEXT:       </div>
+// CHECK-HTML-RECTANGLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">area</h3>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>public double area()</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>Defined at line 6 of file {{.*}}Rectangle.cpp</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <div>
+// CHECK-HTML-RECTANGLE-NEXT:         <div></div>
+// CHECK-HTML-RECTANGLE-NEXT:       </div>
+// CHECK-HTML-RECTANGLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>public double perimeter()</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <p>Defined at line 10 of file {{.*}}Rectangle.cpp</p>
+// CHECK-HTML-RECTANGLE-NEXT:       <div>
+// CHECK-HTML-RECTANGLE-NEXT:         <div></div>
+// CHECK-HTML-RECTANGLE-NEXT:       </div>
+// CHECK-HTML-RECTANGLE-NEXT:     </div>
+// CHECK-HTML-RECTANGLE-NEXT:   </div>
+// CHECK-HTML-RECTANGLE-NEXT:   <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+// CHECK-HTML-RECTANGLE-NEXT:     <ol>
+// CHECK-HTML-RECTANGLE-NEXT:       <li>
+// CHECK-HTML-RECTANGLE-NEXT:         <span>
+// CHECK-HTML-RECTANGLE-NEXT:           <a href="#Members">Members</a>
+// CHECK-HTML-RECTANGLE-NEXT:         </span>
+// CHECK-HTML-RECTANGLE-NEXT:       </li>
+// CHECK-HTML-RECTANGLE-NEXT:       <li>
+// CHECK-HTML-RECTANGLE-NEXT:         <span>
+// CHECK-HTML-RECTANGLE-NEXT:           <a href="#Functions">Functions</a>
+// CHECK-HTML-RECTANGLE-NEXT:         </span>
+// CHECK-HTML-RECTANGLE-NEXT:         <ul>
+// CHECK-HTML-RECTANGLE-NEXT:           <li>
+// CHECK-HTML-RECTANGLE-NEXT:             <span>
+// CHECK-HTML-RECTANGLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">Rectangle</a>
+// CHECK-HTML-RECTANGLE-NEXT:             </span>
+// CHECK-HTML-RECTANGLE-NEXT:           </li>
+// CHECK-HTML-RECTANGLE-NEXT:           <li>
+// CHECK-HTML-RECTANGLE-NEXT:             <span>
+// CHECK-HTML-RECTANGLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">area</a>
+// CHECK-HTML-RECTANGLE-NEXT:             </span>
+// CHECK-HTML-RECTANGLE-NEXT:           </li>
+// CHECK-HTML-RECTANGLE-NEXT:           <li>
+// CHECK-HTML-RECTANGLE-NEXT:             <span>
+// CHECK-HTML-RECTANGLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">perimeter</a>
+// CHECK-HTML-RECTANGLE-NEXT:             </span>
+// CHECK-HTML-RECTANGLE-NEXT:           </li>
+// CHECK-HTML-RECTANGLE-NEXT:         </ul>
+// CHECK-HTML-RECTANGLE-NEXT:       </li>
+// CHECK-HTML-RECTANGLE-NEXT:     </ol>
+// CHECK-HTML-RECTANGLE-NEXT:   </div>
+// CHECK-HTML-RECTANGLE-NEXT: </main>
+
+// CHECK-HTML-CIRCLE: <!DOCTYPE html>
+// CHECK-HTML-CIRCLE-NEXT: <meta charset="utf-8"/>
+// CHECK-HTML-CIRCLE-NEXT: <title>class Circle</title>
+// CHECK-HTML-CIRCLE-NEXT: <link rel="stylesheet" href="{{.*}}clang-doc-default-stylesheet.css"/>
+// CHECK-HTML-CIRCLE-NEXT: <script src="{{.*}}index.js"></script>
+// CHECK-HTML-CIRCLE-NEXT: <script src="{{.*}}index_json.js"></script>
+// CHECK-HTML-CIRCLE-NEXT: <header id="project-title"></header>
+// CHECK-HTML-CIRCLE-NEXT: <main>
+// CHECK-HTML-CIRCLE-NEXT:   <div id="sidebar-left" path="GlobalNamespace" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+// CHECK-HTML-CIRCLE-NEXT:   <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+// CHECK-HTML-CIRCLE-NEXT:     <h1>class Circle</h1>
+// CHECK-HTML-CIRCLE-NEXT:     <p>Defined at line 10 of file {{.*}}Circle.h</p>
+// CHECK-HTML-CIRCLE-NEXT:     <div>
+// CHECK-HTML-CIRCLE-NEXT:       <div>
+// CHECK-HTML-CIRCLE-NEXT:         <p> Represents a circle with a given radius.</p>
+// CHECK-HTML-CIRCLE-NEXT:       </div>
+// CHECK-HTML-CIRCLE-NEXT:     </div>
+// CHECK-HTML-CIRCLE-NEXT:     <p>
+// CHECK-HTML-CIRCLE-NEXT:       Inherits from
+// CHECK-HTML-CIRCLE-NEXT:       <a href="Shape.html">Shape</a>
+// CHECK-HTML-CIRCLE-NEXT:     </p>
+// CHECK-HTML-CIRCLE-NEXT:     <h2 id="Members">Members</h2>
+// CHECK-HTML-CIRCLE-NEXT:     <ul>
+// CHECK-HTML-CIRCLE-NEXT:       <li>private double radius_</li>
+// CHECK-HTML-CIRCLE-NEXT:     </ul>
+// CHECK-HTML-CIRCLE-NEXT:     <h2 id="Functions">Functions</h2>
+// CHECK-HTML-CIRCLE-NEXT:     <div>
+// CHECK-HTML-CIRCLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">Circle</h3>
+// CHECK-HTML-CIRCLE-NEXT:       <p>public void Circle(double radius)</p>
+// CHECK-HTML-CIRCLE-NEXT:       <p>Defined at line 3 of file {{.*}}Circle.cpp</p>
+// CHECK-HTML-CIRCLE-NEXT:       <div>
+// CHECK-HTML-CIRCLE-NEXT:         <div></div>
+// CHECK-HTML-CIRCLE-NEXT:       </div>
+// CHECK-HTML-CIRCLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">area</h3>
+// CHECK-HTML-CIRCLE-NEXT:       <p>public double area()</p>
+// CHECK-HTML-CIRCLE-NEXT:       <p>Defined at line 5 of file {{.*}}Circle.cpp</p>
+// CHECK-HTML-CIRCLE-NEXT:       <div>
+// CHECK-HTML-CIRCLE-NEXT:         <div></div>
+// CHECK-HTML-CIRCLE-NEXT:       </div>
+// CHECK-HTML-CIRCLE-NEXT:       <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
+// CHECK-HTML-CIRCLE-NEXT:       <p>public double perimeter()</p>
+// CHECK-HTML-CIRCLE-NEXT:       <p>Defined at line 9 of file {{.*}}Circle.cpp</p>
+// CHECK-HTML-CIRCLE-NEXT:       <div>
+// CHECK-HTML-CIRCLE-NEXT:         <div></div>
+// CHECK-HTML-CIRCLE-NEXT:       </div>
+// CHECK-HTML-CIRCLE-NEXT:     </div>
+// CHECK-HTML-CIRCLE-NEXT:   </div>
+// CHECK-HTML-CIRCLE-NEXT:   <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+// CHECK-HTML-CIRCLE-NEXT:     <ol>
+// CHECK-HTML-CIRCLE-NEXT:       <li>
+// CHECK-HTML-CIRCLE-NEXT:         <span>
+// CHECK-HTML-CIRCLE-NEXT:           <a href="#Members">Members</a>
+// CHECK-HTML-CIRCLE-NEXT:         </span>
+// CHECK-HTML-CIRCLE-NEXT:       </li>
+// CHECK-HTML-CIRCLE-NEXT:       <li>
+// CHECK-HTML-CIRCLE-NEXT:         <span>
+// CHECK-HTML-CIRCLE-NEXT:           <a href="#Functions">Functions</a>
+// CHECK-HTML-CIRCLE-NEXT:         </span>
+// CHECK-HTML-CIRCLE-NEXT:         <ul>
+// CHECK-HTML-CIRCLE-NEXT:           <li>
+// CHECK-HTML-CIRCLE-NEXT:             <span>
+// CHECK-HTML-CIRCLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">Circle</a>
+// CHECK-HTML-CIRCLE-NEXT:             </span>
+// CHECK-HTML-CIRCLE-NEXT:           </li>
+// CHECK-HTML-CIRCLE-NEXT:           <li>
+// CHECK-HTML-CIRCLE-NEXT:             <span>
+// CHECK-HTML-CIRCLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">area</a>
+// CHECK-HTML-CIRCLE-NEXT:             </span>
+// CHECK-HTML-CIRCLE-NEXT:           </li>
+// CHECK-HTML-CIRCLE-NEXT:           <li>
+// CHECK-HTML-CIRCLE-NEXT:             <span>
+// CHECK-HTML-CIRCLE-NEXT:               <a href="#{{([0-9A-F]{40})}}">perimeter</a>
+// CHECK-HTML-CIRCLE-NEXT:             </span>
+// CHECK-HTML-CIRCLE-NEXT:           </li>
+// CHECK-HTML-CIRCLE-NEXT:         </ul>
+// CHECK-HTML-CIRCLE-NEXT:       </li>
+// CHECK-HTML-CIRCLE-NEXT:     </ol>
+// CHECK-HTML-CIRCLE-NEXT:   </div>
+// CHECK-HTML-CIRCLE-NEXT: </main>
\ No newline at end of file



More information about the cfe-commits mailing list