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_escaping(self):
143 with etree.xmlfile(self._file) as xf: 144 with xf.element('test'): 145 xf.write('Comments: <!-- text -->\n') 146 xf.write('Entities: &amp;') 147 self.assertXml( 148 '<test>Comments: &lt;!-- text --&gt;\nEntities: &amp;amp;</test>')
149
150 - def test_encoding(self):
151 with etree.xmlfile(self._file, encoding='utf16') as xf: 152 with xf.element('test'): 153 xf.write('toast') 154 self.assertXml('<test>toast</test>', encoding='utf16')
155
156 - def test_buffering(self):
157 with etree.xmlfile(self._file, buffered=False) as xf: 158 with xf.element('test'): 159 self.assertXml("<test>") 160 xf.write('toast') 161 self.assertXml("<test>toast") 162 with xf.element('taste'): 163 self.assertXml("<test>toast<taste>") 164 xf.write('some', etree.Element("more"), "toast") 165 self.assertXml("<test>toast<taste>some<more/>toast") 166 self.assertXml("<test>toast<taste>some<more/>toast</taste>") 167 xf.write('end') 168 self.assertXml("<test>toast<taste>some<more/>toast</taste>end") 169 self.assertXml("<test>toast<taste>some<more/>toast</taste>end</test>") 170 self.assertXml("<test>toast<taste>some<more/>toast</taste>end</test>")
171
172 - def test_flush(self):
173 with etree.xmlfile(self._file, buffered=True) as xf: 174 with xf.element('test'): 175 self.assertXml("") 176 xf.write('toast') 177 self.assertXml("") 178 with xf.element('taste'): 179 self.assertXml("") 180 xf.flush() 181 self.assertXml("<test>toast<taste>") 182 self.assertXml("<test>toast<taste>") 183 self.assertXml("<test>toast<taste>") 184 self.assertXml("<test>toast<taste></taste></test>")
185
187 try: 188 with etree.xmlfile(self._file) as xf: 189 xf.write('toast') 190 except etree.LxmlSyntaxError: 191 self.assertTrue(True) 192 else: 193 self.assertTrue(False)
194
196 with etree.xmlfile(self._file) as xf: 197 with xf.element('test'): 198 pass 199 try: 200 xf.write('toast') 201 except etree.LxmlSyntaxError: 202 self.assertTrue(True) 203 else: 204 self.assertTrue(False)
205
207 with etree.xmlfile(self._file) as xf: 208 with xf.element('test'): 209 pass 210 try: 211 xf.write(etree.Element('test')) 212 except etree.LxmlSyntaxError: 213 self.assertTrue(True) 214 else: 215 self.assertTrue(False)
216
218 cm_exit = None 219 try: 220 with etree.xmlfile(self._file) as xf: 221 x = xf.element('test') 222 cm_exit = x.__exit__ 223 x.__enter__() 224 raise ValueError('123') 225 except ValueError: 226 self.assertTrue(cm_exit) 227 try: 228 cm_exit(ValueError, ValueError("huhu"), None) 229 except etree.LxmlSyntaxError: 230 self.assertTrue(True) 231 else: 232 self.assertTrue(False) 233 else: 234 self.assertTrue(False)
235
236 - def _read_file(self):
237 pos = self._file.tell() 238 self._file.seek(0) 239 try: 240 return self._file.read() 241 finally: 242 self._file.seek(pos)
243
244 - def _parse_file(self):
245 pos = self._file.tell() 246 self._file.seek(0) 247 try: 248 return etree.parse(self._file) 249 finally: 250 self._file.seek(pos)
251
252 - def tearDown(self):
253 if self._file is not None: 254 self._file.close()
255
256 - def assertXml(self, expected, encoding='utf8'):
257 self.assertEqual(self._read_file().decode(encoding), expected)
258
259 260 -class BytesIOXmlFileTestCase(_XmlFileTestCaseBase):
261 - def setUp(self):
262 self._file = BytesIO()
263
264 - def test_filelike_close(self):
265 with etree.xmlfile(self._file, close=True) as xf: 266 with xf.element('test'): 267 pass 268 self.assertRaises(ValueError, self._file.getvalue)
269
270 271 -class TempXmlFileTestCase(_XmlFileTestCaseBase):
272 - def setUp(self):
273 self._file = tempfile.TemporaryFile()
274
275 276 -class TempPathXmlFileTestCase(_XmlFileTestCaseBase):
277 - def setUp(self):
278 self._tmpfile = tempfile.NamedTemporaryFile() 279 self._file = self._tmpfile.name
280
281 - def tearDown(self):
282 try: 283 self._tmpfile.close() 284 finally: 285 if os.path.exists(self._tmpfile.name): 286 os.unlink(self._tmpfile.name)
287
288 - def _read_file(self):
289 self._tmpfile.seek(0) 290 return self._tmpfile.read()
291
292 - def _parse_file(self):
293 self._tmpfile.seek(0) 294 return etree.parse(self._tmpfile)
295 296 @skipIf(True, "temp file behaviour is too platform specific here")
297 - def test_buffering(self):
298 pass
299 300 @skipIf(True, "temp file behaviour is too platform specific here")
301 - def test_flush(self):
302 pass
303
304 305 -class SimpleFileLikeXmlFileTestCase(_XmlFileTestCaseBase):
306 - class SimpleFileLike(object):
307 - def __init__(self, target):
308 self._target = target 309 self.write = target.write 310 self.tell = target.tell 311 self.seek = target.seek 312 self.closed = False
313
314 - def close(self):
315 assert not self.closed 316 self.closed = True 317 self._target.close()
318
319 - def setUp(self):
320 self._target = BytesIO() 321 self._file = self.SimpleFileLike(self._target)
322
323 - def _read_file(self):
324 return self._target.getvalue()
325
326 - def _parse_file(self):
327 pos = self._file.tell() 328 self._target.seek(0) 329 try: 330 return etree.parse(self._target) 331 finally: 332 self._target.seek(pos)
333
335 with etree.xmlfile(self._file) as xf: 336 with xf.element('test'): 337 pass 338 self.assertFalse(self._file.closed)
339
340 - def test_filelike_close(self):
341 with etree.xmlfile(self._file, close=True) as xf: 342 with xf.element('test'): 343 pass 344 self.assertTrue(self._file.closed) 345 self._file = None # prevent closing in tearDown()
346
347 348 -class HtmlFileTestCase(_XmlFileTestCaseBase):
349 - def setUp(self):
350 self._file = BytesIO()
351
352 - def test_void_elements(self):
353 # http://www.w3.org/TR/html5/syntax.html#elements-0 354 void_elements = set([ 355 "area", "base", "br", "col", "embed", "hr", "img", 356 "input", "keygen", "link", "meta", "param", 357 "source", "track", "wbr" 358 ]) 359 360 # FIXME: These don't get serialized as void elements. 361 void_elements.difference_update([ 362 'area', 'embed', 'keygen', 'source', 'track', 'wbr' 363 ]) 364 365 for tag in sorted(void_elements): 366 with etree.htmlfile(self._file) as xf: 367 xf.write(etree.Element(tag)) 368 self.assertXml('<%s>' % tag) 369 self._file = BytesIO()
370
371 - def test_write_declaration(self):
372 with etree.htmlfile(self._file) as xf: 373 try: 374 xf.write_declaration() 375 except etree.LxmlSyntaxError: 376 self.assertTrue(True) 377 else: 378 self.assertTrue(False) 379 xf.write(etree.Element('html'))
380
382 with etree.htmlfile(self._file) as xf: 383 xf.write(etree.Element('{some_ns}some_tag')) 384 self.assertXml('<ns0:some_tag xmlns:ns0="some_ns"></ns0:some_tag>')
385
387 with etree.htmlfile(self._file) as xf: 388 with xf.element("{some_ns}some_tag"): 389 pass 390 self.assertXml('<ns0:some_tag xmlns:ns0="some_ns"></ns0:some_tag>')
391
392 393 -def test_suite():
394 suite = unittest.TestSuite() 395 suite.addTests([unittest.makeSuite(BytesIOXmlFileTestCase), 396 unittest.makeSuite(TempXmlFileTestCase), 397 unittest.makeSuite(TempPathXmlFileTestCase), 398 unittest.makeSuite(SimpleFileLikeXmlFileTestCase), 399 unittest.makeSuite(HtmlFileTestCase), 400 ]) 401 return suite
402 403 if __name__ == '__main__': 404 print('to test use test.py %s' % __file__) 405