Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor tests for readible output #18

Merged
merged 1 commit into from Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Empty file added tests/__init__.py
Empty file.
71 changes: 71 additions & 0 deletions tests/assertions.py
@@ -0,0 +1,71 @@
from xml import etree
from xml.dom import minidom
import textwrap


def assert_xml_equal(xml_string, expected_xml_string):
"""
Assert equality of two xml strings, particularly that the contents of
each string have the same elements, with the same attributes (e.g. class,
text) and the same non-xml string contents
"""
# this prints a human-formatted string of what the test passed in -- useful
# if you need to modify test expectations after you've modified
# a rendering and tested it visually
print(to_readable_error_output(xml_string))

assert_elements_equal(
etree.ElementTree.fromstring(tostring(xml_string)),
etree.ElementTree.fromstring(tostring(expected_xml_string)),
)


def assert_elements_equal(element, reference_element):
"""
Assert, recursively, the equality of two etree objects.
"""
assert (
element.text == reference_element.text
), f"Text doesn't match: {element.text} =/= {reference_element.text}."
assert (
element.attrib == reference_element.attrib
), f"Attrib doesn't match: {element.attrib} =/= {reference_element.attrib}"
assert len(element) == len(
reference_element
), f"Expected {len(reference_element)} children but got {len(element)}"
for sub_element, reference_sub_element in zip(element, reference_element):
assert_elements_equal(sub_element, reference_sub_element)


def tostring(xml_string):
"""
Wraps `xml_string` in a div so it can be rendered, even if it has multiple roots.
"""
return remove_indents(f"<div>{remove_indents(xml_string)}</div>").encode("utf-8")


def to_readable_error_output(xml_string):
return textwrap.dedent(
"\n".join(
minidom.parseString(tostring(xml_string))
.toprettyxml(indent=" ")
.split("\n")[2:-2] # remove xml declaration and div added by `tostring`
)
) # dent by " "


def remove_indents(html):
"""
Remove leading whitespace from a string

e.g.
input: output:
. <div> . <div>
. <p>Some Text</p> . <p>Some Text</p>
. <div> . <div>
. Some more text . Some more text
. </div> . </div>
. </div> . </div>
"""
lines = [el.lstrip() for el in html.split("\n")]
return "".join([el for el in lines if el or el != "\n"])
118 changes: 93 additions & 25 deletions tests/test_extension.py
@@ -1,4 +1,5 @@
import markdown
from .assertions import assert_xml_equal


def test_docstring():
Expand All @@ -9,25 +10,55 @@ def test_docstring():
:docstring:
"""
output = markdown.markdown(content, extensions=["mkautodoc"])
assert output.splitlines() == [
"<h1>Example</h1>",
'<div class="autodoc">',
'<div class="autodoc-signature"><code>mocklib.<strong>example_function</strong></code><span class="autodoc-punctuation">(</span><em class="autodoc-param">a</em><span class="autodoc-punctuation">, </span><em class="autodoc-param">b=None</em><span class="autodoc-punctuation">, </span><em class="autodoc-param">*args</em><span class="autodoc-punctuation">, </span><em class="autodoc-param">**kwargs</em><span class="autodoc-punctuation">)</span></div>',
'<div class="autodoc-docstring"><p>This is a function with a <em>docstring</em>.</p></div>',
"</div>",
]
assert_xml_equal(
output,
"""
<h1>Example</h1>
<div class="autodoc">
<div class="autodoc-signature">
<code>
mocklib.
<strong>example_function</strong>
</code>
<span class="autodoc-punctuation">(</span>
<em class="autodoc-param">a</em>
<span class="autodoc-punctuation">, </span>
<em class="autodoc-param">b=None</em>
<span class="autodoc-punctuation">, </span>
<em class="autodoc-param">*args</em>
<span class="autodoc-punctuation">, </span>
<em class="autodoc-param">**kwargs</em>
<span class="autodoc-punctuation">)</span>
</div>
<div class="autodoc-docstring">
<p>
This is a function with a <em>docstring</em>.
</p>
</div>
</div>""",
)


def test_async_function():
content = """
::: mocklib.example_async_function
"""
output = markdown.markdown(content, extensions=["mkautodoc"])
assert output.splitlines() == [
'<div class="autodoc">',
'<div class="autodoc-signature"><em>async </em><code>mocklib.<strong>example_async_function</strong></code><span class="autodoc-punctuation">(</span><span class="autodoc-punctuation">)</span></div>',
"</div>",
]
assert_xml_equal(
output,
"""
<div class="autodoc">
<div class="autodoc-signature">
<em>async </em>
<code>
mocklib.
<strong>example_async_function</strong>
</code>
<span class="autodoc-punctuation">(</span>
<span class="autodoc-punctuation">)</span>
</div>
</div>""",
)


def test_members():
Expand All @@ -39,16 +70,53 @@ def test_members():
:members:
"""
output = markdown.markdown(content, extensions=["mkautodoc"])
assert output.splitlines() == [
"<h1>Example</h1>",
'<div class="autodoc">',
'<div class="autodoc-signature"><em>class </em><code>mocklib.<strong>ExampleClass</strong></code><span class="autodoc-punctuation">(</span><span class="autodoc-punctuation">)</span></div>',
'<div class="autodoc-docstring"><p>This is a class with a <em>docstring</em>.</p></div>',
'<div class="autodoc-members">',
'<div class="autodoc-signature"><code><strong>example_method</strong></code><span class="autodoc-punctuation">(</span><em class="autodoc-param">self</em><span class="autodoc-punctuation">, </span><em class="autodoc-param">a</em><span class="autodoc-punctuation">, </span><em class="autodoc-param">b=None</em><span class="autodoc-punctuation">)</span></div>',
'<div class="autodoc-docstring"><p>This is a method with a <em>docstring</em>.</p></div>',
'<div class="autodoc-signature"><code><strong>example_property</strong></code></div>',
'<div class="autodoc-docstring"><p>This is a property with a <em>docstring</em>.</p></div>',
"</div>",
"</div>",
]
assert_xml_equal(
output,
"""
<h1>Example</h1>
<div class="autodoc">
<div class="autodoc-signature">
<em>class </em>
<code>
mocklib.
<strong>ExampleClass</strong>
</code>
<span class="autodoc-punctuation">(</span>
<span class="autodoc-punctuation">)</span>
</div>
<div class="autodoc-docstring">
<p>
This is a class with a <em>docstring</em>.
</p>
</div>
<div class="autodoc-members">
<div class="autodoc-signature">
<code>
<strong>example_method</strong>
</code>
<span class="autodoc-punctuation">(</span>
<em class="autodoc-param">self</em>
<span class="autodoc-punctuation">, </span>
<em class="autodoc-param">a</em>
<span class="autodoc-punctuation">, </span>
<em class="autodoc-param">b=None</em>
<span class="autodoc-punctuation">)</span>
</div>
<div class="autodoc-docstring">
<p>
This is a method with a <em>docstring</em>.
</p>
</div>
<div class="autodoc-signature">
<code>
<strong>example_property</strong>
</code>
</div>
<div class="autodoc-docstring">
<p>
This is a property with a <em>docstring</em>.
</p>
</div>
</div>
</div>""",
)