aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaylan Limberg <waylan.limberg@icloud.com>2016-02-23 20:02:10 -0500
committerWaylan Limberg <waylan.limberg@icloud.com>2018-01-08 20:41:18 -0500
commit76e0a63e12dd964311c4350a5735bb7f51ef87a6 (patch)
tree9d98ed9341b144b3e5ff6133f7427b71ab428d8a
parenta102ed4be389d661ced9eff232af8bb90032a0f8 (diff)
downloadmarkdown-76e0a63e12dd964311c4350a5735bb7f51ef87a6.tar.gz
markdown-76e0a63e12dd964311c4350a5735bb7f51ef87a6.tar.bz2
markdown-76e0a63e12dd964311c4350a5735bb7f51ef87a6.zip
Provide new testing framework.
As a part of the Markdown lib, test tools can be used by third party extensions. Also keeps test dir clean as it only contains actual tests. More work in this vein to come as the need for Nose is removed. Tests are defined as Unittests rather than in text files allowing features to be more easily broken into units and run individually. Based completely on standard lib unittest with no external dependencies. Use `python -m unittest tests.test_syntax` to run. Pulled some tests from https://github.com/karlcow/markdown-testsuite. Many more test units to pull from that source. As we encounter the need to edit an existing textfile-based test, or add a new test, a new test should be created with this framework and the old test should be deleted. Also need to delete existing testfile-based tests which are covered in the new tests included here.
-rw-r--r--markdown/test_tools.py44
-rw-r--r--tests/test_syntax/__init__.py0
-rw-r--r--tests/test_syntax/blocks/__init__.py0
-rw-r--r--tests/test_syntax/blocks/test_code_blocks.py67
-rw-r--r--tests/test_syntax/blocks/test_headers.py688
-rw-r--r--tests/test_syntax/blocks/test_hr.py342
-rw-r--r--tests/test_syntax/blocks/test_paragraphs.py208
7 files changed, 1349 insertions, 0 deletions
diff --git a/markdown/test_tools.py b/markdown/test_tools.py
new file mode 100644
index 0000000..cebb2bb
--- /dev/null
+++ b/markdown/test_tools.py
@@ -0,0 +1,44 @@
+import unittest
+import textwrap
+from markdown import markdown
+
+
+class TestCase(unittest.TestCase):
+ """
+ A unittest.TestCase subclass with helpers for testing Markdown output.
+
+ Define `default_kwargs` as a dict of keywords to pass to Markdown for each
+ test. The defaults can be overridden on individual tests.
+
+ The `assertMarkdownRenders` method accepts the source text, the expected
+ output, and any keywords to pass to Markdown. The `default_kwargs` are used
+ except where overridden by `kwargs`. The ouput and expected ouput are passed
+ to `TestCase.assertMultiLineEqual`. An AssertionError is raised with a diff
+ if the actual output does not equal the expected output.
+
+ The `dedent` method is available to dedent triple-quoted strings if
+ necessary.
+
+ In all other respects, behaves as unittest.TestCase.
+ """
+
+ default_kwargs = {}
+
+ def assertMarkdownRenders(self, source, expected, **kwargs):
+ """
+ Test that source Markdown text renders to expected output with given keywords.
+ """
+
+ kws = self.default_kwargs.copy()
+ kws.update(kwargs)
+ output = markdown(source, **kws)
+ self.assertMultiLineEqual(output, expected)
+
+ def dedent(self, text):
+ """
+ Dedent text.
+ """
+
+ # TODO: If/when actual output ends with a newline, then use:
+ # return textwrap.dedent(text.strip('/n'))
+ return textwrap.dedent(text).strip()
diff --git a/tests/test_syntax/__init__.py b/tests/test_syntax/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/test_syntax/__init__.py
diff --git a/tests/test_syntax/blocks/__init__.py b/tests/test_syntax/blocks/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/test_syntax/blocks/__init__.py
diff --git a/tests/test_syntax/blocks/test_code_blocks.py b/tests/test_syntax/blocks/test_code_blocks.py
new file mode 100644
index 0000000..00e6070
--- /dev/null
+++ b/tests/test_syntax/blocks/test_code_blocks.py
@@ -0,0 +1,67 @@
+from markdown.test_tools import TestCase
+
+
+class TestCodeBlocks(TestCase):
+
+ def test_spaced_codeblock(self):
+ self.assertMarkdownRenders(
+ ' # A code block.',
+
+ self.dedent(
+ """
+ <pre><code># A code block.
+ </code></pre>
+ """
+ )
+ )
+
+ def test_tabbed_codeblock(self):
+ self.assertMarkdownRenders(
+ '\t# A code block.',
+
+ self.dedent(
+ """
+ <pre><code># A code block.
+ </code></pre>
+ """
+ )
+ )
+
+ def test_multiline_codeblock(self):
+ self.assertMarkdownRenders(
+ ' # Line 1\n # Line 2\n',
+
+ self.dedent(
+ """
+ <pre><code># Line 1
+ # Line 2
+ </code></pre>
+ """
+ )
+ )
+
+ def test_codeblock_with_blankline(self):
+ self.assertMarkdownRenders(
+ ' # Line 1\n\n # Line 2\n',
+
+ self.dedent(
+ """
+ <pre><code># Line 1
+
+ # Line 2
+ </code></pre>
+ """
+ )
+ )
+
+ def test_codeblock_escape(self):
+ self.assertMarkdownRenders(
+ ' <foo & bar>',
+
+ self.dedent(
+ """
+ <pre><code>&lt;foo &amp; bar&gt;
+ </code></pre>
+ """
+ )
+ )
diff --git a/tests/test_syntax/blocks/test_headers.py b/tests/test_syntax/blocks/test_headers.py
new file mode 100644
index 0000000..63e3a7f
--- /dev/null
+++ b/tests/test_syntax/blocks/test_headers.py
@@ -0,0 +1,688 @@
+import unittest
+from markdown.test_tools import TestCase
+
+
+class TestSetextHeaders(TestCase):
+
+ def test_setext_h1(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H1
+ =============
+ """
+ ),
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_setext_h2(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H2
+ -------------
+ """
+ ),
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_setext_h1_mismatched_length(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H1
+ ===
+ """
+ ),
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_setext_h2_mismatched_length(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H2
+ ---
+ """
+ ),
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_setext_h1_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H1
+ =============
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h1>This is an H1</h1>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_setext_h2_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is an H2
+ -------------
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h2>This is an H2</h2>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ # TODO: fix this
+ # see http://johnmacfarlane.net/babelmark2/?normalize=1&text=Paragraph%0AAn+H1%0A%3D%3D%3D%3D%3D
+ @unittest.skip('This is broken in Python-Markdown')
+ def test_p_followed_by_setext_h1(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is a Paragraph.
+ Followed by an H1 with no blank line.
+ =====================================
+ """
+ ),
+ self.dedent(
+ """
+ <p>This is a Paragraph.</p>
+ <h1>Followed by an H1 with no blank line.</h1>
+ """
+ )
+ )
+
+ # TODO: fix this
+ # see http://johnmacfarlane.net/babelmark2/?normalize=1&text=Paragraph%0AAn+H2%0A-----
+ @unittest.skip('This is broken in Python-Markdown')
+ def test_p_followed_by_setext_h2(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is a Paragraph.
+ Followed by an H2 with no blank line.
+ -------------------------------------
+ """
+ ),
+ self.dedent(
+ """
+ <p>This is a Paragraph.</p>
+ <h2>Followed by an H2 with no blank line.</h2>
+ """
+ )
+ )
+
+
+class TestHashHeaders(TestCase):
+
+ def test_hash_h1_open(self):
+ self.assertMarkdownRenders(
+ '# This is an H1',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_open(self):
+ self.assertMarkdownRenders(
+ '## This is an H2',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_open(self):
+ self.assertMarkdownRenders(
+ '### This is an H3',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_open(self):
+ self.assertMarkdownRenders(
+ '#### This is an H4',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_open(self):
+ self.assertMarkdownRenders(
+ '##### This is an H5',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_open(self):
+ self.assertMarkdownRenders(
+ '###### This is an H6',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_open(self):
+ self.assertMarkdownRenders(
+ '####### This is an H6',
+
+ '<h6># This is an H6</h6>'
+ )
+
+ def test_hash_h1_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '#This is an H1',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '##This is an H2',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '###This is an H3',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '####This is an H4',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '#####This is an H5',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '######This is an H6',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_open_missing_space(self):
+ self.assertMarkdownRenders(
+ '#######This is an H6',
+
+ '<h6>#This is an H6</h6>'
+ )
+
+ def test_hash_h1_closed(self):
+ self.assertMarkdownRenders(
+ '# This is an H1 #',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_closed(self):
+ self.assertMarkdownRenders(
+ '## This is an H2 ##',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_closed(self):
+ self.assertMarkdownRenders(
+ '### This is an H3 ###',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_closed(self):
+ self.assertMarkdownRenders(
+ '#### This is an H4 ####',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_closed(self):
+ self.assertMarkdownRenders(
+ '##### This is an H5 #####',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_closed(self):
+ self.assertMarkdownRenders(
+ '###### This is an H6 ######',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_closed(self):
+ self.assertMarkdownRenders(
+ '####### This is an H6 #######',
+
+ '<h6># This is an H6</h6>'
+ )
+
+ def test_hash_h1_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '#This is an H1#',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '##This is an H2##',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '###This is an H3###',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '####This is an H4####',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '#####This is an H5#####',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '######This is an H6######',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_closed_missing_space(self):
+ self.assertMarkdownRenders(
+ '#######This is an H6#######',
+
+ '<h6>#This is an H6</h6>'
+ )
+
+ def test_hash_h1_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '# This is an H1 ##',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '## This is an H2 #',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '### This is an H3 #',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '#### This is an H4 #',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '##### This is an H5 #',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '###### This is an H6 #',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_closed_mismatch(self):
+ self.assertMarkdownRenders(
+ '####### This is an H6 ##################',
+
+ '<h6># This is an H6</h6>'
+ )
+
+ def test_hash_h1_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ # This is an H1
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h1>This is an H1</h1>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h2_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ## This is an H2
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h2>This is an H2</h2>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h3_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ### This is an H3
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h3>This is an H3</h3>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h4_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ #### This is an H4
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h4>This is an H4</h4>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h5_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ##### This is an H5
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h5>This is an H5</h5>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h6_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ###### This is an H6
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h6>This is an H6</h6>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hash_h1_leading_space(self):
+ self.assertMarkdownRenders(
+ ' # This is an H1',
+
+ '<p># This is an H1</p>'
+ )
+
+ def test_hash_h2_leading_space(self):
+ self.assertMarkdownRenders(
+ ' ## This is an H2',
+
+ '<p>## This is an H2</p>'
+ )
+
+ def test_hash_h3_leading_space(self):
+ self.assertMarkdownRenders(
+ ' ### This is an H3',
+
+ '<p>### This is an H3</p>'
+ )
+
+ def test_hash_h4_leading_space(self):
+ self.assertMarkdownRenders(
+ ' #### This is an H4',
+
+ '<p>#### This is an H4</p>'
+ )
+
+ def test_hash_h5_leading_space(self):
+ self.assertMarkdownRenders(
+ ' ##### This is an H5',
+
+ '<p>##### This is an H5</p>'
+ )
+
+ def test_hash_h6_leading_space(self):
+ self.assertMarkdownRenders(
+ ' ###### This is an H6',
+
+ '<p>###### This is an H6</p>'
+ )
+
+ def test_hash_h1_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '# This is an H1 ',
+
+ '<h1>This is an H1</h1>'
+ )
+
+ def test_hash_h2_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '## This is an H2 ',
+
+ '<h2>This is an H2</h2>'
+ )
+
+ def test_hash_h3_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '### This is an H3 ',
+
+ '<h3>This is an H3</h3>'
+ )
+
+ def test_hash_h4_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '#### This is an H4 ',
+
+ '<h4>This is an H4</h4>'
+ )
+
+ def test_hash_h5_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '##### This is an H5 ',
+
+ '<h5>This is an H5</h5>'
+ )
+
+ def test_hash_h6_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '###### This is an H6 ',
+
+ '<h6>This is an H6</h6>'
+ )
+
+ def test_hash_gt6_open_trailing_space(self):
+ self.assertMarkdownRenders(
+ '####### This is an H6 ',
+
+ '<h6># This is an H6</h6>'
+ )
+
+ # TODO: Possably change the following behavior. While this follows the behavior
+ # of markdown.pl, it is rather uncommon and not nessecarily intuitive.
+ # See: http://johnmacfarlane.net/babelmark2/?normalize=1&text=%23+This+is+an+H1+%23+
+ def test_hash_h1_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '# This is an H1 # ',
+
+ '<h1>This is an H1 #</h1>'
+ )
+
+ def test_hash_h2_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '## This is an H2 ## ',
+
+ '<h2>This is an H2 ##</h2>'
+ )
+
+ def test_hash_h3_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '### This is an H3 ### ',
+
+ '<h3>This is an H3 ###</h3>'
+ )
+
+ def test_hash_h4_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '#### This is an H4 #### ',
+
+ '<h4>This is an H4 ####</h4>'
+ )
+
+ def test_hash_h5_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '##### This is an H5 ##### ',
+
+ '<h5>This is an H5 #####</h5>'
+ )
+
+ def test_hash_h6_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '###### This is an H6 ###### ',
+
+ '<h6>This is an H6 ######</h6>'
+ )
+
+ def test_hash_gt6_closed_trailing_space(self):
+ self.assertMarkdownRenders(
+ '####### This is an H6 ####### ',
+
+ '<h6># This is an H6 #######</h6>'
+ )
+
+ def test_no_blank_lines_between_hashs(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ # This is an H1
+ ## This is an H2
+ """
+ ),
+ self.dedent(
+ """
+ <h1>This is an H1</h1>
+ <h2>This is an H2</h2>
+ """
+ )
+ )
+
+ def test_random_hash_levels(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ### H3
+ ###### H6
+ # H1
+ ##### H5
+ #### H4
+ ## H2
+ ### H3
+ """
+ ),
+ self.dedent(
+ """
+ <h3>H3</h3>
+ <h6>H6</h6>
+ <h1>H1</h1>
+ <h5>H5</h5>
+ <h4>H4</h4>
+ <h2>H2</h2>
+ <h3>H3</h3>
+ """
+ )
+ )
+
+ def test_hash_followed_by_p(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ # This is an H1
+ Followed by a Paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <h1>This is an H1</h1>
+ <p>Followed by a Paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_p_followed_by_hash(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is a Paragraph.
+ # Followed by an H1 with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <p>This is a Paragraph.</p>
+ <h1>Followed by an H1 with no blank line.</h1>
+ """
+ )
+ )
diff --git a/tests/test_syntax/blocks/test_hr.py b/tests/test_syntax/blocks/test_hr.py
new file mode 100644
index 0000000..ffd0823
--- /dev/null
+++ b/tests/test_syntax/blocks/test_hr.py
@@ -0,0 +1,342 @@
+from markdown.test_tools import TestCase
+
+
+class TestHorizontalRules(TestCase):
+
+ def test_hr_asterisks(self):
+ self.assertMarkdownRenders(
+ '***',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces(self):
+ self.assertMarkdownRenders(
+ '* * *',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_long(self):
+ self.assertMarkdownRenders(
+ '*******',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces_long(self):
+ self.assertMarkdownRenders(
+ '* * * * * * *',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_1_indent(self):
+ self.assertMarkdownRenders(
+ ' ***',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces_1_indent(self):
+ self.assertMarkdownRenders(
+ ' * * *',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_2_indent(self):
+ self.assertMarkdownRenders(
+ ' ***',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces_2_indent(self):
+ self.assertMarkdownRenders(
+ ' * * *',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_3_indent(self):
+ self.assertMarkdownRenders(
+ ' ***',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces_3_indent(self):
+ self.assertMarkdownRenders(
+ ' * * *',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_trailing_space(self):
+ self.assertMarkdownRenders(
+ '*** ',
+
+ '<hr />'
+ )
+
+ def test_hr_asterisks_spaces_trailing_space(self):
+ self.assertMarkdownRenders(
+ '* * * ',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens(self):
+ self.assertMarkdownRenders(
+ '---',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces(self):
+ self.assertMarkdownRenders(
+ '- - -',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_long(self):
+ self.assertMarkdownRenders(
+ '-------',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces_long(self):
+ self.assertMarkdownRenders(
+ '- - - - - - -',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_1_indent(self):
+ self.assertMarkdownRenders(
+ ' ---',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces_1_indent(self):
+ self.assertMarkdownRenders(
+ ' - - -',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_2_indent(self):
+ self.assertMarkdownRenders(
+ ' ---',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces_2_indent(self):
+ self.assertMarkdownRenders(
+ ' - - -',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_3_indent(self):
+ self.assertMarkdownRenders(
+ ' ---',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces_3_indent(self):
+ self.assertMarkdownRenders(
+ ' - - -',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_trailing_space(self):
+ self.assertMarkdownRenders(
+ '--- ',
+
+ '<hr />'
+ )
+
+ def test_hr_hyphens_spaces_trailing_space(self):
+ self.assertMarkdownRenders(
+ '- - - ',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores(self):
+ self.assertMarkdownRenders(
+ '___',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces(self):
+ self.assertMarkdownRenders(
+ '_ _ _',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_long(self):
+ self.assertMarkdownRenders(
+ '_______',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces_long(self):
+ self.assertMarkdownRenders(
+ '_ _ _ _ _ _ _',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_1_indent(self):
+ self.assertMarkdownRenders(
+ ' ___',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces_1_indent(self):
+ self.assertMarkdownRenders(
+ ' _ _ _',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_2_indent(self):
+ self.assertMarkdownRenders(
+ ' ___',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces_2_indent(self):
+ self.assertMarkdownRenders(
+ ' _ _ _',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_3_indent(self):
+ self.assertMarkdownRenders(
+ ' ___',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces_3_indent(self):
+ self.assertMarkdownRenders(
+ ' _ _ _',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_trailing_space(self):
+ self.assertMarkdownRenders(
+ '___ ',
+
+ '<hr />'
+ )
+
+ def test_hr_underscores_spaces_trailing_space(self):
+ self.assertMarkdownRenders(
+ '_ _ _ ',
+
+ '<hr />'
+ )
+
+ def test_hr_before_paragraph(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ ***
+ An HR followed by a paragraph with no blank line.
+ """
+ ),
+ self.dedent(
+ """
+ <hr />
+ <p>An HR followed by a paragraph with no blank line.</p>
+ """
+ )
+ )
+
+ def test_hr_after_paragraph(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ A paragraph followed by an HR with no blank line.
+ ***
+ """
+ ),
+ self.dedent(
+ """
+ <p>A paragraph followed by an HR with no blank line.</p>
+ <hr />
+ """
+ )
+ )
+
+ def test_not_hr_2_asterisks(self):
+ self.assertMarkdownRenders(
+ '**',
+
+ '<p>**</p>'
+ )
+
+ def test_not_hr_2_asterisks_spaces(self):
+ self.assertMarkdownRenders(
+ '* *',
+
+ self.dedent(
+ """
+ <ul>
+ <li>*</li>
+ </ul>
+ """
+ )
+ )
+
+ def test_not_hr_2_hyphens(self):
+ self.assertMarkdownRenders(
+ '--',
+
+ '<p>--</p>'
+ )
+
+ def test_not_hr_2_hyphens_spaces(self):
+ self.assertMarkdownRenders(
+ '- -',
+
+ self.dedent(
+ """
+ <ul>
+ <li>-</li>
+ </ul>
+ """
+ )
+ )
+
+ def test_not_hr_2_underscores(self):
+ self.assertMarkdownRenders(
+ '__',
+
+ '<p>__</p>'
+ )
+
+ def test_not_hr_2_underscores_spaces(self):
+ self.assertMarkdownRenders(
+ '_ _',
+
+ '<p>_ _</p>'
+ )
diff --git a/tests/test_syntax/blocks/test_paragraphs.py b/tests/test_syntax/blocks/test_paragraphs.py
new file mode 100644
index 0000000..b458fc1
--- /dev/null
+++ b/tests/test_syntax/blocks/test_paragraphs.py
@@ -0,0 +1,208 @@
+from markdown.test_tools import TestCase
+
+
+class TestParagraphBlocks(TestCase):
+
+ def test_simple_paragraph(self):
+ self.assertMarkdownRenders(
+ 'A simple paragraph.',
+
+ '<p>A simple paragraph.</p>'
+ )
+
+ def test_blank_line_before_paragraph(self):
+ self.assertMarkdownRenders(
+ '\nA paragraph preceded by a blank line.',
+
+ '<p>A paragraph preceded by a blank line.</p>'
+ )
+
+ def test_multiline_paragraph(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ This is a paragraph
+ on multiple lines
+ with hard returns.
+ """
+ ),
+ self.dedent(
+ """
+ <p>This is a paragraph
+ on multiple lines
+ with hard returns.</p>
+ """
+ )
+ )
+
+ def test_paragraph_long_line(self):
+ self.assertMarkdownRenders(
+ 'A very long long long long long long long long long long long long long long long long long long long '
+ 'long long long long long long long long long long long long long paragraph on 1 line.',
+
+ '<p>A very long long long long long long long long long long long long long long long long long long '
+ 'long long long long long long long long long long long long long long paragraph on 1 line.</p>'
+ )
+
+ def test_2_paragraphs_long_line(self):
+ self.assertMarkdownRenders(
+ 'A very long long long long long long long long long long long long long long long long long long long '
+ 'long long long long long long long long long long long long long paragraph on 1 line.\n\n'
+
+ 'A new long long long long long long long long long long long long long long long '
+ 'long paragraph on 1 line.',
+
+ '<p>A very long long long long long long long long long long long long long long long long long long '
+ 'long long long long long long long long long long long long long long paragraph on 1 line.</p>\n'
+ '<p>A new long long long long long long long long long long long long long long long '
+ 'long paragraph on 1 line.</p>'
+ )
+
+ def test_consecutive_paragraphs(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ Paragraph 1.
+
+ Paragraph 2.
+ """
+ ),
+ self.dedent(
+ """
+ <p>Paragraph 1.</p>
+ <p>Paragraph 2.</p>
+ """
+ )
+ )
+
+ def test_consecutive_paragraphs_tab(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ Paragraph followed by a line with a tab only.
+ \t
+ Paragraph after a line with a tab only.
+ """
+ ),
+ self.dedent(
+ """
+ <p>Paragraph followed by a line with a tab only.</p>
+ <p>Paragraph after a line with a tab only.</p>
+ """
+ )
+ )
+
+ def test_consecutive_paragraphs_space(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ Paragraph followed by a line with a space only.
+
+ Paragraph after a line with a space only.
+ """
+ ),
+ self.dedent(
+ """
+ <p>Paragraph followed by a line with a space only.</p>
+ <p>Paragraph after a line with a space only.</p>
+ """
+ )
+ )
+
+ def test_consecutive_multiline_paragraphs(self):
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+ Paragraph 1, line 1.
+ Paragraph 1, line 2.
+
+ Paragraph 2, line 1.
+ Paragraph 2, line 2.
+ """
+ ),
+ self.dedent(
+ """
+ <p>Paragraph 1, line 1.
+ Paragraph 1, line 2.</p>
+ <p>Paragraph 2, line 1.
+ Paragraph 2, line 2.</p>
+ """
+ )
+ )
+
+ def test_paragraph_leading_space(self):
+ self.assertMarkdownRenders(
+ ' A paragraph with 1 leading space.',
+
+ '<p>A paragraph with 1 leading space.</p>'
+ )
+
+ def test_paragraph_2_leading_spaces(self):
+ self.assertMarkdownRenders(
+ ' A paragraph with 2 leading spaces.',
+
+ '<p>A paragraph with 2 leading spaces.</p>'
+ )
+
+ def test_paragraph_3_leading_spaces(self):
+ self.assertMarkdownRenders(
+ ' A paragraph with 3 leading spaces.',
+
+ '<p>A paragraph with 3 leading spaces.</p>'
+ )
+
+ def test_paragraph_trailing_leading_space(self):
+ self.assertMarkdownRenders(
+ ' A paragraph with 1 trailing and 1 leading space. ',
+
+ '<p>A paragraph with 1 trailing and 1 leading space. </p>'
+ )
+
+ def test_paragraph_trailing_tab(self):
+ self.assertMarkdownRenders(
+ 'A paragraph with 1 trailing tab.\t',
+
+ '<p>A paragraph with 1 trailing tab. </p>'
+ )
+
+ def test_paragraphs_CR(self):
+ self.assertMarkdownRenders(
+ 'Paragraph 1, line 1.\rParagraph 1, line 2.\r\rParagraph 2, line 1.\rParagraph 2, line 2.\r',
+
+ self.dedent(
+ """
+ <p>Paragraph 1, line 1.
+ Paragraph 1, line 2.</p>
+ <p>Paragraph 2, line 1.
+ Paragraph 2, line 2.</p>
+ """
+ )
+ )
+
+ def test_paragraphs_LF(self):
+ self.assertMarkdownRenders(
+ 'Paragraph 1, line 1.\nParagraph 1, line 2.\n\nParagraph 2, line 1.\nParagraph 2, line 2.\n',
+
+ self.dedent(
+ """
+ <p>Paragraph 1, line 1.
+ Paragraph 1, line 2.</p>
+ <p>Paragraph 2, line 1.
+ Paragraph 2, line 2.</p>
+ """
+ )
+ )
+
+ def test_paragraphs_CR_LF(self):
+ self.assertMarkdownRenders(
+ 'Paragraph 1, line 1.\r\nParagraph 1, line 2.\r\n\r\nParagraph 2, line 1.\r\nParagraph 2, line 2.\r\n',
+
+ self.dedent(
+ """
+ <p>Paragraph 1, line 1.
+ Paragraph 1, line 2.</p>
+ <p>Paragraph 2, line 1.
+ Paragraph 2, line 2.</p>
+ """
+ )
+ )