chiark / gitweb /
documentation/doxygen: explicitly check for warning logs.
authorVladimír Vondruš <mosra@centrum.cz>
Sun, 9 Jan 2022 18:32:30 +0000 (19:32 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Sun, 9 Jan 2022 22:50:25 +0000 (23:50 +0100)
The output was quite a mess already, and that's just because I didn't
know about assertLogs() until now.

20 files changed:
documentation/doxygen.py
documentation/test_doxygen/compound_listing/Class_8h.html
documentation/test_doxygen/compound_listing/Directory/Sub/Class.h
documentation/test_doxygen/compound_listing/annotated.html
documentation/test_doxygen/compound_listing/structRoot_1_1Directory_1_1Sub_1_1Warning.html [new file with mode: 0644]
documentation/test_doxygen/contents_autobrief_heading/namespaceNamespace.html
documentation/test_doxygen/contents_autobrief_heading/namespaceNamespace_1814.html [new file with mode: 0644]
documentation/test_doxygen/contents_autobrief_hr/namespaceNamespace.html
documentation/test_doxygen/contents_autobrief_hr/namespaceNamespace_1814.html [new file with mode: 0644]
documentation/test_doxygen/contents_sections_headings/Doxyfile
documentation/test_doxygen/contents_sections_headings/File.h
documentation/test_doxygen/contents_sections_headings/File_8h.html
documentation/test_doxygen/contents_sections_headings/Warnings.h [new file with mode: 0644]
documentation/test_doxygen/contents_sections_headings/Warnings_8h.html [new file with mode: 0644]
documentation/test_doxygen/cpp_friends/File.h
documentation/test_doxygen/cpp_friends/structWarning.html [new file with mode: 0644]
documentation/test_doxygen/test_compound.py
documentation/test_doxygen/test_contents.py
documentation/test_doxygen/test_cpp.py
documentation/test_doxygen/test_doxyfile.py

index e1483d287fe7156151a84aa679f6dcf694a221f4..e29d4f363197aadddab68bad23bb6638960eb539 100755 (executable)
@@ -409,7 +409,7 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET.
             out.params.update(parsed.params)
         if parsed.return_value:
             if out.return_value:
-                logging.warning("{}: superfluous @return section found, ignoring: {} ".format(state.current, ''.join(i.itertext())))
+                logging.warning("{}: superfluous @return section found, ignoring: {}".format(state.current, ''.join(i.itertext()).rstrip()))
             else:
                 out.return_value = parsed.return_value
         if parsed.return_values:
@@ -812,7 +812,7 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET.
             # Return value is separated from the text flow
             if i.attrib['kind'] == 'return':
                 if out.return_value:
-                    logging.warning("{}: superfluous @return section found, ignoring: {} ".format(state.current, ''.join(i.itertext())))
+                    logging.warning("{}: superfluous @return section found, ignoring: {}".format(state.current, ''.join(i.itertext()).rstrip()))
                 else:
                     out.return_value = parse_desc(state, i)
 
@@ -2176,26 +2176,28 @@ def is_a_stupid_empty_markdown_page(compounddef: ET.Element):
     return compounddef.find('compoundname').text.startswith('md_') and compounddef.find('compoundname').text.endswith(compounddef.find('title').text) and not compounddef.find('briefdescription') and not compounddef.find('detaileddescription')
 
 def extract_metadata(state: State, xml):
-    basename = os.path.basename(xml)
+    # parse_desc() / parse_inline_desc() is called from here, be sure to set
+    # current filename so it's reflected in possible warnings
+    state.current = os.path.basename(xml)
 
     # These early returns should be kept consistent with parse_xml()
-    if basename == 'Doxyfile.xml':
-        logging.debug("Ignoring {}".format(basename))
+    if state.current == 'Doxyfile.xml':
+        logging.debug("Ignoring {}".format(state.current))
         return
 
-    logging.debug("Extracting metadata from {}".format(basename))
+    logging.debug("Extracting metadata from {}".format(state.current))
 
     try:
         tree = ET.parse(xml)
     except ET.ParseError as e:
-        logging.error("{}: XML parse error, skipping whole file: {}".format(basename, e))
+        logging.error("{}: XML parse error, skipping whole file: {}".format(state.current, e))
         return
 
     root = tree.getroot()
 
     # From index.xml we need just list of all example files in correct order,
     # nothing else
-    if basename == 'index.xml':
+    if state.current == 'index.xml':
         for i in root:
             if i.attrib['kind'] == 'example':
                 compound = Empty()
@@ -2207,16 +2209,16 @@ def extract_metadata(state: State, xml):
 
     # From other files we expect <doxygen><compounddef>
     if root.tag != 'doxygen':
-        logging.warning("{}: root element expected to be <doxygen> but is <{}>, skipping whole file".format(basename, root.tag))
+        logging.warning("{}: root element expected to be <doxygen> but is <{}>, skipping whole file".format(state.current, root.tag))
         return
     compounddef: ET.Element = root[0]
     if compounddef.tag != 'compounddef':
-        logging.warning("{}: first child element expected to be <compounddef> but is <{}>, skipping whole file".format(basename, compounddef.tag))
+        logging.warning("{}: first child element expected to be <compounddef> but is <{}>, skipping whole file".format(state.current, compounddef.tag))
         return
     assert len([i for i in root]) == 1
 
     if compounddef.attrib['kind'] not in ['namespace', 'group', 'class', 'struct', 'union', 'dir', 'file', 'page']:
-        logging.debug("No useful info in {}, skipping".format(basename))
+        logging.debug("No useful info in {}, skipping".format(state.current))
         return
 
     # In order to show also undocumented members, go through all empty
index 0d902bc5644ec09407ec4d4cf27b10ff80d416c6..2cd3964bed180c1f83ae46747106f0e25a69935c 100644 (file)
               union <a href="unionRoot_1_1Directory_1_1Sub_1_1Class_1_1Bar.html" class="m-doc">Root::Directory::Sub::Class::Bar</a>
             </dt>
             <dd>A protected subclass.</dd>
+            <dt>
+              struct <a href="structRoot_1_1Directory_1_1Sub_1_1Warning.html" class="m-doc">Root::Directory::Sub::Warning</a>
+            </dt>
+            <dd>A struct producing warnings.</dd>
           </dl>
         </section>
       </div>
index d5ca95cbb144d4ead8b495314cb76d7b0a17d684..2e0f44860f19eaf7b62398ab4b9cdcd33351fa0c 100644 (file)
@@ -89,17 +89,6 @@ class Class {
         /** @brief A protected variable */
         std::string logger;
 
-        /** @{ */ /* Group w/o a name */
-
-        /** @brief A member that gets ignored because the group has no name */
-        int member;
-
-        /* Since 1.8.17, the original short-hand group closing doesn't work
-           anymore. FFS. */
-        /**
-         * @}
-         */
-
         /** @{ @name Group full of non-public stuff which should be marked as such */
 
         /** @brief Protected flag in a group */
@@ -140,6 +129,20 @@ class Class {
         void foobar();
 };
 
+/** @brief A struct producing warnings */
+struct Warning {
+    /** @{ */ /* Group w/o a name */
+
+    /** @brief A member that gets ignored because the group has no name */
+    int member;
+
+    /* Since 1.8.17, the original short-hand group closing doesn't work
+        anymore. FFS. */
+    /**
+        * @}
+        */
+};
+
 /** @relatedalso Class
  * @brief An enum
  */
index b09eef7ff498d9c9dad427cc123c580be087916f..6927170da590cc82fde986a97b95ebda3813e198 100644 (file)
@@ -55,6 +55,7 @@
                           <li>class <a href="classRoot_1_1Directory_1_1Sub_1_1Class_1_1Private.html" class="m-doc">Private</a> <span class="m-doc">This shouldn&#x27;t appear in the docs.</span></li>
                         </ul>
                       </li>
+                      <li>struct <a href="structRoot_1_1Directory_1_1Sub_1_1Warning.html" class="m-doc">Warning</a> <span class="m-doc">A struct producing warnings.</span></li>
                     </ul>
                   </li>
                   <li>class <a href="classRoot_1_1Directory_1_1Class.html" class="m-doc">Class</a> <span class="m-doc">A class.</span></li>
diff --git a/documentation/test_doxygen/compound_listing/structRoot_1_1Directory_1_1Sub_1_1Warning.html b/documentation/test_doxygen/compound_listing/structRoot_1_1Directory_1_1Sub_1_1Warning.html
new file mode 100644 (file)
index 0000000..846e3da
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Root::Directory::Sub::Warning struct | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+      <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+        <a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
+        <a id="m-navbar-hide" href="#" title="Hide navigation"></a>
+      </div>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-6 m-col-m-none">
+            <li><a href="pages.html">Pages</a></li>
+            <li><a href="namespaces.html">Namespaces</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="3">
+            <li><a href="annotated.html">Classes</a></li>
+            <li><a href="files.html">Files</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          <span class="m-breadcrumb"><a href="namespaceRoot.html">Root</a>::<wbr/></span><span class="m-breadcrumb"><a href="namespaceRoot_1_1Directory.html">Directory</a>::<wbr/></span><span class="m-breadcrumb"><a href="namespaceRoot_1_1Directory_1_1Sub.html">Sub</a>::<wbr/></span>Warning <span class="m-thin">struct</span>
+          <div class="m-doc-include m-code m-inverted m-text-right"><span class="cp">#include</span> <a class="cpf" href="Class_8h.html">&lt;Directory/Sub/Class.h&gt;</a></div>
+        </h1>
+        <p>A struct producing warnings.</p>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index b8734d1f8d22899a240b623e263aba0df7ba75b2..14842f4fa8ab5529ccc2796dd09d82abc1499f44 100644 (file)
         <h1>
           Namespace <span class="m-thin">namespace</span>
         </h1>
+        <p>===============</p>
+        <nav class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li><a href="#autotoc_md0">The Thing</a></li>
+          </ul>
+        </nav>
+<section id="autotoc_md0"><h2><a href="#autotoc_md0">The Thing</a></h2></section>
       </div>
     </div>
   </div>
diff --git a/documentation/test_doxygen/contents_autobrief_heading/namespaceNamespace_1814.html b/documentation/test_doxygen/contents_autobrief_heading/namespaceNamespace_1814.html
new file mode 100644 (file)
index 0000000..b8734d1
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Namespace namespace | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Namespace <span class="m-thin">namespace</span>
+        </h1>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index 75ca144bd62b09e66f938d1a2bd3250531f507a4..a4f37a1c1ed5242b3322ad9cba5747afa3b09908 100644 (file)
             </li>
           </ul>
         </nav>
-<p>SOME HEAVY LICENSE HEADER WITH SOME HEAVY WORDS</p><hr/>
+<hr/><p>SOME HEAVY LICENSE HEADER WITH SOME HEAVY WORDS</p><hr/>
         <section id="func-members">
           <h2><a href="#func-members">Functions</a></h2>
           <dl class="m-doc">
-            <dt>
-              <span class="m-doc-wrap-bumper">void <a href="#a0f1fe1a972c7c4196988a1bdde63ec77" class="m-doc-self" id="a0f1fe1a972c7c4196988a1bdde63ec77">foo</a>(</span><span class="m-doc-wrap">)</span>
+            <dt id="a0f1fe1a972c7c4196988a1bdde63ec77">
+              <span class="m-doc-wrap-bumper">void <a href="#a0f1fe1a972c7c4196988a1bdde63ec77" class="m-doc-self">foo</a>(</span><span class="m-doc-wrap">)</span>
             </dt>
             <dd>Some normal brief documentation.</dd>
           </dl>
diff --git a/documentation/test_doxygen/contents_autobrief_hr/namespaceNamespace_1814.html b/documentation/test_doxygen/contents_autobrief_hr/namespaceNamespace_1814.html
new file mode 100644 (file)
index 0000000..75ca144
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Namespace namespace | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Namespace <span class="m-thin">namespace</span>
+        </h1>
+        <nav class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#func-members">Functions</a></li>
+              </ul>
+            </li>
+          </ul>
+        </nav>
+<p>SOME HEAVY LICENSE HEADER WITH SOME HEAVY WORDS</p><hr/>
+        <section id="func-members">
+          <h2><a href="#func-members">Functions</a></h2>
+          <dl class="m-doc">
+            <dt>
+              <span class="m-doc-wrap-bumper">void <a href="#a0f1fe1a972c7c4196988a1bdde63ec77" class="m-doc-self" id="a0f1fe1a972c7c4196988a1bdde63ec77">foo</a>(</span><span class="m-doc-wrap">)</span>
+            </dt>
+            <dd>Some normal brief documentation.</dd>
+          </dl>
+        </section>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index 6576c77191e9cd9dc97c2a5e18112a2a189e102e..01f509ead2604f27b89b52352c1723aba546f499 100644 (file)
@@ -1,4 +1,4 @@
-INPUT                   = File.h input.dox
+INPUT                   = File.h Warnings.h input.dox
 QUIET                   = YES
 GENERATE_HTML           = NO
 GENERATE_LATEX          = NO
index 3690b455134e36d5c1b0bd7b676ce21faa854091..96a861dc83d2788e8432bd09fbe8d0bc6343a679 100644 (file)
@@ -27,14 +27,3 @@ Mooore.
 @return Does not return anything.
 */
 void foo(int bar);
-
-/**
-@brief This produces warnings
-
-#### Markdown heading 4 that's rendered the same as 3
-
-Markdown heading, underlined, is misparsed
-##########################################
-
-*/
-void bar(int foo);
index 815db321847232c178218a29e486211602fa2ba0..4975083aac19e8ce7f9ebf2f0179e2384f20802e 100644 (file)
               <span class="m-doc-wrap-bumper">void <a href="#adc5bb4b0f2fddd234994abbe97abb8b1" class="m-doc">foo</a>(</span><span class="m-doc-wrap">int bar)</span>
             </dt>
             <dd>A function.</dd>
-            <dt>
-              <span class="m-doc-wrap-bumper">void <a href="#ac03b94e5ed1aeeba4c9d31498e9a767a" class="m-doc">bar</a>(</span><span class="m-doc-wrap">int foo)</span>
-            </dt>
-            <dd>This produces warnings.</dd>
           </dl>
         </section>
         <section>
             </table>
 <h4 id="autotoc_md0">A top-level header</h4><h5 id="autotoc_md1">A second-level header</h5><h6 id="autotoc_md2">A third-level header</h6><h4 id="foo-usage">Usage</h4><p>This is usage.</p><h5 id="foo-usage-more">More</h5><p>A subsection.</p><h6 id="foo-usage-more-more">More.</h6><p>Mooore.</p>
           </div></section>
-          <section class="m-doc-details" id="ac03b94e5ed1aeeba4c9d31498e9a767a"><div>
-            <h3>
-              <span class="m-doc-wrap-bumper">void </span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#ac03b94e5ed1aeeba4c9d31498e9a767a" class="m-doc-self">bar</a>(</span><span class="m-doc-wrap">int foo)</span></span>
-            </h3>
-            <p>This produces warnings.</p>
-<h6 id="autotoc_md3">Markdown heading 4 that&#x27;s rendered the same as 3</h6><p>Markdown heading, underlined, is misparsed</p>
-          </div></section>
         </section>
       </div>
     </div>
diff --git a/documentation/test_doxygen/contents_sections_headings/Warnings.h b/documentation/test_doxygen/contents_sections_headings/Warnings.h
new file mode 100644 (file)
index 0000000..ce4a8a8
--- /dev/null
@@ -0,0 +1,14 @@
+/** @file
+ * @brief A file producing warnings
+ */
+
+/**
+@brief This produces warnings
+
+#### Markdown heading 4 that's rendered the same as 3
+
+Markdown heading, underlined, is misparsed
+##########################################
+
+*/
+void bar(int foo);
diff --git a/documentation/test_doxygen/contents_sections_headings/Warnings_8h.html b/documentation/test_doxygen/contents_sections_headings/Warnings_8h.html
new file mode 100644 (file)
index 0000000..51c0aef
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Warnings.h file | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Warnings.h <span class="m-thin">file</span>
+        </h1>
+        <p>A file producing warnings.</p>
+        <nav class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#func-members">Functions</a></li>
+              </ul>
+            </li>
+          </ul>
+        </nav>
+        <section id="func-members">
+          <h2><a href="#func-members">Functions</a></h2>
+          <dl class="m-doc">
+            <dt>
+              <span class="m-doc-wrap-bumper">void <a href="#ac03b94e5ed1aeeba4c9d31498e9a767a" class="m-doc">bar</a>(</span><span class="m-doc-wrap">int foo)</span>
+            </dt>
+            <dd>This produces warnings.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Function documentation</h2>
+          <section class="m-doc-details" id="ac03b94e5ed1aeeba4c9d31498e9a767a"><div>
+            <h3>
+              <span class="m-doc-wrap-bumper">void </span><span class="m-doc-wrap"><span class="m-doc-wrap-bumper"><a href="#ac03b94e5ed1aeeba4c9d31498e9a767a" class="m-doc-self">bar</a>(</span><span class="m-doc-wrap">int foo)</span></span>
+            </h3>
+            <p>This produces warnings.</p>
+<h6 id="autotoc_md3">Markdown heading 4 that&#x27;s rendered the same as 3</h6><p>Markdown heading, underlined, is misparsed</p>
+          </div></section>
+        </section>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index 848ae8d707c35ef3dd08f15a3365adb15bdf7164..f909d7e96300dfb8adb46bbae039088798b305e8 100644 (file)
@@ -26,17 +26,11 @@ class Class {
         friend struct FriendStruct;
         friend union FriendUnion;
 
-        /** @brief Ignored friend class with a warning because it has docs */
-        friend class FriendClassWarning;
-
         /** @brief A friend function */
         friend void friendFunction(int a, void* b);
 
         /** @{ @name Group with friend functions */
 
-        /** @brief Ignored friend class with a warning because it has docs */
-        friend class GroupedFriendClassWarning;
-
         /** @brief A friend grouped function */
         friend void friendGroupedFunction();
 
@@ -47,6 +41,23 @@ class Class {
          */
 };
 
+/** @brief A class producing warnings */
+struct Warning {
+    /** @brief Ignored friend class with a warning because it has docs */
+    friend class FriendClassWarning;
+
+    /** @{ @name Group with friend functions */
+
+    /** @brief Ignored friend class with a warning because it has docs */
+    friend class GroupedFriendClassWarning;
+
+    /* Since 1.8.17, the original short-hand group closing doesn't work
+        anymore. FFS. */
+    /**
+     * @}
+     */
+};
+
 /** @brief Class with template parameters */
 template<class T, class U = void, class = int> class Template {
     protected: /* Shouldn't matter */
diff --git a/documentation/test_doxygen/cpp_friends/structWarning.html b/documentation/test_doxygen/cpp_friends/structWarning.html
new file mode 100644 (file)
index 0000000..c28c927
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Warning struct | My Project</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+  <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Project</a>
+    </div>
+  </div>
+</nav></header>
+<main><article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>
+          Warning <span class="m-thin">struct</span>
+          <div class="m-doc-include m-code m-inverted m-text-right"><span class="cp">#include</span> <a class="cpf" href="File_8h.html">&lt;File.h&gt;</a></div>
+        </h1>
+        <p>A class producing warnings.</p>
+      </div>
+    </div>
+  </div>
+</article></main>
+</body>
+</html>
index a6e2e82fe43178efaf060bb454ebd434583c5e03..ab36224946a65d834b27612f913a4762ea42b2a5 100644 (file)
@@ -63,6 +63,15 @@ class Listing(IntegrationTestCase):
         self.run_doxygen(wildcard='classRoot_1_1Directory_1_1Sub_1_1Class.xml')
         self.assertEqual(*self.actual_expected_contents('classRoot_1_1Directory_1_1Sub_1_1Class.html'))
 
+    def test_class_no_group_name_warning(self):
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='structRoot_1_1Directory_1_1Sub_1_1Warning.xml')
+
+        self.assertEqual(*self.actual_expected_contents('structRoot_1_1Directory_1_1Sub_1_1Warning.html'))
+        self.assertEqual(cm.output, [
+            "ERROR:root:structRoot_1_1Directory_1_1Sub_1_1Warning.xml: member groups without @name are not supported, ignoring"
+        ])
+
     def test_page_no_toc(self):
         self.run_doxygen(wildcard='page-no-toc.xml')
         self.assertEqual(*self.actual_expected_contents('page-no-toc.html'))
@@ -81,8 +90,14 @@ class Detailed(IntegrationTestCase):
         self.assertEqual(*self.actual_expected_contents('structTemplate_3_01void_01_4.html'))
 
     def test_class_template_warnings(self):
-        self.run_doxygen(wildcard='structTemplateWarning.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='structTemplateWarning.xml')
+
         self.assertEqual(*self.actual_expected_contents('structTemplateWarning.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:structTemplateWarning.xml: unexpected @param / @return / @retval / @exception found in top-level description, ignoring",
+            "WARNING:root:structTemplateWarning.xml: template parameter description doesn't match parameter names: {'WTF': 'And this one does not exist'}"
+        ])
 
     def test_function(self):
         self.run_doxygen(wildcard='namespaceFoo.xml')
@@ -93,8 +108,15 @@ class Detailed(IntegrationTestCase):
         self.assertEqual(*self.actual_expected_contents('namespaceEno.html'))
 
     def test_function_enum_warnings(self):
-        self.run_doxygen(wildcard='namespaceWarning.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='namespaceWarning.xml')
+
         self.assertEqual(*self.actual_expected_contents('namespaceWarning.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:namespaceWarning.xml: superfluous @return section found, ignoring: Returns something, but second time. This is ignored.",
+            "WARNING:root:namespaceWarning.xml: superfluous @return section found, ignoring: Returns something, third time, in a different paragraph. Ignored as well.",
+            "WARNING:root:namespaceWarning.xml: function parameter description doesn't match parameter names: {'wrong': ('This parameter is not here', '')}"
+        ])
 
     def test_typedef(self):
         self.run_doxygen(wildcard='namespaceType.xml')
index 277216da5630fe8e49088de7f6a616738ade876f..5215edf8ebeeae66583ac2d73a58d4bbf9e80be8 100644 (file)
@@ -89,8 +89,15 @@ class Code(IntegrationTestCase):
         self.assertEqual(*self.actual_expected_contents('index.html'))
 
     def test_warnings(self):
-        self.run_doxygen(wildcard='warnings.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='warnings.xml')
+
         self.assertEqual(*self.actual_expected_contents('warnings.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:warnings.xml: no filename attribute in <programlisting>, assuming C++",
+            "WARNING:root:warnings.xml: inline code has multiple lines, fallback to a code block",
+            "WARNING:root:warnings.xml: inline code has multiple lines, fallback to a code block"
+        ])
 
 class CodeLanguage(IntegrationTestCase):
     @unittest.skipUnless(LooseVersion(doxygen_version()) > LooseVersion("1.8.13"),
@@ -108,8 +115,15 @@ class CodeLanguage(IntegrationTestCase):
     @unittest.skipUnless(LooseVersion(doxygen_version()) > LooseVersion("1.8.13"),
                          "https://github.com/doxygen/doxygen/pull/621")
     def test_warnings(self):
-        self.run_doxygen(wildcard='warnings.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='warnings.xml')
+
         self.assertEqual(*self.actual_expected_contents('warnings.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:warnings.xml: no filename attribute in <programlisting>, assuming C++",
+            "WARNING:root:warnings.xml: unrecognized language of .whatthehell in <programlisting>, highlighting disabled",
+            "WARNING:root:warnings.xml: @include / @snippet / @skip[line] produced an empty code block, probably a wrong match expression?"
+        ])
 
 class Image(IntegrationTestCase):
     def test(self):
@@ -118,11 +132,16 @@ class Image(IntegrationTestCase):
         self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'tiny.png')))
 
     def test_warnings(self):
-        self.run_doxygen(wildcard='warnings.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='warnings.xml')
+
         self.assertEqual(*self.actual_expected_contents('warnings.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:warnings.xml: image nonexistent.png was not found in XML_OUTPUT"
+        ])
 
     @unittest.skipUnless(LooseVersion(doxygen_version()) > LooseVersion("1.8.15"),
-                         "fully fixed after 1:8.15")
+                         "fully fixed after 1.8.15")
     def test_imagelink(self):
         self.run_doxygen(wildcard='imagelink.xml')
         self.assertEqual(*self.actual_expected_contents('imagelink.html'))
@@ -283,19 +302,58 @@ class AutobriefCppComments(IntegrationTestCase):
 class AutobriefHr(IntegrationTestCase):
     @unittest.skipUnless(LooseVersion(doxygen_version()) < LooseVersion("1.8.15"),
                          "1.8.15 doesn't put <hruler> into <briefdescription> anymore")
+    def test_1814(self):
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='namespaceNamespace.xml')
+
+        self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html', 'namespaceNamespace_1814.html'))
+        # Twice because it's a namespace docs and once it's parsed in
+        # extract_metadata() and once in parse_xml()
+        self.assertEqual(cm.output, 2*[
+            "WARNING:root:namespaceNamespace.xml: JAVADOC_AUTOBRIEF / QT_AUTOBRIEF produced a brief description with block elements. That's not supported, ignoring the whole contents of <hr/>"
+        ])
+
+    @unittest.skipUnless(LooseVersion(doxygen_version()) >= LooseVersion("1.8.15"),
+                         "1.8.15 doesn't put <hruler> into <briefdescription> anymore")
     def test(self):
+        # No warnings should be produced here
+        # TODO use self.assertNoLongs() on 3.10+
         self.run_doxygen(wildcard='namespaceNamespace.xml')
         self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html'))
 
 class AutobriefMultiline(IntegrationTestCase):
     def test(self):
-        self.run_doxygen(wildcard='namespaceNamespace.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='namespaceNamespace.xml')
+
         self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html'))
+        # Twice because it's a namespace docs and once it's parsed in
+        # extract_metadata() and once in parse_xml(). Can't put it into a
+        # function doc because the @{ then wouldn't work there as it has no
+        # associated @name.
+        self.assertEqual(cm.output, 2*[
+            "WARNING:root:namespaceNamespace.xml: JAVADOC_AUTOBRIEF / QT_AUTOBRIEF produced a multi-line brief description. That's not supported, using just the first paragraph of <p>First line of a brief output</p><p>Second line of a brief output gets ignored with a warning.</p>",
+        ])
 
 class AutobriefHeading(IntegrationTestCase):
     @unittest.skipUnless(LooseVersion(doxygen_version()) < LooseVersion("1.8.15"),
                          "1.8.15 doesn't put <heading> into <briefdescription> anymore")
+    def test_1814(self):
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='namespaceNamespace.xml')
+
+        self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html', 'namespaceNamespace_1814.html'))
+        # Twice because it's a namespace docs and once it's parsed in
+        # extract_metadata() and once in parse_xml()
+        self.assertEqual(cm.output, 2*[
+            "WARNING:root:namespaceNamespace.xml: JAVADOC_AUTOBRIEF / QT_AUTOBRIEF produced a brief description with block elements. That's not supported, ignoring the whole contents of <p>===============</p><h4>The Thing </h4>",
+        ])
+
+    @unittest.skipUnless(LooseVersion(doxygen_version()) >= LooseVersion("1.8.15"),
+                         "1.8.15 doesn't put <heading> into <briefdescription> anymore")
     def test(self):
+        # No warnings should be produced here
+        # TODO use self.assertNoLongs() on 3.10+
         self.run_doxygen(wildcard='namespaceNamespace.xml')
         self.assertEqual(*self.actual_expected_contents('namespaceNamespace.html'))
 
@@ -309,14 +367,23 @@ class SectionsHeadings(IntegrationTestCase):
         self.run_doxygen(wildcard='indexpage.xml')
         self.assertEqual(*self.actual_expected_contents('index.html'))
 
-    def test_warnings(self):
-        self.run_doxygen(wildcard='warnings.xml')
-        self.assertEqual(*self.actual_expected_contents('warnings.html'))
-
     def test_functions(self):
         self.run_doxygen(wildcard='File_8h.xml')
         self.assertEqual(*self.actual_expected_contents('File_8h.html'))
 
+    def test_warnings(self):
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='*arnings*.xml')
+
+        self.assertEqual(*self.actual_expected_contents('warnings.html'))
+        self.assertEqual(*self.actual_expected_contents('Warnings_8h.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:Warnings_8h.xml: more than three levels of sections in member descriptions are not supported, stopping at <h6>",
+            "WARNING:root:Warnings_8h.xml: a Markdown heading underline was apparently misparsed by Doxygen, prefix the headings with # instead",
+            "WARNING:root:warnings.xml: more than five levels of Markdown headings for top-level docs are not supported, stopping at <h6>",
+            "WARNING:root:warnings.xml: a Markdown heading underline was apparently misparsed by Doxygen, prefix the headings with # instead",
+        ])
+
 class AnchorInBothGroupAndNamespace(IntegrationTestCase):
     def test(self):
         self.run_doxygen(wildcard='*.xml')
@@ -330,8 +397,19 @@ class AnchorHtmlNoPrefixBug(IntegrationTestCase):
 
 class UnexpectedSections(IntegrationTestCase):
     def test(self):
-        self.run_doxygen(wildcard='File_8h.xml')
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='File_8h.xml')
+
         self.assertEqual(*self.actual_expected_contents('File_8h.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:File_8h.xml: unexpected @tparam / @param / @return / @retval / @exception found inside a @section, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @param / @return / @retval / @exception found in top-level description, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @tparam / @retval / @exception found in macro description, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @tparam / @param / @return / @retval / @exception found in enum description, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @tparam / @param / @return / @retval / @exception found in enum value description, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @param / @return / @retval / @exception found in typedef description, ignoring",
+            "WARNING:root:File_8h.xml: unexpected @param / @return / @retval / @exception found in variable description, ignoring",
+        ])
 
 class Dot(IntegrationTestCase):
     def test(self):
index 7886627cdb8193a68ba057579a329092a76fb0a2..fed05c759872f1e09a9027b31f5e828aa5a39820 100644 (file)
@@ -65,6 +65,15 @@ class Friends(IntegrationTestCase):
         self.assertEqual(*self.actual_expected_contents('classClass.html'))
         self.assertEqual(*self.actual_expected_contents('classTemplate.html'))
 
+    def test_warnings(self):
+        with self.assertLogs() as cm:
+            self.run_doxygen(wildcard='structWarning.xml')
+        self.assertEqual(*self.actual_expected_contents('structWarning.html'))
+        self.assertEqual(cm.output, [
+            "WARNING:root:structWarning.xml: doxygen is unable to cross-link friend class GroupedFriendClassWarning, ignoring, sorry",
+            "WARNING:root:structWarning.xml: doxygen is unable to cross-link friend class FriendClassWarning, ignoring, sorry"
+        ])
+
 class SignalsSlots(IntegrationTestCase):
     def test(self):
         self.run_doxygen(wildcard='classClass.xml')
index e944e89337687650fc442eb8a9f24483355c700f..070f4f870844dee2d632260cecccb1a42048a6df 100644 (file)
@@ -132,8 +132,12 @@ copy a link to the result using <span class="m-label m-dim">⌘</span>
 
     def test_subdirs(self):
         state = State(copy.deepcopy(default_config))
-        with self.assertRaises(NotImplementedError):
-            parse_doxyfile(state, 'test_doxygen/doxyfile/Doxyfile-subdirs')
+        with self.assertLogs() as cm:
+            with self.assertRaises(NotImplementedError):
+                parse_doxyfile(state, 'test_doxygen/doxyfile/Doxyfile-subdirs')
+        self.assertEqual(cm.output, [
+            "CRITICAL:root:test_doxygen/doxyfile/Doxyfile-subdirs: CREATE_SUBDIRS is not supported, sorry. Disable it and try again."
+        ])
 
 class UpgradeCustomVariables(BaseTestCase):
     def test(self):