Package lxml :: Package tests :: Module test_dtd
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_dtd

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Test cases related to DTD parsing and validation 
  5  """ 
  6   
  7  import unittest, sys, os.path 
  8   
  9  this_dir = os.path.dirname(__file__) 
 10  if this_dir not in sys.path: 
 11      sys.path.insert(0, this_dir) # needed for Py3 
 12   
 13  from common_imports import etree, StringIO, BytesIO, _bytes, doctest 
 14  from common_imports import HelperTestCase, fileInTestDir, make_doctest, skipIf 
15 16 -class ETreeDtdTestCase(HelperTestCase):
17 - def test_dtd(self):
18 pass
19
20 - def test_dtd_file(self):
21 parse = etree.parse 22 tree = parse(fileInTestDir("test.xml")) 23 root = tree.getroot() 24 25 dtd = etree.DTD(fileInTestDir("test.dtd")) 26 self.assertTrue(dtd.validate(root))
27
28 - def test_dtd_stringio(self):
29 root = etree.XML(_bytes("<b/>")) 30 dtd = etree.DTD(BytesIO("<!ELEMENT b EMPTY>")) 31 self.assertTrue(dtd.validate(root))
32
33 - def test_dtd_parse_invalid(self):
34 fromstring = etree.fromstring 35 parser = etree.XMLParser(dtd_validation=True) 36 xml = _bytes('<!DOCTYPE b SYSTEM "%s"><b><a/></b>' % fileInTestDir("test.dtd")) 37 self.assertRaises(etree.XMLSyntaxError, 38 fromstring, xml, parser=parser)
39
41 fromstring = etree.fromstring 42 dtd_filename = fileInTestDir("__nosuch.dtd") 43 parser = etree.XMLParser(dtd_validation=True) 44 xml = _bytes('<!DOCTYPE b SYSTEM "%s"><b><a/></b>' % dtd_filename) 45 self.assertRaises(etree.XMLSyntaxError, 46 fromstring, xml, parser=parser) 47 errors = None 48 try: 49 fromstring(xml, parser=parser) 50 except etree.XMLSyntaxError: 51 e = sys.exc_info()[1] 52 errors = [ entry.message for entry in e.error_log 53 if dtd_filename in entry.message ] 54 self.assertTrue(errors)
55
56 - def test_dtd_parse_valid(self):
57 parser = etree.XMLParser(dtd_validation=True) 58 xml = '<!DOCTYPE a SYSTEM "%s"><a><b/></a>' % fileInTestDir("test.dtd") 59 root = etree.fromstring(xml, parser=parser)
60
62 parser = etree.XMLParser(dtd_validation=True) 63 xml = '<!DOCTYPE a SYSTEM "test.dtd"><a><b/></a>' 64 root = etree.fromstring(xml, parser=parser, 65 base_url=fileInTestDir("test.xml"))
66
67 - def test_dtd_invalid(self):
68 root = etree.XML("<b><a/></b>") 69 dtd = etree.DTD(BytesIO("<!ELEMENT b EMPTY>")) 70 self.assertRaises(etree.DocumentInvalid, dtd.assertValid, root)
71
72 - def test_dtd_assertValid(self):
73 root = etree.XML("<b><a/></b>") 74 dtd = etree.DTD(BytesIO("<!ELEMENT b (a)><!ELEMENT a EMPTY>")) 75 dtd.assertValid(root)
76
77 - def test_dtd_internal(self):
78 root = etree.XML(_bytes(''' 79 <!DOCTYPE b SYSTEM "none" [ 80 <!ELEMENT b (a)> 81 <!ELEMENT a EMPTY> 82 ]> 83 <b><a/></b> 84 ''')) 85 dtd = etree.ElementTree(root).docinfo.internalDTD 86 self.assertTrue(dtd) 87 dtd.assertValid(root)
88
90 root = etree.XML(_bytes(''' 91 <!DOCTYPE b SYSTEM "none" [ 92 <!ELEMENT b (a)> 93 <!ELEMENT a (c)> 94 <!ELEMENT c EMPTY> 95 ]> 96 <b><a/></b> 97 ''')) 98 dtd = etree.ElementTree(root).docinfo.internalDTD 99 self.assertTrue(dtd) 100 self.assertFalse(dtd.validate(root))
101
102 - def test_dtd_broken(self):
103 self.assertRaises(etree.DTDParseError, etree.DTD, 104 BytesIO("<!ELEMENT b HONKEY>"))
105
106 - def test_parse_file_dtd(self):
107 parser = etree.XMLParser(attribute_defaults=True) 108 109 tree = etree.parse(fileInTestDir('test.xml'), parser) 110 root = tree.getroot() 111 112 self.assertEqual( 113 "valueA", 114 root.get("default")) 115 self.assertEqual( 116 "valueB", 117 root[0].get("default"))
118 119 @skipIf(etree.LIBXML_VERSION == (2, 9, 0), 120 "DTD loading is broken for incremental parsing in libxml2 2.9.0")
122 iterparse = etree.iterparse 123 iterator = iterparse(fileInTestDir("test.xml"), events=('start',), 124 attribute_defaults=True) 125 attributes = [ element.get("default") 126 for event, element in iterator ] 127 self.assertEqual( 128 ["valueA", "valueB"], 129 attributes)
130 131 @skipIf(etree.LIBXML_VERSION == (2, 9, 0), 132 "DTD loading is broken for incremental parsing in libxml2 2.9.0")
134 iterparse = etree.iterparse 135 iterator = iterparse(fileInTestDir("test.xml"), events=('end',), 136 attribute_defaults=True) 137 attributes = [ element.get("default") 138 for event, element in iterator ] 139 self.assertEqual( 140 ["valueB", "valueA"], 141 attributes)
142
143 - def test_dtd_attrs(self):
144 dtd = etree.DTD(fileInTestDir("test.dtd")) 145 146 # Test DTD.system_url attribute 147 self.assertTrue(dtd.system_url.endswith("test.dtd")) 148 149 # Test elements and their attributes 150 a = dtd.elements()[0] 151 self.assertEqual(a.name, "a") 152 self.assertEqual(a.type, "element") 153 self.assertEqual(a.content.name, "b") 154 self.assertEqual(a.content.type, "element") 155 self.assertEqual(a.content.occur, "once") 156 157 aattr = a.attributes()[0] 158 self.assertEqual(aattr.name, "default") 159 self.assertEqual(aattr.type, "enumeration") 160 self.assertEqual(aattr.values(), ["valueA", "valueB"]) 161 self.assertEqual(aattr.default_value, "valueA") 162 163 b = dtd.elements()[1] 164 self.assertEqual(b.name, "b") 165 self.assertEqual(b.type, "empty") 166 self.assertEqual(b.content, None) 167 168 # Test entities and their attributes 169 c = dtd.entities()[0] 170 self.assertEqual(c.name, "c") 171 self.assertEqual(c.orig, "&#42;") 172 self.assertEqual(c.content, "*") 173 174 # Test DTD.name attribute 175 root = etree.XML(_bytes(''' 176 <!DOCTYPE a SYSTEM "none" [ 177 <!ELEMENT a EMPTY> 178 ]> 179 <a/> 180 ''')) 181 dtd = etree.ElementTree(root).docinfo.internalDTD 182 self.assertEqual(dtd.name, "a") 183 184 # Test DTD.name and DTD.systemID attributes 185 parser = etree.XMLParser(dtd_validation=True) 186 xml = '<!DOCTYPE a SYSTEM "test.dtd"><a><b/></a>' 187 root = etree.fromstring(xml, parser=parser, 188 base_url=fileInTestDir("test.xml")) 189 190 dtd = root.getroottree().docinfo.internalDTD 191 self.assertEqual(dtd.name, "a") 192 self.assertEqual(dtd.system_url, "test.dtd")
193
194 195 -def test_suite():
196 suite = unittest.TestSuite() 197 suite.addTests([unittest.makeSuite(ETreeDtdTestCase)]) 198 suite.addTests( 199 [make_doctest('../../../doc/validation.txt')]) 200 return suite
201 202 if __name__ == '__main__': 203 print('to test use test.py %s' % __file__) 204