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