aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaylan Limberg <waylan.limberg@icloud.com>2018-07-23 16:16:42 -0400
committerWaylan Limberg <waylan.limberg@icloud.com>2018-07-24 09:19:08 -0400
commit727adc8a053402d3e9a38424ff67bde697674156 (patch)
treef4175caeab373faecc6597eb36516ff8001f58e2
parent8cd1ce45fdd795fafc334bfbe37948557826cdb8 (diff)
downloadmarkdown-727adc8a053402d3e9a38424ff67bde697674156.tar.gz
markdown-727adc8a053402d3e9a38424ff67bde697674156.tar.bz2
markdown-727adc8a053402d3e9a38424ff67bde697674156.zip
Improve serializer test coverage
Should be 100% coverage now. The ProcessingInstruction needed to be imported directly from ElementTree as PY27 was using a PIProxy which resulted in a bug. Interestingly, PY3 worked fine. Also removed the encoding code as it was not used. Besides it was only ever accessable from a private function.
-rw-r--r--markdown/serializers.py17
-rw-r--r--tests/test_apis.py70
2 files changed, 67 insertions, 20 deletions
diff --git a/markdown/serializers.py b/markdown/serializers.py
index 63446b9..187d755 100644
--- a/markdown/serializers.py
+++ b/markdown/serializers.py
@@ -39,6 +39,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
+from xml.etree.ElementTree import ProcessingInstruction
from . import util
ElementTree = util.etree.ElementTree
QName = util.etree.QName
@@ -46,8 +47,6 @@ if hasattr(util.etree, 'test_comment'): # pragma: no cover
Comment = util.etree.test_comment
else: # pragma: no cover
Comment = util.etree.Comment
-PI = util.etree.PI
-ProcessingInstruction = util.etree.ProcessingInstruction
__all__ = ['to_html_string', 'to_xhtml_string']
@@ -66,13 +65,6 @@ def _raise_serialization_error(text): # pragma: no cover
)
-def _encode(text, encoding):
- try:
- return text.encode(encoding, "xmlcharrefreplace")
- except (TypeError, AttributeError): # pragma: no cover
- _raise_serialization_error(text)
-
-
def _escape_cdata(text):
# escape character data
try:
@@ -181,15 +173,12 @@ def _serialize_html(write, elem, format):
write(_escape_cdata(elem.tail))
-def _write_html(root, encoding=None, format="html"):
+def _write_html(root, format="html"):
assert root is not None
data = []
write = data.append
_serialize_html(write, root, format)
- if encoding is None:
- return "".join(data)
- else:
- return _encode("".join(data), encoding)
+ return "".join(data)
# --------------------------------------------------------------------
diff --git a/tests/test_apis.py b/tests/test_apis.py
index a627c79..2875c85 100644
--- a/tests/test_apis.py
+++ b/tests/test_apis.py
@@ -18,6 +18,7 @@ from logging import DEBUG, WARNING, CRITICAL
import yaml
import tempfile
from io import BytesIO
+from xml.etree.ElementTree import ProcessingInstruction
PY3 = sys.version_info[0] == 3
@@ -465,23 +466,47 @@ class testSerializers(unittest.TestCase):
def testHtml(self):
""" Test HTML serialization. """
el = markdown.util.etree.Element('div')
+ el.set('id', 'foo<&">')
p = markdown.util.etree.SubElement(el, 'p')
- p.text = 'foo'
+ p.text = 'foo <&escaped>'
+ p.set('hidden', 'hidden')
markdown.util.etree.SubElement(el, 'hr')
+ non_element = markdown.util.etree.SubElement(el, None)
+ non_element.text = 'non-element text'
+ script = markdown.util.etree.SubElement(non_element, 'script')
+ script.text = '<&"test\nescaping">'
+ el.tail = "tail text"
self.assertEqual(
markdown.serializers.to_html_string(el),
- '<div><p>foo</p><hr></div>'
+ '<div id="foo&lt;&amp;&quot;&gt;">'
+ '<p hidden>foo &lt;&amp;escaped&gt;</p>'
+ '<hr>'
+ 'non-element text'
+ '<script><&"test\nescaping"></script>'
+ '</div>tail text'
)
def testXhtml(self):
"""" Test XHTML serialization. """
el = markdown.util.etree.Element('div')
+ el.set('id', 'foo<&">')
p = markdown.util.etree.SubElement(el, 'p')
- p.text = 'foo'
+ p.text = 'foo<&escaped>'
+ p.set('hidden', 'hidden')
markdown.util.etree.SubElement(el, 'hr')
+ non_element = markdown.util.etree.SubElement(el, None)
+ non_element.text = 'non-element text'
+ script = markdown.util.etree.SubElement(non_element, 'script')
+ script.text = '<&"test\nescaping">'
+ el.tail = "tail text"
self.assertEqual(
markdown.serializers.to_xhtml_string(el),
- '<div><p>foo</p><hr /></div>'
+ '<div id="foo&lt;&amp;&quot;&gt;">'
+ '<p hidden="hidden">foo&lt;&amp;escaped&gt;</p>'
+ '<hr />'
+ 'non-element text'
+ '<script><&"test\nescaping"></script>'
+ '</div>tail text'
)
def testMixedCaseTags(self):
@@ -496,8 +521,17 @@ class testSerializers(unittest.TestCase):
'<MixedCase>not valid <EMPHASIS>html</EMPHASIS><HR /></MixedCase>'
)
- def testQName(self):
- """ Test serialization of QName. """
+ def testProsessingInstruction(self):
+ """ Test serialization of ProcessignInstruction. """
+ pi = ProcessingInstruction('foo', text='<&"test\nescaping">')
+ self.assertIs(pi.tag, ProcessingInstruction)
+ self.assertEqual(
+ markdown.serializers.to_xhtml_string(pi),
+ '<?foo &lt;&amp;"test\nescaping"&gt;?>'
+ )
+
+ def testQNameTag(self):
+ """ Test serialization of QName tag. """
div = markdown.util.etree.Element('div')
qname = markdown.util.etree.QName('http://www.w3.org/1998/Math/MathML', 'math')
math = markdown.util.etree.SubElement(div, qname)
@@ -525,6 +559,30 @@ class testSerializers(unittest.TestCase):
'</div>'
)
+ def testQNameAttribute(self):
+ """ Test serialization of QName attribute. """
+ div = markdown.util.etree.Element('div')
+ div.set(markdown.util.etree.QName('foo'), markdown.util.etree.QName('bar'))
+ self.assertEqual(
+ markdown.serializers.to_xhtml_string(div),
+ '<div foo="bar"></div>'
+ )
+
+ def testBadQNameTag(self):
+ """ Test serialization of QName with no tag. """
+ qname = markdown.util.etree.QName('http://www.w3.org/1998/Math/MathML')
+ el = markdown.util.etree.Element(qname)
+ self.assertRaises(ValueError, markdown.serializers.to_xhtml_string, el)
+
+ def testQNameEscaping(self):
+ """ Test QName escaping. """
+ qname = markdown.util.etree.QName('<&"test\nescaping">', 'div')
+ el = markdown.util.etree.Element(qname)
+ self.assertEqual(
+ markdown.serializers.to_xhtml_string(el),
+ '<div xmlns="&lt;&amp;&quot;test&#10;escaping&quot;&gt;"></div>'
+ )
+
def buildExtension(self):
""" Build an extension which registers fakeSerializer. """
def fakeSerializer(elem):