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_api_internal(self):
103 root = etree.XML(_bytes(''' 104 <!DOCTYPE b SYSTEM "none" [ 105 <!ATTLIST a 106 attr1 (x | y | z) "z" 107 attr2 CDATA #FIXED "X" 108 > 109 <!ELEMENT b (a)> 110 <!ELEMENT a EMPTY> 111 ]> 112 <b><a/></b> 113 ''')) 114 dtd = etree.ElementTree(root).docinfo.internalDTD 115 self.assertTrue(dtd) 116 dtd.assertValid(root) 117 118 seen = [] 119 for el in dtd.iterelements(): 120 if el.name == 'a': 121 self.assertEqual(2, len(el.attributes())) 122 for attr in el.iterattributes(): 123 if attr.name == 'attr1': 124 self.assertEqual('enumeration', attr.type) 125 self.assertEqual('none', attr.default) 126 self.assertEqual('z', attr.default_value) 127 values = attr.values() 128 values.sort() 129 self.assertEqual(['x', 'y', 'z'], values) 130 else: 131 self.assertEqual('attr2', attr.name) 132 self.assertEqual('cdata', attr.type) 133 self.assertEqual('fixed', attr.default) 134 self.assertEqual('X', attr.default_value) 135 else: 136 self.assertEqual('b', el.name) 137 self.assertEqual(0, len(el.attributes())) 138 seen.append(el.name) 139 seen.sort() 140 self.assertEqual(['a', 'b'], seen) 141 self.assertEqual(2, len(dtd.elements()))
142
143 - def test_internal_dtds(self):
144 for el_count in range(2, 5): 145 for attr_count in range(4): 146 root = etree.XML(_bytes(''' 147 <!DOCTYPE el0 SYSTEM "none" [ 148 ''' + ''.join([''' 149 <!ATTLIST el%d 150 attr%d (x | y | z) "z" 151 > 152 ''' % (e, a) for a in range(attr_count) for e in range(el_count) 153 ]) + ''.join([''' 154 <!ELEMENT el%d EMPTY> 155 ''' % e for e in range(1, el_count) 156 ]) + ''' 157 ''' + '<!ELEMENT el0 (%s)>' % '|'.join([ 158 'el%d' % e for e in range(1, el_count)]) + ''' 159 ]> 160 <el0><el1 %s /></el0> 161 ''' % ' '.join(['attr%d="x"' % a for a in range(attr_count)]))) 162 dtd = etree.ElementTree(root).docinfo.internalDTD 163 self.assertTrue(dtd) 164 dtd.assertValid(root) 165 166 e = -1 167 for e, el in enumerate(dtd.iterelements()): 168 self.assertEqual(attr_count, len(el.attributes())) 169 a = -1 170 for a, attr in enumerate(el.iterattributes()): 171 self.assertEqual('enumeration', attr.type) 172 self.assertEqual('none', attr.default) 173 self.assertEqual('z', attr.default_value) 174 values = sorted(attr.values()) 175 self.assertEqual(['x', 'y', 'z'], values) 176 self.assertEqual(attr_count - 1, a) 177 self.assertEqual(el_count - 1, e) 178 self.assertEqual(el_count, len(dtd.elements()))
179
180 - def test_dtd_broken(self):
181 self.assertRaises(etree.DTDParseError, etree.DTD, 182 BytesIO("<!ELEMENT b HONKEY>"))
183
184 - def test_parse_file_dtd(self):
185 parser = etree.XMLParser(attribute_defaults=True) 186 187 tree = etree.parse(fileInTestDir('test.xml'), parser) 188 root = tree.getroot() 189 190 self.assertEqual( 191 "valueA", 192 root.get("default")) 193 self.assertEqual( 194 "valueB", 195 root[0].get("default"))
196 197 @skipIf(etree.LIBXML_VERSION == (2, 9, 0), 198 "DTD loading is broken for incremental parsing in libxml2 2.9.0")
200 iterparse = etree.iterparse 201 iterator = iterparse(fileInTestDir("test.xml"), events=('start',), 202 attribute_defaults=True) 203 attributes = [ element.get("default") 204 for event, element in iterator ] 205 self.assertEqual( 206 ["valueA", "valueB"], 207 attributes)
208 209 @skipIf(etree.LIBXML_VERSION == (2, 9, 0), 210 "DTD loading is broken for incremental parsing in libxml2 2.9.0")
212 iterparse = etree.iterparse 213 iterator = iterparse(fileInTestDir("test.xml"), events=('end',), 214 attribute_defaults=True) 215 attributes = [ element.get("default") 216 for event, element in iterator ] 217 self.assertEqual( 218 ["valueB", "valueA"], 219 attributes)
220
221 - def test_dtd_attrs(self):
222 dtd = etree.DTD(fileInTestDir("test.dtd")) 223 224 # Test DTD.system_url attribute 225 self.assertTrue(dtd.system_url.endswith("test.dtd")) 226 227 # Test elements and their attributes 228 a = dtd.elements()[0] 229 self.assertEqual(a.name, "a") 230 self.assertEqual(a.type, "element") 231 self.assertEqual(a.content.name, "b") 232 self.assertEqual(a.content.type, "element") 233 self.assertEqual(a.content.occur, "once") 234 235 aattr = a.attributes()[0] 236 self.assertEqual(aattr.name, "default") 237 self.assertEqual(aattr.type, "enumeration") 238 self.assertEqual(aattr.values(), ["valueA", "valueB"]) 239 self.assertEqual(aattr.default_value, "valueA") 240 241 b = dtd.elements()[1] 242 self.assertEqual(b.name, "b") 243 self.assertEqual(b.type, "empty") 244 self.assertEqual(b.content, None) 245 246 # Test entities and their attributes 247 c = dtd.entities()[0] 248 self.assertEqual(c.name, "c") 249 self.assertEqual(c.orig, "&#42;") 250 self.assertEqual(c.content, "*") 251 252 # Test DTD.name attribute 253 root = etree.XML(_bytes(''' 254 <!DOCTYPE a SYSTEM "none" [ 255 <!ELEMENT a EMPTY> 256 ]> 257 <a/> 258 ''')) 259 dtd = etree.ElementTree(root).docinfo.internalDTD 260 self.assertEqual(dtd.name, "a") 261 262 # Test DTD.name and DTD.systemID attributes 263 parser = etree.XMLParser(dtd_validation=True) 264 xml = '<!DOCTYPE a SYSTEM "test.dtd"><a><b/></a>' 265 root = etree.fromstring(xml, parser=parser, 266 base_url=fileInTestDir("test.xml")) 267 268 dtd = root.getroottree().docinfo.internalDTD 269 self.assertEqual(dtd.name, "a") 270 self.assertEqual(dtd.system_url, "test.dtd")
271
272 273 -def test_suite():
274 suite = unittest.TestSuite() 275 suite.addTests([unittest.makeSuite(ETreeDtdTestCase)]) 276 suite.addTests( 277 [make_doctest('../../../doc/validation.txt')]) 278 return suite
279 280 if __name__ == '__main__': 281 print('to test use test.py %s' % __file__) 282