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