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

Source Code for Module lxml.tests.test_incremental_xmlfile

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Tests for the incremental XML serialisation API. 
  5   
  6  Tests require Python 2.5 or later. 
  7  """ 
  8   
  9  from __future__ import with_statement 
 10   
 11  import unittest 
 12  import tempfile, os, sys 
 13   
 14  this_dir = os.path.dirname(__file__) 
 15  if this_dir not in sys.path: 
 16      sys.path.insert(0, this_dir) # needed for Py3 
 17   
 18  from common_imports import etree, BytesIO, HelperTestCase, skipIf 
19 20 -class _XmlFileTestCaseBase(HelperTestCase):
21 _file = None # to be set by specific subtypes below 22
23 - def test_element(self):
24 with etree.xmlfile(self._file) as xf: 25 with xf.element('test'): 26 pass 27 self.assertXml('<test></test>')
28
29 - def test_element_write_text(self):
30 with etree.xmlfile(self._file) as xf: 31 with xf.element('test'): 32 xf.write('toast') 33 self.assertXml('<test>toast</test>')
34
35 - def test_element_nested(self):
36 with etree.xmlfile(self._file) as xf: 37 with xf.element('test'): 38 with xf.element('toast'): 39 with xf.element('taste'): 40 xf.write('conTent') 41 self.assertXml('<test><toast><taste>conTent</taste></toast></test>')
42
44 with etree.xmlfile(self._file) as xf: 45 with xf.element('test'): 46 xf.write('con') 47 with xf.element('toast'): 48 xf.write('tent') 49 with xf.element('taste'): 50 xf.write('inside') 51 xf.write('tnet') 52 xf.write('noc') 53 self.assertXml('<test>con<toast>tent<taste>inside</taste>' 54 'tnet</toast>noc</test>')
55
56 - def test_write_Element(self):
57 with etree.xmlfile(self._file) as xf: 58 xf.write(etree.Element('test')) 59 self.assertXml('<test/>')
60
62 element = etree.Element('test') 63 with etree.xmlfile(self._file) as xf: 64 with xf.element('test'): 65 for i in range(100): 66 xf.write(element) 67 68 tree = self._parse_file() 69 self.assertTrue(tree is not None) 70 self.assertEqual(100, len(tree.getroot())) 71 self.assertEqual(set(['test']), set(el.tag for el in tree.getroot()))
72
73 - def test_namespace_nsmap(self):
74 with etree.xmlfile(self._file) as xf: 75 with xf.element('{nsURI}test', nsmap={'x': 'nsURI'}): 76 pass 77 self.assertXml('<x:test xmlns:x="nsURI"></x:test>')
78
80 with etree.xmlfile(self._file) as xf: 81 with xf.element('test', nsmap={'x': 'nsURI'}): 82 with xf.element('{nsURI}toast'): 83 pass 84 self.assertXml('<test xmlns:x="nsURI"><x:toast></x:toast></test>')
85
86 - def test_anonymous_namespace(self):
87 with etree.xmlfile(self._file) as xf: 88 with xf.element('{nsURI}test'): 89 pass 90 self.assertXml('<ns0:test xmlns:ns0="nsURI"></ns0:test>')
91
93 with etree.xmlfile(self._file) as xf: 94 with xf.element('test'): 95 with xf.element('{nsURI}toast'): 96 pass 97 self.assertXml('<test><ns0:toast xmlns:ns0="nsURI"></ns0:toast></test>')
98
99 - def test_default_namespace(self):
100 with etree.xmlfile(self._file) as xf: 101 with xf.element('{nsURI}test', nsmap={None: 'nsURI'}): 102 pass 103 self.assertXml('<test xmlns="nsURI"></test>')
104
106 with etree.xmlfile(self._file) as xf: 107 with xf.element('{nsURI}test', nsmap={None: 'nsURI'}): 108 with xf.element('{nsURI}toast'): 109 pass 110 self.assertXml('<test xmlns="nsURI"><toast></toast></test>')
111
113 with etree.xmlfile(self._file) as xf: 114 with xf.element('{nsURI}test', nsmap={None: 'nsURI', 'p': 'ns2'}): 115 with xf.element('{nsURI}toast'): 116 pass 117 with xf.element('{ns2}toast'): 118 pass 119 self.assertXml( 120 '<test xmlns="nsURI" xmlns:p="ns2"><toast></toast><p:toast></p:toast></test>')
121
122 - def test_pi(self):
123 with etree.xmlfile(self._file) as xf: 124 xf.write(etree.ProcessingInstruction('pypi')) 125 with xf.element('test'): 126 pass 127 self.assertXml('<?pypi ?><test></test>')
128
129 - def test_comment(self):
130 with etree.xmlfile(self._file) as xf: 131 xf.write(etree.Comment('a comment')) 132 with xf.element('test'): 133 pass 134 self.assertXml('<!--a comment--><test></test>')
135
136 - def test_attribute(self):
137 with etree.xmlfile(self._file) as xf: 138 with xf.element('test', attrib={'k': 'v'}): 139 pass 140 self.assertXml('<test k="v"></test>')
141
142 - def test_attribute_extra(self):
143 with etree.xmlfile(self._file) as xf: 144 with xf.element('test', attrib={'k': 'v'}, n='N'): 145 pass 146 self.assertXml('<test k="v" n="N"></test>')
147
149 with etree.xmlfile(self._file) as xf: 150 with xf.element('test', attrib={'k': 'v'}, k='V'): 151 pass 152 self.assertXml('<test k="V"></test>')
153
154 - def test_escaping(self):
155 with etree.xmlfile(self._file) as xf: 156 with xf.element('test'): 157 xf.write('Comments: <!-- text -->\n') 158 xf.write('Entities: &amp;') 159 self.assertXml( 160 '<test>Comments: &lt;!-- text --&gt;\nEntities: &amp;amp;</test>')
161
162 - def test_encoding(self):
163 with etree.xmlfile(self._file, encoding='utf16') as xf: 164 with xf.element('test'): 165 xf.write('toast') 166 self.assertXml('<test>toast</test>', encoding='utf16')
167
168 - def test_buffering(self):
169 with etree.xmlfile(self._file, buffered=False) as xf: 170 with xf.element('test'): 171 self.assertXml("<test>") 172 xf.write('toast') 173 self.assertXml("<test>toast") 174 with xf.element('taste'): 175 self.assertXml("<test>toast<taste>") 176 xf.write('some', etree.Element("more"), "toast") 177 self.assertXml("<test>toast<taste>some<more/>toast") 178 self.assertXml("<test>toast<taste>some<more/>toast</taste>") 179 xf.write('end') 180 self.assertXml("<test>toast<taste>some<more/>toast</taste>end") 181 self.assertXml("<test>toast<taste>some<more/>toast</taste>end</test>") 182 self.assertXml("<test>toast<taste>some<more/>toast</taste>end</test>")
183
184 - def test_flush(self):
185 with etree.xmlfile(self._file, buffered=True) as xf: 186 with xf.element('test'): 187 self.assertXml("") 188 xf.write('toast') 189 self.assertXml("") 190 with xf.element('taste'): 191 self.assertXml("") 192 xf.flush() 193 self.assertXml("<test>toast<taste>") 194 self.assertXml("<test>toast<taste>") 195 self.assertXml("<test>toast<taste>") 196 self.assertXml("<test>toast<taste></taste></test>")
197
199 try: 200 with etree.xmlfile(self._file) as xf: 201 xf.write('toast') 202 except etree.LxmlSyntaxError: 203 self.assertTrue(True) 204 else: 205 self.assertTrue(False)
206
208 with etree.xmlfile(self._file) as xf: 209 with xf.element('test'): 210 pass 211 try: 212 xf.write('toast') 213 except etree.LxmlSyntaxError: 214 self.assertTrue(True) 215 else: 216 self.assertTrue(False)
217
219 with etree.xmlfile(self._file) as xf: 220 with xf.element('test'): 221 pass 222 try: 223 xf.write(etree.Element('test')) 224 except etree.LxmlSyntaxError: 225 self.assertTrue(True) 226 else: 227 self.assertTrue(False)
228
230 cm_exit = None 231 try: 232 with etree.xmlfile(self._file) as xf: 233 x = xf.element('test') 234 cm_exit = x.__exit__ 235 x.__enter__() 236 raise ValueError('123') 237 except ValueError: 238 self.assertTrue(cm_exit) 239 try: 240 cm_exit(ValueError, ValueError("huhu"), None) 241 except etree.LxmlSyntaxError: 242 self.assertTrue(True) 243 else: 244 self.assertTrue(False) 245 else: 246 self.assertTrue(False)
247
248 - def _read_file(self):
249 pos = self._file.tell() 250 self._file.seek(0) 251 try: 252 return self._file.read() 253 finally: 254 self._file.seek(pos)
255
256 - def _parse_file(self):
257 pos = self._file.tell() 258 self._file.seek(0) 259 try: 260 return etree.parse(self._file) 261 finally: 262 self._file.seek(pos)
263
264 - def tearDown(self):
265 if self._file is not None: 266 self._file.close()
267
268 - def assertXml(self, expected, encoding='utf8'):
269 self.assertEqual(self._read_file().decode(encoding), expected)
270
271 272 -class BytesIOXmlFileTestCase(_XmlFileTestCaseBase):
273 - def setUp(self):
274 self._file = BytesIO()
275
276 - def test_filelike_close(self):
277 with etree.xmlfile(self._file, close=True) as xf: 278 with xf.element('test'): 279 pass 280 self.assertRaises(ValueError, self._file.getvalue)
281
282 283 -class TempXmlFileTestCase(_XmlFileTestCaseBase):
284 - def setUp(self):
285 self._file = tempfile.TemporaryFile()
286
287 288 -class TempPathXmlFileTestCase(_XmlFileTestCaseBase):
289 - def setUp(self):
290 self._tmpfile = tempfile.NamedTemporaryFile() 291 self._file = self._tmpfile.name
292
293 - def tearDown(self):
294 try: 295 self._tmpfile.close() 296 finally: 297 if os.path.exists(self._tmpfile.name): 298 os.unlink(self._tmpfile.name)
299
300 - def _read_file(self):
301 self._tmpfile.seek(0) 302 return self._tmpfile.read()
303
304 - def _parse_file(self):
305 self._tmpfile.seek(0) 306 return etree.parse(self._tmpfile)
307 308 @skipIf(True, "temp file behaviour is too platform specific here")
309 - def test_buffering(self):
310 pass
311 312 @skipIf(True, "temp file behaviour is too platform specific here")
313 - def test_flush(self):
314 pass
315
316 317 -class SimpleFileLikeXmlFileTestCase(_XmlFileTestCaseBase):
318 - class SimpleFileLike(object):
319 - def __init__(self, target):
320 self._target = target 321 self.write = target.write 322 self.tell = target.tell 323 self.seek = target.seek 324 self.closed = False
325
326 - def close(self):
327 assert not self.closed 328 self.closed = True 329 self._target.close()
330
331 - def setUp(self):
332 self._target = BytesIO() 333 self._file = self.SimpleFileLike(self._target)
334
335 - def _read_file(self):
336 return self._target.getvalue()
337
338 - def _parse_file(self):
339 pos = self._file.tell() 340 self._target.seek(0) 341 try: 342 return etree.parse(self._target) 343 finally: 344 self._target.seek(pos)
345
347 with etree.xmlfile(self._file) as xf: 348 with xf.element('test'): 349 pass 350 self.assertFalse(self._file.closed)
351
352 - def test_filelike_close(self):
353 with etree.xmlfile(self._file, close=True) as xf: 354 with xf.element('test'): 355 pass 356 self.assertTrue(self._file.closed) 357 self._file = None # prevent closing in tearDown()
358
359 360 -class HtmlFileTestCase(_XmlFileTestCaseBase):
361 - def setUp(self):
362 self._file = BytesIO()
363
364 - def test_void_elements(self):
365 # http://www.w3.org/TR/html5/syntax.html#elements-0 366 void_elements = set([ 367 "area", "base", "br", "col", "embed", "hr", "img", 368 "input", "keygen", "link", "meta", "param", 369 "source", "track", "wbr" 370 ]) 371 372 # FIXME: These don't get serialized as void elements. 373 void_elements.difference_update([ 374 'area', 'embed', 'keygen', 'source', 'track', 'wbr' 375 ]) 376 377 for tag in sorted(void_elements): 378 with etree.htmlfile(self._file) as xf: 379 xf.write(etree.Element(tag)) 380 self.assertXml('<%s>' % tag) 381 self._file = BytesIO()
382
383 - def test_write_declaration(self):
384 with etree.htmlfile(self._file) as xf: 385 try: 386 xf.write_declaration() 387 except etree.LxmlSyntaxError: 388 self.assertTrue(True) 389 else: 390 self.assertTrue(False) 391 xf.write(etree.Element('html'))
392
394 with etree.htmlfile(self._file) as xf: 395 xf.write(etree.Element('{some_ns}some_tag')) 396 self.assertXml('<ns0:some_tag xmlns:ns0="some_ns"></ns0:some_tag>')
397
399 with etree.htmlfile(self._file) as xf: 400 with xf.element("{some_ns}some_tag"): 401 pass 402 self.assertXml('<ns0:some_tag xmlns:ns0="some_ns"></ns0:some_tag>')
403
404 405 -def test_suite():
406 suite = unittest.TestSuite() 407 suite.addTests([unittest.makeSuite(BytesIOXmlFileTestCase), 408 unittest.makeSuite(TempXmlFileTestCase), 409 unittest.makeSuite(TempPathXmlFileTestCase), 410 unittest.makeSuite(SimpleFileLikeXmlFileTestCase), 411 unittest.makeSuite(HtmlFileTestCase), 412 ]) 413 return suite
414 415 if __name__ == '__main__': 416 print('to test use test.py %s' % __file__) 417