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:
# 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)
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()
# 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
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>
/** @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 */
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
*/
<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'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>
--- /dev/null
+<!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"><Directory/Sub/Class.h></a></div>
+ </h1>
+ <p>A struct producing warnings.</p>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
<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>
--- /dev/null
+<!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>
</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>
--- /dev/null
+<!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>
-INPUT = File.h input.dox
+INPUT = File.h Warnings.h input.dox
QUIET = YES
GENERATE_HTML = NO
GENERATE_LATEX = NO
@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);
<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's rendered the same as 3</h6><p>Markdown heading, underlined, is misparsed</p>
- </div></section>
</section>
</div>
</div>
--- /dev/null
+/** @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);
--- /dev/null
+<!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's rendered the same as 3</h6><p>Markdown heading, underlined, is misparsed</p>
+ </div></section>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
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();
*/
};
+/** @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 */
--- /dev/null
+<!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"><File.h></a></div>
+ </h1>
+ <p>A class producing warnings.</p>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
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'))
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')
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')
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"),
@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):
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'))
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'))
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')
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):
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')
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):