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  import os.path
      11  import unittest
      12  import copy
      13  import sys
      14  import re
      15  import operator
      16  import tempfile
      17  import gzip
      18
      19  this_dir = os.path.dirname(__file__)
      20  if this_dir not in sys.path:
      21      sys.path.insert(0, this_dir) # needed for Py3
      22
      23  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
      24  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
      25  from common_imports import canonicalize, sorted, _str, _bytes
      26
      27  print("")
      28  print("TESTED VERSION: %s" % etree.__version__)
      29  print("    Python:           " + repr(sys.version_info))
      30  print("    lxml.etree:       " + repr(etree.LXML_VERSION))
      31  print("    libxml used:      " + repr(etree.LIBXML_VERSION))
      32  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION))
      33  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION))
      34  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
      35  print("")
      36
      37  try:
      38      _unicode = unicode
      39  except NameError:
      40      # Python 3
      41      _unicode = str
      42
      43 -class ETreeOnlyTestCase(HelperTestCase):
      44      """Tests only for etree, not ElementTree"""
      45      etree = etree
      46
      47 -    def test_version(self):
      48          self.assert_(isinstance(etree.__version__, _unicode))
      49          self.assert_(isinstance(etree.LXML_VERSION, tuple))
      50          self.assertEqual(len(etree.LXML_VERSION), 4)
      51          self.assert_(isinstance(etree.LXML_VERSION[0], int))
      52          self.assert_(isinstance(etree.LXML_VERSION[1], int))
      53          self.assert_(isinstance(etree.LXML_VERSION[2], int))
      54          self.assert_(isinstance(etree.LXML_VERSION[3], int))
      55          self.assert_(etree.__version__.startswith(
      56              str(etree.LXML_VERSION[0])))
      57
      58 -    def test_c_api(self):
      59          if hasattr(self.etree, '__pyx_capi__'):
      60              # newer Pyrex compatible C-API
      61              self.assert_(isinstance(self.etree.__pyx_capi__, dict))
      62              self.assert_(len(self.etree.__pyx_capi__) > 0)
      63          else:
      64              # older C-API mechanism
      65              self.assert_(hasattr(self.etree, '_import_c_api'))
      66
      67 -    def test_element_names(self):
      68          Element = self.etree.Element
      69          el = Element('name')
      70          self.assertEquals(el.tag, 'name')
      71          el = Element('{}name')
      72          self.assertEquals(el.tag, 'name')
      73
      74 -    def test_element_name_empty(self):
      75          Element = self.etree.Element
      76          el = Element('name')
      77          self.assertRaises(ValueError, Element, '{}')
      78          self.assertRaises(ValueError, setattr, el, 'tag', '{}')
      79
      80          self.assertRaises(ValueError, Element, '{test}')
      81          self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
      82
      83 -    def test_element_name_colon(self):
      84          Element = self.etree.Element
      85          self.assertRaises(ValueError, Element, 'p:name')
      86          self.assertRaises(ValueError, Element, '{test}p:name')
      87
      88          el = Element('name')
      89          self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
      90
      91 -    def test_element_name_quote(self):
      92          Element = self.etree.Element
      93          self.assertRaises(ValueError, Element, "p'name")
      94          self.assertRaises(ValueError, Element, 'p"name')
      95
      96          self.assertRaises(ValueError, Element, "{test}p'name")
      97          self.assertRaises(ValueError, Element, '{test}p"name')
      98
      99          el = Element('name')
     100          self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
     101          self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
     102
     103 -    def test_element_name_space(self):
     104          Element = self.etree.Element
     105          self.assertRaises(ValueError, Element, ' name ')
     106          self.assertRaises(ValueError, Element, 'na me')
     107          self.assertRaises(ValueError, Element, '{test} name')
     108
     109          el = Element('name')
     110          self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
     111
     112 -    def test_subelement_name_empty(self):
     113          Element = self.etree.Element
     114          SubElement = self.etree.SubElement
     115
     116          el = Element('name')
     117          self.assertRaises(ValueError, SubElement, el, '{}')
     118          self.assertRaises(ValueError, SubElement, el, '{test}')
     119
     120 -    def test_subelement_name_colon(self):
     121          Element = self.etree.Element
     122          SubElement = self.etree.SubElement
     123
     124          el = Element('name')
     125          self.assertRaises(ValueError, SubElement, el, 'p:name')
     126          self.assertRaises(ValueError, SubElement, el, '{test}p:name')
     127
     128 -    def test_subelement_name_quote(self):
     129          Element = self.etree.Element
     130          SubElement = self.etree.SubElement
     131
     132          el = Element('name')
     133          self.assertRaises(ValueError, SubElement, el, "p'name")
     134          self.assertRaises(ValueError, SubElement, el, "{test}p'name")
     135
     136          self.assertRaises(ValueError, SubElement, el, 'p"name')
     137          self.assertRaises(ValueError, SubElement, el, '{test}p"name')
     138
     139 -    def test_subelement_name_space(self):
     140          Element = self.etree.Element
     141          SubElement = self.etree.SubElement
     142
     143          el = Element('name')
     144          self.assertRaises(ValueError, SubElement, el, ' name ')
     145          self.assertRaises(ValueError, SubElement, el, 'na me')
     146          self.assertRaises(ValueError, SubElement, el, '{test} name')
     147
     148 -    def test_subelement_attribute_invalid(self):
     149          Element = self.etree.Element
     150          SubElement = self.etree.SubElement
     151
     152          el = Element('name')
     153          self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
     154          self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
     155          self.assertEquals(0, len(el))
     156
     157 -    def test_qname_empty(self):
     158          QName = self.etree.QName
     159          self.assertRaises(ValueError, QName, '')
     160          self.assertRaises(ValueError, QName, 'test', '')
     161
     162 -    def test_qname_colon(self):
     163          QName = self.etree.QName
     164          self.assertRaises(ValueError, QName, 'p:name')
     165          self.assertRaises(ValueError, QName, 'test', 'p:name')
     166
     167 -    def test_qname_space(self):
     168          QName = self.etree.QName
     169          self.assertRaises(ValueError, QName, ' name ')
     170          self.assertRaises(ValueError, QName, 'na me')
     171          self.assertRaises(ValueError, QName, 'test', ' name')
     172
     173 -    def test_qname_namespace_localname(self):
     174          # ET doesn't have namespace/localname properties on QNames
     175          QName = self.etree.QName
     176          namespace, localname = 'http://myns', 'a'
     177          qname = QName(namespace, localname)
     178          self.assertEquals(namespace, qname.namespace)
     179          self.assertEquals(localname, qname.localname)
     180
     181 -    def test_qname_element(self):
     182          # ET doesn't have namespace/localname properties on QNames
     183          QName = self.etree.QName
     184          qname1 = QName('http://myns', 'a')
     185          a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
     186
     187          qname2 = QName(a)
     188          self.assertEquals(a.tag, qname1.text)
     189          self.assertEquals(qname1.text, qname2.text)
     190          self.assertEquals(qname1, qname2)
     191
     192 -    def test_qname_text_resolve(self):
     193          # ET doesn't resove QNames as text values
     194          etree = self.etree
     195          qname = etree.QName('http://myns', 'a')
     196          a = etree.Element(qname, nsmap={'p' : 'http://myns'})
     197          a.text = qname
     198
     199          self.assertEquals("p:a", a.text)
     200
     201 -    def test_nsmap_prefix_invalid(self):
     202          etree = self.etree
     203          self.assertRaises(ValueError,
     204                            etree.Element, "root", nsmap={'"' : 'testns'})
     205          self.assertRaises(ValueError,
     206                            etree.Element, "root", nsmap={'&' : 'testns'})
     207          self.assertRaises(ValueError,
     208                            etree.Element, "root", nsmap={'a:b' : 'testns'})
     209
     210 -    def test_attribute_has_key(self):
     211          # ET in Py 3.x has no "attrib.has_key()" method
     212          XML = self.etree.XML
     213
     214          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     215          self.assertEquals(
     216              True, root.attrib.has_key('bar'))
     217          self.assertEquals(
     218              False, root.attrib.has_key('baz'))
     219          self.assertEquals(
     220              False, root.attrib.has_key('hah'))
     221          self.assertEquals(
     222              True,
     223              root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
     224
     225 -    def test_attribute_set(self):
     226          Element = self.etree.Element
     227          root = Element("root")
     228          root.set("attr", "TEST")
     229          self.assertEquals("TEST", root.get("attr"))
     230
     231 -    def test_attribute_set_invalid(self):
     232          # ElementTree accepts arbitrary attribute values
     233          # lxml.etree allows only strings
     234          Element = self.etree.Element
     235          root = Element("root")
     236          self.assertRaises(TypeError, root.set, "newattr", 5)
     237          self.assertRaises(TypeError, root.set, "newattr", None)
     238
     239 -    def test_strip_attributes(self):
     240          XML = self.etree.XML
     241          xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
     242
     243          root = XML(xml)
     244          self.etree.strip_attributes(root, 'a')
     245          self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
     246                            self._writeElement(root))
     247
     248          root = XML(xml)
     249          self.etree.strip_attributes(root, 'b', 'c')
     250          self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'),
     251                            self._writeElement(root))
     252
     253 -    def test_strip_attributes_ns(self):
     254          XML = self.etree.XML
     255          xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
     256
     257          root = XML(xml)
     258          self.etree.strip_attributes(root, 'a')
     259          self.assertEquals(
     260              _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
     261              self._writeElement(root))
     262
     263          root = XML(xml)
     264          self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
     265          self.assertEquals(
     266              _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
     267              self._writeElement(root))
     268
     269          root = XML(xml)
     270          self.etree.strip_attributes(root, '{http://test/ns}*')
     271          self.assertEquals(
     272              _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
     273              self._writeElement(root))
     274
     275 -    def test_strip_elements(self):
     276          XML = self.etree.XML
     277          xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
     278
     279          root = XML(xml)
     280          self.etree.strip_elements(root, 'a')
     281          self.assertEquals(_bytes('<test><x></x></test>'),
     282                            self._writeElement(root))
     283
     284          root = XML(xml)
     285          self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
     286          self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'),
     287                            self._writeElement(root))
     288
     289          root = XML(xml)
     290          self.etree.strip_elements(root, 'c')
     291          self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
     292                            self._writeElement(root))
     293
     294 -    def test_strip_elements_ns(self):
     295          XML = self.etree.XML
     296          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     297
     298          root = XML(xml)
     299          self.etree.strip_elements(root, 'a')
     300          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'),
     301                            self._writeElement(root))
     302
     303          root = XML(xml)
     304          self.etree.strip_elements(root, '{urn:a}b', 'c')
     305          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     306                            self._writeElement(root))
     307
     308          root = XML(xml)
     309          self.etree.strip_elements(root, '{urn:a}*', 'c')
     310          self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     311                            self._writeElement(root))
     312
     313          root = XML(xml)
     314          self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
     315          self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     316                            self._writeElement(root))
     317
     318 -    def test_strip_tags(self):
     319          XML = self.etree.XML
     320          xml = _bytes('<test>TEST<a>A<b>B<c/>CT</b>BT</a>AT<x>X<a>A<b/>BT<c/>CT</a>AT</x>XT</test>')
     321
     322          root = XML(xml)
     323          self.etree.strip_tags(root, 'a')
     324          self.assertEquals(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'),
     325                            self._writeElement(root))
     326
     327          root = XML(xml)
     328          self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z')
     329          self.assertEquals(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'),
     330                            self._writeElement(root))
     331
     332          root = XML(xml)
     333          self.etree.strip_tags(root, 'c')
     334          self.assertEquals(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'),
     335                            self._writeElement(root))
     336
     337 -    def test_strip_tags_pi_comment(self):
     338          XML = self.etree.XML
     339          PI = self.etree.ProcessingInstruction
     340          Comment = self.etree.Comment
     341          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     342
     343          root = XML(xml)
     344          self.etree.strip_tags(root, PI)
     345          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'),
     346                            self._writeElement(root))
     347
     348          root = XML(xml)
     349          self.etree.strip_tags(root, Comment)
     350          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'),
     351                            self._writeElement(root))
     352
     353          root = XML(xml)
     354          self.etree.strip_tags(root, PI, Comment)
     355          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     356                            self._writeElement(root))
     357
     358          root = XML(xml)
     359          self.etree.strip_tags(root, Comment, PI)
     360          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     361                            self._writeElement(root))
     362
     363 -    def test_strip_tags_pi_comment_all(self):
     364          XML = self.etree.XML
     365          ElementTree = self.etree.ElementTree
     366          PI = self.etree.ProcessingInstruction
     367          Comment = self.etree.Comment
     368          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     369
     370          root = XML(xml)
     371          self.etree.strip_tags(ElementTree(root), PI)
     372          self.assertEquals(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'),
     373                            self._writeElement(root))
     374
     375          root = XML(xml)
     376          self.etree.strip_tags(ElementTree(root), Comment)
     377          self.assertEquals(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'),
     378                            self._writeElement(root))
     379
     380          root = XML(xml)
     381          self.etree.strip_tags(ElementTree(root), PI, Comment)
     382          self.assertEquals(_bytes('<test>TESTXT</test>'),
     383                            self._writeElement(root))
     384
     385          root = XML(xml)
     386          self.etree.strip_tags(ElementTree(root), Comment, PI)
     387          self.assertEquals(_bytes('<test>TESTXT</test>'),
     388                            self._writeElement(root))
     389
     390 -    def test_strip_tags_doc_style(self):
     391          XML = self.etree.XML
     392          xml = _bytes('''
     393          <div>
     394              <div>
     395                  I like <strong>sheep</strong>.
     396                  <br/>
     397                  I like lots of <strong>sheep</strong>.
     398                  <br/>
     399                  Click <a href="http://www.sheep.com">here</a> for <a href="http://www.sheep.com">those</a> sheep.
     400                  <br/>
     401              </div>
     402          </div>
     403          '''.strip())
     404
     405          root = XML(xml)
     406          self.etree.strip_tags(root, 'a')
     407          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')),
     408                            self._writeElement(root))
     409
     410          root = XML(xml)
     411          self.etree.strip_tags(root, 'a', 'br')
     412          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''),
     413                                   re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)),
     414                            self._writeElement(root))
     415
     416 -    def test_strip_tags_ns(self):
     417          XML = self.etree.XML
     418          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>CT</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     419
     420          root = XML(xml)
     421          self.etree.strip_tags(root, 'a')
     422          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'),
     423                            self._writeElement(root))
     424
     425          root = XML(xml)
     426          self.etree.strip_tags(root, '{urn:a}b', 'c')
     427          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     428                            self._writeElement(root))
     429
     430          root = XML(xml)
     431          self.etree.strip_tags(root, '{urn:a}*', 'c')
     432          self.assertEquals(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     433                            self._writeElement(root))
     434
     435 -    def test_strip_tags_and_remove(self):
     436          # previously crashed
     437          HTML = self.etree.HTML
     438          root = HTML(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'))[0][0]
     439          self.assertEquals(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'),
     440                            self.etree.tostring(root))
     441          self.etree.strip_tags(root, 'b')
     442          self.assertEquals(_bytes('<div><h1>title</h1> foo <p>boo</p></div>'),
     443                            self.etree.tostring(root))
     444          root.remove(root[0])
     445          self.assertEquals(_bytes('<div><p>boo</p></div>'),
     446                            self.etree.tostring(root))
     447
     448 -    def test_pi(self):
     449          # lxml.etree separates target and text
     450          Element = self.etree.Element
     451          SubElement = self.etree.SubElement
     452          ProcessingInstruction = self.etree.ProcessingInstruction
     453
     454          a = Element('a')
     455          a.append(ProcessingInstruction('foo', 'some more text'))
     456          self.assertEquals(a[0].target, 'foo')
     457          self.assertEquals(a[0].text, 'some more text')
     458
     459 -    def test_pi_parse(self):
     460          XML = self.etree.XML
     461          root = XML(_bytes("<test><?mypi my test ?></test>"))
     462          self.assertEquals(root[0].target, "mypi")
     463          self.assertEquals(root[0].text, "my test ")
     464
     465 -    def test_pi_pseudo_attributes_get(self):
     466          XML = self.etree.XML
     467          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
     468          self.assertEquals(root[0].target, "mypi")
     469          self.assertEquals(root[0].get('my'), "1")
     470          self.assertEquals(root[0].get('test'), " abc ")
     471          self.assertEquals(root[0].get('quotes'), "' '")
     472          self.assertEquals(root[0].get('only'), None)
     473          self.assertEquals(root[0].get('names'), None)
     474          self.assertEquals(root[0].get('nope'), None)
     475
     476 -    def test_pi_pseudo_attributes_attrib(self):
     477          XML = self.etree.XML
     478          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
     479          self.assertEquals(root[0].target, "mypi")
     480          self.assertEquals(root[0].attrib['my'], "1")
     481          self.assertEquals(root[0].attrib['test'], " abc ")
     482          self.assertEquals(root[0].attrib['quotes'], "' '")
     483          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
     484          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
     485          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
     486
     487 -    def test_deepcopy_pi(self):
     488          # previously caused a crash
     489          ProcessingInstruction = self.etree.ProcessingInstruction
     490
     491          a = ProcessingInstruction("PI", "ONE")
     492          b = copy.deepcopy(a)
     493          b.text = "ANOTHER"
     494
     495          self.assertEquals('ONE',     a.text)
     496          self.assertEquals('ANOTHER', b.text)
     497
     498 -    def test_deepcopy_elementtree_pi(self):
     499          XML = self.etree.XML
     500          tostring = self.etree.tostring
     501          root = XML(_bytes("<?mypi my test ?><test/><!--comment -->"))
     502          tree1 = self.etree.ElementTree(root)
     503          self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
     504                            tostring(tree1))
     505
     506          tree2 = copy.deepcopy(tree1)
     507          self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
     508                            tostring(tree2))
     509
     510          root2 = copy.deepcopy(tree1.getroot())
     511          self.assertEquals(_bytes("<test/>"),
     512                            tostring(root2))
     513
     514 -    def test_deepcopy_elementtree_dtd(self):
     515          XML = self.etree.XML
     516          tostring = self.etree.tostring
     517          xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
     518          root = XML(xml)
     519          tree1 = self.etree.ElementTree(root)
     520          self.assertEquals(xml, tostring(tree1))
     521
     522          tree2 = copy.deepcopy(tree1)
     523          self.assertEquals(xml, tostring(tree2))
     524
     525          root2 = copy.deepcopy(tree1.getroot())
     526          self.assertEquals(_bytes("<test/>"),
     527                            tostring(root2))
     528
     529 -    def test_attribute_set(self):
     530          # ElementTree accepts arbitrary attribute values
     531          # lxml.etree allows only strings
     532          Element = self.etree.Element
     533
     534          root = Element("root")
     535          root.set("attr", "TEST")
     536          self.assertEquals("TEST", root.get("attr"))
     537          self.assertRaises(TypeError, root.set, "newattr", 5)
     538
     539 -    def test_parse_remove_comments(self):
     540          fromstring = self.etree.fromstring
     541          tostring = self.etree.tostring
     542          XMLParser = self.etree.XMLParser
     543
     544          xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     545          parser = XMLParser(remove_comments=True)
     546          root = fromstring(xml, parser)
     547          self.assertEquals(
     548              _bytes('<a><b><c/></b></a>'),
     549              tostring(root))
     550
     551 -    def test_parse_remove_pis(self):
     552          parse = self.etree.parse
     553          tostring = self.etree.tostring
     554          XMLParser = self.etree.XMLParser
     555
     556          xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>')
     557
     558          f = BytesIO(xml)
     559          tree = parse(f)
     560          self.assertEquals(
     561              xml,
     562              tostring(tree))
     563
     564          parser = XMLParser(remove_pis=True)
     565          tree = parse(f, parser)
     566          self.assertEquals(
     567              _bytes('<a><b><c/></b></a>'),
     568              tostring(tree))
     569
     570 -    def test_parse_parser_type_error(self):
     571          # ET raises IOError only
     572          parse = self.etree.parse
     573          self.assertRaises(TypeError, parse, 'notthere.xml', object())
     574
     575 -    def test_iterparse_tree_comments(self):
     576          # ET removes comments
     577          iterparse = self.etree.iterparse
     578          tostring = self.etree.tostring
     579
     580          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     581          events = list(iterparse(f))
     582          root = events[-1][1]
     583          self.assertEquals(3, len(events))
     584          self.assertEquals(
     585              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
     586              tostring(root))
     587
     588 -    def test_iterparse_comments(self):
     589          # ET removes comments
     590          iterparse = self.etree.iterparse
     591          tostring = self.etree.tostring
     592
     593          def name(event, el):
     594              if event == 'comment':
     595                  return el.text
     596              else:
     597                  return el.tag
     598
     599          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     600          events = list(iterparse(f, events=('end', 'comment')))
     601          root = events[-1][1]
     602          self.assertEquals(6, len(events))
     603          self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'],
     604                            [ name(*item) for item in events ])
     605          self.assertEquals(
     606              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
     607              tostring(root))
     608
     609 -    def test_iterparse_pis(self):
     610          # ET removes pis
     611          iterparse = self.etree.iterparse
     612          tostring = self.etree.tostring
     613          ElementTree = self.etree.ElementTree
     614
     615          def name(event, el):
     616              if event == 'pi':
     617                  return (el.target, el.text)
     618              else:
     619                  return el.tag
     620
     621          f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
     622          events = list(iterparse(f, events=('end', 'pi')))
     623          root = events[-2][1]
     624          self.assertEquals(8, len(events))
     625          self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
     626                             ('pid','d'), 'a', ('pie','e')],
     627                            [ name(*item) for item in events ])
     628          self.assertEquals(
     629              _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
     630              tostring(ElementTree(root)))
     631
     632 -    def test_iterparse_remove_comments(self):
     633          iterparse = self.etree.iterparse
     634          tostring = self.etree.tostring
     635
     636          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     637          events = list(iterparse(f, remove_comments=True,
     638                                  events=('end', 'comment')))
     639          root = events[-1][1]
     640          self.assertEquals(3, len(events))
     641          self.assertEquals(['c', 'b', 'a'],
     642                            [ el.tag for (event, el) in events ])
     643          self.assertEquals(
     644              _bytes('<a><b><c/></b></a>'),
     645              tostring(root))
     646
     647 -    def test_iterparse_broken(self):
     648          iterparse = self.etree.iterparse
     649          f = BytesIO('<a><b><c/></a>')
     650          # ET raises ExpatError, lxml raises XMLSyntaxError
     651          self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
     652
     653 -    def test_iterparse_strip(self):
     654          iterparse = self.etree.iterparse
     655          f = BytesIO("""
     656                 <a>  \n \n  <b> b test </b>  \n
     657
     658                 \n\t <c> \n </c> </a>  \n """)
     659          iterator = iterparse(f, remove_blank_text=True)
     660          text = [ (element.text, element.tail)
     661                   for event, element in iterator ]
     662          self.assertEquals(
     663              [(" b test ", None), (" \n ", None), (None, None)],
     664              text)
     665
     666 -    def test_iterparse_tag(self):
     667          iterparse = self.etree.iterparse
     668          f = BytesIO('<a><b><d/></b><c/></a>')
     669
     670          iterator = iterparse(f, tag="b", events=('start', 'end'))
     671          events = list(iterator)
     672          root = iterator.root
     673          self.assertEquals(
     674              [('start', root[0]), ('end', root[0])],
     675              events)
     676
     677 -    def test_iterparse_tag_all(self):
     678          iterparse = self.etree.iterparse
     679          f = BytesIO('<a><b><d/></b><c/></a>')
     680
     681          iterator = iterparse(f, tag="*", events=('start', 'end'))
     682          events = list(iterator)
     683          self.assertEquals(
     684              8,
     685              len(events))
     686
     687 -    def test_iterparse_tag_ns(self):
     688          iterparse = self.etree.iterparse
     689          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     690
     691          iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
     692          events = list(iterator)
     693          root = iterator.root
     694          self.assertEquals(
     695              [('start', root[0]), ('end', root[0])],
     696              events)
     697
     698 -    def test_iterparse_tag_ns_empty(self):
     699          iterparse = self.etree.iterparse
     700          f = BytesIO('<a><b><d/></b><c/></a>')
     701          iterator = iterparse(f, tag="{}b", events=('start', 'end'))
     702          events = list(iterator)
     703          root = iterator.root
     704          self.assertEquals(
     705              [('start', root[0]), ('end', root[0])],
     706              events)
     707
     708          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     709          iterator = iterparse(f, tag="{}b", events=('start', 'end'))
     710          events = list(iterator)
     711          root = iterator.root
     712          self.assertEquals([], events)
     713
     714 -    def test_iterparse_tag_ns_all(self):
     715          iterparse = self.etree.iterparse
     716          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     717          iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
     718          events = list(iterator)
     719          self.assertEquals(8, len(events))
     720
     721 -    def test_iterparse_tag_ns_empty_all(self):
     722          iterparse = self.etree.iterparse
     723          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     724          iterator = iterparse(f, tag="{}*", events=('start', 'end'))
     725          events = list(iterator)
     726          self.assertEquals([], events)
     727
     728          f = BytesIO('<a><b><d/></b><c/></a>')
     729          iterator = iterparse(f, tag="{}*", events=('start', 'end'))
     730          events = list(iterator)
     731          self.assertEquals(8, len(events))
     732
     733 -    def test_iterparse_encoding_error(self):
     734          text = _str('Søk på nettet')
     735          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
     736          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
     737                        ).encode('iso-8859-1')
     738
     739          self.assertRaises(self.etree.ParseError,
     740                            list, self.etree.iterparse(BytesIO(xml_latin1)))
     741
     742 -    def test_iterparse_encoding_8bit_override(self):
     743          text = _str('Søk på nettet', encoding="UTF-8")
     744          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
     745          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
     746                        ).encode('iso-8859-1')
     747
     748          iterator = self.etree.iterparse(BytesIO(xml_latin1),
     749                                          encoding="iso-8859-1")
     750          self.assertEquals(1, len(list(iterator)))
     751
     752          a = iterator.root
     753          self.assertEquals(a.text, text)
     754
     755 -    def test_iterparse_keep_cdata(self):
     756          tostring = self.etree.tostring
     757          f = BytesIO('<root><![CDATA[test]]></root>')
     758          context = self.etree.iterparse(f, strip_cdata=False)
     759          content = [ el.text for event,el in context ]
     760
     761          self.assertEquals(['test'], content)
     762          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
     763                            tostring(context.root))
     764
     765 -    def test_parser_encoding_unknown(self):
     766          self.assertRaises(
     767              LookupError, self.etree.XMLParser, encoding="hopefully unknown")
     768
     769 -    def test_parser_encoding(self):
     770          self.etree.XMLParser(encoding="ascii")
     771          self.etree.XMLParser(encoding="utf-8")
     772          self.etree.XMLParser(encoding="iso-8859-1")
     773
     774 -    def test_feed_parser_recover(self):
     775          parser = self.etree.XMLParser(recover=True)
     776
     777          parser.feed('<?xml version=')
     778          parser.feed('"1.0"?><ro')
     779          parser.feed('ot><')
     780          parser.feed('a test="works"')
     781          parser.feed('><othertag/></root') # <a> not closed!
     782          parser.feed('>')
     783
     784          root = parser.close()
     785
     786          self.assertEquals(root.tag, "root")
     787          self.assertEquals(len(root), 1)
     788          self.assertEquals(root[0].tag, "a")
     789          self.assertEquals(root[0].get("test"), "works")
     790          self.assertEquals(len(root[0]), 1)
     791          self.assertEquals(root[0][0].tag, "othertag")
     792          # FIXME: would be nice to get some errors logged ...
     793          #self.assert_(len(parser.error_log) > 0, "error log is empty")
     794
     795 -    def test_elementtree_parser_target_type_error(self):
     796          assertEquals = self.assertEquals
     797          assertFalse  = self.assertFalse
     798
     799          events = []
     800          class Target(object):
     801              def start(self, tag, attrib):
     802                  events.append("start")
     803                  assertFalse(attrib)
     804                  assertEquals("TAG", tag)
     805              def end(self, tag):
     806                  events.append("end")
     807                  assertEquals("TAG", tag)
     808              def close(self):
     809                  return "DONE" # no Element!
     810
     811          parser = self.etree.XMLParser(target=Target())
     812          tree = self.etree.ElementTree()
     813
     814          self.assertRaises(TypeError,
     815                            tree.parse, BytesIO("<TAG/>"), parser=parser)
     816          self.assertEquals(["start", "end"], events)
     817
     818 -    def test_parser_target_feed_exception(self):
     819          # ET doesn't call .close() on errors
     820          events = []
     821          class Target(object):
     822              def start(self, tag, attrib):
     823                  events.append("start-" + tag)
     824              def end(self, tag):
     825                  events.append("end-" + tag)
     826                  if tag == 'a':
     827                      raise ValueError("dead and gone")
     828              def data(self, data):
     829                  events.append("data-" + data)
     830              def close(self):
     831                  events.append("close")
     832                  return "DONE"
     833
     834          parser = self.etree.XMLParser(target=Target())
     835
     836          try:
     837              parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
     838              done = parser.close()
     839              self.fail("error expected, but parsing succeeded")
     840          except ValueError:
     841              done = 'value error received as expected'
     842
     843          self.assertEquals(["start-root", "data-A", "start-a",
     844                             "data-ca", "end-a", "close"],
     845                            events)
     846
     847 -    def test_parser_target_fromstring_exception(self):
     848          # ET doesn't call .close() on errors
     849          events = []
     850          class Target(object):
     851              def start(self, tag, attrib):
     852                  events.append("start-" + tag)
     853              def end(self, tag):
     854                  events.append("end-" + tag)
     855                  if tag == 'a':
     856                      raise ValueError("dead and gone")
     857              def data(self, data):
     858                  events.append("data-" + data)
     859              def close(self):
     860                  events.append("close")
     861                  return "DONE"
     862
     863          parser = self.etree.XMLParser(target=Target())
     864
     865          try:
     866              done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
     867                                           parser=parser)
     868              self.fail("error expected, but parsing succeeded")
     869          except ValueError:
     870              done = 'value error received as expected'
     871
     872          self.assertEquals(["start-root", "data-A", "start-a",
     873                             "data-ca", "end-a", "close"],
     874                            events)
     875
     876 -    def test_parser_target_comment(self):
     877          events = []
     878          class Target(object):
     879              def start(self, tag, attrib):
     880                  events.append("start-" + tag)
     881              def end(self, tag):
     882                  events.append("end-" + tag)
     883              def data(self, data):
     884                  events.append("data-" + data)
     885              def comment(self, text):
     886                  events.append("comment-" + text)
     887              def close(self):
     888                  return "DONE"
     889
     890          parser = self.etree.XMLParser(target=Target())
     891
     892          parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
     893          done = parser.close()
     894
     895          self.assertEquals("DONE", done)
     896          self.assertEquals(["comment-a", "start-root", "data-A", "comment-b",
     897                             "start-sub", "end-sub", "comment-c", "data-B",
     898                             "end-root", "comment-d"],
     899                            events)
     900
     901 -    def test_parser_target_pi(self):
     902          events = []
     903          class Target(object):
     904              def start(self, tag, attrib):
     905                  events.append("start-" + tag)
     906              def end(self, tag):
     907                  events.append("end-" + tag)
     908              def data(self, data):
     909                  events.append("data-" + data)
     910              def pi(self, target, data):
     911                  events.append("pi-" + target + "-" + data)
     912              def close(self):
     913                  return "DONE"
     914
     915          parser = self.etree.XMLParser(target=Target())
     916
     917          parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
     918          done = parser.close()
     919
     920          self.assertEquals("DONE", done)
     921          self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b",
     922                             "data-B", "end-root", "pi-test-c"],
     923                            events)
     924
     925 -    def test_parser_target_cdata(self):
     926          events = []
     927          class Target(object):
     928              def start(self, tag, attrib):
     929                  events.append("start-" + tag)
     930              def end(self, tag):
     931                  events.append("end-" + tag)
     932              def data(self, data):
     933                  events.append("data-" + data)
     934              def close(self):
     935                  return "DONE"
     936
     937          parser = self.etree.XMLParser(target=Target(),
     938                                        strip_cdata=False)
     939
     940          parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
     941          done = parser.close()
     942
     943          self.assertEquals("DONE", done)
     944          self.assertEquals(["start-root", "data-A", "start-a",
     945                             "data-ca", "end-a", "data-B", "end-root"],
     946                            events)
     947
     948 -    def test_parser_target_recover(self):
     949          events = []
     950          class Target(object):
     951              def start(self, tag, attrib):
     952                  events.append("start-" + tag)
     953              def end(self, tag):
     954                  events.append("end-" + tag)
     955              def data(self, data):
     956                  events.append("data-" + data)
     957              def close(self):
     958                  events.append("close")
     959                  return "DONE"
     960
     961          parser = self.etree.XMLParser(target=Target(),
     962                                        recover=True)
     963
     964          parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
     965          done = parser.close()
     966
     967          self.assertEquals("DONE", done)
     968          self.assertEquals(["start-root", "data-A", "start-a",
     969                             "data-ca", "end-a", "data-B",
     970                             "end-root", "close"],
     971                            events)
     972
     973 -    def test_iterwalk_tag(self):
     974          iterwalk = self.etree.iterwalk
     975          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
     976
     977          iterator = iterwalk(root, tag="b", events=('start', 'end'))
     978          events = list(iterator)
     979          self.assertEquals(
     980              [('start', root[0]), ('end', root[0])],
     981              events)
     982
     983 -    def test_iterwalk_tag_all(self):
     984          iterwalk = self.etree.iterwalk
     985          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
     986
     987          iterator = iterwalk(root, tag="*", events=('start', 'end'))
     988          events = list(iterator)
     989          self.assertEquals(
     990              8,
     991              len(events))
     992
     993 -    def test_iterwalk(self):
     994          iterwalk = self.etree.iterwalk
     995          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
     996
     997          events = list(iterwalk(root))
     998          self.assertEquals(
     999              [('end', root[0]), ('end', root[1]), ('end', root)],
    1000              events)
    1001
    1002 -    def test_iterwalk_start(self):
    1003          iterwalk = self.etree.iterwalk
    1004          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1005
    1006          iterator = iterwalk(root, events=('start',))
    1007          events = list(iterator)
    1008          self.assertEquals(
    1009              [('start', root), ('start', root[0]), ('start', root[1])],
    1010              events)
    1011
    1012 -    def test_iterwalk_start_end(self):
    1013          iterwalk = self.etree.iterwalk
    1014          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1015
    1016          iterator = iterwalk(root, events=('start','end'))
    1017          events = list(iterator)
    1018          self.assertEquals(
    1019              [('start', root), ('start', root[0]), ('end', root[0]),
    1020               ('start', root[1]), ('end', root[1]), ('end', root)],
    1021              events)
    1022
    1023 -    def test_iterwalk_clear(self):
    1024          iterwalk = self.etree.iterwalk
    1025          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1026
    1027          iterator = iterwalk(root)
    1028          for event, elem in iterator:
    1029              elem.clear()
    1030
    1031          self.assertEquals(0,
    1032                            len(root))
    1033
    1034 -    def test_iterwalk_attrib_ns(self):
    1035          iterwalk = self.etree.iterwalk
    1036          root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
    1037
    1038          attr_name = '{testns}bla'
    1039          events = []
    1040          iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
    1041          for event, elem in iterator:
    1042              events.append(event)
    1043              if event == 'start':
    1044                  if elem.tag != '{ns1}a':
    1045                      elem.set(attr_name, 'value')
    1046
    1047          self.assertEquals(
    1048              ['start-ns', 'start', 'start', 'start-ns', 'start',
    1049               'end', 'end-ns', 'end', 'end', 'end-ns'],
    1050              events)
    1051
    1052          self.assertEquals(
    1053              None,
    1054              root.get(attr_name))
    1055          self.assertEquals(
    1056              'value',
    1057              root[0].get(attr_name))
    1058
    1059 -    def test_iterwalk_getiterator(self):
    1060          iterwalk = self.etree.iterwalk
    1061          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
    1062
    1063          counts = []
    1064          for event, elem in iterwalk(root):
    1065              counts.append(len(list(elem.getiterator())))
    1066          self.assertEquals(
    1067              [1,2,1,4],
    1068              counts)
    1069
    1070 -    def test_resolve_string_dtd(self):
    1071          parse = self.etree.parse
    1072          parser = self.etree.XMLParser(dtd_validation=True)
    1073          assertEqual = self.assertEqual
    1074          test_url = _str("__nosuch.dtd")
    1075
    1076          class MyResolver(self.etree.Resolver):
    1077              def resolve(self, url, id, context):
    1078                  assertEqual(url, test_url)
    1079                  return self.resolve_string(
    1080                      _str('''<!ENTITY myentity "%s">
    1081                          <!ELEMENT doc ANY>''') % url, context)
    1082
    1083          parser.resolvers.add(MyResolver())
    1084
    1085          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1086          tree = parse(StringIO(xml), parser)
    1087          root = tree.getroot()
    1088          self.assertEquals(root.text, test_url)
    1089
    1090 -    def test_resolve_bytes_dtd(self):
    1091          parse = self.etree.parse
    1092          parser = self.etree.XMLParser(dtd_validation=True)
    1093          assertEqual = self.assertEqual
    1094          test_url = _str("__nosuch.dtd")
    1095
    1096          class MyResolver(self.etree.Resolver):
    1097              def resolve(self, url, id, context):
    1098                  assertEqual(url, test_url)
    1099                  return self.resolve_string(
    1100                      (_str('''<!ENTITY myentity "%s">
    1101                               <!ELEMENT doc ANY>''') % url).encode('utf-8'),
    1102                      context)
    1103
    1104          parser.resolvers.add(MyResolver())
    1105
    1106          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1107          tree = parse(StringIO(xml), parser)
    1108          root = tree.getroot()
    1109          self.assertEquals(root.text, test_url)
    1110
    1111 -    def test_resolve_filelike_dtd(self):
    1112          parse = self.etree.parse
    1113          parser = self.etree.XMLParser(dtd_validation=True)
    1114          assertEqual = self.assertEqual
    1115          test_url = _str("__nosuch.dtd")
    1116
    1117          class MyResolver(self.etree.Resolver):
    1118              def resolve(self, url, id, context):
    1119                  assertEqual(url, test_url)
    1120                  return self.resolve_file(
    1121                      SillyFileLike(
    1122                          _str('''<!ENTITY myentity "%s">
    1123                          <!ELEMENT doc ANY>''') % url), context)
    1124
    1125          parser.resolvers.add(MyResolver())
    1126
    1127          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1128          tree = parse(StringIO(xml), parser)
    1129          root = tree.getroot()
    1130          self.assertEquals(root.text, test_url)
    1131
    1132 -    def test_resolve_filename_dtd(self):
    1133          parse = self.etree.parse
    1134          parser = self.etree.XMLParser(attribute_defaults=True)
    1135          assertEqual = self.assertEqual
    1136          test_url = _str("__nosuch.dtd")
    1137
    1138          class MyResolver(self.etree.Resolver):
    1139              def resolve(self, url, id, context):
    1140                  assertEqual(url, test_url)
    1141                  return self.resolve_filename(
    1142                      fileInTestDir('test.dtd'), context)
    1143
    1144          parser.resolvers.add(MyResolver())
    1145
    1146          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1147          tree = parse(StringIO(xml), parser)
    1148          root = tree.getroot()
    1149          self.assertEquals(
    1150              root.attrib,    {'default': 'valueA'})
    1151          self.assertEquals(
    1152              root[0].attrib, {'default': 'valueB'})
    1153
    1154 -    def test_resolve_filename_dtd_relative(self):
    1155          parse = self.etree.parse
    1156          parser = self.etree.XMLParser(attribute_defaults=True)
    1157          assertEqual = self.assertEqual
    1158          test_url = _str("__nosuch.dtd")
    1159
    1160          class MyResolver(self.etree.Resolver):
    1161              def resolve(self, url, id, context):
    1162                  assertEqual(url, fileInTestDir(test_url))
    1163                  return self.resolve_filename(
    1164                      fileInTestDir('test.dtd'), context)
    1165
    1166          parser.resolvers.add(MyResolver())
    1167
    1168          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1169          tree = parse(StringIO(xml), parser,
    1170                       base_url=fileInTestDir('__test.xml'))
    1171          root = tree.getroot()
    1172          self.assertEquals(
    1173              root.attrib,    {'default': 'valueA'})
    1174          self.assertEquals(
    1175              root[0].attrib, {'default': 'valueB'})
    1176
    1177 -    def test_resolve_file_dtd(self):
    1178          parse = self.etree.parse
    1179          parser = self.etree.XMLParser(attribute_defaults=True)
    1180          assertEqual = self.assertEqual
    1181          test_url = _str("__nosuch.dtd")
    1182
    1183          class MyResolver(self.etree.Resolver):
    1184              def resolve(self, url, id, context):
    1185                  assertEqual(url, test_url)
    1186                  return self.resolve_file(
    1187                      open(fileInTestDir('test.dtd'), 'rb'), context)
    1188
    1189          parser.resolvers.add(MyResolver())
    1190
    1191          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1192          tree = parse(StringIO(xml), parser)
    1193          root = tree.getroot()
    1194          self.assertEquals(
    1195              root.attrib,    {'default': 'valueA'})
    1196          self.assertEquals(
    1197              root[0].attrib, {'default': 'valueB'})
    1198
    1199 -    def test_resolve_empty(self):
    1200          parse = self.etree.parse
    1201          parser = self.etree.XMLParser(load_dtd=True)
    1202          assertEqual = self.assertEqual
    1203          test_url = _str("__nosuch.dtd")
    1204
    1205          class check(object):
    1206              resolved = False
    1207
    1208          class MyResolver(self.etree.Resolver):
    1209              def resolve(self, url, id, context):
    1210                  assertEqual(url, test_url)
    1211                  check.resolved = True
    1212                  return self.resolve_empty(context)
    1213
    1214          parser.resolvers.add(MyResolver())
    1215
    1216          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1217          self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
    1218          self.assert_(check.resolved)
    1219
    1220 -    def test_resolve_error(self):
    1221          parse = self.etree.parse
    1222          parser = self.etree.XMLParser(dtd_validation=True)
    1223
    1224          class _LocalException(Exception):
    1225              pass
    1226
    1227          class MyResolver(self.etree.Resolver):
    1228              def resolve(self, url, id, context):
    1229                  raise _LocalException
    1230
    1231          parser.resolvers.add(MyResolver())
    1232
    1233          xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
    1234          self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
    1235
    1236      if etree.LIBXML_VERSION > (2,6,20):
    1237 -        def test_entity_parse(self):
    1238              parse = self.etree.parse
    1239              tostring = self.etree.tostring
    1240              parser = self.etree.XMLParser(resolve_entities=False)
    1241              Entity = self.etree.Entity
    1242
    1243              xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
    1244              tree = parse(BytesIO(xml), parser)
    1245              root = tree.getroot()
    1246              self.assertEquals(root[0].tag, Entity)
    1247              self.assertEquals(root[0].text, "&myentity;")
    1248              self.assertEquals(root[0].tail, None)
    1249              self.assertEquals(root[0].name, "myentity")
    1250
    1251              self.assertEquals(_bytes('<doc>&myentity;</doc>'),
    1252                                tostring(root))
    1253
    1254 -        def test_entity_restructure(self):
    1255              xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]>
    1256                  <root>
    1257                    <child1/>
    1258                    <child2/>
    1259                    <child3>&nbsp;</child3>
    1260                  </root>''')
    1261
    1262              parser = self.etree.XMLParser(resolve_entities=False)
    1263              root = etree.fromstring(xml, parser)
    1264              self.assertEquals([ el.tag for el in root ],
    1265                                ['child1', 'child2', 'child3'])
    1266
    1267              root[0] = root[-1]
    1268              self.assertEquals([ el.tag for el in root ],
    1269                                ['child3', 'child2'])
    1270              self.assertEquals(root[0][0].text, '&nbsp;')
    1271              self.assertEquals(root[0][0].name, 'nbsp')
    1272
    1273 -    def test_entity_append(self):
    1274          Entity = self.etree.Entity
    1275          Element = self.etree.Element
    1276          tostring = self.etree.tostring
    1277
    1278          root = Element("root")
    1279          root.append( Entity("test") )
    1280
    1281          self.assertEquals(root[0].tag, Entity)
    1282          self.assertEquals(root[0].text, "&test;")
    1283          self.assertEquals(root[0].tail, None)
    1284          self.assertEquals(root[0].name, "test")
    1285
    1286          self.assertEquals(_bytes('<root>&test;</root>'),
    1287                            tostring(root))
    1288
    1289 -    def test_entity_values(self):
    1290          Entity = self.etree.Entity
    1291          self.assertEquals(Entity("test").text, '&test;')
    1292          self.assertEquals(Entity("#17683").text, '&#17683;')
    1293          self.assertEquals(Entity("#x1768").text, '&#x1768;')
    1294          self.assertEquals(Entity("#x98AF").text, '&#x98AF;')
    1295
    1296 -    def test_entity_error(self):
    1297          Entity = self.etree.Entity
    1298          self.assertRaises(ValueError, Entity, 'a b c')
    1299          self.assertRaises(ValueError, Entity, 'a,b')
    1300          self.assertRaises(ValueError, Entity, 'a\0b')
    1301          self.assertRaises(ValueError, Entity, '#abc')
    1302          self.assertRaises(ValueError, Entity, '#xxyz')
    1303
    1304 -    def test_cdata(self):
    1305          CDATA = self.etree.CDATA
    1306          Element = self.etree.Element
    1307          tostring = self.etree.tostring
    1308
    1309          root = Element("root")
    1310          root.text = CDATA('test')
    1311
    1312          self.assertEquals('test',
    1313                            root.text)
    1314          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1315                            tostring(root))
    1316
    1317 -    def test_cdata_type(self):
    1318          CDATA = self.etree.CDATA
    1319          Element = self.etree.Element
    1320          root = Element("root")
    1321
    1322          root.text = CDATA("test")
    1323          self.assertEquals('test', root.text)
    1324
    1325          root.text = CDATA(_str("test"))
    1326          self.assertEquals('test', root.text)
    1327
    1328          self.assertRaises(TypeError, CDATA, 1)
    1329
    1330 -    def test_cdata_errors(self):
    1331          CDATA = self.etree.CDATA
    1332          Element = self.etree.Element
    1333
    1334          root = Element("root")
    1335          cdata = CDATA('test')
    1336
    1337          self.assertRaises(TypeError,
    1338                            setattr, root, 'tail', cdata)
    1339          self.assertRaises(TypeError,
    1340                            root.set, 'attr', cdata)
    1341          self.assertRaises(TypeError,
    1342                            operator.setitem, root.attrib, 'attr', cdata)
    1343
    1344 -    def test_cdata_parser(self):
    1345          tostring = self.etree.tostring
    1346          parser = self.etree.XMLParser(strip_cdata=False)
    1347          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
    1348
    1349          self.assertEquals('test', root.text)
    1350          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1351                            tostring(root))
    1352
    1353 -    def test_cdata_xpath(self):
    1354          tostring = self.etree.tostring
    1355          parser = self.etree.XMLParser(strip_cdata=False)
    1356          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
    1357          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1358                            tostring(root))
    1359
    1360          self.assertEquals(['test'], root.xpath('//text()'))
    1361
    1362      # TypeError in etree, AssertionError in ElementTree;
    1363 -    def test_setitem_assert(self):
    1364          Element = self.etree.Element
    1365          SubElement = self.etree.SubElement
    1366
    1367          a = Element('a')
    1368          b = SubElement(a, 'b')
    1369
    1370          self.assertRaises(TypeError,
    1371                            a.__setitem__, 0, 'foo')
    1372
    1373 -    def test_append_error(self):
    1374          Element = self.etree.Element
    1375          root = Element('root')
    1376          # raises AssertionError in ElementTree
    1377          self.assertRaises(TypeError, root.append, None)
    1378          self.assertRaises(TypeError, root.extend, [None])
    1379          self.assertRaises(TypeError, root.extend, [Element('one'), None])
    1380          self.assertEquals('one', root[0].tag)
    1381
    1382 -    def test_addnext(self):
    1383          Element = self.etree.Element
    1384          SubElement = self.etree.SubElement
    1385          root = Element('root')
    1386          SubElement(root, 'a')
    1387          SubElement(root, 'b')
    1388
    1389          self.assertEquals(['a', 'b'],
    1390                            [c.tag for c in root])
    1391          root[1].addnext(root[0])
    1392          self.assertEquals(['b', 'a'],
    1393                            [c.tag for c in root])
    1394
    1395 -    def test_addprevious(self):
    1396          Element = self.etree.Element
    1397          SubElement = self.etree.SubElement
    1398          root = Element('root')
    1399          SubElement(root, 'a')
    1400          SubElement(root, 'b')
    1401
    1402          self.assertEquals(['a', 'b'],
    1403                            [c.tag for c in root])
    1404          root[0].addprevious(root[1])
    1405          self.assertEquals(['b', 'a'],
    1406                            [c.tag for c in root])
    1407
    1408 -    def test_addnext_root(self):
    1409          Element = self.etree.Element
    1410          a = Element('a')
    1411          b = Element('b')
    1412          self.assertRaises(TypeError, a.addnext, b)
    1413
    1414 -    def test_addnext_root(self):
    1415          Element = self.etree.Element
    1416          a = Element('a')
    1417          b = Element('b')
    1418          self.assertRaises(TypeError, a.addnext, b)
    1419
    1420 -    def test_addprevious_pi(self):
    1421          Element = self.etree.Element
    1422          SubElement = self.etree.SubElement
    1423          PI = self.etree.PI
    1424          root = Element('root')
    1425          SubElement(root, 'a')
    1426          pi = PI('TARGET', 'TEXT')
    1427          pi.tail = "TAIL"
    1428
    1429          self.assertEquals(_bytes('<root><a></a></root>'),
    1430                            self._writeElement(root))
    1431          root[0].addprevious(pi)
    1432          self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
    1433                            self._writeElement(root))
    1434
    1435 -    def test_addprevious_root_pi(self):
    1436          Element = self.etree.Element
    1437          PI = self.etree.PI
    1438          root = Element('root')
    1439          pi = PI('TARGET', 'TEXT')
    1440          pi.tail = "TAIL"
    1441
    1442          self.assertEquals(_bytes('<root></root>'),
    1443                            self._writeElement(root))
    1444          root.addprevious(pi)
    1445          self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'),
    1446                            self._writeElement(root))
    1447
    1448 -    def test_addnext_pi(self):
    1449          Element = self.etree.Element
    1450          SubElement = self.etree.SubElement
    1451          PI = self.etree.PI
    1452          root = Element('root')
    1453          SubElement(root, 'a')
    1454          pi = PI('TARGET', 'TEXT')
    1455          pi.tail = "TAIL"
    1456
    1457          self.assertEquals(_bytes('<root><a></a></root>'),
    1458                            self._writeElement(root))
    1459          root[0].addnext(pi)
    1460          self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
    1461                            self._writeElement(root))
    1462
    1463 -    def test_addnext_root_pi(self):
    1464          Element = self.etree.Element
    1465          PI = self.etree.PI
    1466          root = Element('root')
    1467          pi = PI('TARGET', 'TEXT')
    1468          pi.tail = "TAIL"
    1469
    1470          self.assertEquals(_bytes('<root></root>'),
    1471                            self._writeElement(root))
    1472          root.addnext(pi)
    1473          self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'),
    1474                            self._writeElement(root))
    1475
    1476 -    def test_addnext_comment(self):
    1477          Element = self.etree.Element
    1478          SubElement = self.etree.SubElement
    1479          Comment = self.etree.Comment
    1480          root = Element('root')
    1481          SubElement(root, 'a')
    1482          comment = Comment('TEXT ')
    1483          comment.tail = "TAIL"
    1484
    1485          self.assertEquals(_bytes('<root><a></a></root>'),
    1486                            self._writeElement(root))
    1487          root[0].addnext(comment)
    1488          self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
    1489                            self._writeElement(root))
    1490
    1491 -    def test_addnext_root_comment(self):
    1492          Element = self.etree.Element
    1493          Comment = self.etree.Comment
    1494          root = Element('root')
    1495          comment = Comment('TEXT ')
    1496          comment.tail = "TAIL"
    1497
    1498          self.assertEquals(_bytes('<root></root>'),
    1499                            self._writeElement(root))
    1500          root.addnext(comment)
    1501          self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'),
    1502                            self._writeElement(root))
    1503
    1504 -    def test_addprevious_comment(self):
    1505          Element = self.etree.Element
    1506          SubElement = self.etree.SubElement
    1507          Comment = self.etree.Comment
    1508          root = Element('root')
    1509          SubElement(root, 'a')
    1510          comment = Comment('TEXT ')
    1511          comment.tail = "TAIL"
    1512
    1513          self.assertEquals(_bytes('<root><a></a></root>'),
    1514                            self._writeElement(root))
    1515          root[0].addprevious(comment)
    1516          self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
    1517                            self._writeElement(root))
    1518
    1519 -    def test_addprevious_root_comment(self):
    1520          Element = self.etree.Element
    1521          Comment = self.etree.Comment
    1522          root = Element('root')
    1523          comment = Comment('TEXT ')
    1524          comment.tail = "TAIL"
    1525
    1526          self.assertEquals(_bytes('<root></root>'),
    1527                            self._writeElement(root))
    1528          root.addprevious(comment)
    1529          self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'),
    1530                            self._writeElement(root))
    1531
    1532      # ET's Elements have items() and key(), but not values()
    1533 -    def test_attribute_values(self):
    1534          XML = self.etree.XML
    1535
    1536          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
    1537          values = root.values()
    1538          values.sort()
    1539          self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
    1540
    1541      # gives error in ElementTree
    1542 -    def test_comment_empty(self):
    1543          Element = self.etree.Element
    1544          Comment = self.etree.Comment
    1545
    1546          a = Element('a')
    1547          a.append(Comment())
    1548          self.assertEquals(
    1549              _bytes('<a><!----></a>'),
    1550              self._writeElement(a))
    1551
    1552      # ElementTree ignores comments
    1553 -    def test_comment_parse_empty(self):
    1554          ElementTree = self.etree.ElementTree
    1555          tostring = self.etree.tostring
    1556
    1557          xml = _bytes('<a><b/><!----><c/></a>')
    1558          f = BytesIO(xml)
    1559          doc = ElementTree(file=f)
    1560          a = doc.getroot()
    1561          self.assertEquals(
    1562              '',
    1563              a[1].text)
    1564          self.assertEquals(
    1565              xml,
    1566              tostring(a))
    1567
    1568      # ElementTree ignores comments
    1569 -    def test_comment_no_proxy_yet(self):
    1570          ElementTree = self.etree.ElementTree
    1571
    1572          f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
    1573          doc = ElementTree(file=f)
    1574          a = doc.getroot()
    1575          self.assertEquals(
    1576              ' hoi ',
    1577              a[1].text)
    1578
    1579      # does not raise an exception in ElementTree
    1580 -    def test_comment_immutable(self):
    1581          Element = self.etree.Element
    1582          Comment = self.etree.Comment
    1583
    1584          c = Comment()
    1585          el = Element('myel')
    1586
    1587          self.assertRaises(TypeError, c.append, el)
    1588          self.assertRaises(TypeError, c.insert, 0, el)
    1589          self.assertRaises(TypeError, c.set, "myattr", "test")
    1590
    1591      # test passing 'None' to dump
    1592 -    def test_dump_none(self):
    1593          self.assertRaises(TypeError, self.etree.dump, None)
    1594
    1595 -    def test_prefix(self):
    1596          ElementTree = self.etree.ElementTree
    1597
    1598          f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
    1599          doc = ElementTree(file=f)
    1600          a = doc.getroot()
    1601          self.assertEquals(
    1602              None,
    1603              a.prefix)
    1604          self.assertEquals(
    1605              'foo',
    1606              a[0].prefix)
    1607
    1608 -    def test_prefix_default_ns(self):
    1609          ElementTree = self.etree.ElementTree
    1610
    1611          f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
    1612          doc = ElementTree(file=f)
    1613          a = doc.getroot()
    1614          self.assertEquals(
    1615              None,
    1616              a.prefix)
    1617          self.assertEquals(
    1618              None,
    1619              a[0].prefix)
    1620
    1621 -    def test_getparent(self):
    1622          Element = self.etree.Element
    1623          SubElement = self.etree.SubElement
    1624
    1625          a = Element('a')
    1626          b = SubElement(a, 'b')
    1627          c = SubElement(a, 'c')
    1628          d = SubElement(b, 'd')
    1629          self.assertEquals(
    1630              None,
    1631              a.getparent())
    1632          self.assertEquals(
    1633              a,
    1634              b.getparent())
    1635          self.assertEquals(
    1636              b.getparent(),
    1637              c.getparent())
    1638          self.assertEquals(
    1639              b,
    1640              d.getparent())
    1641
    1642 -    def test_iterchildren(self):
    1643          XML = self.etree.XML
    1644
    1645          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1646          result = []
    1647          for el in root.iterchildren():
    1648              result.append(el.tag)
    1649          self.assertEquals(['one', 'two', 'three'], result)
    1650
    1651 -    def test_iterchildren_reversed(self):
    1652          XML = self.etree.XML
    1653
    1654          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1655          result = []
    1656          for el in root.iterchildren(reversed=True):
    1657              result.append(el.tag)
    1658          self.assertEquals(['three', 'two', 'one'], result)
    1659
    1660 -    def test_iterchildren_tag(self):
    1661          XML = self.etree.XML
    1662
    1663          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1664          result = []
    1665          for el in root.iterchildren(tag='two'):
    1666              result.append(el.text)
    1667          self.assertEquals(['Two', 'Bla'], result)
    1668
    1669 -    def test_iterchildren_tag_reversed(self):
    1670          XML = self.etree.XML
    1671
    1672          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1673          result = []
    1674          for el in root.iterchildren(reversed=True, tag='two'):
    1675              result.append(el.text)
    1676          self.assertEquals(['Bla', 'Two'], result)
    1677
    1678 -    def test_iterchildren_tag_multiple(self):
    1679          XML = self.etree.XML
    1680
    1681          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
    1682          result = []
    1683          for el in root.iterchildren(tag=['two', 'three']):
    1684              result.append(el.text)
    1685          self.assertEquals(['Two', 'Bla', None], result)
    1686
    1687 -    def test_iterchildren_tag_multiple_reversed(self):
    1688          XML = self.etree.XML
    1689
    1690          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
    1691          result = []
    1692          for el in root.iterchildren(reversed=True, tag=['two', 'three']):
    1693              result.append(el.text)
    1694          self.assertEquals([None, 'Bla', 'Two'], result)
    1695
    1696 -    def test_iterancestors(self):
    1697          Element    = self.etree.Element
    1698          SubElement = self.etree.SubElement
    1699
    1700          a = Element('a')
    1701          b = SubElement(a, 'b')
    1702          c = SubElement(a, 'c')
    1703          d = SubElement(b, 'd')
    1704          self.assertEquals(
    1705              [],
    1706              list(a.iterancestors()))
    1707          self.assertEquals(
    1708              [a],
    1709              list(b.iterancestors()))
    1710          self.assertEquals(
    1711              [a],
    1712              list(c.iterancestors()))
    1713          self.assertEquals(
    1714              [b, a],
    1715              list(d.iterancestors()))
    1716
    1717 -    def test_iterancestors_tag(self):
    1718          Element    = self.etree.Element
    1719          SubElement = self.etree.SubElement
    1720
    1721          a = Element('a')
    1722          b = SubElement(a, 'b')
    1723          c = SubElement(a, 'c')
    1724          d = SubElement(b, 'd')
    1725          self.assertEquals(
    1726              [a],
    1727              list(d.iterancestors(tag='a')))
    1728          self.assertEquals(
    1729              [b, a],
    1730                 list(d.iterancestors(tag='*')))
    1731
    1732 -    def test_iterancestors_tag_multiple(self):
    1733          Element    = self.etree.Element
    1734          SubElement = self.etree.SubElement
    1735
    1736          a = Element('a')
    1737          b = SubElement(a, 'b')
    1738          c = SubElement(a, 'c')
    1739          d = SubElement(b, 'd')
    1740          self.assertEquals(
    1741              [b, a],
    1742                 list(d.iterancestors(tag=('a', 'b'))))
    1743          self.assertEquals(
    1744              [],
    1745                 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
    1746          self.assertEquals(
    1747              [],
    1748                list(d.iterancestors(tag=('d', 'x'))))
    1749          self.assertEquals(
    1750              [b, a],
    1751                list(d.iterancestors(tag=('b', '*'))))
    1752          self.assertEquals(
    1753              [b],
    1754                list(d.iterancestors(tag=('b', 'c'))))
    1755
    1756 -    def test_iterdescendants(self):
    1757          Element = self.etree.Element
    1758          SubElement = self.etree.SubElement
    1759
    1760          a = Element('a')
    1761          b = SubElement(a, 'b')
    1762          c = SubElement(a, 'c')
    1763          d = SubElement(b, 'd')
    1764          e = SubElement(c, 'e')
    1765
    1766          self.assertEquals(
    1767              [b, d, c, e],
    1768              list(a.iterdescendants()))
    1769          self.assertEquals(
    1770              [],
    1771              list(d.iterdescendants()))
    1772
    1773 -    def test_iterdescendants_tag(self):
    1774          Element = self.etree.Element
    1775          SubElement = self.etree.SubElement
    1776
    1777          a = Element('a')
    1778          b = SubElement(a, 'b')
    1779          c = SubElement(a, 'c')
    1780          d = SubElement(b, 'd')
    1781          e = SubElement(c, 'e')
    1782
    1783          self.assertEquals(
    1784              [],
    1785              list(a.iterdescendants('a')))
    1786          a2 = SubElement(e, 'a')
    1787          self.assertEquals(
    1788              [a2],
    1789              list(a.iterdescendants('a')))
    1790          self.assertEquals(
    1791              [a2],
    1792              list(c.iterdescendants('a')))
    1793
    1794 -    def test_iterdescendants_tag_multiple(self):
    1795          Element = self.etree.Element
    1796          SubElement = self.etree.SubElement
    1797
    1798          a = Element('a')
    1799          b = SubElement(a, 'b')
    1800          c = SubElement(a, 'c')
    1801          d = SubElement(b, 'd')
    1802          e = SubElement(c, 'e')
    1803
    1804          self.assertEquals(
    1805              [b, e],
    1806              list(a.iterdescendants(tag=('a', 'b', 'e'))))
    1807          a2 = SubElement(e, 'a')
    1808          self.assertEquals(
    1809              [b, a2],
    1810              list(a.iterdescendants(tag=('a', 'b'))))
    1811          self.assertEquals(
    1812              [],
    1813              list(c.iterdescendants(tag=('x', 'y', 'z'))))
    1814          self.assertEquals(
    1815              [b, d, c, e, a2],
    1816                list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
    1817
    1818 -    def test_getroottree(self):
    1819          Element = self.etree.Element
    1820          SubElement = self.etree.SubElement
    1821
    1822          a = Element('a')
    1823          b = SubElement(a, 'b')
    1824          c = SubElement(a, 'c')
    1825          d = SubElement(b, 'd')
    1826          self.assertEquals(
    1827              a,
    1828              a.getroottree().getroot())
    1829          self.assertEquals(
    1830              a,
    1831              b.getroottree().getroot())
    1832          self.assertEquals(
    1833              a,
    1834              d.getroottree().getroot())
    1835
    1836 -    def test_getnext(self):
    1837          Element    = self.etree.Element
    1838          SubElement = self.etree.SubElement
    1839
    1840          a = Element('a')
    1841          b = SubElement(a, 'b')
    1842          c = SubElement(a, 'c')
    1843          self.assertEquals(
    1844              None,
    1845              a.getnext())
    1846          self.assertEquals(
    1847              c,
    1848              b.getnext())
    1849          self.assertEquals(
    1850              None,
    1851              c.getnext())
    1852
    1853 -    def test_getprevious(self):
    1854          Element    = self.etree.Element
    1855          SubElement = self.etree.SubElement
    1856
    1857          a = Element('a')
    1858          b = SubElement(a, 'b')
    1859          c = SubElement(a, 'c')
    1860          d = SubElement(b, 'd')
    1861          self.assertEquals(
    1862              None,
    1863              a.getprevious())
    1864          self.assertEquals(
    1865              b,
    1866              c.getprevious())
    1867          self.assertEquals(
    1868              None,
    1869              b.getprevious())
    1870
    1871 -    def test_itersiblings(self):
    1872          Element    = self.etree.Element
    1873          SubElement = self.etree.SubElement
    1874
    1875          a = Element('a')
    1876          b = SubElement(a, 'b')
    1877          c = SubElement(a, 'c')
    1878          d = SubElement(b, 'd')
    1879          self.assertEquals(
    1880              [],
    1881              list(a.itersiblings()))
    1882          self.assertEquals(
    1883              [c],
    1884              list(b.itersiblings()))
    1885          self.assertEquals(
    1886              [],
    1887              list(c.itersiblings()))
    1888          self.assertEquals(
    1889              [b],
    1890              list(c.itersiblings(preceding=True)))
    1891          self.assertEquals(
    1892              [],
    1893              list(b.itersiblings(preceding=True)))
    1894
    1895 -    def test_itersiblings_tag(self):
    1896          Element    = self.etree.Element
    1897          SubElement = self.etree.SubElement
    1898
    1899          a = Element('a')
    1900          b = SubElement(a, 'b')
    1901          c = SubElement(a, 'c')
    1902          d = SubElement(b, 'd')
    1903          self.assertEquals(
    1904              [],
    1905              list(a.itersiblings(tag='XXX')))
    1906          self.assertEquals(
    1907              [c],
    1908              list(b.itersiblings(tag='c')))
    1909          self.assertEquals(
    1910              [c],
    1911              list(b.itersiblings(tag='*')))
    1912          self.assertEquals(
    1913              [b],
    1914              list(c.itersiblings(preceding=True, tag='b')))
    1915          self.assertEquals(
    1916              [],
    1917              list(c.itersiblings(preceding=True, tag='c')))
    1918
    1919 -    def test_itersiblings_tag_multiple(self):
    1920          Element    = self.etree.Element
    1921          SubElement = self.etree.SubElement
    1922
    1923          a = Element('a')
    1924          b = SubElement(a, 'b')
    1925          c = SubElement(a, 'c')
    1926          d = SubElement(b, 'd')
    1927          e = SubElement(a, 'e')
    1928          self.assertEquals(
    1929              [],
    1930              list(a.itersiblings(tag=('XXX', 'YYY'))))
    1931          self.assertEquals(
    1932              [c, e],
    1933              list(b.itersiblings(tag=('c', 'd', 'e'))))
    1934          self.assertEquals(
    1935              [b],
    1936              list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
    1937          self.assertEquals(
    1938              [c, b],
    1939              list(e.itersiblings(preceding=True, tag=('c', '*'))))
    1940
    1941 -    def test_parseid(self):
    1942          parseid = self.etree.parseid
    1943          XML     = self.etree.XML
    1944          xml_text = _bytes('''
    1945          <!DOCTYPE document [
    1946          <!ELEMENT document (h1,p)*>
    1947          <!ELEMENT h1 (#PCDATA)>
    1948          <!ATTLIST h1 myid ID #REQUIRED>
    1949          <!ELEMENT p  (#PCDATA)>
    1950          <!ATTLIST p  someid ID #REQUIRED>
    1951          ]>
    1952          <document>
    1953            <h1 myid="chapter1">...</h1>
    1954            <p id="note1" class="note">...</p>
    1955            <p>Regular paragraph.</p>
    1956            <p xml:id="xmlid">XML:ID paragraph.</p>
    1957            <p someid="warn1" class="warning">...</p>
    1958          </document>
    1959          ''')
    1960
    1961          tree, dic = parseid(BytesIO(xml_text))
    1962          root = tree.getroot()
    1963          root2 = XML(xml_text)
    1964          self.assertEquals(self._writeElement(root),
    1965                            self._writeElement(root2))
    1966          expected = {
    1967              "chapter1" : root[0],
    1968              "xmlid"    : root[3],
    1969              "warn1"    : root[4]
    1970              }
    1971          self.assert_("chapter1" in dic)
    1972          self.assert_("warn1" in dic)
    1973          self.assert_("xmlid" in dic)
    1974          self._checkIDDict(dic, expected)
    1975
    1976 -    def test_XMLDTDID(self):
    1977          XMLDTDID = self.etree.XMLDTDID
    1978          XML      = self.etree.XML
    1979          xml_text = _bytes('''
    1980          <!DOCTYPE document [
    1981          <!ELEMENT document (h1,p)*>
    1982          <!ELEMENT h1 (#PCDATA)>
    1983          <!ATTLIST h1 myid ID #REQUIRED>
    1984          <!ELEMENT p  (#PCDATA)>
    1985          <!ATTLIST p  someid ID #REQUIRED>
    1986          ]>
    1987          <document>
    1988            <h1 myid="chapter1">...</h1>
    1989            <p id="note1" class="note">...</p>
    1990            <p>Regular paragraph.</p>
    1991            <p xml:id="xmlid">XML:ID paragraph.</p>
    1992            <p someid="warn1" class="warning">...</p>
    1993          </document>
    1994          ''')
    1995
    1996          root, dic = XMLDTDID(xml_text)
    1997          root2 = XML(xml_text)
    1998          self.assertEquals(self._writeElement(root),
    1999                            self._writeElement(root2))
    2000          expected = {
    2001              "chapter1" : root[0],
    2002              "xmlid"    : root[3],
    2003              "warn1"    : root[4]
    2004              }
    2005          self.assert_("chapter1" in dic)
    2006          self.assert_("warn1" in dic)
    2007          self.assert_("xmlid" in dic)
    2008          self._checkIDDict(dic, expected)
    2009
    2010 -    def test_XMLDTDID_empty(self):
    2011          XMLDTDID = self.etree.XMLDTDID
    2012          XML      = self.etree.XML
    2013          xml_text = _bytes('''
    2014          <document>
    2015            <h1 myid="chapter1">...</h1>
    2016            <p id="note1" class="note">...</p>
    2017            <p>Regular paragraph.</p>
    2018            <p someid="warn1" class="warning">...</p>
    2019          </document>
    2020          ''')
    2021
    2022          root, dic = XMLDTDID(xml_text)
    2023          root2 = XML(xml_text)
    2024          self.assertEquals(self._writeElement(root),
    2025                            self._writeElement(root2))
    2026          expected = {}
    2027          self._checkIDDict(dic, expected)
    2028
    2029 -    def _checkIDDict(self, dic, expected):
    2030          self.assertEquals(len(dic),
    2031                            len(expected))
    2032          self.assertEquals(sorted(dic.items()),
    2033                            sorted(expected.items()))
    2034          if sys.version_info < (3,):
    2035              self.assertEquals(sorted(dic.iteritems()),
    2036                                sorted(expected.iteritems()))
    2037          self.assertEquals(sorted(dic.keys()),
    2038                            sorted(expected.keys()))
    2039          if sys.version_info < (3,):
    2040              self.assertEquals(sorted(dic.iterkeys()),
    2041                                sorted(expected.iterkeys()))
    2042          if sys.version_info < (3,):
    2043              self.assertEquals(sorted(dic.values()),
    2044                                sorted(expected.values()))
    2045              self.assertEquals(sorted(dic.itervalues()),
    2046                                sorted(expected.itervalues()))
    2047
    2048 -    def test_namespaces(self):
    2049          etree = self.etree
    2050
    2051          r = {'foo': 'http://ns.infrae.com/foo'}
    2052          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2053          self.assertEquals(
    2054              'foo',
    2055              e.prefix)
    2056          self.assertEquals(
    2057              _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
    2058              self._writeElement(e))
    2059
    2060 -    def test_namespaces_default(self):
    2061          etree = self.etree
    2062
    2063          r = {None: 'http://ns.infrae.com/foo'}
    2064          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2065          self.assertEquals(
    2066              None,
    2067              e.prefix)
    2068          self.assertEquals(
    2069              '{http://ns.infrae.com/foo}bar',
    2070              e.tag)
    2071          self.assertEquals(
    2072              _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
    2073              self._writeElement(e))
    2074
    2075 -    def test_namespaces_default_and_attr(self):
    2076          etree = self.etree
    2077
    2078          r = {None: 'http://ns.infrae.com/foo',
    2079               'hoi': 'http://ns.infrae.com/hoi'}
    2080          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2081          e.set('{http://ns.infrae.com/hoi}test', 'value')
    2082          self.assertEquals(
    2083              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
    2084              self._writeElement(e))
    2085
    2086 -    def test_namespaces_elementtree(self):
    2087          etree = self.etree
    2088          r = {None: 'http://ns.infrae.com/foo',
    2089               'hoi': 'http://ns.infrae.com/hoi'}
    2090          e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
    2091          tree = etree.ElementTree(element=e)
    2092          etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
    2093          self.assertEquals(
    2094              _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
    2095              self._writeElement(e))
    2096
    2097 -    def test_namespaces_default_copy_element(self):
    2098          etree = self.etree
    2099
    2100          r = {None: 'http://ns.infrae.com/foo'}
    2101          e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2102          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2103
    2104          e1.append(e2)
    2105
    2106          self.assertEquals(
    2107              None,
    2108              e1.prefix)
    2109          self.assertEquals(
    2110              None,
    2111              e1[0].prefix)
    2112          self.assertEquals(
    2113              '{http://ns.infrae.com/foo}bar',
    2114              e1.tag)
    2115          self.assertEquals(
    2116              '{http://ns.infrae.com/foo}bar',
    2117              e1[0].tag)
    2118
    2119 -    def test_namespaces_copy_element(self):
    2120          etree = self.etree
    2121
    2122          r = {None: 'http://ns.infrae.com/BAR'}
    2123          e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
    2124          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2125
    2126          e1.append(e2)
    2127
    2128          self.assertEquals(
    2129              None,
    2130              e1.prefix)
    2131          self.assertNotEquals(
    2132              None,
    2133              e2.prefix)
    2134          self.assertEquals(
    2135              '{http://ns.infrae.com/BAR}bar',
    2136              e1.tag)
    2137          self.assertEquals(
    2138              '{http://ns.infrae.com/foo}bar',
    2139              e2.tag)
    2140
    2141 -    def test_namespaces_reuse_after_move(self):
    2142          ns_href = "http://a.b.c"
    2143          one = self.etree.fromstring(
    2144              _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
    2145          baz = one[0][0]
    2146
    2147          two = self.etree.fromstring(
    2148              _bytes('<root xmlns:ns="%s"/>' % ns_href))
    2149          two.append(baz)
    2150          del one # make sure the source document is deallocated
    2151
    2152          self.assertEquals('{%s}baz' % ns_href, baz.tag)
    2153          self.assertEquals(
    2154              _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
    2155              self.etree.tostring(two))
    2156
    2157 -    def test_namespace_cleanup(self):
    2158          xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
    2159          root = self.etree.fromstring(xml)
    2160          self.assertEquals(xml,
    2161                            self.etree.tostring(root))
    2162          self.etree.cleanup_namespaces(root)
    2163          self.assertEquals(
    2164              _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
    2165              self.etree.tostring(root))
    2166
    2167 -    def test_element_nsmap(self):
    2168          etree = self.etree
    2169
    2170          r = {None: 'http://ns.infrae.com/foo',
    2171               'hoi': 'http://ns.infrae.com/hoi'}
    2172          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2173          self.assertEquals(
    2174              r,
    2175              e.nsmap)
    2176
    2177 -    def test_subelement_nsmap(self):
    2178          etree = self.etree
    2179
    2180          re = {None: 'http://ns.infrae.com/foo',
    2181               'hoi': 'http://ns.infrae.com/hoi'}
    2182          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
    2183
    2184          rs = {None: 'http://ns.infrae.com/honk',
    2185               'top': 'http://ns.infrae.com/top'}
    2186          s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
    2187
    2188          r = re.copy()
    2189          r.update(rs)
    2190          self.assertEquals(re, e.nsmap)
    2191          self.assertEquals(r,  s.nsmap)
    2192
    2193 -    def test_html_prefix_nsmap(self):
    2194          etree = self.etree
    2195          el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
    2196          self.assertEquals({'hha': None}, el.nsmap)
    2197
    2198 -    def test_getiterator_filter_multiple(self):
    2199          Element = self.etree.Element
    2200          SubElement = self.etree.SubElement
    2201
    2202          a = Element('a')
    2203          b = SubElement(a, 'b')
    2204          c = SubElement(a, 'c')
    2205          d = SubElement(b, 'd')
    2206          e = SubElement(c, 'e')
    2207          f = SubElement(c, 'f')
    2208
    2209          self.assertEquals(
    2210              [a, b],
    2211                 list(a.getiterator('a', 'b')))
    2212          self.assertEquals(
    2213              [],
    2214                list(a.getiterator('x', 'y')))
    2215          self.assertEquals(
    2216              [a, f],
    2217                list(a.getiterator('f', 'a')))
    2218          self.assertEquals(
    2219              [c, e, f],
    2220                 list(c.getiterator('c', '*', 'a')))
    2221          self.assertEquals(
    2222              [],
    2223                    list(a.getiterator( (), () )))
    2224
    2225 -    def test_getiterator_filter_multiple_tuple(self):
    2226          Element = self.etree.Element
    2227          SubElement = self.etree.SubElement
    2228
    2229          a = Element('a')
    2230          b = SubElement(a, 'b')
    2231          c = SubElement(a, 'c')
    2232          d = SubElement(b, 'd')
    2233          e = SubElement(c, 'e')
    2234          f = SubElement(c, 'f')
    2235
    2236          self.assertEquals(
    2237              [a, b],
    2238                    list(a.getiterator( ('a', 'b') )))
    2239          self.assertEquals(
    2240              [],
    2241                list(a.getiterator( ('x', 'y') )))
    2242          self.assertEquals(
    2243              [a, f],
    2244                    list(a.getiterator( ('f', 'a') )))
    2245          self.assertEquals(
    2246              [c, e, f],
    2247                       list(c.getiterator( ('c', '*', 'a') )))
    2248          self.assertEquals(
    2249              [],
    2250                list(a.getiterator( () )))
    2251
    2252 -    def test_getiterator_filter_namespace(self):
    2253          Element = self.etree.Element
    2254          SubElement = self.etree.SubElement
    2255
    2256          a = Element('{a}a')
    2257          b = SubElement(a, '{a}b')
    2258          c = SubElement(a, '{a}c')
    2259          d = SubElement(b, '{b}d')
    2260          e = SubElement(c, '{a}e')
    2261          f = SubElement(c, '{b}f')
    2262
    2263          self.assertEquals(
    2264              [a],
    2265              list(a.getiterator('{a}a')))
    2266          self.assertEquals(
    2267              [],
    2268              list(a.getiterator('{b}a')))
    2269          self.assertEquals(
    2270              [],
    2271              list(a.getiterator('a')))
    2272          self.assertEquals(
    2273              [f],
    2274              list(c.getiterator('{b}*')))
    2275          self.assertEquals(
    2276              [d, f],
    2277              list(a.getiterator('{b}*')))
    2278
    2279 -    def test_getiterator_filter_entities(self):
    2280          Element = self.etree.Element
    2281          Entity = self.etree.Entity
    2282          SubElement = self.etree.SubElement
    2283
    2284          a = Element('a')
    2285          b = SubElement(a, 'b')
    2286          entity_b = Entity("TEST-b")
    2287          b.append(entity_b)
    2288
    2289          self.assertEquals(
    2290              [entity_b],
    2291              list(a.getiterator(Entity)))
    2292
    2293          entity_a = Entity("TEST-a")
    2294          a.append(entity_a)
    2295
    2296          self.assertEquals(
    2297              [entity_b, entity_a],
    2298              list(a.getiterator(Entity)))
    2299
    2300          self.assertEquals(
    2301              [entity_b],
    2302              list(b.getiterator(Entity)))
    2303
    2304 -    def test_getiterator_filter_element(self):
    2305          Element = self.etree.Element
    2306          Comment = self.etree.Comment
    2307          PI = self.etree.PI
    2308          SubElement = self.etree.SubElement
    2309
    2310          a = Element('a')
    2311          b = SubElement(a, 'b')
    2312          a.append(Comment("test"))
    2313          a.append(PI("pi", "content"))
    2314          c = SubElement(a, 'c')
    2315
    2316          self.assertEquals(
    2317              [a, b, c],
    2318              list(a.getiterator(Element)))
    2319
    2320 -    def test_getiterator_filter_all_comment_pi(self):
    2321          # ElementTree iterates over everything here
    2322          Element = self.etree.Element
    2323          Comment = self.etree.Comment
    2324          PI = self.etree.PI
    2325          SubElement = self.etree.SubElement
    2326
    2327          a = Element('a')
    2328          b = SubElement(a, 'b')
    2329          a.append(Comment("test"))
    2330          a.append(PI("pi", "content"))
    2331          c = SubElement(a, 'c')
    2332
    2333          self.assertEquals(
    2334              [a, b, c],
    2335              list(a.getiterator('*')))
    2336
    2337 -    def test_elementtree_find_qname(self):
    2338          XML = self.etree.XML
    2339          ElementTree = self.etree.ElementTree
    2340          QName = self.etree.QName
    2341          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2342          self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
    2343
    2344 -    def test_elementtree_findall_qname(self):
    2345          XML = self.etree.XML
    2346          ElementTree = self.etree.ElementTree
    2347          QName = self.etree.QName
    2348          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2349          self.assertEquals(len(list(tree.findall(QName("c")))), 1)
    2350
    2351 -    def test_elementtree_findall_ns_qname(self):
    2352          XML = self.etree.XML
    2353          ElementTree = self.etree.ElementTree
    2354          QName = self.etree.QName
    2355          tree = ElementTree(XML(
    2356                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
    2357          self.assertEquals(len(list(tree.findall(QName("b")))), 2)
    2358          self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
    2359
    2360 -    def test_findall_ns(self):
    2361          XML = self.etree.XML
    2362          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
    2363          self.assertEquals(len(root.findall(".//{X}b")), 2)
    2364          self.assertEquals(len(root.findall(".//{X}*")), 2)
    2365          self.assertEquals(len(root.findall(".//b")), 3)
    2366
    2367 -    def test_index(self):
    2368          etree = self.etree
    2369          e = etree.Element('foo')
    2370          for i in range(10):
    2371              etree.SubElement(e, 'a%s' % i)
    2372          for i in range(10):
    2373              self.assertEquals(
    2374                  i,
    2375                  e.index(e[i]))
    2376          self.assertEquals(
    2377              3, e.index(e[3], 3))
    2378          self.assertRaises(
    2379              ValueError, e.index, e[3], 4)
    2380          self.assertRaises(
    2381              ValueError, e.index, e[3], 0, 2)
    2382          self.assertRaises(
    2383              ValueError, e.index, e[8], 0, -3)
    2384          self.assertRaises(
    2385              ValueError, e.index, e[8], -5, -3)
    2386          self.assertEquals(
    2387              8, e.index(e[8], 0, -1))
    2388          self.assertEquals(
    2389              8, e.index(e[8], -12, -1))
    2390          self.assertEquals(
    2391              0, e.index(e[0], -12, -1))
    2392
    2393 -    def test_replace(self):
    2394          etree = self.etree
    2395          e = etree.Element('foo')
    2396          for i in range(10):
    2397              el = etree.SubElement(e, 'a%s' % i)
    2398              el.text = "text%d" % i
    2399              el.tail = "tail%d" % i
    2400
    2401          child0 = e[0]
    2402          child1 = e[1]
    2403          child2 = e[2]
    2404
    2405          e.replace(e[0], e[1])
    2406          self.assertEquals(
    2407              9, len(e))
    2408          self.assertEquals(
    2409              child1, e[0])
    2410          self.assertEquals(
    2411              child1.text, "text1")
    2412          self.assertEquals(
    2413              child1.tail, "tail1")
    2414          self.assertEquals(
    2415              child0.tail, "tail0")
    2416          self.assertEquals(
    2417              child2, e[1])
    2418
    2419          e.replace(e[-1], e[0])
    2420          self.assertEquals(
    2421              child1, e[-1])
    2422          self.assertEquals(
    2423              child1.text, "text1")
    2424          self.assertEquals(
    2425              child1.tail, "tail1")
    2426          self.assertEquals(
    2427              child2, e[0])
    2428
    2429 -    def test_replace_new(self):
    2430          etree = self.etree
    2431          e = etree.Element('foo')
    2432          for i in range(10):
    2433              etree.SubElement(e, 'a%s' % i)
    2434
    2435          new_element = etree.Element("test")
    2436          new_element.text = "TESTTEXT"
    2437          new_element.tail = "TESTTAIL"
    2438          child1 = e[1]
    2439          e.replace(e[0], new_element)
    2440          self.assertEquals(
    2441              new_element, e[0])
    2442          self.assertEquals(
    2443              "TESTTEXT",
    2444              e[0].text)
    2445          self.assertEquals(
    2446              "TESTTAIL",
    2447              e[0].tail)
    2448          self.assertEquals(
    2449              child1, e[1])
    2450
    2451 -    def test_setslice_all_empty_reversed(self):
    2452          Element = self.etree.Element
    2453          SubElement = self.etree.SubElement
    2454
    2455          a = Element('a')
    2456
    2457          e = Element('e')
    2458          f = Element('f')
    2459          g = Element('g')
    2460
    2461          s = [e, f, g]
    2462          a[::-1] = s
    2463          self.assertEquals(
    2464              [g, f, e],
    2465              list(a))
    2466
    2467 -    def test_setslice_step(self):
    2468          Element = self.etree.Element
    2469          SubElement = self.etree.SubElement
    2470
    2471          a = Element('a')
    2472          b = SubElement(a, 'b')
    2473          c = SubElement(a, 'c')
    2474          d = SubElement(a, 'd')
    2475          e = SubElement(a, 'e')
    2476
    2477          x = Element('x')
    2478          y = Element('y')
    2479
    2480          a[1::2] = [x, y]
    2481          self.assertEquals(
    2482              [b, x, d, y],
    2483              list(a))
    2484
    2485 -    def test_setslice_step_negative(self):
    2486          Element = self.etree.Element
    2487          SubElement = self.etree.SubElement
    2488
    2489          a = Element('a')
    2490          b = SubElement(a, 'b')
    2491          c = SubElement(a, 'c')
    2492          d = SubElement(a, 'd')
    2493          e = SubElement(a, 'e')
    2494
    2495          x = Element('x')
    2496          y = Element('y')
    2497
    2498          a[1::-1] = [x, y]
    2499          self.assertEquals(
    2500              [y, x, d, e],
    2501              list(a))
    2502
    2503 -    def test_setslice_step_negative2(self):
    2504          Element = self.etree.Element
    2505          SubElement = self.etree.SubElement
    2506
    2507          a = Element('a')
    2508          b = SubElement(a, 'b')
    2509          c = SubElement(a, 'c')
    2510          d = SubElement(a, 'd')
    2511          e = SubElement(a, 'e')
    2512
    2513          x = Element('x')
    2514          y = Element('y')
    2515
    2516          a[::-2] = [x, y]
    2517          self.assertEquals(
    2518              [b, y, d, x],
    2519              list(a))
    2520
    2521 -    def test_setslice_step_overrun(self):
    2522          Element = self.etree.Element
    2523          SubElement = self.etree.SubElement
    2524          try:
    2525              slice
    2526          except NameError:
    2527              print("slice() not found")
    2528              return
    2529
    2530          a = Element('a')
    2531          b = SubElement(a, 'b')
    2532          c = SubElement(a, 'c')
    2533          d = SubElement(a, 'd')
    2534          e = SubElement(a, 'e')
    2535
    2536          x = Element('x')
    2537          y = Element('y')
    2538          z = Element('z')
    2539
    2540          self.assertRaises(
    2541              ValueError,
    2542              operator.setitem, a, slice(1,None,2), [x, y, z])
    2543
    2544          self.assertEquals(
    2545              [b, c, d, e],
    2546              list(a))
    2547
    2548 -    def test_sourceline_XML(self):
    2549          XML = self.etree.XML
    2550          root = XML(_bytes('''<?xml version="1.0"?>
    2551          <root><test>
    2552
    2553          <bla/></test>
    2554          </root>
    2555          '''))
    2556
    2557          self.assertEquals(
    2558              [2, 2, 4],
    2559              [ el.sourceline for el in root.getiterator() ])
    2560
    2561 -    def test_sourceline_parse(self):
    2562          parse = self.etree.parse
    2563          tree = parse(fileInTestDir('include/test_xinclude.xml'))
    2564
    2565          self.assertEquals(
    2566              [1, 2, 3],
    2567              [ el.sourceline for el in tree.getiterator() ])
    2568
    2569 -    def test_sourceline_iterparse_end(self):
    2570          iterparse = self.etree.iterparse
    2571          lines = [ el.sourceline for (event, el) in
    2572                    iterparse(fileInTestDir('include/test_xinclude.xml')) ]
    2573
    2574          self.assertEquals(
    2575              [2, 3, 1],
    2576              lines)
    2577
    2578 -    def test_sourceline_iterparse_start(self):
    2579          iterparse = self.etree.iterparse
    2580          lines = [ el.sourceline for (event, el) in
    2581                    iterparse(fileInTestDir('include/test_xinclude.xml'),
    2582                              events=("start",)) ]
    2583
    2584          self.assertEquals(
    2585              [1, 2, 3],
    2586              lines)
    2587
    2588 -    def test_sourceline_element(self):
    2589          Element = self.etree.Element
    2590          SubElement = self.etree.SubElement
    2591          el = Element("test")
    2592          self.assertEquals(None, el.sourceline)
    2593
    2594          child = SubElement(el, "test")
    2595          self.assertEquals(None, el.sourceline)
    2596          self.assertEquals(None, child.sourceline)
    2597
    2598 -    def test_XML_base_url_docinfo(self):
    2599          etree = self.etree
    2600          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2601          docinfo = root.getroottree().docinfo
    2602          self.assertEquals(docinfo.URL, "http://no/such/url")
    2603
    2604 -    def test_XML_set_base_url_docinfo(self):
    2605          etree = self.etree
    2606          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2607          docinfo = root.getroottree().docinfo
    2608          self.assertEquals(docinfo.URL, "http://no/such/url")
    2609          docinfo.URL = "https://secret/url"
    2610          self.assertEquals(docinfo.URL, "https://secret/url")
    2611
    2612 -    def test_parse_stringio_base_url(self):
    2613          etree = self.etree
    2614          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2615          docinfo = tree.docinfo
    2616          self.assertEquals(docinfo.URL, "http://no/such/url")
    2617
    2618 -    def test_parse_base_url_docinfo(self):
    2619          etree = self.etree
    2620          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    2621                             base_url="http://no/such/url")
    2622          docinfo = tree.docinfo
    2623          self.assertEquals(docinfo.URL, "http://no/such/url")
    2624
    2625 -    def test_HTML_base_url_docinfo(self):
    2626          etree = self.etree
    2627          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
    2628          docinfo = root.getroottree().docinfo
    2629          self.assertEquals(docinfo.URL, "http://no/such/url")
    2630
    2631 -    def test_docinfo_public(self):
    2632          etree = self.etree
    2633          xml_header = '<?xml version="1.0" encoding="ascii"?>'
    2634          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2635          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2636          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
    2637
    2638          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2639
    2640          tree = etree.parse(BytesIO(xml))
    2641          docinfo = tree.docinfo
    2642          self.assertEquals(docinfo.encoding,    "ascii")
    2643          self.assertEquals(docinfo.xml_version, "1.0")
    2644          self.assertEquals(docinfo.public_id,   pub_id)
    2645          self.assertEquals(docinfo.system_url,  sys_id)
    2646          self.assertEquals(docinfo.root_name,   'html')
    2647          self.assertEquals(docinfo.doctype, doctype_string)
    2648
    2649 -    def test_docinfo_system(self):
    2650          etree = self.etree
    2651          xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
    2652          sys_id = "some.dtd"
    2653          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
    2654          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2655
    2656          tree = etree.parse(BytesIO(xml))
    2657          docinfo = tree.docinfo
    2658          self.assertEquals(docinfo.encoding,    "UTF-8")
    2659          self.assertEquals(docinfo.xml_version, "1.0")
    2660          self.assertEquals(docinfo.public_id,   None)
    2661          self.assertEquals(docinfo.system_url,  sys_id)
    2662          self.assertEquals(docinfo.root_name,   'html')
    2663          self.assertEquals(docinfo.doctype, doctype_string)
    2664
    2665 -    def test_docinfo_empty(self):
    2666          etree = self.etree
    2667          xml = _bytes('<html><body></body></html>')
    2668          tree = etree.parse(BytesIO(xml))
    2669          docinfo = tree.docinfo
    2670          self.assertEquals(docinfo.encoding,    "UTF-8")
    2671          self.assertEquals(docinfo.xml_version, "1.0")
    2672          self.assertEquals(docinfo.public_id,   None)
    2673          self.assertEquals(docinfo.system_url,  None)
    2674          self.assertEquals(docinfo.root_name,   'html')
    2675          self.assertEquals(docinfo.doctype, '')
    2676
    2677 -    def test_docinfo_name_only(self):
    2678          etree = self.etree
    2679          xml = _bytes('<!DOCTYPE root><root></root>')
    2680          tree = etree.parse(BytesIO(xml))
    2681          docinfo = tree.docinfo
    2682          self.assertEquals(docinfo.encoding,    "UTF-8")
    2683          self.assertEquals(docinfo.xml_version, "1.0")
    2684          self.assertEquals(docinfo.public_id,   None)
    2685          self.assertEquals(docinfo.system_url,  None)
    2686          self.assertEquals(docinfo.root_name,   'root')
    2687          self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
    2688
    2689 -    def test_doctype_name_only_roundtrip(self):
    2690          etree = self.etree
    2691          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2692          tree = etree.parse(BytesIO(xml))
    2693          self.assertEquals(xml, etree.tostring(tree))
    2694
    2695 -    def test_doctype_output_override(self):
    2696          etree = self.etree
    2697          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2698          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2699          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
    2700
    2701          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2702          tree = etree.parse(BytesIO(xml))
    2703          self.assertEquals(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
    2704                            etree.tostring(tree, doctype=doctype_string))
    2705
    2706 -    def test_xml_base(self):
    2707          etree = self.etree
    2708          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2709          self.assertEquals(root.base, "http://no/such/url")
    2710          self.assertEquals(
    2711              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2712          root.base = "https://secret/url"
    2713          self.assertEquals(root.base, "https://secret/url")
    2714          self.assertEquals(
    2715              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2716              "https://secret/url")
    2717
    2718 -    def test_xml_base_attribute(self):
    2719          etree = self.etree
    2720          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2721          self.assertEquals(root.base, "http://no/such/url")
    2722          self.assertEquals(
    2723              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2724          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2725                   "https://secret/url")
    2726          self.assertEquals(root.base, "https://secret/url")
    2727          self.assertEquals(
    2728              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2729              "https://secret/url")
    2730
    2731 -    def test_html_base(self):
    2732          etree = self.etree
    2733          root = etree.HTML(_bytes("<html><body></body></html>"),
    2734                            base_url="http://no/such/url")
    2735          self.assertEquals(root.base, "http://no/such/url")
    2736
    2737 -    def test_html_base_tag(self):
    2738          etree = self.etree
    2739          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
    2740          self.assertEquals(root.base, "http://no/such/url")
    2741
    2742 -    def test_parse_fileobject_unicode(self):
    2743          # parse from a file object that returns unicode strings
    2744          f = LargeFileLikeUnicode()
    2745          tree = self.etree.parse(f)
    2746          root = tree.getroot()
    2747          self.assert_(root.tag.endswith('root'))
    2748
    2749 -    def test_dtd_io(self):
    2750          # check that DTDs that go in also go back out
    2751          xml = _bytes('''\
    2752          <!DOCTYPE test SYSTEM "test.dtd" [
    2753            <!ENTITY entity "tasty">
    2754            <!ELEMENT test (a)>
    2755            <!ELEMENT a (#PCDATA)>
    2756          ]>
    2757          <test><a>test-test</a></test>\
    2758          ''')
    2759          tree = self.etree.parse(BytesIO(xml))
    2760          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
    2761                           xml.replace(_bytes(" "), _bytes("")))
    2762
    2763 -    def test_byte_zero(self):
    2764          Element = self.etree.Element
    2765
    2766          a = Element('a')
    2767          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
    2768          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
    2769
    2770          self.assertRaises(ValueError, Element, 'ha\0ho')
    2771
    2772 -    def test_unicode_byte_zero(self):
    2773          Element = self.etree.Element
    2774
    2775          a = Element('a')
    2776          self.assertRaises(ValueError, setattr, a, "text",
    2777                            _str('ha\0ho'))
    2778          self.assertRaises(ValueError, setattr, a, "tail",
    2779                            _str('ha\0ho'))
    2780
    2781          self.assertRaises(ValueError, Element,
    2782                            _str('ha\0ho'))
    2783
    2784 -    def test_byte_invalid(self):
    2785          Element = self.etree.Element
    2786
    2787          a = Element('a')
    2788          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
    2789          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
    2790
    2791          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
    2792          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
    2793
    2794          self.assertRaises(ValueError, Element, 'ha\x07ho')
    2795          self.assertRaises(ValueError, Element, 'ha\x02ho')
    2796
    2797 -    def test_unicode_byte_invalid(self):
    2798          Element = self.etree.Element
    2799
    2800          a = Element('a')
    2801          self.assertRaises(ValueError, setattr, a, "text",
    2802                            _str('ha\x07ho'))
    2803          self.assertRaises(ValueError, setattr, a, "text",
    2804                            _str('ha\x02ho'))
    2805
    2806          self.assertRaises(ValueError, setattr, a, "tail",
    2807                            _str('ha\x07ho'))
    2808          self.assertRaises(ValueError, setattr, a, "tail",
    2809                            _str('ha\x02ho'))
    2810
    2811          self.assertRaises(ValueError, Element,
    2812                            _str('ha\x07ho'))
    2813          self.assertRaises(ValueError, Element,
    2814                            _str('ha\x02ho'))
    2815
    2816 -    def test_unicode_byte_invalid_sequence(self):
    2817          Element = self.etree.Element
    2818
    2819          a = Element('a')
    2820          self.assertRaises(ValueError, setattr, a, "text",
    2821                            _str('ha\u1234\x07ho'))
    2822          self.assertRaises(ValueError, setattr, a, "text",
    2823                            _str('ha\u1234\x02ho'))
    2824
    2825          self.assertRaises(ValueError, setattr, a, "tail",
    2826                            _str('ha\u1234\x07ho'))
    2827          self.assertRaises(ValueError, setattr, a, "tail",
    2828                            _str('ha\u1234\x02ho'))
    2829
    2830          self.assertRaises(ValueError, Element,
    2831                            _str('ha\u1234\x07ho'))
    2832          self.assertRaises(ValueError, Element,
    2833                            _str('ha\u1234\x02ho'))
    2834
    2835 -    def test_encoding_tostring_utf16(self):
    2836          # ElementTree fails to serialize this
    2837          tostring = self.etree.tostring
    2838          Element = self.etree.Element
    2839          SubElement = self.etree.SubElement
    2840
    2841          a = Element('a')
    2842          b = SubElement(a, 'b')
    2843          c = SubElement(a, 'c')
    2844
    2845          result = tostring(a, encoding='UTF-16')
    2846          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2847                            canonicalize(result))
    2848
    2849 -    def test_tostring_none(self):
    2850          # ElementTree raises an AssertionError here
    2851          tostring = self.etree.tostring
    2852          self.assertRaises(TypeError, self.etree.tostring, None)
    2853
    2854 -    def test_tostring_pretty(self):
    2855          tostring = self.etree.tostring
    2856          Element = self.etree.Element
    2857          SubElement = self.etree.SubElement
    2858
    2859          a = Element('a')
    2860          b = SubElement(a, 'b')
    2861          c = SubElement(a, 'c')
    2862
    2863          result = tostring(a)
    2864          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2865
    2866          result = tostring(a, pretty_print=False)
    2867          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2868
    2869          result = tostring(a, pretty_print=True)
    2870          self.assertEquals(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n"))
    2871
    2872 -    def test_tostring_with_tail(self):
    2873          tostring = self.etree.tostring
    2874          Element = self.etree.Element
    2875          SubElement = self.etree.SubElement
    2876
    2877          a = Element('a')
    2878          a.tail = "aTAIL"
    2879          b = SubElement(a, 'b')
    2880          b.tail = "bTAIL"
    2881          c = SubElement(a, 'c')
    2882
    2883          result = tostring(a)
    2884          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2885
    2886          result = tostring(a, with_tail=False)
    2887          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>"))
    2888
    2889          result = tostring(a, with_tail=True)
    2890          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2891
    2892 -    def test_standalone(self):
    2893          tostring = self.etree.tostring
    2894          XML = self.etree.XML
    2895          ElementTree = self.etree.ElementTree
    2896          Element = self.etree.Element
    2897
    2898          tree = Element("root").getroottree()
    2899          self.assertEquals(None, tree.docinfo.standalone)
    2900
    2901          tree = XML(_bytes("<root/>")).getroottree()
    2902          self.assertEquals(None, tree.docinfo.standalone)
    2903
    2904          tree = XML(_bytes(
    2905              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
    2906              )).getroottree()
    2907          self.assertEquals(True, tree.docinfo.standalone)
    2908
    2909          tree = XML(_bytes(
    2910              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
    2911              )).getroottree()
    2912          self.assertEquals(False, tree.docinfo.standalone)
    2913
    2914 -    def test_tostring_standalone(self):
    2915          tostring = self.etree.tostring
    2916          XML = self.etree.XML
    2917          ElementTree = self.etree.ElementTree
    2918
    2919          root = XML(_bytes("<root/>"))
    2920
    2921          tree = ElementTree(root)
    2922          self.assertEquals(None, tree.docinfo.standalone)
    2923
    2924          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2925          self.assertEquals(result, _bytes(
    2926              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2927
    2928          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2929                            standalone=True)
    2930          self.assertEquals(result, _bytes(
    2931              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2932
    2933          tree = ElementTree(XML(result))
    2934          self.assertEquals(True, tree.docinfo.standalone)
    2935
    2936          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2937                            standalone=False)
    2938          self.assertEquals(result, _bytes(
    2939              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
    2940
    2941          tree = ElementTree(XML(result))
    2942          self.assertEquals(False, tree.docinfo.standalone)
    2943
    2944 -    def test_tostring_standalone_in_out(self):
    2945          tostring = self.etree.tostring
    2946          XML = self.etree.XML
    2947          ElementTree = self.etree.ElementTree
    2948
    2949          root = XML(_bytes(
    2950              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
    2951
    2952          tree = ElementTree(root)
    2953          self.assertEquals(True, tree.docinfo.standalone)
    2954
    2955          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2956          self.assertEquals(result, _bytes(
    2957              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2958
    2959          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2960                            standalone=True)
    2961          self.assertEquals(result, _bytes(
    2962              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2963
    2964 -    def test_tostring_method_text_encoding(self):
    2965          tostring = self.etree.tostring
    2966          Element = self.etree.Element
    2967          SubElement = self.etree.SubElement
    2968
    2969          a = Element('a')
    2970          a.text = "A"
    2971          a.tail = "tail"
    2972          b = SubElement(a, 'b')
    2973          b.text = "B"
    2974          b.tail = _str("Søk på nettet")
    2975          c = SubElement(a, 'c')
    2976          c.text = "C"
    2977
    2978          result = tostring(a, method="text", encoding="UTF-16")
    2979
    2980          self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"),
    2981                            result)
    2982
    2983 -    def test_tostring_method_text_unicode(self):
    2984          tostring = self.etree.tostring
    2985          Element = self.etree.Element
    2986          SubElement = self.etree.SubElement
    2987
    2988          a = Element('a')
    2989          a.text = _str('Søk på nettetA')
    2990          a.tail = "tail"
    2991          b = SubElement(a, 'b')
    2992          b.text = "B"
    2993          b.tail = _str('Søk på nettetB')
    2994          c = SubElement(a, 'c')
    2995          c.text = "C"
    2996
    2997          self.assertRaises(UnicodeEncodeError,
    2998                            tostring, a, method="text")
    2999
    3000          self.assertEquals(
    3001              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
    3002              tostring(a, encoding="UTF-8", method="text"))
    3003
    3004 -    def test_tounicode(self):
    3005          tounicode = self.etree.tounicode
    3006          Element = self.etree.Element
    3007          SubElement = self.etree.SubElement
    3008
    3009          a = Element('a')
    3010          b = SubElement(a, 'b')
    3011          c = SubElement(a, 'c')
    3012
    3013          self.assert_(isinstance(tounicode(a), _unicode))
    3014          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    3015                            canonicalize(tounicode(a)))
    3016
    3017 -    def test_tounicode_element(self):
    3018          tounicode = self.etree.tounicode
    3019          Element = self.etree.Element
    3020          SubElement = self.etree.SubElement
    3021
    3022          a = Element('a')
    3023          b = SubElement(a, 'b')
    3024          c = SubElement(a, 'c')
    3025          d = SubElement(c, 'd')
    3026          self.assert_(isinstance(tounicode(b), _unicode))
    3027          self.assert_(isinstance(tounicode(c), _unicode))
    3028          self.assertEquals(_bytes('<b></b>'),
    3029                            canonicalize(tounicode(b)))
    3030          self.assertEquals(_bytes('<c><d></d></c>'),
    3031                            canonicalize(tounicode(c)))
    3032
    3033 -    def test_tounicode_none(self):
    3034          tounicode = self.etree.tounicode
    3035          self.assertRaises(TypeError, self.etree.tounicode, None)
    3036
    3037 -    def test_tounicode_element_tail(self):
    3038          tounicode = self.etree.tounicode
    3039          Element = self.etree.Element
    3040          SubElement = self.etree.SubElement
    3041
    3042          a = Element('a')
    3043          b = SubElement(a, 'b')
    3044          c = SubElement(a, 'c')
    3045          d = SubElement(c, 'd')
    3046          b.tail = 'Foo'
    3047
    3048          self.assert_(isinstance(tounicode(b), _unicode))
    3049          self.assert_(tounicode(b) == '<b/>Foo' or
    3050                       tounicode(b) == '<b />Foo')
    3051
    3052 -    def test_tounicode_pretty(self):
    3053          tounicode = self.etree.tounicode
    3054          Element = self.etree.Element
    3055          SubElement = self.etree.SubElement
    3056
    3057          a = Element('a')
    3058          b = SubElement(a, 'b')
    3059          c = SubElement(a, 'c')
    3060
    3061          result = tounicode(a)
    3062          self.assertEquals(result, "<a><b/><c/></a>")
    3063
    3064          result = tounicode(a, pretty_print=False)
    3065          self.assertEquals(result, "<a><b/><c/></a>")
    3066
    3067          result = tounicode(a, pretty_print=True)
    3068          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    3069
    3070 -    def test_tostring_unicode(self):
    3071          tostring = self.etree.tostring
    3072          Element = self.etree.Element
    3073          SubElement = self.etree.SubElement
    3074
    3075          a = Element('a')
    3076          b = SubElement(a, 'b')
    3077          c = SubElement(a, 'c')
    3078
    3079          self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode))
    3080          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    3081                            canonicalize(tostring(a, encoding=_unicode)))
    3082
    3083 -    def test_tostring_unicode_element(self):
    3084          tostring = self.etree.tostring
    3085          Element = self.etree.Element
    3086          SubElement = self.etree.SubElement
    3087
    3088          a = Element('a')
    3089          b = SubElement(a, 'b')
    3090          c = SubElement(a, 'c')
    3091          d = SubElement(c, 'd')
    3092          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    3093          self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode))
    3094          self.assertEquals(_bytes('<b></b>'),
    3095                            canonicalize(tostring(b, encoding=_unicode)))
    3096          self.assertEquals(_bytes('<c><d></d></c>'),
    3097                            canonicalize(tostring(c, encoding=_unicode)))
    3098
    3099 -    def test_tostring_unicode_none(self):
    3100          tostring = self.etree.tostring
    3101          self.assertRaises(TypeError, self.etree.tostring,
    3102                            None, encoding=_unicode)
    3103
    3104 -    def test_tostring_unicode_element_tail(self):
    3105          tostring = self.etree.tostring
    3106          Element = self.etree.Element
    3107          SubElement = self.etree.SubElement
    3108
    3109          a = Element('a')
    3110          b = SubElement(a, 'b')
    3111          c = SubElement(a, 'c')
    3112          d = SubElement(c, 'd')
    3113          b.tail = 'Foo'
    3114
    3115          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    3116          self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or
    3117                       tostring(b, encoding=_unicode) == '<b />Foo')
    3118
    3119 -    def test_tostring_unicode_pretty(self):
    3120          tostring = self.etree.tostring
    3121          Element = self.etree.Element
    3122          SubElement = self.etree.SubElement
    3123
    3124          a = Element('a')
    3125          b = SubElement(a, 'b')
    3126          c = SubElement(a, 'c')
    3127
    3128          result = tostring(a, encoding=_unicode)
    3129          self.assertEquals(result, "<a><b/><c/></a>")
    3130
    3131          result = tostring(a, encoding=_unicode, pretty_print=False)
    3132          self.assertEquals(result, "<a><b/><c/></a>")
    3133
    3134          result = tostring(a, encoding=_unicode, pretty_print=True)
    3135          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    3136
    3137      # helper methods
    3138
    3139 -    def _writeElement(self, element, encoding='us-ascii', compression=0):
    3140          """Write out element for comparison.
    3141          """
    3142          ElementTree = self.etree.ElementTree
    3143          f = BytesIO()
    3144          tree = ElementTree(element=element)
    3145          tree.write(f, encoding=encoding, compression=compression)
    3146          data = f.getvalue()
    3147          if compression:
    3148              data = zlib.decompress(data)
    3149          return canonicalize(data)
    3150
    3151
    3152 -class _XIncludeTestCase(HelperTestCase):
    3153 -    def test_xinclude_text(self):
    3154          filename = fileInTestDir('test_broken.xml')
    3155          root = etree.XML(_bytes('''\
    3156          <doc xmlns:xi="http://www.w3.org/2001/XInclude">
    3157            <xi:include href="%s" parse="text"/>
    3158          </doc>
    3159          ''' % filename))
    3160          old_text = root.text
    3161          content = read_file(filename)
    3162          old_tail = root[0].tail
    3163
    3164          self.include( etree.ElementTree(root) )
    3165          self.assertEquals(old_text + content + old_tail,
    3166                            root.text)
    3167
    3168 -    def test_xinclude(self):
    3169          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
    3170          self.assertNotEquals(
    3171              'a',
    3172              tree.getroot()[1].tag)
    3173          # process xincludes
    3174          self.include( tree )
    3175          # check whether we find it replaced with included data
    3176          self.assertEquals(
    3177              'a',
    3178              tree.getroot()[1].tag)
    3179
    3180 -    def test_xinclude_resolver(self):
    3181          class res(etree.Resolver):
    3182              include_text = read_file(fileInTestDir('test.xml'))
    3183              called = {}
    3184              def resolve(self, url, id, context):
    3185                  if url.endswith(".dtd"):
    3186                      self.called["dtd"] = True
    3187                      return self.resolve_filename(
    3188                          fileInTestDir('test.dtd'), context)
    3189                  elif url.endswith("test_xinclude.xml"):
    3190                      self.called["input"] = True
    3191                      return None # delegate to default resolver
    3192                  else:
    3193                      self.called["include"] = True
    3194                      return self.resolve_string(self.include_text, context)
    3195
    3196          res_instance = res()
    3197          parser = etree.XMLParser(load_dtd = True)
    3198          parser.resolvers.add(res_instance)
    3199
    3200          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    3201                             parser = parser)
    3202
    3203          self.include(tree)
    3204
    3205          called = list(res_instance.called.items())
    3206          called.sort()
    3207          self.assertEquals(
    3208              [("dtd", True), ("include", True), ("input", True)],
    3209              called)
    3210
    3211 -class ETreeXIncludeTestCase(_XIncludeTestCase):
    3212 -    def include(self, tree):
    3213          tree.xinclude()
    3214
    3215
    3216 -class ElementIncludeTestCase(_XIncludeTestCase):
    3217      from lxml import ElementInclude
    3218 -    def include(self, tree):
    3219          self.ElementInclude.include(tree.getroot())
    3220
    3221
    3222 -class ETreeC14NTestCase(HelperTestCase):
    3223 -    def test_c14n(self):
    3224          tree = self.parse(_bytes('<a><b/></a>'))
    3225          f = BytesIO()
    3226          tree.write_c14n(f)
    3227          s = f.getvalue()
    3228          self.assertEquals(_bytes('<a><b></b></a>'),
    3229                            s)
    3230
    3231 -    def test_c14n_gzip(self):
    3232          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3233          f = BytesIO()
    3234          tree.write_c14n(f, compression=9)
    3235          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3236          try:
    3237              s = gzfile.read()
    3238          finally:
    3239              gzfile.close()
    3240          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3241                            s)
    3242
    3243 -    def test_c14n_file(self):
    3244          tree = self.parse(_bytes('<a><b/></a>'))
    3245          handle, filename = tempfile.mkstemp()
    3246          try:
    3247              tree.write_c14n(filename)
    3248              data = read_file(filename, 'rb')
    3249          finally:
    3250              os.close(handle)
    3251              os.remove(filename)
    3252          self.assertEquals(_bytes('<a><b></b></a>'),
    3253                            data)
    3254
    3255 -    def test_c14n_file_gzip(self):
    3256          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3257          handle, filename = tempfile.mkstemp()
    3258          try:
    3259              tree.write_c14n(filename, compression=9)
    3260              f = gzip.open(filename, 'rb')
    3261              try:
    3262                  data = f.read()
    3263              finally:
    3264                  f.close()
    3265          finally:
    3266              os.close(handle)
    3267              os.remove(filename)
    3268          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3269                            data)
    3270
    3271 -    def test_c14n_with_comments(self):
    3272          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3273          f = BytesIO()
    3274          tree.write_c14n(f)
    3275          s = f.getvalue()
    3276          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3277                            s)
    3278          f = BytesIO()
    3279          tree.write_c14n(f, with_comments=True)
    3280          s = f.getvalue()
    3281          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3282                            s)
    3283          f = BytesIO()
    3284          tree.write_c14n(f, with_comments=False)
    3285          s = f.getvalue()
    3286          self.assertEquals(_bytes('<a><b></b></a>'),
    3287                            s)
    3288
    3289 -    def test_c14n_tostring_with_comments(self):
    3290          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3291          s = etree.tostring(tree, method='c14n')
    3292          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3293                            s)
    3294          s = etree.tostring(tree, method='c14n', with_comments=True)
    3295          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3296                            s)
    3297          s = etree.tostring(tree, method='c14n', with_comments=False)
    3298          self.assertEquals(_bytes('<a><b></b></a>'),
    3299                            s)
    3300
    3301 -    def test_c14n_element_tostring_with_comments(self):
    3302          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3303          s = etree.tostring(tree.getroot(), method='c14n')
    3304          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3305                            s)
    3306          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
    3307          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3308                            s)
    3309          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
    3310          self.assertEquals(_bytes('<a><b></b></a>'),
    3311                            s)
    3312
    3313 -    def test_c14n_exclusive(self):
    3314          tree = self.parse(_bytes(
    3315                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3316          f = BytesIO()
    3317          tree.write_c14n(f)
    3318          s = f.getvalue()
    3319          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3320                            s)
    3321          f = BytesIO()
    3322          tree.write_c14n(f, exclusive=False)
    3323          s = f.getvalue()
    3324          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3325                            s)
    3326          f = BytesIO()
    3327          tree.write_c14n(f, exclusive=True)
    3328          s = f.getvalue()
    3329          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3330                            s)
    3331
    3332 -    def test_c14n_tostring_exclusive(self):
    3333          tree = self.parse(_bytes(
    3334                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3335          s = etree.tostring(tree, method='c14n')
    3336          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3337                            s)
    3338          s = etree.tostring(tree, method='c14n', exclusive=False)
    3339          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3340                            s)
    3341          s = etree.tostring(tree, method='c14n', exclusive=True)
    3342          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3343                            s)
    3344
    3345 -    def test_c14n_element_tostring_exclusive(self):
    3346          tree = self.parse(_bytes(
    3347                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3348          s = etree.tostring(tree.getroot(), method='c14n')
    3349          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3350                            s)
    3351          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
    3352          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3353                            s)
    3354          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
    3355          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3356                            s)
    3357
    3358          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
    3359          self.assertEquals(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
    3360                            s)
    3361          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
    3362          self.assertEquals(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
    3363                            s)
    3364
    3365
    3366 -class ETreeWriteTestCase(HelperTestCase):
    3367 -    def test_write(self):
    3368          tree = self.parse(_bytes('<a><b/></a>'))
    3369          f = BytesIO()
    3370          tree.write(f)
    3371          s = f.getvalue()
    3372          self.assertEquals(_bytes('<a><b/></a>'),
    3373                            s)
    3374
    3375 -    def test_write_gzip(self):
    3376          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3377          f = BytesIO()
    3378          tree.write(f, compression=9)
    3379          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3380          try:
    3381              s = gzfile.read()
    3382          finally:
    3383              gzfile.close()
    3384          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3385                            s)
    3386
    3387 -    def test_write_gzip_level(self):
    3388          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3389          f = BytesIO()
    3390          tree.write(f, compression=0)
    3391          s0 = f.getvalue()
    3392
    3393          f = BytesIO()
    3394          tree.write(f)
    3395          self.assertEquals(f.getvalue(), s0)
    3396
    3397          f = BytesIO()
    3398          tree.write(f, compression=1)
    3399          s = f.getvalue()
    3400          self.assert_(len(s) <= len(s0))
    3401          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3402          try:
    3403              s1 = gzfile.read()
    3404          finally:
    3405              gzfile.close()
    3406
    3407          f = BytesIO()
    3408          tree.write(f, compression=9)
    3409          s = f.getvalue()
    3410          self.assert_(len(s) <= len(s0))
    3411          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3412          try:
    3413              s9 = gzfile.read()
    3414          finally:
    3415              gzfile.close()
    3416
    3417          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3418                            s0)
    3419          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3420                            s1)
    3421          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3422                            s9)
    3423
    3424 -    def test_write_file(self):
    3425          tree = self.parse(_bytes('<a><b/></a>'))
    3426          handle, filename = tempfile.mkstemp()
    3427          try:
    3428              tree.write(filename)
    3429              data = read_file(filename, 'rb')
    3430          finally:
    3431              os.close(handle)
    3432              os.remove(filename)
    3433          self.assertEquals(_bytes('<a><b/></a>'),
    3434                            data)
    3435
    3436 -    def test_write_file_gzip(self):
    3437          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3438          handle, filename = tempfile.mkstemp()
    3439          try:
    3440              tree.write(filename, compression=9)
    3441              f = gzip.open(filename, 'rb')
    3442              try:
    3443                  data = f.read()
    3444              finally:
    3445                  f.close()
    3446          finally:
    3447              os.close(handle)
    3448              os.remove(filename)
    3449          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3450                            data)
    3451
    3452 -    def test_write_file_gzip_parse(self):
    3453          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3454          handle, filename = tempfile.mkstemp()
    3455          try:
    3456              tree.write(filename, compression=9)
    3457              data = etree.tostring(etree.parse(filename))
    3458          finally:
    3459              os.close(handle)
    3460              os.remove(filename)
    3461          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3462                            data)
    3463
    3464 -    def test_write_file_gzipfile_parse(self):
    3465          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3466          handle, filename = tempfile.mkstemp()
    3467          try:
    3468              tree.write(filename, compression=9)
    3469              data = etree.tostring(etree.parse(
    3470                  gzip.GzipFile(filename)))
    3471          finally:
    3472              os.close(handle)
    3473              os.remove(filename)
    3474          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3475                            data)
    3476
    3477 -class ETreeErrorLogTest(HelperTestCase):
    3478      etree = etree
    3479
    3480 -    def test_parse_error_logging(self):
    3481          parse = self.etree.parse
    3482          f = BytesIO('<a><b></c></b></a>')
    3483          self.etree.clear_error_log()
    3484          try:
    3485              parse(f)
    3486              logs = None
    3487          except SyntaxError:
    3488              e = sys.exc_info()[1]
    3489              logs = e.error_log
    3490          f.close()
    3491          self.assert_([ log for log in logs
    3492                         if 'mismatch' in log.message ])
    3493          self.assert_([ log for log in logs
    3494                         if 'PARSER'   in log.domain_name])
    3495          self.assert_([ log for log in logs
    3496                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
    3497          self.assert_([ log for log in logs
    3498                         if 1 == log.line ])
    3499          self.assert_([ log for log in logs
    3500                         if 15 == log.column ])
    3501
    3502 -    def _test_python_error_logging(self):
    3503          """This can't really be tested as long as there isn't a way to
    3504          reset the logging setup ...
    3505          """
    3506          parse = self.etree.parse
    3507
    3508          messages = []
    3509          class Logger(self.etree.PyErrorLog):
    3510              def log(self, entry, message, *args):
    3511                  messages.append(message)
    3512
    3513          self.etree.use_global_python_log(Logger())
    3514          f = BytesIO('<a><b></c></b></a>')
    3515          try:
    3516              parse(f)
    3517          except SyntaxError:
    3518              pass
    3519          f.close()
    3520
    3521          self.assert_([ message for message in messages
    3522                         if 'mismatch' in message ])
    3523          self.assert_([ message for message in messages
    3524                         if ':PARSER:'   in message])
    3525          self.assert_([ message for message in messages
    3526                         if ':ERR_TAG_NAME_MISMATCH:' in message ])
    3527          self.assert_([ message for message in messages
    3528                         if ':1:15:' in message ])
    3529
    3530 -def test_suite():
    3531      suite = unittest.TestSuite()
    3532      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
    3533      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
    3534      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
    3535      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
    3536      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
    3537      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
    3538      suite.addTests(
    3539          [make_doctest('../../../doc/tutorial.txt')])
    3540      suite.addTests(
    3541          [make_doctest('../../../doc/api.txt')])
    3542      suite.addTests(
    3543          [make_doctest('../../../doc/FAQ.txt')])
    3544      suite.addTests(
    3545          [make_doctest('../../../doc/parsing.txt')])
    3546      suite.addTests(
    3547          [make_doctest('../../../doc/resolvers.txt')])
    3548      return suite
    3549
    3550  if __name__ == '__main__':
    3551      print('to test use test.py %s' % __file__)
    3552