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