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

Source Code for Module lxml.tests.test_etree

   1  # -*- coding: utf-8 -*- 
   2   
   3  """ 
   4  Tests specific to the extended etree API 
   5   
   6  Tests that apply to the general ElementTree API should go into 
   7  test_elementtree 
   8  """ 
   9   
  10   
  11  import unittest, copy, sys 
  12   
  13  from common_imports import etree, StringIO, HelperTestCase, fileInTestDir 
  14  from common_imports import SillyFileLike, canonicalize, doctest 
  15   
  16  print 
  17  print "TESTED VERSION:", etree.__version__ 
  18  print "    Python:           ", sys.version_info 
  19  print "    lxml.etree:       ", etree.LXML_VERSION 
  20  print "    libxml used:      ", etree.LIBXML_VERSION 
  21  print "    libxml compiled:  ", etree.LIBXML_COMPILED_VERSION 
  22  print "    libxslt used:     ", etree.LIBXSLT_VERSION 
  23  print "    libxslt compiled: ", etree.LIBXSLT_COMPILED_VERSION 
  24  print 
  25   
  26  try: 
  27      sorted 
  28  except NameError: 
  29      # Python 2.3 
30 - def sorted(seq):
31 seq = list(seq) 32 seq.sort() 33 return seq
34
35 -class ETreeOnlyTestCase(HelperTestCase):
36 """Tests only for etree, not ElementTree""" 37 etree = etree 38
39 - def test_version(self):
40 self.assert_(isinstance(etree.__version__, str)) 41 self.assert_(isinstance(etree.LXML_VERSION, tuple)) 42 self.assertEqual(len(etree.LXML_VERSION), 4) 43 self.assert_(isinstance(etree.LXML_VERSION[0], int)) 44 self.assert_(isinstance(etree.LXML_VERSION[1], int)) 45 self.assert_(isinstance(etree.LXML_VERSION[2], int)) 46 self.assert_(isinstance(etree.LXML_VERSION[3], int)) 47 self.assert_(etree.__version__.startswith( 48 str(etree.LXML_VERSION[0])))
49
50 - def test_c_api(self):
51 self.assert_(hasattr(self.etree, '_import_c_api'))
52
53 - def test_element_names(self):
54 Element = self.etree.Element 55 el = Element('name') 56 self.assertEquals(el.tag, 'name') 57 el = Element('{}name') 58 self.assertEquals(el.tag, 'name')
59
60 - def test_element_name_empty(self):
61 Element = self.etree.Element 62 el = Element('name') 63 self.assertRaises(ValueError, Element, '{}') 64 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 65 66 self.assertRaises(ValueError, Element, '{test}') 67 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
68
69 - def test_element_name_colon(self):
70 Element = self.etree.Element 71 self.assertRaises(ValueError, Element, 'p:name') 72 self.assertRaises(ValueError, Element, '{test}p:name') 73 74 el = Element('name') 75 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
76
77 - def test_element_name_space(self):
78 Element = self.etree.Element 79 self.assertRaises(ValueError, Element, ' name ') 80 self.assertRaises(ValueError, Element, 'na me') 81 self.assertRaises(ValueError, Element, '{test} name') 82 83 el = Element('name') 84 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
85
87 Element = self.etree.Element 88 SubElement = self.etree.SubElement 89 90 el = Element('name') 91 self.assertRaises(ValueError, SubElement, el, '{}') 92 self.assertRaises(ValueError, SubElement, el, '{test}')
93
95 Element = self.etree.Element 96 SubElement = self.etree.SubElement 97 98 el = Element('name') 99 self.assertRaises(ValueError, SubElement, el, 'p:name') 100 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
101
102 - def test_subelement_name_space(self):
103 Element = self.etree.Element 104 SubElement = self.etree.SubElement 105 106 el = Element('name') 107 self.assertRaises(ValueError, SubElement, el, ' name ') 108 self.assertRaises(ValueError, SubElement, el, 'na me') 109 self.assertRaises(ValueError, SubElement, el, '{test} name')
110
111 - def test_qname_empty(self):
112 QName = self.etree.QName 113 self.assertRaises(ValueError, QName, '') 114 self.assertRaises(ValueError, QName, 'test', '')
115
116 - def test_qname_colon(self):
117 QName = self.etree.QName 118 self.assertRaises(ValueError, QName, 'p:name') 119 self.assertRaises(ValueError, QName, 'test', 'p:name')
120
121 - def test_qname_space(self):
122 QName = self.etree.QName 123 self.assertRaises(ValueError, QName, ' name ') 124 self.assertRaises(ValueError, QName, 'na me') 125 self.assertRaises(ValueError, QName, 'test', ' name')
126
127 - def test_qname_text_resolve(self):
128 # ET doesn't resove QNames as text values 129 etree = self.etree 130 qname = etree.QName('http://myns', 'a') 131 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 132 a.text = qname 133 134 self.assertEquals("p:a", a.text)
135
136 - def test_attribute_set(self):
137 Element = self.etree.Element 138 root = Element("root") 139 root.set("attr", "TEST") 140 self.assertEquals("TEST", root.get("attr"))
141
142 - def test_attribute_set_invalid(self):
143 # ElementTree accepts arbitrary attribute values 144 # lxml.etree allows only strings 145 Element = self.etree.Element 146 root = Element("root") 147 self.assertRaises(TypeError, root.set, "newattr", 5) 148 self.assertRaises(TypeError, root.set, "newattr", None)
149
150 - def test_attrib_pop(self):
151 ElementTree = self.etree.ElementTree 152 153 f = StringIO('<doc one="One" two="Two"/>') 154 doc = ElementTree(file=f) 155 root = doc.getroot() 156 self.assertEquals('One', root.attrib['one']) 157 self.assertEquals('Two', root.attrib['two']) 158 159 self.assertEquals('One', root.attrib.pop('one')) 160 161 self.assertEquals(None, root.attrib.get('one')) 162 self.assertEquals('Two', root.attrib['two'])
163
164 - def test_attrib_pop_unknown(self):
165 root = self.etree.XML('<doc one="One" two="Two"/>') 166 self.assertRaises(KeyError, root.attrib.pop, 'NONE') 167 168 self.assertEquals('One', root.attrib['one']) 169 self.assertEquals('Two', root.attrib['two'])
170
171 - def test_attrib_pop_default(self):
172 root = self.etree.XML('<doc one="One" two="Two"/>') 173 self.assertEquals('Three', root.attrib.pop('three', 'Three'))
174
176 root = self.etree.XML('<doc/>') 177 self.assertEquals('Three', root.attrib.pop('three', 'Three'))
178
180 root = self.etree.XML('<doc one="One" two="Two"/>') 181 self.assertRaises(TypeError, root.attrib.pop, 'One', None, None)
182
183 - def test_pi(self):
184 # lxml.etree separates target and text 185 Element = self.etree.Element 186 SubElement = self.etree.SubElement 187 ProcessingInstruction = self.etree.ProcessingInstruction 188 189 a = Element('a') 190 a.append(ProcessingInstruction('foo', 'some more text')) 191 self.assertEquals(a[0].target, 'foo') 192 self.assertEquals(a[0].text, 'some more text')
193
194 - def test_pi_parse(self):
195 XML = self.etree.XML 196 root = XML("<test><?mypi my test ?></test>") 197 self.assertEquals(root[0].target, "mypi") 198 self.assertEquals(root[0].text, "my test ")
199
200 - def test_deepcopy_pi(self):
201 # previously caused a crash 202 ProcessingInstruction = self.etree.ProcessingInstruction 203 204 a = ProcessingInstruction("PI", "ONE") 205 b = copy.deepcopy(a) 206 b.text = "ANOTHER" 207 208 self.assertEquals('ONE', a.text) 209 self.assertEquals('ANOTHER', b.text)
210
211 - def test_deepcopy_comment(self):
212 # previously caused a crash 213 # not supported by ET! 214 Comment = self.etree.Comment 215 216 a = Comment("ONE") 217 b = copy.deepcopy(a) 218 b.text = "ANOTHER" 219 220 self.assertEquals('ONE', a.text) 221 self.assertEquals('ANOTHER', b.text)
222
223 - def test_attribute_set(self):
224 # ElementTree accepts arbitrary attribute values 225 # lxml.etree allows only strings 226 Element = self.etree.Element 227 228 root = Element("root") 229 root.set("attr", "TEST") 230 self.assertEquals("TEST", root.get("attr")) 231 self.assertRaises(TypeError, root.set, "newattr", 5)
232
233 - def test_parse_error(self):
234 # ET raises ExpatError 235 parse = self.etree.parse 236 # from StringIO 237 f = StringIO('<a><b></c></b></a>') 238 self.assertRaises(SyntaxError, parse, f) 239 f.close()
240
241 - def test_parse_remove_comments(self):
242 parse = self.etree.parse 243 tostring = self.etree.tostring 244 XMLParser = self.etree.XMLParser 245 246 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 247 parser = XMLParser(remove_comments=True) 248 tree = parse(f, parser) 249 self.assertEquals( 250 '<a><b><c/></b></a>', 251 tostring(tree))
252
253 - def test_parse_remove_pis(self):
254 parse = self.etree.parse 255 tostring = self.etree.tostring 256 XMLParser = self.etree.XMLParser 257 258 xml = '<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>' 259 260 f = StringIO(xml) 261 tree = parse(f) 262 self.assertEquals( 263 xml, 264 tostring(tree)) 265 266 f = StringIO(xml) 267 parser = XMLParser(remove_pis=True) 268 tree = parse(f, parser) 269 self.assertEquals( 270 '<a><b><c/></b></a>', 271 tostring(tree))
272
274 # ET raises IOError only 275 parse = self.etree.parse 276 self.assertRaises(TypeError, parse, 'notthere.xml', object())
277
278 - def test_parse_error_logging(self):
279 parse = self.etree.parse 280 # from StringIO 281 f = StringIO('<a><b></c></b></a>') 282 self.etree.clearErrorLog() 283 try: 284 parse(f) 285 logs = None 286 except SyntaxError, e: 287 logs = e.error_log 288 f.close() 289 self.assert_([ log for log in logs 290 if 'mismatch' in log.message ]) 291 self.assert_([ log for log in logs 292 if 'PARSER' in log.domain_name]) 293 self.assert_([ log for log in logs 294 if 'TAG_NAME_MISMATCH' in log.type_name ]) 295 self.assert_([ log for log in logs 296 if 1 == log.line ]) 297 self.assert_([ log for log in logs 298 if 15 == log.column ])
299
300 - def test_parse_error_from_file(self):
301 parse = self.etree.parse 302 # from file 303 f = open(fileInTestDir('test_broken.xml'), 'r') 304 self.assertRaises(SyntaxError, parse, f) 305 f.close()
306
307 - def test_iterparse_comments(self):
308 # ET removes comments 309 iterparse = self.etree.iterparse 310 tostring = self.etree.tostring 311 312 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 313 events = list(iterparse(f)) 314 root = events[-1][1] 315 self.assertEquals(3, len(events)) 316 self.assertEquals( 317 '<a><!--A--><b><!-- B --><c/></b><!--C--></a>', 318 tostring(root))
319
321 iterparse = self.etree.iterparse 322 tostring = self.etree.tostring 323 324 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 325 events = list(iterparse(f, remove_comments=True)) 326 root = events[-1][1] 327 self.assertEquals( 328 '<a><b><c/></b></a>', 329 tostring(root))
330
331 - def test_iterparse_broken(self):
332 iterparse = self.etree.iterparse 333 f = StringIO('<a><b><c/></a>') 334 # ET raises ExpatError, lxml raises XMLSyntaxError 335 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
336
337 - def test_iterparse_strip(self):
338 iterparse = self.etree.iterparse 339 f = StringIO(""" 340 <a> \n \n <b> b test </b> \n 341 342 \n\t <c> \n </c> </a> \n """) 343 iterator = iterparse(f, remove_blank_text=True) 344 text = [ (element.text, element.tail) 345 for event, element in iterator ] 346 self.assertEquals( 347 [(" b test ", None), (" \n ", None), (None, None)], 348 text)
349
350 - def test_iterparse_tag(self):
351 iterparse = self.etree.iterparse 352 f = StringIO('<a><b><d/></b><c/></a>') 353 354 iterator = iterparse(f, tag="b", events=('start', 'end')) 355 events = list(iterator) 356 root = iterator.root 357 self.assertEquals( 358 [('start', root[0]), ('end', root[0])], 359 events)
360
361 - def test_iterparse_tag_all(self):
362 iterparse = self.etree.iterparse 363 f = StringIO('<a><b><d/></b><c/></a>') 364 365 iterator = iterparse(f, tag="*", events=('start', 'end')) 366 events = list(iterator) 367 self.assertEquals( 368 8, 369 len(events))
370
371 - def test_iterwalk_tag(self):
372 iterwalk = self.etree.iterwalk 373 root = self.etree.XML('<a><b><d/></b><c/></a>') 374 375 iterator = iterwalk(root, tag="b", events=('start', 'end')) 376 events = list(iterator) 377 self.assertEquals( 378 [('start', root[0]), ('end', root[0])], 379 events)
380
381 - def test_iterwalk_tag_all(self):
382 iterwalk = self.etree.iterwalk 383 root = self.etree.XML('<a><b><d/></b><c/></a>') 384 385 iterator = iterwalk(root, tag="*", events=('start', 'end')) 386 events = list(iterator) 387 self.assertEquals( 388 8, 389 len(events))
390
391 - def test_iterwalk(self):
392 iterwalk = self.etree.iterwalk 393 root = self.etree.XML('<a><b></b><c/></a>') 394 395 events = list(iterwalk(root)) 396 self.assertEquals( 397 [('end', root[0]), ('end', root[1]), ('end', root)], 398 events)
399
400 - def test_iterwalk_start(self):
401 iterwalk = self.etree.iterwalk 402 root = self.etree.XML('<a><b></b><c/></a>') 403 404 iterator = iterwalk(root, events=('start',)) 405 events = list(iterator) 406 self.assertEquals( 407 [('start', root), ('start', root[0]), ('start', root[1])], 408 events)
409
410 - def test_iterwalk_start_end(self):
411 iterwalk = self.etree.iterwalk 412 root = self.etree.XML('<a><b></b><c/></a>') 413 414 iterator = iterwalk(root, events=('start','end')) 415 events = list(iterator) 416 self.assertEquals( 417 [('start', root), ('start', root[0]), ('end', root[0]), 418 ('start', root[1]), ('end', root[1]), ('end', root)], 419 events)
420
421 - def test_iterwalk_clear(self):
422 iterwalk = self.etree.iterwalk 423 root = self.etree.XML('<a><b></b><c/></a>') 424 425 iterator = iterwalk(root) 426 for event, elem in iterator: 427 elem.clear() 428 429 self.assertEquals(0, 430 len(root))
431
432 - def test_iterwalk_attrib_ns(self):
433 iterwalk = self.etree.iterwalk 434 root = self.etree.XML('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>') 435 436 attr_name = '{testns}bla' 437 events = [] 438 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 439 for event, elem in iterator: 440 events.append(event) 441 if event == 'start': 442 if elem.tag != '{ns1}a': 443 elem.set(attr_name, 'value') 444 445 self.assertEquals( 446 ['start-ns', 'start', 'start', 'start-ns', 'start', 447 'end', 'end-ns', 'end', 'end', 'end-ns'], 448 events) 449 450 self.assertEquals( 451 None, 452 root.get(attr_name)) 453 self.assertEquals( 454 'value', 455 root[0].get(attr_name))
456
457 - def test_iterwalk_getiterator(self):
458 iterwalk = self.etree.iterwalk 459 root = self.etree.XML('<a><b><d/></b><c/></a>') 460 461 counts = [] 462 for event, elem in iterwalk(root): 463 counts.append(len(list(elem.getiterator()))) 464 self.assertEquals( 465 [1,2,1,4], 466 counts)
467
468 - def test_resolve_string_dtd(self):
469 parse = self.etree.parse 470 parser = self.etree.XMLParser(dtd_validation=True) 471 assertEqual = self.assertEqual 472 test_url = u"__nosuch.dtd" 473 474 class MyResolver(self.etree.Resolver): 475 def resolve(self, url, id, context): 476 assertEqual(url, test_url) 477 return self.resolve_string( 478 u'''<!ENTITY myentity "%s"> 479 <!ELEMENT doc ANY>''' % url, context)
480 481 parser.resolvers.add(MyResolver()) 482 483 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url 484 tree = parse(StringIO(xml), parser) 485 root = tree.getroot() 486 self.assertEquals(root.text, test_url) 487
488 - def test_resolve_empty(self):
489 parse = self.etree.parse 490 parser = self.etree.XMLParser(load_dtd=True) 491 assertEqual = self.assertEqual 492 test_url = u"__nosuch.dtd" 493 494 class check(object): 495 resolved = False
496 497 class MyResolver(self.etree.Resolver): 498 def resolve(self, url, id, context): 499 assertEqual(url, test_url) 500 check.resolved = True 501 return self.resolve_empty(context) 502 503 parser.resolvers.add(MyResolver()) 504 505 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url 506 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 507 self.assert_(check.resolved) 508
509 - def test_resolve_error(self):
510 parse = self.etree.parse 511 parser = self.etree.XMLParser(dtd_validation=True) 512 test_url = u"__nosuch.dtd" 513 514 class _LocalException(Exception): 515 pass
516 517 class MyResolver(self.etree.Resolver): 518 def resolve(self, url, id, context): 519 raise _LocalException 520 521 parser.resolvers.add(MyResolver()) 522 523 xml = u'<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 524 self.assertRaises(_LocalException, parse, StringIO(xml), parser) 525 526 if etree.LIBXML_VERSION > (2,6,20):
527 - def test_entity_parse(self):
528 parse = self.etree.parse 529 tostring = self.etree.tostring 530 parser = self.etree.XMLParser(resolve_entities=False) 531 Entity = self.etree.Entity 532 533 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 534 tree = parse(StringIO(xml), parser) 535 root = tree.getroot() 536 self.assertEquals(root[0].tag, Entity) 537 self.assertFalse(root[0].text) 538 self.assertEquals(root[0].tail, None) 539 self.assertEquals(root[0].name, "myentity") 540 541 self.assertEquals('<doc>&myentity;</doc>', 542 tostring(root))
543
544 - def test_entity_append(self):
545 Entity = self.etree.Entity 546 Element = self.etree.Element 547 tostring = self.etree.tostring 548 549 root = Element("root") 550 root.append( Entity("test") ) 551 552 self.assertEquals(root[0].tag, Entity) 553 self.assertFalse(root[0].text) 554 self.assertEquals(root[0].tail, None) 555 self.assertEquals(root[0].name, "test") 556 557 self.assertEquals('<root>&test;</root>', 558 tostring(root))
559 560 # TypeError in etree, AssertionError in ElementTree;
561 - def test_setitem_assert(self):
562 Element = self.etree.Element 563 SubElement = self.etree.SubElement 564 565 a = Element('a') 566 b = SubElement(a, 'b') 567 568 self.assertRaises(TypeError, 569 a.__setitem__, 0, 'foo')
570
571 - def test_append_None(self):
572 # raises AssertionError in ElementTree 573 Element = self.etree.Element 574 self.assertRaises(TypeError, Element('a').append, None)
575
576 - def test_addnext(self):
577 Element = self.etree.Element 578 SubElement = self.etree.SubElement 579 root = Element('root') 580 SubElement(root, 'a') 581 SubElement(root, 'b') 582 583 self.assertEquals(['a', 'b'], 584 [c.tag for c in root]) 585 root[1].addnext(root[0]) 586 self.assertEquals(['b', 'a'], 587 [c.tag for c in root])
588
589 - def test_addprevious(self):
590 Element = self.etree.Element 591 SubElement = self.etree.SubElement 592 root = Element('root') 593 SubElement(root, 'a') 594 SubElement(root, 'b') 595 596 self.assertEquals(['a', 'b'], 597 [c.tag for c in root]) 598 root[0].addprevious(root[1]) 599 self.assertEquals(['b', 'a'], 600 [c.tag for c in root])
601
602 - def test_addnext_root(self):
603 Element = self.etree.Element 604 a = Element('a') 605 b = Element('b') 606 self.assertRaises(TypeError, a.addnext, b)
607
608 - def test_addnext_root(self):
609 Element = self.etree.Element 610 a = Element('a') 611 b = Element('b') 612 self.assertRaises(TypeError, a.addnext, b)
613
614 - def test_addprevious_pi(self):
615 Element = self.etree.Element 616 SubElement = self.etree.SubElement 617 PI = self.etree.PI 618 root = Element('root') 619 SubElement(root, 'a') 620 pi = PI('TARGET', 'TEXT') 621 pi.tail = "TAIL" 622 623 self.assertEquals('<root><a></a></root>', 624 self._writeElement(root)) 625 root[0].addprevious(pi) 626 self.assertEquals('<root><?TARGET TEXT?>TAIL<a></a></root>', 627 self._writeElement(root))
628
629 - def test_addprevious_root_pi(self):
630 Element = self.etree.Element 631 PI = self.etree.PI 632 root = Element('root') 633 pi = PI('TARGET', 'TEXT') 634 pi.tail = "TAIL" 635 636 self.assertEquals('<root></root>', 637 self._writeElement(root)) 638 root.addprevious(pi) 639 self.assertEquals('<?TARGET TEXT?>\n<root></root>', 640 self._writeElement(root))
641
642 - def test_addnext_pi(self):
643 Element = self.etree.Element 644 SubElement = self.etree.SubElement 645 PI = self.etree.PI 646 root = Element('root') 647 SubElement(root, 'a') 648 pi = PI('TARGET', 'TEXT') 649 pi.tail = "TAIL" 650 651 self.assertEquals('<root><a></a></root>', 652 self._writeElement(root)) 653 root[0].addnext(pi) 654 self.assertEquals('<root><a></a><?TARGET TEXT?>TAIL</root>', 655 self._writeElement(root))
656
657 - def test_addnext_root_pi(self):
658 Element = self.etree.Element 659 PI = self.etree.PI 660 root = Element('root') 661 pi = PI('TARGET', 'TEXT') 662 pi.tail = "TAIL" 663 664 self.assertEquals('<root></root>', 665 self._writeElement(root)) 666 root.addnext(pi) 667 self.assertEquals('<root></root>\n<?TARGET TEXT?>', 668 self._writeElement(root))
669
670 - def test_addnext_comment(self):
671 Element = self.etree.Element 672 SubElement = self.etree.SubElement 673 Comment = self.etree.Comment 674 root = Element('root') 675 SubElement(root, 'a') 676 comment = Comment('TEXT ') 677 comment.tail = "TAIL" 678 679 self.assertEquals('<root><a></a></root>', 680 self._writeElement(root)) 681 root[0].addnext(comment) 682 self.assertEquals('<root><a></a><!--TEXT -->TAIL</root>', 683 self._writeElement(root))
684
685 - def test_addnext_root_comment(self):
686 Element = self.etree.Element 687 Comment = self.etree.Comment 688 root = Element('root') 689 comment = Comment('TEXT ') 690 comment.tail = "TAIL" 691 692 self.assertEquals('<root></root>', 693 self._writeElement(root)) 694 root.addnext(comment) 695 self.assertEquals('<root></root>\n<!--TEXT -->', 696 self._writeElement(root))
697
698 - def test_addprevious_comment(self):
699 Element = self.etree.Element 700 SubElement = self.etree.SubElement 701 Comment = self.etree.Comment 702 root = Element('root') 703 SubElement(root, 'a') 704 comment = Comment('TEXT ') 705 comment.tail = "TAIL" 706 707 self.assertEquals('<root><a></a></root>', 708 self._writeElement(root)) 709 root[0].addprevious(comment) 710 self.assertEquals('<root><!--TEXT -->TAIL<a></a></root>', 711 self._writeElement(root))
712
713 - def test_addprevious_root_comment(self):
714 Element = self.etree.Element 715 Comment = self.etree.Comment 716 root = Element('root') 717 comment = Comment('TEXT ') 718 comment.tail = "TAIL" 719 720 self.assertEquals('<root></root>', 721 self._writeElement(root)) 722 root.addprevious(comment) 723 self.assertEquals('<!--TEXT -->\n<root></root>', 724 self._writeElement(root))
725 726 # ET's Elements have items() and key(), but not values()
727 - def test_attribute_values(self):
728 XML = self.etree.XML 729 730 root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>') 731 values = root.values() 732 values.sort() 733 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
734 735 # gives error in ElementTree
736 - def test_comment_empty(self):
737 Element = self.etree.Element 738 Comment = self.etree.Comment 739 740 a = Element('a') 741 a.append(Comment()) 742 self.assertEquals( 743 '<a><!----></a>', 744 self._writeElement(a))
745 746 # ElementTree ignores comments
747 - def test_comment_parse_empty(self):
748 ElementTree = self.etree.ElementTree 749 tostring = self.etree.tostring 750 751 xml = '<a><b/><!----><c/></a>' 752 f = StringIO(xml) 753 doc = ElementTree(file=f) 754 a = doc.getroot() 755 self.assertEquals( 756 '', 757 a[1].text) 758 self.assertEquals( 759 xml, 760 tostring(a))
761 762 # ElementTree ignores comments
763 - def test_comment_no_proxy_yet(self):
764 ElementTree = self.etree.ElementTree 765 766 f = StringIO('<a><b></b><!-- hoi --><c></c></a>') 767 doc = ElementTree(file=f) 768 a = doc.getroot() 769 self.assertEquals( 770 ' hoi ', 771 a[1].text)
772 773 # ElementTree adds whitespace around comments
774 - def test_comment_text(self):
775 Element = self.etree.Element 776 Comment = self.etree.Comment 777 tostring = self.etree.tostring 778 779 a = Element('a') 780 a.append(Comment('foo')) 781 self.assertEquals( 782 '<a><!--foo--></a>', 783 tostring(a)) 784 785 a[0].text = "TEST" 786 self.assertEquals( 787 '<a><!--TEST--></a>', 788 tostring(a))
789 790 # ElementTree adds whitespace around comments
791 - def test_comment_whitespace(self):
792 Element = self.etree.Element 793 Comment = self.etree.Comment 794 tostring = self.etree.tostring 795 796 a = Element('a') 797 a.append(Comment(' foo ')) 798 self.assertEquals( 799 '<a><!-- foo --></a>', 800 tostring(a))
801 802 # does not raise an exception in ElementTree
803 - def test_comment_immutable(self):
804 Element = self.etree.Element 805 Comment = self.etree.Comment 806 807 c = Comment() 808 el = Element('myel') 809 810 self.assertRaises(TypeError, c.append, el) 811 self.assertRaises(TypeError, c.insert, 0, el) 812 self.assertRaises(TypeError, c.set, "myattr", "test")
813 814 # test weird dictionary interaction leading to segfault previously
815 - def test_weird_dict_interaction(self):
816 root = self.etree.Element('root') 817 add = self.etree.ElementTree(file=StringIO('<foo>Foo</foo>')) 818 root.append(self.etree.Element('baz'))
819 820 # test passing 'None' to dump
821 - def test_dump_none(self):
822 self.assertRaises(TypeError, etree.dump, None)
823
824 - def test_prefix(self):
825 ElementTree = self.etree.ElementTree 826 827 f = StringIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 828 doc = ElementTree(file=f) 829 a = doc.getroot() 830 self.assertEquals( 831 None, 832 a.prefix) 833 self.assertEquals( 834 'foo', 835 a[0].prefix)
836
837 - def test_prefix_default_ns(self):
838 ElementTree = self.etree.ElementTree 839 840 f = StringIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 841 doc = ElementTree(file=f) 842 a = doc.getroot() 843 self.assertEquals( 844 None, 845 a.prefix) 846 self.assertEquals( 847 None, 848 a[0].prefix)
849
850 - def test_getparent(self):
851 Element = self.etree.Element 852 SubElement = self.etree.SubElement 853 854 a = Element('a') 855 b = SubElement(a, 'b') 856 c = SubElement(a, 'c') 857 d = SubElement(b, 'd') 858 self.assertEquals( 859 None, 860 a.getparent()) 861 self.assertEquals( 862 a, 863 b.getparent()) 864 self.assertEquals( 865 b.getparent(), 866 c.getparent()) 867 self.assertEquals( 868 b, 869 d.getparent())
870
871 - def test_iterchildren(self):
872 XML = self.etree.XML 873 874 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 875 result = [] 876 for el in root.iterchildren(): 877 result.append(el.tag) 878 self.assertEquals(['one', 'two', 'three'], result)
879
880 - def test_iterchildren_reversed(self):
881 XML = self.etree.XML 882 883 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 884 result = [] 885 for el in root.iterchildren(reversed=True): 886 result.append(el.tag) 887 self.assertEquals(['three', 'two', 'one'], result)
888
889 - def test_iterchildren_tag(self):
890 XML = self.etree.XML 891 892 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 893 result = [] 894 for el in root.iterchildren(tag='two'): 895 result.append(el.text) 896 self.assertEquals(['Two', 'Bla'], result)
897
898 - def test_iterchildren_tag_reversed(self):
899 XML = self.etree.XML 900 901 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 902 result = [] 903 for el in root.iterchildren(reversed=True, tag='two'): 904 result.append(el.text) 905 self.assertEquals(['Bla', 'Two'], result)
906
907 - def test_iterancestors(self):
908 Element = self.etree.Element 909 SubElement = self.etree.SubElement 910 911 a = Element('a') 912 b = SubElement(a, 'b') 913 c = SubElement(a, 'c') 914 d = SubElement(b, 'd') 915 self.assertEquals( 916 [], 917 list(a.iterancestors())) 918 self.assertEquals( 919 [a], 920 list(b.iterancestors())) 921 self.assertEquals( 922 a, 923 c.iterancestors().next()) 924 self.assertEquals( 925 [b, a], 926 list(d.iterancestors()))
927
928 - def test_iterancestors_tag(self):
929 Element = self.etree.Element 930 SubElement = self.etree.SubElement 931 932 a = Element('a') 933 b = SubElement(a, 'b') 934 c = SubElement(a, 'c') 935 d = SubElement(b, 'd') 936 self.assertEquals( 937 [a], 938 list(d.iterancestors(tag='a')))
939
940 - def test_iterdescendants(self):
941 Element = self.etree.Element 942 SubElement = self.etree.SubElement 943 944 a = Element('a') 945 b = SubElement(a, 'b') 946 c = SubElement(a, 'c') 947 d = SubElement(b, 'd') 948 e = SubElement(c, 'e') 949 950 self.assertEquals( 951 [b, d, c, e], 952 list(a.iterdescendants())) 953 self.assertEquals( 954 [], 955 list(d.iterdescendants()))
956
957 - def test_iterdescendants_tag(self):
958 Element = self.etree.Element 959 SubElement = self.etree.SubElement 960 961 a = Element('a') 962 b = SubElement(a, 'b') 963 c = SubElement(a, 'c') 964 d = SubElement(b, 'd') 965 e = SubElement(c, 'e') 966 967 self.assertEquals( 968 [], 969 list(a.iterdescendants('a'))) 970 a2 = SubElement(e, 'a') 971 self.assertEquals( 972 [a2], 973 list(a.iterdescendants('a'))) 974 self.assertEquals( 975 [a2], 976 list(c.iterdescendants('a')))
977
978 - def test_getroottree(self):
979 Element = self.etree.Element 980 SubElement = self.etree.SubElement 981 982 a = Element('a') 983 b = SubElement(a, 'b') 984 c = SubElement(a, 'c') 985 d = SubElement(b, 'd') 986 self.assertEquals( 987 a, 988 a.getroottree().getroot()) 989 self.assertEquals( 990 a, 991 b.getroottree().getroot()) 992 self.assertEquals( 993 a, 994 d.getroottree().getroot())
995
996 - def test_getnext(self):
997 Element = self.etree.Element 998 SubElement = self.etree.SubElement 999 1000 a = Element('a') 1001 b = SubElement(a, 'b') 1002 c = SubElement(a, 'c') 1003 self.assertEquals( 1004 None, 1005 a.getnext()) 1006 self.assertEquals( 1007 c, 1008 b.getnext()) 1009 self.assertEquals( 1010 None, 1011 c.getnext())
1012
1013 - def test_getprevious(self):
1014 Element = self.etree.Element 1015 SubElement = self.etree.SubElement 1016 1017 a = Element('a') 1018 b = SubElement(a, 'b') 1019 c = SubElement(a, 'c') 1020 d = SubElement(b, 'd') 1021 self.assertEquals( 1022 None, 1023 a.getprevious()) 1024 self.assertEquals( 1025 b, 1026 c.getprevious()) 1027 self.assertEquals( 1028 None, 1029 b.getprevious())
1030
1031 - def test_itersiblings(self):
1032 Element = self.etree.Element 1033 SubElement = self.etree.SubElement 1034 1035 a = Element('a') 1036 b = SubElement(a, 'b') 1037 c = SubElement(a, 'c') 1038 d = SubElement(b, 'd') 1039 self.assertEquals( 1040 [], 1041 list(a.itersiblings())) 1042 self.assertEquals( 1043 [c], 1044 list(b.itersiblings())) 1045 self.assertEquals( 1046 c, 1047 b.itersiblings().next()) 1048 self.assertEquals( 1049 [], 1050 list(c.itersiblings())) 1051 self.assertEquals( 1052 [b], 1053 list(c.itersiblings(preceding=True))) 1054 self.assertEquals( 1055 [], 1056 list(b.itersiblings(preceding=True)))
1057
1058 - def test_itersiblings_tag(self):
1059 Element = self.etree.Element 1060 SubElement = self.etree.SubElement 1061 1062 a = Element('a') 1063 b = SubElement(a, 'b') 1064 c = SubElement(a, 'c') 1065 d = SubElement(b, 'd') 1066 self.assertEquals( 1067 [], 1068 list(a.itersiblings(tag='XXX'))) 1069 self.assertEquals( 1070 [c], 1071 list(b.itersiblings(tag='c'))) 1072 self.assertEquals( 1073 [b], 1074 list(c.itersiblings(preceding=True, tag='b'))) 1075 self.assertEquals( 1076 [], 1077 list(c.itersiblings(preceding=True, tag='c')))
1078
1079 - def test_parseid(self):
1080 parseid = self.etree.parseid 1081 XML = self.etree.XML 1082 xml_text = ''' 1083 <!DOCTYPE document [ 1084 <!ELEMENT document (h1,p)*> 1085 <!ELEMENT h1 (#PCDATA)> 1086 <!ATTLIST h1 myid ID #REQUIRED> 1087 <!ELEMENT p (#PCDATA)> 1088 <!ATTLIST p someid ID #REQUIRED> 1089 ]> 1090 <document> 1091 <h1 myid="chapter1">...</h1> 1092 <p id="note1" class="note">...</p> 1093 <p>Regular paragraph.</p> 1094 <p xml:id="xmlid">XML:ID paragraph.</p> 1095 <p someid="warn1" class="warning">...</p> 1096 </document> 1097 ''' 1098 1099 tree, dic = parseid(StringIO(xml_text)) 1100 root = tree.getroot() 1101 root2 = XML(xml_text) 1102 self.assertEquals(self._writeElement(root), 1103 self._writeElement(root2)) 1104 expected = { 1105 "chapter1" : root[0], 1106 "xmlid" : root[3], 1107 "warn1" : root[4] 1108 } 1109 self.assert_("chapter1" in dic) 1110 self.assert_("warn1" in dic) 1111 self.assert_("xmlid" in dic) 1112 self._checkIDDict(dic, expected)
1113
1114 - def test_XMLDTDID(self):
1115 XMLDTDID = self.etree.XMLDTDID 1116 XML = self.etree.XML 1117 xml_text = ''' 1118 <!DOCTYPE document [ 1119 <!ELEMENT document (h1,p)*> 1120 <!ELEMENT h1 (#PCDATA)> 1121 <!ATTLIST h1 myid ID #REQUIRED> 1122 <!ELEMENT p (#PCDATA)> 1123 <!ATTLIST p someid ID #REQUIRED> 1124 ]> 1125 <document> 1126 <h1 myid="chapter1">...</h1> 1127 <p id="note1" class="note">...</p> 1128 <p>Regular paragraph.</p> 1129 <p xml:id="xmlid">XML:ID paragraph.</p> 1130 <p someid="warn1" class="warning">...</p> 1131 </document> 1132 ''' 1133 1134 root, dic = XMLDTDID(xml_text) 1135 root2 = XML(xml_text) 1136 self.assertEquals(self._writeElement(root), 1137 self._writeElement(root2)) 1138 expected = { 1139 "chapter1" : root[0], 1140 "xmlid" : root[3], 1141 "warn1" : root[4] 1142 } 1143 self.assert_("chapter1" in dic) 1144 self.assert_("warn1" in dic) 1145 self.assert_("xmlid" in dic) 1146 self._checkIDDict(dic, expected)
1147
1148 - def test_XMLDTDID_empty(self):
1149 XMLDTDID = self.etree.XMLDTDID 1150 XML = self.etree.XML 1151 xml_text = ''' 1152 <document> 1153 <h1 myid="chapter1">...</h1> 1154 <p id="note1" class="note">...</p> 1155 <p>Regular paragraph.</p> 1156 <p someid="warn1" class="warning">...</p> 1157 </document> 1158 ''' 1159 1160 root, dic = XMLDTDID(xml_text) 1161 root2 = XML(xml_text) 1162 self.assertEquals(self._writeElement(root), 1163 self._writeElement(root2)) 1164 expected = {} 1165 self._checkIDDict(dic, expected)
1166
1167 - def _checkIDDict(self, dic, expected):
1168 self.assertEquals(dic, expected) 1169 self.assertEquals(len(dic), 1170 len(expected)) 1171 self.assertEquals(sorted(dic.items()), 1172 sorted(expected.items())) 1173 self.assertEquals(sorted(dic.iteritems()), 1174 sorted(expected.iteritems())) 1175 self.assertEquals(sorted(dic.keys()), 1176 sorted(expected.keys())) 1177 self.assertEquals(sorted(dic.iterkeys()), 1178 sorted(expected.iterkeys())) 1179 self.assertEquals(sorted(dic.values()), 1180 sorted(expected.values())) 1181 self.assertEquals(sorted(dic.itervalues()), 1182 sorted(expected.itervalues()))
1183
1184 - def test_namespaces(self):
1185 etree = self.etree 1186 1187 r = {'foo': 'http://ns.infrae.com/foo'} 1188 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1189 self.assertEquals( 1190 'foo', 1191 e.prefix) 1192 self.assertEquals( 1193 '<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>', 1194 self._writeElement(e))
1195
1196 - def test_namespaces_default(self):
1197 etree = self.etree 1198 1199 r = {None: 'http://ns.infrae.com/foo'} 1200 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1201 self.assertEquals( 1202 None, 1203 e.prefix) 1204 self.assertEquals( 1205 '{http://ns.infrae.com/foo}bar', 1206 e.tag) 1207 self.assertEquals( 1208 '<bar xmlns="http://ns.infrae.com/foo"></bar>', 1209 self._writeElement(e))
1210
1211 - def test_namespaces_default_and_attr(self):
1212 etree = self.etree 1213 1214 r = {None: 'http://ns.infrae.com/foo', 1215 'hoi': 'http://ns.infrae.com/hoi'} 1216 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1217 e.set('{http://ns.infrae.com/hoi}test', 'value') 1218 self.assertEquals( 1219 '<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>', 1220 self._writeElement(e))
1221
1222 - def test_namespaces_elementtree(self):
1223 etree = self.etree 1224 r = {None: 'http://ns.infrae.com/foo', 1225 'hoi': 'http://ns.infrae.com/hoi'} 1226 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1227 tree = etree.ElementTree(element=e) 1228 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1229 self.assertEquals( 1230 '<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>', 1231 self._writeElement(e))
1232
1233 - def test_namespaces_default_copy_element(self):
1234 etree = self.etree 1235 1236 r = {None: 'http://ns.infrae.com/foo'} 1237 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1238 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1239 1240 e1.append(e2) 1241 1242 self.assertEquals( 1243 None, 1244 e1.prefix) 1245 self.assertEquals( 1246 None, 1247 e1[0].prefix) 1248 self.assertEquals( 1249 '{http://ns.infrae.com/foo}bar', 1250 e1.tag) 1251 self.assertEquals( 1252 '{http://ns.infrae.com/foo}bar', 1253 e1[0].tag)
1254
1255 - def test_namespaces_copy_element(self):
1256 etree = self.etree 1257 1258 r = {None: 'http://ns.infrae.com/BAR'} 1259 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1260 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1261 1262 e1.append(e2) 1263 1264 self.assertEquals( 1265 None, 1266 e1.prefix) 1267 self.assertNotEquals( 1268 None, 1269 e2.prefix) 1270 self.assertEquals( 1271 '{http://ns.infrae.com/BAR}bar', 1272 e1.tag) 1273 self.assertEquals( 1274 '{http://ns.infrae.com/foo}bar', 1275 e2.tag)
1276
1277 - def test_namespaces_reuse_after_move(self):
1278 ns_href = "http://a.b.c" 1279 one = self.etree.parse( 1280 StringIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1281 baz = one.getroot()[0][0] 1282 1283 two = self.etree.parse( 1284 StringIO('<root xmlns:ns="%s"/>' % ns_href)) 1285 two.getroot().append(baz) 1286 del one # make sure the source document is deallocated 1287 1288 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1289 self.assertEquals( 1290 '<root xmlns:ns="%s"><ns:baz/></root>' % ns_href, 1291 self.etree.tostring(two))
1292
1293 - def _test_namespaces_after_serialize(self):
1294 # FIXME: this currently fails - fix serializer.pxi! 1295 parse = self.etree.parse 1296 tostring = self.etree.tostring 1297 1298 ns_href = "http://a.b.c" 1299 one = parse( 1300 StringIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1301 baz = one.getroot()[0][0] 1302 1303 print tostring(baz) 1304 parsed = parse(StringIO( tostring(baz) )).getroot() 1305 1306 self.assertEquals('{%s}baz' % ns_href, parsed.tag)
1307
1308 - def test_element_nsmap(self):
1309 etree = self.etree 1310 1311 r = {None: 'http://ns.infrae.com/foo', 1312 'hoi': 'http://ns.infrae.com/hoi'} 1313 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1314 self.assertEquals( 1315 r, 1316 e.nsmap)
1317
1318 - def test_subelement_nsmap(self):
1319 etree = self.etree 1320 1321 re = {None: 'http://ns.infrae.com/foo', 1322 'hoi': 'http://ns.infrae.com/hoi'} 1323 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 1324 1325 rs = {None: 'http://ns.infrae.com/honk', 1326 'top': 'http://ns.infrae.com/top'} 1327 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 1328 1329 r = re.copy() 1330 r.update(rs) 1331 self.assertEquals( 1332 re, 1333 e.nsmap) 1334 self.assertEquals( 1335 r, 1336 s.nsmap)
1337
1338 - def test_getiterator_filter_namespace(self):
1339 Element = self.etree.Element 1340 SubElement = self.etree.SubElement 1341 1342 a = Element('{a}a') 1343 b = SubElement(a, '{a}b') 1344 c = SubElement(a, '{a}c') 1345 d = SubElement(b, '{b}d') 1346 e = SubElement(c, '{a}e') 1347 f = SubElement(c, '{b}f') 1348 1349 self.assertEquals( 1350 [a], 1351 list(a.getiterator('{a}a'))) 1352 self.assertEquals( 1353 [], 1354 list(a.getiterator('{b}a'))) 1355 self.assertEquals( 1356 [], 1357 list(a.getiterator('a'))) 1358 self.assertEquals( 1359 [f], 1360 list(c.getiterator('{b}*'))) 1361 self.assertEquals( 1362 [d, f], 1363 list(a.getiterator('{b}*')))
1364
1365 - def test_getiterator_filter_entities(self):
1366 Element = self.etree.Element 1367 Entity = self.etree.Entity 1368 SubElement = self.etree.SubElement 1369 1370 a = Element('a') 1371 b = SubElement(a, 'b') 1372 entity_b = Entity("TEST-b") 1373 b.append(entity_b) 1374 1375 self.assertEquals( 1376 [entity_b], 1377 list(a.getiterator(Entity))) 1378 1379 entity_a = Entity("TEST-a") 1380 a.append(entity_a) 1381 1382 self.assertEquals( 1383 [entity_b, entity_a], 1384 list(a.getiterator(Entity))) 1385 1386 self.assertEquals( 1387 [entity_b], 1388 list(b.getiterator(Entity)))
1389
1390 - def test_getiterator_filter_element(self):
1391 Element = self.etree.Element 1392 Comment = self.etree.Comment 1393 PI = self.etree.PI 1394 SubElement = self.etree.SubElement 1395 1396 a = Element('a') 1397 b = SubElement(a, 'b') 1398 a.append(Comment("test")) 1399 a.append(PI("pi", "content")) 1400 c = SubElement(a, 'c') 1401 1402 self.assertEquals( 1403 [a, b, c], 1404 list(a.getiterator(Element)))
1405
1406 - def test_getiterator_filter_all_comment_pi(self):
1407 # ElementTree iterates over everything here 1408 Element = self.etree.Element 1409 Comment = self.etree.Comment 1410 PI = self.etree.PI 1411 SubElement = self.etree.SubElement 1412 1413 a = Element('a') 1414 b = SubElement(a, 'b') 1415 a.append(Comment("test")) 1416 a.append(PI("pi", "content")) 1417 c = SubElement(a, 'c') 1418 1419 self.assertEquals( 1420 [a, b, c], 1421 list(a.getiterator('*')))
1422
1423 - def test_itertext(self):
1424 # ET 1.3+ 1425 XML = self.etree.XML 1426 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1427 1428 text = list(root.itertext()) 1429 self.assertEquals(["RTEXT", "ATAIL", "CTEXT", "CTAIL"], 1430 text)
1431
1432 - def test_itertext_child(self):
1433 # ET 1.3+ 1434 XML = self.etree.XML 1435 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1436 1437 text = list(root[2].itertext()) 1438 self.assertEquals(["CTEXT"], 1439 text)
1440
1441 - def test_findall_ns(self):
1442 XML = self.etree.XML 1443 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>') 1444 self.assertEquals(len(root.findall(".//{X}b")), 2) 1445 self.assertEquals(len(root.findall(".//{X}*")), 2) 1446 self.assertEquals(len(root.findall(".//b")), 3)
1447
1448 - def test_index(self):
1449 etree = self.etree 1450 e = etree.Element('foo') 1451 for i in range(10): 1452 etree.SubElement(e, 'a%s' % i) 1453 for i in range(10): 1454 self.assertEquals( 1455 i, 1456 e.index(e[i])) 1457 self.assertEquals( 1458 3, e.index(e[3], 3)) 1459 self.assertRaises( 1460 ValueError, e.index, e[3], 4) 1461 self.assertRaises( 1462 ValueError, e.index, e[3], 0, 2) 1463 self.assertRaises( 1464 ValueError, e.index, e[8], 0, -3) 1465 self.assertRaises( 1466 ValueError, e.index, e[8], -5, -3) 1467 self.assertEquals( 1468 8, e.index(e[8], 0, -1)) 1469 self.assertEquals( 1470 8, e.index(e[8], -12, -1)) 1471 self.assertEquals( 1472 0, e.index(e[0], -12, -1))
1473
1474 - def test_replace(self):
1475 etree = self.etree 1476 e = etree.Element('foo') 1477 for i in range(10): 1478 el = etree.SubElement(e, 'a%s' % i) 1479 el.text = "text%d" % i 1480 el.tail = "tail%d" % i 1481 1482 child0 = e[0] 1483 child1 = e[1] 1484 child2 = e[2] 1485 1486 e.replace(e[0], e[1]) 1487 self.assertEquals( 1488 9, len(e)) 1489 self.assertEquals( 1490 child1, e[0]) 1491 self.assertEquals( 1492 child1.text, "text1") 1493 self.assertEquals( 1494 child1.tail, "tail1") 1495 self.assertEquals( 1496 child0.tail, "tail0") 1497 self.assertEquals( 1498 child2, e[1]) 1499 1500 e.replace(e[-1], e[0]) 1501 self.assertEquals( 1502 child1, e[-1]) 1503 self.assertEquals( 1504 child1.text, "text1") 1505 self.assertEquals( 1506 child1.tail, "tail1") 1507 self.assertEquals( 1508 child2, e[0])
1509
1510 - def test_replace_new(self):
1511 etree = self.etree 1512 e = etree.Element('foo') 1513 for i in range(10): 1514 etree.SubElement(e, 'a%s' % i) 1515 1516 new_element = etree.Element("test") 1517 new_element.text = "TESTTEXT" 1518 new_element.tail = "TESTTAIL" 1519 child1 = e[1] 1520 e.replace(e[0], new_element) 1521 self.assertEquals( 1522 new_element, e[0]) 1523 self.assertEquals( 1524 "TESTTEXT", 1525 e[0].text) 1526 self.assertEquals( 1527 "TESTTAIL", 1528 e[0].tail) 1529 self.assertEquals( 1530 child1, e[1])
1531
1532 - def test_extend(self):
1533 etree = self.etree 1534 root = etree.Element('foo') 1535 for i in range(3): 1536 element = etree.SubElement(root, 'a%s' % i) 1537 element.text = "text%d" % i 1538 element.tail = "tail%d" % i 1539 1540 elements = [] 1541 for i in range(3): 1542 new_element = etree.Element("test%s" % i) 1543 new_element.text = "TEXT%s" % i 1544 new_element.tail = "TAIL%s" % i 1545 elements.append(new_element) 1546 1547 root.extend(elements) 1548 1549 self.assertEquals( 1550 ["a0", "a1", "a2", "test0", "test1", "test2"], 1551 [ el.tag for el in root ]) 1552 self.assertEquals( 1553 ["text0", "text1", "text2", "TEXT0", "TEXT1", "TEXT2"], 1554 [ el.text for el in root ]) 1555 self.assertEquals( 1556 ["tail0", "tail1", "tail2", "TAIL0", "TAIL1", "TAIL2"], 1557 [ el.tail for el in root ])
1558
1559 - def test_sourceline_XML(self):
1560 XML = self.etree.XML 1561 root = XML('''<?xml version="1.0"?> 1562 <root><test> 1563 1564 <bla/></test> 1565 </root> 1566 ''') 1567 1568 self.assertEquals( 1569 [2, 2, 4], 1570 [ el.sourceline for el in root.getiterator() ])
1571
1572 - def test_sourceline_parse(self):
1573 parse = self.etree.parse 1574 tree = parse(fileInTestDir('include/test_xinclude.xml')) 1575 1576 self.assertEquals( 1577 [1, 2, 3], 1578 [ el.sourceline for el in tree.getiterator() ])
1579
1580 - def test_sourceline_iterparse_end(self):
1581 iterparse = self.etree.iterparse 1582 lines = list( 1583 el.sourceline for (event, el) in 1584 iterparse(fileInTestDir('include/test_xinclude.xml'))) 1585 1586 self.assertEquals( 1587 [2, 3, 1], 1588 lines)
1589
1590 - def test_sourceline_iterparse_start(self):
1591 iterparse = self.etree.iterparse 1592 lines = list( 1593 el.sourceline for (event, el) in 1594 iterparse(fileInTestDir('include/test_xinclude.xml'), 1595 events=("start",))) 1596 1597 self.assertEquals( 1598 [1, 2, 3], 1599 lines)
1600
1601 - def test_sourceline_element(self):
1602 Element = self.etree.Element 1603 SubElement = self.etree.SubElement 1604 el = Element("test") 1605 self.assertEquals(None, el.sourceline) 1606 1607 child = SubElement(el, "test") 1608 self.assertEquals(None, el.sourceline) 1609 self.assertEquals(None, child.sourceline)
1610
1611 - def test_XML_base_url_docinfo(self):
1612 etree = self.etree 1613 root = etree.XML("<root/>", base_url="http://no/such/url") 1614 docinfo = root.getroottree().docinfo 1615 self.assertEquals(docinfo.URL, "http://no/such/url")
1616
1617 - def test_HTML_base_url_docinfo(self):
1618 etree = self.etree 1619 root = etree.HTML("<html/>", base_url="http://no/such/url") 1620 docinfo = root.getroottree().docinfo 1621 self.assertEquals(docinfo.URL, "http://no/such/url")
1622
1623 - def test_docinfo_public(self):
1624 etree = self.etree 1625 xml_header = '<?xml version="1.0" encoding="ascii"?>' 1626 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 1627 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 1628 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 1629 1630 xml = xml_header + doctype_string + '<html><body></body></html>' 1631 1632 tree = etree.parse(StringIO(xml)) 1633 docinfo = tree.docinfo 1634 self.assertEquals(docinfo.encoding, "ascii") 1635 self.assertEquals(docinfo.xml_version, "1.0") 1636 self.assertEquals(docinfo.public_id, pub_id) 1637 self.assertEquals(docinfo.system_url, sys_id) 1638 self.assertEquals(docinfo.root_name, 'html') 1639 self.assertEquals(docinfo.doctype, doctype_string)
1640
1641 - def test_docinfo_system(self):
1642 etree = self.etree 1643 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 1644 sys_id = "some.dtd" 1645 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 1646 xml = xml_header + doctype_string + '<html><body></body></html>' 1647 1648 tree = etree.parse(StringIO(xml)) 1649 docinfo = tree.docinfo 1650 self.assertEquals(docinfo.encoding, "UTF-8") 1651 self.assertEquals(docinfo.xml_version, "1.0") 1652 self.assertEquals(docinfo.public_id, None) 1653 self.assertEquals(docinfo.system_url, sys_id) 1654 self.assertEquals(docinfo.root_name, 'html') 1655 self.assertEquals(docinfo.doctype, doctype_string)
1656
1657 - def test_docinfo_empty(self):
1658 etree = self.etree 1659 xml = '<html><body></body></html>' 1660 tree = etree.parse(StringIO(xml)) 1661 docinfo = tree.docinfo 1662 self.assertEquals(docinfo.encoding, None) 1663 self.assertEquals(docinfo.xml_version, "1.0") 1664 self.assertEquals(docinfo.public_id, None) 1665 self.assertEquals(docinfo.system_url, None) 1666 self.assertEquals(docinfo.root_name, 'html') 1667 self.assertEquals(docinfo.doctype, '')
1668
1669 - def test_dtd_io(self):
1670 # check that DTDs that go in also go back out 1671 xml = '''\ 1672 <!DOCTYPE test SYSTEM "test.dtd" [ 1673 <!ENTITY entity "tasty"> 1674 <!ELEMENT test (a)> 1675 <!ELEMENT a (#PCDATA)> 1676 ]> 1677 <test><a>test-test</a></test>\ 1678 ''' 1679 root = self.etree.parse(StringIO(xml)) 1680 self.assertEqual(self.etree.tostring(root).replace(" ", ""), 1681 xml.replace(" ", ""))
1682
1683 - def test_byte_zero(self):
1684 Element = self.etree.Element 1685 1686 a = Element('a') 1687 self.assertRaises(AssertionError, setattr, a, "text", 'ha\0ho') 1688 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\0ho') 1689 1690 self.assertRaises(AssertionError, Element, 'ha\0ho')
1691
1692 - def test_unicode_byte_zero(self):
1693 Element = self.etree.Element 1694 1695 a = Element('a') 1696 self.assertRaises(AssertionError, setattr, a, "text", u'ha\0ho') 1697 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\0ho') 1698 1699 self.assertRaises(AssertionError, Element, u'ha\0ho')
1700
1701 - def test_byte_invalid(self):
1702 Element = self.etree.Element 1703 1704 a = Element('a') 1705 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x07ho') 1706 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x02ho') 1707 1708 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x07ho') 1709 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x02ho') 1710 1711 self.assertRaises(AssertionError, Element, 'ha\x07ho') 1712 self.assertRaises(AssertionError, Element, 'ha\x02ho')
1713
1714 - def test_unicode_byte_invalid(self):
1715 Element = self.etree.Element 1716 1717 a = Element('a') 1718 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x07ho') 1719 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x02ho') 1720 1721 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x07ho') 1722 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x02ho') 1723 1724 self.assertRaises(AssertionError, Element, u'ha\x07ho') 1725 self.assertRaises(AssertionError, Element, u'ha\x02ho')
1726
1727 - def test_encoding_tostring_utf16(self):
1728 # ElementTree fails to serialize this 1729 tostring = self.etree.tostring 1730 Element = self.etree.Element 1731 SubElement = self.etree.SubElement 1732 1733 a = Element('a') 1734 b = SubElement(a, 'b') 1735 c = SubElement(a, 'c') 1736 1737 result = unicode(tostring(a, 'UTF-16'), 'UTF-16') 1738 self.assertEquals('<a><b></b><c></c></a>', 1739 canonicalize(result))
1740
1741 - def test_tostring_none(self):
1742 # ElementTree raises an AssertionError here 1743 tostring = self.etree.tostring 1744 self.assertRaises(TypeError, self.etree.tostring, None)
1745
1746 - def test_tostring_pretty(self):
1747 tostring = self.etree.tostring 1748 Element = self.etree.Element 1749 SubElement = self.etree.SubElement 1750 1751 a = Element('a') 1752 b = SubElement(a, 'b') 1753 c = SubElement(a, 'c') 1754 1755 result = tostring(a) 1756 self.assertEquals(result, "<a><b/><c/></a>") 1757 1758 result = tostring(a, pretty_print=False) 1759 self.assertEquals(result, "<a><b/><c/></a>") 1760 1761 result = tostring(a, pretty_print=True) 1762 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>")
1763
1764 - def test_tostring_method_text_encoding(self):
1765 tostring = self.etree.tostring 1766 Element = self.etree.Element 1767 SubElement = self.etree.SubElement 1768 1769 a = Element('a') 1770 a.text = "A" 1771 a.tail = "tail" 1772 b = SubElement(a, 'b') 1773 b.text = "B" 1774 b.tail = u"Søk på nettet" 1775 c = SubElement(a, 'c') 1776 c.text = "C" 1777 1778 result = tostring(a, method="text", encoding="UTF-16") 1779 1780 self.assertEquals(u'ABSøk på nettetCtail'.encode("UTF-16"), 1781 result)
1782
1783 - def test_tounicode(self):
1784 tounicode = self.etree.tounicode 1785 Element = self.etree.Element 1786 SubElement = self.etree.SubElement 1787 1788 a = Element('a') 1789 b = SubElement(a, 'b') 1790 c = SubElement(a, 'c') 1791 1792 self.assert_(isinstance(tounicode(a), unicode)) 1793 self.assertEquals('<a><b></b><c></c></a>', 1794 canonicalize(tounicode(a)))
1795
1796 - def test_tounicode_element(self):
1797 tounicode = self.etree.tounicode 1798 Element = self.etree.Element 1799 SubElement = self.etree.SubElement 1800 1801 a = Element('a') 1802 b = SubElement(a, 'b') 1803 c = SubElement(a, 'c') 1804 d = SubElement(c, 'd') 1805 self.assert_(isinstance(tounicode(b), unicode)) 1806 self.assert_(isinstance(tounicode(c), unicode)) 1807 self.assertEquals('<b></b>', 1808 canonicalize(tounicode(b))) 1809 self.assertEquals('<c><d></d></c>', 1810 canonicalize(tounicode(c)))
1811
1812 - def test_tounicode_none(self):
1813 tounicode = self.etree.tounicode 1814 self.assertRaises(TypeError, self.etree.tounicode, None)
1815
1816 - def test_tounicode_element_tail(self):
1817 tounicode = self.etree.tounicode 1818 Element = self.etree.Element 1819 SubElement = self.etree.SubElement 1820 1821 a = Element('a') 1822 b = SubElement(a, 'b') 1823 c = SubElement(a, 'c') 1824 d = SubElement(c, 'd') 1825 b.tail = 'Foo' 1826 1827 self.assert_(isinstance(tounicode(b), unicode)) 1828 self.assert_(tounicode(b) == '<b/>Foo' or 1829 tounicode(b) == '<b />Foo')
1830
1831 - def test_tounicode_pretty(self):
1832 tounicode = self.etree.tounicode 1833 Element = self.etree.Element 1834 SubElement = self.etree.SubElement 1835 1836 a = Element('a') 1837 b = SubElement(a, 'b') 1838 c = SubElement(a, 'c') 1839 1840 result = tounicode(a) 1841 self.assertEquals(result, "<a><b/><c/></a>") 1842 1843 result = tounicode(a, pretty_print=False) 1844 self.assertEquals(result, "<a><b/><c/></a>") 1845 1846 result = tounicode(a, pretty_print=True) 1847 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>")
1848
1849 - def _writeElement(self, element, encoding='us-ascii'):
1850 """Write out element for comparison. 1851 """ 1852 ElementTree = self.etree.ElementTree 1853 f = StringIO() 1854 tree = ElementTree(element=element) 1855 tree.write(f, encoding) 1856 data = f.getvalue() 1857 return canonicalize(data)
1858 1859
1860 -class XIncludeTestCase(HelperTestCase):
1861 - def test_xinclude_text(self):
1862 filename = fileInTestDir('test_broken.xml') 1863 root = etree.XML('''\ 1864 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 1865 <xi:include href="%s" parse="text"/> 1866 </doc> 1867 ''' % filename) 1868 old_text = root.text 1869 content = open(filename).read() 1870 old_tail = root[0].tail 1871 1872 self.include( etree.ElementTree(root) ) 1873 self.assertEquals(old_text + content + old_tail, 1874 root.text)
1875
1876 - def test_xinclude(self):
1877 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 1878 self.assertNotEquals( 1879 'a', 1880 tree.getroot()[1].tag) 1881 # process xincludes 1882 self.include( tree ) 1883 # check whether we find it replaced with included data 1884 self.assertEquals( 1885 'a', 1886 tree.getroot()[1].tag)
1887
1888 -class ETreeXIncludeTestCase(XIncludeTestCase):
1889 - def include(self, tree):
1890 tree.xinclude()
1891 1892
1893 -class ElementIncludeTestCase(XIncludeTestCase):
1894 from lxml import ElementInclude
1895 - def include(self, tree):
1896 self.ElementInclude.include(tree.getroot())
1897 1898
1899 -class ETreeC14NTestCase(HelperTestCase):
1900 - def test_c14n(self):
1901 tree = self.parse('<a><b/></a>') 1902 f = StringIO() 1903 tree.write_c14n(f) 1904 s = f.getvalue() 1905 self.assertEquals('<a><b></b></a>', 1906 s)
1907
1908 -def test_suite():
1909 suite = unittest.TestSuite() 1910 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 1911 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 1912 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 1913 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 1914 suite.addTests( 1915 [doctest.DocFileSuite('../../../doc/tutorial.txt')]) 1916 suite.addTests( 1917 [doctest.DocFileSuite('../../../doc/api.txt')]) 1918 suite.addTests( 1919 [doctest.DocFileSuite('../../../doc/parsing.txt')]) 1920 suite.addTests( 1921 [doctest.DocFileSuite('../../../doc/resolvers.txt')]) 1922 return suite
1923 1924 if __name__ == '__main__': 1925 print 'to test use test.py %s' % __file__ 1926