-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
324 lines (274 loc) · 16.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="The Python-Markdown Project">
<link rel="canonical" href="https://Python-Markdown.github.io/test_tools/">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="<code>markdown</code>" href="../reference/markdown/" />
<link rel="prev" title="Extension API" href="../extensions/api/" />
<title>Test Tools — Python-Markdown 3.8 documentation</title>
<link rel="stylesheet" href="../static/nature.css" type="text/css" />
<link rel="stylesheet" href="../static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../assets/_mkdocstrings.css" type="text/css" />
<link rel="stylesheet" href="../custom.css" type="text/css" />
<link rel="stylesheet" href="../mkdocstrings.css" type="text/css" />
<script type="text/javascript" src="../static/jquery.js"></script>
<script type="text/javascript" src="../static/underscore.js"></script>
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="https://github.com/Python-Markdown/markdown" title="View this project on GitHub"><img src="../static/github.png" width=16px style="vertical-align: middle; margin-top: -1px" /></a>
</li>
<li class="right" style="margin-right: 10px">
<a href="../sitemap.html" title="Sitemap" accesskey="I">index</a>
</li>
<li class="right">
<a href="../reference/markdown/" title="<code>markdown</code>" accesskey="N">next</a> |
</li>
<li class="right">
<a href="../extensions/api/" title="Extension API" accesskey="P">previous</a> |
</li>
<li><img src="../py.png"
alt="icon" style="vertical-align: middle; margin-top: -1px"/></li>
<li class="nav-item nav-item-0">
<a href="..">Python-Markdown 3.8 documentation</a> »
</li>
<li class="nav-item">
<a href="./">Test Tools</a>
» </li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main"><h1 id="test-tools">Test Tools<a class="headerlink" href="#test-tools" title="Permanent link">¶</a></h1>
<p>Python-Markdown provides some testing tools which simplify testing actual
Markdown output against expected output. The tools are built on the Python
standard library <a href="https://docs.python.org/3/library/unittest.html"><code>unittest</code></a>. Therefore, no additional libraries are
required. While Python-Markdown uses the tools for its own tests, they were
designed and built so that third party extensions could use them as well.
Therefore, the tools are importable from <code>markdown.test_tools</code>.</p>
<p>The test tools include two different <code>unittest.TestCase</code> subclasses:
<code>markdown.test_tools.TestCase</code> and <code>markdown.test_tools.LegacyTestCase</code>.</p>
<h2 id="markdowntest_toolstestcase"><code>markdown.test_tools.TestCase</code><a class="headerlink" href="#markdowntest_toolstestcase" title="Permanent link">¶</a></h2>
<p>The <code>markdown.test_tools.TestCase</code> class is a <code>unittest.TestCase</code> subclass with
a few additional helpers to make testing Markdown output easier.</p>
<dl>
<dt>Properties</dt>
<dd><code>default_kwargs</code>: A <code>dict</code> of keywords to pass to Markdown for each
test. The defaults can be overridden on individual tests.</dd>
<dt>Methods</dt>
<dd><code>assertMarkdownRenders</code>: accepts the source text, the expected output, an optional
dictionary of <code>expected_attrs</code>, and any keywords to pass to Markdown. The
<code>default_kwargs</code> defined on the class are used except where overridden by
keyword arguments. The output and expected output are passed to
<code>TestCase.assertMultiLineEqual</code>. An <code>AssertionError</code> is raised with a diff
if the actual output does not equal the expected output. The optional
keyword <code>expected_attrs</code> accepts a dictionary of attribute names as keys with
expected values. Each value is checked against the attribute of that
name on the instance of the <code>Markdown</code> class using <code>TestCase.assertEqual</code>. An
<code>AssertionError</code> is raised if any value does not match the expected value.</dd>
<dd><code>dedent</code>: Dedent triple-quoted strings.</dd>
</dl>
<p>In all other respects, <code>markdown.test_tools.TestCase</code> behaves as
<code>unittest.TestCase</code>. In fact, <code>assertMarkdownRenders</code> tests could be mixed with
other <code>unittest</code> style tests within the same test class.</p>
<p>An example Markdown test might look like this:</p>
<pre class="codehilite"><code class="language-python">from markdown.test_tools import TestCase
class TestHr(TestCase):
def test_hr_before_paragraph(self):
self.assertMarkdownRenders(
# The Markdown source text used as input
self.dedent(
"""
***
An HR followed by a paragraph with no blank line.
"""
),
# The expected HTML output
self.dedent(
"""
<hr>
<p>An HR followed by a paragraph with no blank line.</p>
"""
),
# Other keyword arguments to pass to `markdown.markdown`
output_format='html'
)
</code></pre>
<h2 id="markdowntest_toolslegacytestcase"><code>markdown.test_tools.LegacyTestCase</code><a class="headerlink" href="#markdowntest_toolslegacytestcase" title="Permanent link">¶</a></h2>
<p>In the past Python-Markdown exclusively used file-based tests. Many of those
tests still exist in Python-Markdown’s test suite, including the test files from
the <a href="https://daringfireball.net/projects/markdown/">reference implementation</a> (<code>markdown.pl</code>) and <a href="http://michelf.com/projects/php-markdown/">PHP Markdown</a>.
Each test consists of a matching pair of text and HTML files. The text file
contains a snippet of Markdown source text formatted for a specific syntax
feature and the HTML file contains the expected HTML output of that snippet.
When the test suite is run, each text file is run through Markdown and the
output is compared with the HTML file as a separate unit test. When a test
fails, the error report includes a diff of the expected output compared to the
actual output to easily identify any problems.</p>
<p>A separate <code>markdown.test_tools.LegacyTestCase</code> subclass must be created for
each directory of test files. Various properties can be defined within the
subclass to point to a directory of text-based test files and define various
behaviors/defaults for those tests. The following properties are supported:</p>
<ul>
<li><code>location</code>: A path to the directory of test files. An absolute path is
preferred.</li>
<li><code>exclude</code>: A list of tests to skip. Each test name should comprise of a
file name without an extension.</li>
<li><code>normalize</code>: A boolean value indicating if the HTML should be normalized.
Default: <code>False</code>. Note: Normalization of HTML requires that <a href="http://countergram.github.io/pytidylib/">PyTidyLib</a> be
installed on the system. If PyTidyLib is not installed and <code>normalize</code> is set
to <code>True</code>, then the test will be skipped, regardless of any other settings.</li>
<li><code>input_ext</code>: A string containing the file extension of input files.
Default: <code>.txt</code>.</li>
<li><code>output_ext</code>: A string containing the file extension of expected output files.
Default: <code>html</code>.</li>
<li><code>default_kwargs</code>: A <code>markdown.test_tools.Kwargs</code> instance which stores the
default set of keyword arguments for all test files in the directory.</li>
</ul>
<p>In addition, properties can be defined for each individual set of test files
within the directory. The property should be given the name of the file without
the file extension. Any spaces and dashes in the file name should be replaced
with underscores. The value of the property should be a
<code>markdown.test_tools.Kwargs</code> instance which contains the keyword arguments that
should be passed to <code>markdown.markdown</code> for that test file. The keyword
arguments will “update” the <code>default_kwargs</code>.</p>
<p>When the class instance is created during a test run, it will walk the given
directory and create a separate unit test for each set of test files using the
naming scheme: <code>test_filename</code>. One unit test will be run for each set of input
and output files.</p>
<p>The definition of an example set of tests might look like this:</p>
<pre class="codehilite"><code class="language-python">from markdown.test_tools import LegacyTestCase, Kwargs
import os
# Get location of this file and use to find text file dirs.
parent_test_dir = os.path.abspath(os.path.dirname(__file__))
class TestFoo(LegacyTestCase):
# Define location of text file directory. In this case, the directory is
# named "foo" and is in the same parent directory as this file.
location = os.path.join(parent_test_dir, 'foo')
# Define default keyword arguments. In this case, unless specified
# differently, all tests should use the output format "html".
default_kwargs = Kwargs(output_format='html')
# The "xhtml" test should override the output format and use "xhtml".
xhtml = Kwargs(output_format='xhtml')
# The "toc" test should use the "toc" extension with a custom permalink
# setting.
toc = Kwargs(
extensions=['markdown.extensions.toc'],
extension_configs={'markdown.extensions.toc': {'permalink': "[link]"}}
)
</code></pre>
<p>Note that in the above example, the text file directory may contain many more
text-based test files than <code>xhtml</code> (<code>xhtml.txt</code> and <code>xhtml.html</code>) and <code>toc</code>
(<code>toc.txt</code> and <code>toc.html</code>). As long as each set of files exists as a pair, a
test will be created and run for each of them. Only the <code>xhtml</code> and <code>toc</code> tests
needed to be specifically identified as they had specific, non-default settings
which needed to be defined.</p>
<h2 id="running-python-markdowns-tests">Running Python-Markdown’s Tests<a class="headerlink" href="#running-python-markdowns-tests" title="Permanent link">¶</a></h2>
<p>As all of the tests for the <code>markdown</code> library are unit tests, standard
<code>unittest</code> methods of calling tests can be used. For example, to run all of
Python-Markdown’s tests, from the root of the git repository, run the following
command:</p>
<pre class="codehilite"><code class="language-sh">python -m unittest discover tests
</code></pre>
<p>That simple command will search everything in the <code>tests</code> directory and it’s
sub-directories and run all <code>unittest</code> tests that it finds, including
<code>unittest.TestCase</code>, <code>markdown.test_tools.TestCase</code>, and
<code>markdown.test_tools.LegacyTestCase</code> subclasses. Normal <a href="https://docs.python.org/3/library/unittest.html">unittest</a> discovery
rules apply.</p>
<div class="admonition seealso">
<p class="admonition-title">See Also</p>
<p>See the <a href="../contributing/">Contributing Guide</a> for instructions on setting up a
<a href="../contributing/#development-environment">development environment</a> for running the tests.</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li>
<a class="reference internal" href="#test-tools">Test Tools</a>
<ul>
<li>
<a class="reference internal" href="#markdowntest_toolstestcase">markdown.test_tools.TestCase</a>
</li>
<li>
<a class="reference internal" href="#markdowntest_toolslegacytestcase">markdown.test_tools.LegacyTestCase</a>
</li>
<li>
<a class="reference internal" href="#running-python-markdowns-tests">Running Python-Markdown’s Tests</a>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless">
<a href="../extensions/api/" title="previous page">Extension API</a>
</p>
<h4>Next topic</h4>
<p class="topless">
<a href="../reference/markdown/" title="next page"><code>markdown</code></a>
</p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="https://github.com/Python-Markdown/markdown/issues">Report a Bug</a></li>
<li><a href="https://github.com/Python-Markdown/markdown/edit/master/docs/test_tools.md">Edit on GitHub</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<div><input type="text" name="q" placeholder="Search docs" /></div>
<div><input type="submit" value="Go" /></div>
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="https://github.com/Python-Markdown/markdown" title="View this project on GitHub"><img src="../static/github.png" width=16px style="vertical-align: middle; margin-top: -1px" /></a>
</li>
<li class="right" style="margin-right: 10px">
<a href="../sitemap.html" title="Sitemap" accesskey="I">index</a>
</li>
<li class="right">
<a href="../reference/markdown/" title="<code>markdown</code>" accesskey="N">next</a> |
</li>
<li class="right">
<a href="../extensions/api/" title="Extension API" accesskey="P">previous</a> |
</li>
<li><img src="../py.png"
alt="icon" style="vertical-align: middle; margin-top: -1px"/></li>
<li class="nav-item nav-item-0">
<a href="..">Python-Markdown 3.8 documentation</a> »
</li>
<li class="nav-item">
<a href="./">Test Tools</a>
» </li>
</ul>
</div>
<div class="footer" role="contentinfo">Copyright © 2010-2023, The Python-Markdown Project.
Created using <a href="https://www.mkdocs.org/">MkDocs</a> 1.6.1.
</div>
<script>var base_url = '..';</script>
<script src="../search/main.js"></script>
<!--
MkDocs version : 1.6.1
Docs Build Date UTC : 2025-04-09 17:38:32.454621+00:00
-->
</body>
</html>