symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_sax.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 # regression test for SAX 2.0            -*- coding: iso-8859-1 -*-
       
     2 # $Id: test_sax.py 61997 2008-03-28 07:36:31Z neal.norwitz $
       
     3 
       
     4 from xml.sax import make_parser, ContentHandler, \
       
     5                     SAXException, SAXReaderNotAvailable, SAXParseException
       
     6 try:
       
     7     make_parser()
       
     8 except SAXReaderNotAvailable:
       
     9     # don't try to test this module if we cannot create a parser
       
    10     raise ImportError("no XML parsers available")
       
    11 from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \
       
    12                              XMLFilterBase
       
    13 from xml.sax.expatreader import create_parser
       
    14 from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
       
    15 from cStringIO import StringIO
       
    16 from test.test_support import findfile, run_unittest
       
    17 import unittest
       
    18 import os
       
    19 
       
    20 ns_uri = "http://www.python.org/xml-ns/saxtest/"
       
    21 
       
    22 class XmlTestBase(unittest.TestCase):
       
    23     def verify_empty_attrs(self, attrs):
       
    24         self.assertRaises(KeyError, attrs.getValue, "attr")
       
    25         self.assertRaises(KeyError, attrs.getValueByQName, "attr")
       
    26         self.assertRaises(KeyError, attrs.getNameByQName, "attr")
       
    27         self.assertRaises(KeyError, attrs.getQNameByName, "attr")
       
    28         self.assertRaises(KeyError, attrs.__getitem__, "attr")
       
    29         self.assertEquals(attrs.getLength(), 0)
       
    30         self.assertEquals(attrs.getNames(), [])
       
    31         self.assertEquals(attrs.getQNames(), [])
       
    32         self.assertEquals(len(attrs), 0)
       
    33         self.assertFalse(attrs.has_key("attr"))
       
    34         self.assertEquals(attrs.keys(), [])
       
    35         self.assertEquals(attrs.get("attrs"), None)
       
    36         self.assertEquals(attrs.get("attrs", 25), 25)
       
    37         self.assertEquals(attrs.items(), [])
       
    38         self.assertEquals(attrs.values(), [])
       
    39 
       
    40     def verify_empty_nsattrs(self, attrs):
       
    41         self.assertRaises(KeyError, attrs.getValue, (ns_uri, "attr"))
       
    42         self.assertRaises(KeyError, attrs.getValueByQName, "ns:attr")
       
    43         self.assertRaises(KeyError, attrs.getNameByQName, "ns:attr")
       
    44         self.assertRaises(KeyError, attrs.getQNameByName, (ns_uri, "attr"))
       
    45         self.assertRaises(KeyError, attrs.__getitem__, (ns_uri, "attr"))
       
    46         self.assertEquals(attrs.getLength(), 0)
       
    47         self.assertEquals(attrs.getNames(), [])
       
    48         self.assertEquals(attrs.getQNames(), [])
       
    49         self.assertEquals(len(attrs), 0)
       
    50         self.assertFalse(attrs.has_key((ns_uri, "attr")))
       
    51         self.assertEquals(attrs.keys(), [])
       
    52         self.assertEquals(attrs.get((ns_uri, "attr")), None)
       
    53         self.assertEquals(attrs.get((ns_uri, "attr"), 25), 25)
       
    54         self.assertEquals(attrs.items(), [])
       
    55         self.assertEquals(attrs.values(), [])
       
    56 
       
    57     def verify_attrs_wattr(self, attrs):
       
    58         self.assertEquals(attrs.getLength(), 1)
       
    59         self.assertEquals(attrs.getNames(), ["attr"])
       
    60         self.assertEquals(attrs.getQNames(), ["attr"])
       
    61         self.assertEquals(len(attrs), 1)
       
    62         self.assertTrue(attrs.has_key("attr"))
       
    63         self.assertEquals(attrs.keys(), ["attr"])
       
    64         self.assertEquals(attrs.get("attr"), "val")
       
    65         self.assertEquals(attrs.get("attr", 25), "val")
       
    66         self.assertEquals(attrs.items(), [("attr", "val")])
       
    67         self.assertEquals(attrs.values(), ["val"])
       
    68         self.assertEquals(attrs.getValue("attr"), "val")
       
    69         self.assertEquals(attrs.getValueByQName("attr"), "val")
       
    70         self.assertEquals(attrs.getNameByQName("attr"), "attr")
       
    71         self.assertEquals(attrs["attr"], "val")
       
    72         self.assertEquals(attrs.getQNameByName("attr"), "attr")
       
    73 
       
    74 class MakeParserTest(unittest.TestCase):
       
    75     def test_make_parser2(self):
       
    76         # Creating parsers several times in a row should succeed.
       
    77         # Testing this because there have been failures of this kind
       
    78         # before.
       
    79         from xml.sax import make_parser
       
    80         p = make_parser()
       
    81         from xml.sax import make_parser
       
    82         p = make_parser()
       
    83         from xml.sax import make_parser
       
    84         p = make_parser()
       
    85         from xml.sax import make_parser
       
    86         p = make_parser()
       
    87         from xml.sax import make_parser
       
    88         p = make_parser()
       
    89         from xml.sax import make_parser
       
    90         p = make_parser()
       
    91 
       
    92 
       
    93 # ===========================================================================
       
    94 #
       
    95 #   saxutils tests
       
    96 #
       
    97 # ===========================================================================
       
    98 
       
    99 class SaxutilsTest(unittest.TestCase):
       
   100     # ===== escape
       
   101     def test_escape_basic(self):
       
   102         self.assertEquals(escape("Donald Duck & Co"), "Donald Duck & Co")
       
   103 
       
   104     def test_escape_all(self):
       
   105         self.assertEquals(escape("<Donald Duck & Co>"),
       
   106                           "&lt;Donald Duck &amp; Co&gt;")
       
   107 
       
   108     def test_escape_extra(self):
       
   109         self.assertEquals(escape("Hei på deg", {"å" : "&aring;"}),
       
   110                           "Hei p&aring; deg")
       
   111 
       
   112     # ===== unescape
       
   113     def test_unescape_basic(self):
       
   114         self.assertEquals(unescape("Donald Duck &amp; Co"), "Donald Duck & Co")
       
   115 
       
   116     def test_unescape_all(self):
       
   117         self.assertEquals(unescape("&lt;Donald Duck &amp; Co&gt;"),
       
   118                           "<Donald Duck & Co>")
       
   119 
       
   120     def test_unescape_extra(self):
       
   121         self.assertEquals(unescape("Hei på deg", {"å" : "&aring;"}),
       
   122                           "Hei p&aring; deg")
       
   123 
       
   124     def test_unescape_amp_extra(self):
       
   125         self.assertEquals(unescape("&amp;foo;", {"&foo;": "splat"}), "&foo;")
       
   126 
       
   127     # ===== quoteattr
       
   128     def test_quoteattr_basic(self):
       
   129         self.assertEquals(quoteattr("Donald Duck & Co"),
       
   130                           '"Donald Duck &amp; Co"')
       
   131 
       
   132     def test_single_quoteattr(self):
       
   133         self.assertEquals(quoteattr('Includes "double" quotes'),
       
   134                           '\'Includes "double" quotes\'')
       
   135 
       
   136     def test_double_quoteattr(self):
       
   137         self.assertEquals(quoteattr("Includes 'single' quotes"),
       
   138                           "\"Includes 'single' quotes\"")
       
   139 
       
   140     def test_single_double_quoteattr(self):
       
   141         self.assertEquals(quoteattr("Includes 'single' and \"double\" quotes"),
       
   142                     "\"Includes 'single' and &quot;double&quot; quotes\"")
       
   143 
       
   144     # ===== make_parser
       
   145     def test_make_parser(self):
       
   146         # Creating a parser should succeed - it should fall back
       
   147         # to the expatreader
       
   148         p = make_parser(['xml.parsers.no_such_parser'])
       
   149 
       
   150 
       
   151 # ===== XMLGenerator
       
   152 
       
   153 start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
       
   154 
       
   155 class XmlgenTest(unittest.TestCase):
       
   156     def test_xmlgen_basic(self):
       
   157         result = StringIO()
       
   158         gen = XMLGenerator(result)
       
   159         gen.startDocument()
       
   160         gen.startElement("doc", {})
       
   161         gen.endElement("doc")
       
   162         gen.endDocument()
       
   163 
       
   164         self.assertEquals(result.getvalue(), start + "<doc></doc>")
       
   165 
       
   166     def test_xmlgen_content(self):
       
   167         result = StringIO()
       
   168         gen = XMLGenerator(result)
       
   169 
       
   170         gen.startDocument()
       
   171         gen.startElement("doc", {})
       
   172         gen.characters("huhei")
       
   173         gen.endElement("doc")
       
   174         gen.endDocument()
       
   175 
       
   176         self.assertEquals(result.getvalue(), start + "<doc>huhei</doc>")
       
   177 
       
   178     def test_xmlgen_pi(self):
       
   179         result = StringIO()
       
   180         gen = XMLGenerator(result)
       
   181 
       
   182         gen.startDocument()
       
   183         gen.processingInstruction("test", "data")
       
   184         gen.startElement("doc", {})
       
   185         gen.endElement("doc")
       
   186         gen.endDocument()
       
   187 
       
   188         self.assertEquals(result.getvalue(), start + "<?test data?><doc></doc>")
       
   189 
       
   190     def test_xmlgen_content_escape(self):
       
   191         result = StringIO()
       
   192         gen = XMLGenerator(result)
       
   193 
       
   194         gen.startDocument()
       
   195         gen.startElement("doc", {})
       
   196         gen.characters("<huhei&")
       
   197         gen.endElement("doc")
       
   198         gen.endDocument()
       
   199 
       
   200         self.assertEquals(result.getvalue(),
       
   201             start + "<doc>&lt;huhei&amp;</doc>")
       
   202 
       
   203     def test_xmlgen_attr_escape(self):
       
   204         result = StringIO()
       
   205         gen = XMLGenerator(result)
       
   206 
       
   207         gen.startDocument()
       
   208         gen.startElement("doc", {"a": '"'})
       
   209         gen.startElement("e", {"a": "'"})
       
   210         gen.endElement("e")
       
   211         gen.startElement("e", {"a": "'\""})
       
   212         gen.endElement("e")
       
   213         gen.startElement("e", {"a": "\n\r\t"})
       
   214         gen.endElement("e")
       
   215         gen.endElement("doc")
       
   216         gen.endDocument()
       
   217 
       
   218         self.assertEquals(result.getvalue(), start +
       
   219             ("<doc a='\"'><e a=\"'\"></e>"
       
   220              "<e a=\"'&quot;\"></e>"
       
   221              "<e a=\"&#10;&#13;&#9;\"></e></doc>"))
       
   222 
       
   223     def test_xmlgen_ignorable(self):
       
   224         result = StringIO()
       
   225         gen = XMLGenerator(result)
       
   226 
       
   227         gen.startDocument()
       
   228         gen.startElement("doc", {})
       
   229         gen.ignorableWhitespace(" ")
       
   230         gen.endElement("doc")
       
   231         gen.endDocument()
       
   232 
       
   233         self.assertEquals(result.getvalue(), start + "<doc> </doc>")
       
   234 
       
   235     def test_xmlgen_ns(self):
       
   236         result = StringIO()
       
   237         gen = XMLGenerator(result)
       
   238 
       
   239         gen.startDocument()
       
   240         gen.startPrefixMapping("ns1", ns_uri)
       
   241         gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
       
   242         # add an unqualified name
       
   243         gen.startElementNS((None, "udoc"), None, {})
       
   244         gen.endElementNS((None, "udoc"), None)
       
   245         gen.endElementNS((ns_uri, "doc"), "ns1:doc")
       
   246         gen.endPrefixMapping("ns1")
       
   247         gen.endDocument()
       
   248 
       
   249         self.assertEquals(result.getvalue(), start + \
       
   250            ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' %
       
   251                                          ns_uri))
       
   252 
       
   253     def test_1463026_1(self):
       
   254         result = StringIO()
       
   255         gen = XMLGenerator(result)
       
   256 
       
   257         gen.startDocument()
       
   258         gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'})
       
   259         gen.endElementNS((None, 'a'), 'a')
       
   260         gen.endDocument()
       
   261 
       
   262         self.assertEquals(result.getvalue(), start+'<a b="c"></a>')
       
   263 
       
   264     def test_1463026_2(self):
       
   265         result = StringIO()
       
   266         gen = XMLGenerator(result)
       
   267 
       
   268         gen.startDocument()
       
   269         gen.startPrefixMapping(None, 'qux')
       
   270         gen.startElementNS(('qux', 'a'), 'a', {})
       
   271         gen.endElementNS(('qux', 'a'), 'a')
       
   272         gen.endPrefixMapping(None)
       
   273         gen.endDocument()
       
   274 
       
   275         self.assertEquals(result.getvalue(), start+'<a xmlns="qux"></a>')
       
   276 
       
   277     def test_1463026_3(self):
       
   278         result = StringIO()
       
   279         gen = XMLGenerator(result)
       
   280 
       
   281         gen.startDocument()
       
   282         gen.startPrefixMapping('my', 'qux')
       
   283         gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'})
       
   284         gen.endElementNS(('qux', 'a'), 'a')
       
   285         gen.endPrefixMapping('my')
       
   286         gen.endDocument()
       
   287 
       
   288         self.assertEquals(result.getvalue(),
       
   289             start+'<my:a xmlns:my="qux" b="c"></my:a>')
       
   290 
       
   291 
       
   292 class XMLFilterBaseTest(unittest.TestCase):
       
   293     def test_filter_basic(self):
       
   294         result = StringIO()
       
   295         gen = XMLGenerator(result)
       
   296         filter = XMLFilterBase()
       
   297         filter.setContentHandler(gen)
       
   298 
       
   299         filter.startDocument()
       
   300         filter.startElement("doc", {})
       
   301         filter.characters("content")
       
   302         filter.ignorableWhitespace(" ")
       
   303         filter.endElement("doc")
       
   304         filter.endDocument()
       
   305 
       
   306         self.assertEquals(result.getvalue(), start + "<doc>content </doc>")
       
   307 
       
   308 # ===========================================================================
       
   309 #
       
   310 #   expatreader tests
       
   311 #
       
   312 # ===========================================================================
       
   313 
       
   314 xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read()
       
   315 
       
   316 class ExpatReaderTest(XmlTestBase):
       
   317 
       
   318     # ===== XMLReader support
       
   319 
       
   320     def test_expat_file(self):
       
   321         parser = create_parser()
       
   322         result = StringIO()
       
   323         xmlgen = XMLGenerator(result)
       
   324 
       
   325         parser.setContentHandler(xmlgen)
       
   326         parser.parse(open(findfile("test"+os.extsep+"xml")))
       
   327 
       
   328         self.assertEquals(result.getvalue(), xml_test_out)
       
   329 
       
   330     # ===== DTDHandler support
       
   331 
       
   332     class TestDTDHandler:
       
   333 
       
   334         def __init__(self):
       
   335             self._notations = []
       
   336             self._entities  = []
       
   337 
       
   338         def notationDecl(self, name, publicId, systemId):
       
   339             self._notations.append((name, publicId, systemId))
       
   340 
       
   341         def unparsedEntityDecl(self, name, publicId, systemId, ndata):
       
   342             self._entities.append((name, publicId, systemId, ndata))
       
   343 
       
   344     def test_expat_dtdhandler(self):
       
   345         parser = create_parser()
       
   346         handler = self.TestDTDHandler()
       
   347         parser.setDTDHandler(handler)
       
   348 
       
   349         parser.feed('<!DOCTYPE doc [\n')
       
   350         parser.feed('  <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
       
   351         parser.feed('  <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
       
   352         parser.feed(']>\n')
       
   353         parser.feed('<doc></doc>')
       
   354         parser.close()
       
   355 
       
   356         self.assertEquals(handler._notations,
       
   357             [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)])
       
   358         self.assertEquals(handler._entities, [("img", None, "expat.gif", "GIF")])
       
   359 
       
   360     # ===== EntityResolver support
       
   361 
       
   362     class TestEntityResolver:
       
   363 
       
   364         def resolveEntity(self, publicId, systemId):
       
   365             inpsrc = InputSource()
       
   366             inpsrc.setByteStream(StringIO("<entity/>"))
       
   367             return inpsrc
       
   368 
       
   369     def test_expat_entityresolver(self):
       
   370         parser = create_parser()
       
   371         parser.setEntityResolver(self.TestEntityResolver())
       
   372         result = StringIO()
       
   373         parser.setContentHandler(XMLGenerator(result))
       
   374 
       
   375         parser.feed('<!DOCTYPE doc [\n')
       
   376         parser.feed('  <!ENTITY test SYSTEM "whatever">\n')
       
   377         parser.feed(']>\n')
       
   378         parser.feed('<doc>&test;</doc>')
       
   379         parser.close()
       
   380 
       
   381         self.assertEquals(result.getvalue(), start +
       
   382                           "<doc><entity></entity></doc>")
       
   383 
       
   384     # ===== Attributes support
       
   385 
       
   386     class AttrGatherer(ContentHandler):
       
   387 
       
   388         def startElement(self, name, attrs):
       
   389             self._attrs = attrs
       
   390 
       
   391         def startElementNS(self, name, qname, attrs):
       
   392             self._attrs = attrs
       
   393 
       
   394     def test_expat_attrs_empty(self):
       
   395         parser = create_parser()
       
   396         gather = self.AttrGatherer()
       
   397         parser.setContentHandler(gather)
       
   398 
       
   399         parser.feed("<doc/>")
       
   400         parser.close()
       
   401 
       
   402         self.verify_empty_attrs(gather._attrs)
       
   403 
       
   404     def test_expat_attrs_wattr(self):
       
   405         parser = create_parser()
       
   406         gather = self.AttrGatherer()
       
   407         parser.setContentHandler(gather)
       
   408 
       
   409         parser.feed("<doc attr='val'/>")
       
   410         parser.close()
       
   411 
       
   412         self.verify_attrs_wattr(gather._attrs)
       
   413 
       
   414     def test_expat_nsattrs_empty(self):
       
   415         parser = create_parser(1)
       
   416         gather = self.AttrGatherer()
       
   417         parser.setContentHandler(gather)
       
   418 
       
   419         parser.feed("<doc/>")
       
   420         parser.close()
       
   421 
       
   422         self.verify_empty_nsattrs(gather._attrs)
       
   423 
       
   424     def test_expat_nsattrs_wattr(self):
       
   425         parser = create_parser(1)
       
   426         gather = self.AttrGatherer()
       
   427         parser.setContentHandler(gather)
       
   428 
       
   429         parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
       
   430         parser.close()
       
   431 
       
   432         attrs = gather._attrs
       
   433 
       
   434         self.assertEquals(attrs.getLength(), 1)
       
   435         self.assertEquals(attrs.getNames(), [(ns_uri, "attr")])
       
   436         self.assertTrue((attrs.getQNames() == [] or
       
   437                          attrs.getQNames() == ["ns:attr"]))
       
   438         self.assertEquals(len(attrs), 1)
       
   439         self.assertTrue(attrs.has_key((ns_uri, "attr")))
       
   440         self.assertEquals(attrs.get((ns_uri, "attr")), "val")
       
   441         self.assertEquals(attrs.get((ns_uri, "attr"), 25), "val")
       
   442         self.assertEquals(attrs.items(), [((ns_uri, "attr"), "val")])
       
   443         self.assertEquals(attrs.values(), ["val"])
       
   444         self.assertEquals(attrs.getValue((ns_uri, "attr")), "val")
       
   445         self.assertEquals(attrs[(ns_uri, "attr")], "val")
       
   446 
       
   447     # ===== InputSource support
       
   448 
       
   449     def test_expat_inpsource_filename(self):
       
   450         parser = create_parser()
       
   451         result = StringIO()
       
   452         xmlgen = XMLGenerator(result)
       
   453 
       
   454         parser.setContentHandler(xmlgen)
       
   455         parser.parse(findfile("test"+os.extsep+"xml"))
       
   456 
       
   457         self.assertEquals(result.getvalue(), xml_test_out)
       
   458 
       
   459     def test_expat_inpsource_sysid(self):
       
   460         parser = create_parser()
       
   461         result = StringIO()
       
   462         xmlgen = XMLGenerator(result)
       
   463 
       
   464         parser.setContentHandler(xmlgen)
       
   465         parser.parse(InputSource(findfile("test"+os.extsep+"xml")))
       
   466 
       
   467         self.assertEquals(result.getvalue(), xml_test_out)
       
   468 
       
   469     def test_expat_inpsource_stream(self):
       
   470         parser = create_parser()
       
   471         result = StringIO()
       
   472         xmlgen = XMLGenerator(result)
       
   473 
       
   474         parser.setContentHandler(xmlgen)
       
   475         inpsrc = InputSource()
       
   476         inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml")))
       
   477         parser.parse(inpsrc)
       
   478 
       
   479         self.assertEquals(result.getvalue(), xml_test_out)
       
   480 
       
   481     # ===== IncrementalParser support
       
   482 
       
   483     def test_expat_incremental(self):
       
   484         result = StringIO()
       
   485         xmlgen = XMLGenerator(result)
       
   486         parser = create_parser()
       
   487         parser.setContentHandler(xmlgen)
       
   488 
       
   489         parser.feed("<doc>")
       
   490         parser.feed("</doc>")
       
   491         parser.close()
       
   492 
       
   493         self.assertEquals(result.getvalue(), start + "<doc></doc>")
       
   494 
       
   495     def test_expat_incremental_reset(self):
       
   496         result = StringIO()
       
   497         xmlgen = XMLGenerator(result)
       
   498         parser = create_parser()
       
   499         parser.setContentHandler(xmlgen)
       
   500 
       
   501         parser.feed("<doc>")
       
   502         parser.feed("text")
       
   503 
       
   504         result = StringIO()
       
   505         xmlgen = XMLGenerator(result)
       
   506         parser.setContentHandler(xmlgen)
       
   507         parser.reset()
       
   508 
       
   509         parser.feed("<doc>")
       
   510         parser.feed("text")
       
   511         parser.feed("</doc>")
       
   512         parser.close()
       
   513 
       
   514         self.assertEquals(result.getvalue(), start + "<doc>text</doc>")
       
   515 
       
   516     # ===== Locator support
       
   517 
       
   518     def test_expat_locator_noinfo(self):
       
   519         result = StringIO()
       
   520         xmlgen = XMLGenerator(result)
       
   521         parser = create_parser()
       
   522         parser.setContentHandler(xmlgen)
       
   523 
       
   524         parser.feed("<doc>")
       
   525         parser.feed("</doc>")
       
   526         parser.close()
       
   527 
       
   528         self.assertEquals(parser.getSystemId(), None)
       
   529         self.assertEquals(parser.getPublicId(), None)
       
   530         self.assertEquals(parser.getLineNumber(), 1)
       
   531 
       
   532     def test_expat_locator_withinfo(self):
       
   533         result = StringIO()
       
   534         xmlgen = XMLGenerator(result)
       
   535         parser = create_parser()
       
   536         parser.setContentHandler(xmlgen)
       
   537         parser.parse(findfile("test.xml"))
       
   538 
       
   539         self.assertEquals(parser.getSystemId(), findfile("test.xml"))
       
   540         self.assertEquals(parser.getPublicId(), None)
       
   541 
       
   542 
       
   543 # ===========================================================================
       
   544 #
       
   545 #   error reporting
       
   546 #
       
   547 # ===========================================================================
       
   548 
       
   549 class ErrorReportingTest(unittest.TestCase):
       
   550     def test_expat_inpsource_location(self):
       
   551         parser = create_parser()
       
   552         parser.setContentHandler(ContentHandler()) # do nothing
       
   553         source = InputSource()
       
   554         source.setByteStream(StringIO("<foo bar foobar>"))   #ill-formed
       
   555         name = "a file name"
       
   556         source.setSystemId(name)
       
   557         try:
       
   558             parser.parse(source)
       
   559             self.fail()
       
   560         except SAXException, e:
       
   561             self.assertEquals(e.getSystemId(), name)
       
   562 
       
   563     def test_expat_incomplete(self):
       
   564         parser = create_parser()
       
   565         parser.setContentHandler(ContentHandler()) # do nothing
       
   566         self.assertRaises(SAXParseException, parser.parse, StringIO("<foo>"))
       
   567 
       
   568     def test_sax_parse_exception_str(self):
       
   569         # pass various values from a locator to the SAXParseException to
       
   570         # make sure that the __str__() doesn't fall apart when None is
       
   571         # passed instead of an integer line and column number
       
   572         #
       
   573         # use "normal" values for the locator:
       
   574         str(SAXParseException("message", None,
       
   575                               self.DummyLocator(1, 1)))
       
   576         # use None for the line number:
       
   577         str(SAXParseException("message", None,
       
   578                               self.DummyLocator(None, 1)))
       
   579         # use None for the column number:
       
   580         str(SAXParseException("message", None,
       
   581                               self.DummyLocator(1, None)))
       
   582         # use None for both:
       
   583         str(SAXParseException("message", None,
       
   584                               self.DummyLocator(None, None)))
       
   585 
       
   586     class DummyLocator:
       
   587         def __init__(self, lineno, colno):
       
   588             self._lineno = lineno
       
   589             self._colno = colno
       
   590 
       
   591         def getPublicId(self):
       
   592             return "pubid"
       
   593 
       
   594         def getSystemId(self):
       
   595             return "sysid"
       
   596 
       
   597         def getLineNumber(self):
       
   598             return self._lineno
       
   599 
       
   600         def getColumnNumber(self):
       
   601             return self._colno
       
   602 
       
   603 # ===========================================================================
       
   604 #
       
   605 #   xmlreader tests
       
   606 #
       
   607 # ===========================================================================
       
   608 
       
   609 class XmlReaderTest(XmlTestBase):
       
   610 
       
   611     # ===== AttributesImpl
       
   612     def test_attrs_empty(self):
       
   613         self.verify_empty_attrs(AttributesImpl({}))
       
   614 
       
   615     def test_attrs_wattr(self):
       
   616         self.verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
       
   617 
       
   618     def test_nsattrs_empty(self):
       
   619         self.verify_empty_nsattrs(AttributesNSImpl({}, {}))
       
   620 
       
   621     def test_nsattrs_wattr(self):
       
   622         attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
       
   623                                  {(ns_uri, "attr") : "ns:attr"})
       
   624 
       
   625         self.assertEquals(attrs.getLength(), 1)
       
   626         self.assertEquals(attrs.getNames(), [(ns_uri, "attr")])
       
   627         self.assertEquals(attrs.getQNames(), ["ns:attr"])
       
   628         self.assertEquals(len(attrs), 1)
       
   629         self.assertTrue(attrs.has_key((ns_uri, "attr")))
       
   630         self.assertEquals(attrs.keys(), [(ns_uri, "attr")])
       
   631         self.assertEquals(attrs.get((ns_uri, "attr")), "val")
       
   632         self.assertEquals(attrs.get((ns_uri, "attr"), 25), "val")
       
   633         self.assertEquals(attrs.items(), [((ns_uri, "attr"), "val")])
       
   634         self.assertEquals(attrs.values(), ["val"])
       
   635         self.assertEquals(attrs.getValue((ns_uri, "attr")), "val")
       
   636         self.assertEquals(attrs.getValueByQName("ns:attr"), "val")
       
   637         self.assertEquals(attrs.getNameByQName("ns:attr"), (ns_uri, "attr"))
       
   638         self.assertEquals(attrs[(ns_uri, "attr")], "val")
       
   639         self.assertEquals(attrs.getQNameByName((ns_uri, "attr")), "ns:attr")
       
   640 
       
   641 
       
   642     # During the development of Python 2.5, an attempt to move the "xml"
       
   643     # package implementation to a new package ("xmlcore") proved painful.
       
   644     # The goal of this change was to allow applications to be able to
       
   645     # obtain and rely on behavior in the standard library implementation
       
   646     # of the XML support without needing to be concerned about the
       
   647     # availability of the PyXML implementation.
       
   648     #
       
   649     # While the existing import hackery in Lib/xml/__init__.py can cause
       
   650     # PyXML's _xmlpus package to supplant the "xml" package, that only
       
   651     # works because either implementation uses the "xml" package name for
       
   652     # imports.
       
   653     #
       
   654     # The move resulted in a number of problems related to the fact that
       
   655     # the import machinery's "package context" is based on the name that's
       
   656     # being imported rather than the __name__ of the actual package
       
   657     # containment; it wasn't possible for the "xml" package to be replaced
       
   658     # by a simple module that indirected imports to the "xmlcore" package.
       
   659     #
       
   660     # The following two tests exercised bugs that were introduced in that
       
   661     # attempt.  Keeping these tests around will help detect problems with
       
   662     # other attempts to provide reliable access to the standard library's
       
   663     # implementation of the XML support.
       
   664 
       
   665     def test_sf_1511497(self):
       
   666         # Bug report: http://www.python.org/sf/1511497
       
   667         import sys
       
   668         old_modules = sys.modules.copy()
       
   669         for modname in sys.modules.keys():
       
   670             if modname.startswith("xml."):
       
   671                 del sys.modules[modname]
       
   672         try:
       
   673             import xml.sax.expatreader
       
   674             module = xml.sax.expatreader
       
   675             self.assertEquals(module.__name__, "xml.sax.expatreader")
       
   676         finally:
       
   677             sys.modules.update(old_modules)
       
   678 
       
   679     def test_sf_1513611(self):
       
   680         # Bug report: http://www.python.org/sf/1513611
       
   681         sio = StringIO("invalid")
       
   682         parser = make_parser()
       
   683         from xml.sax import SAXParseException
       
   684         self.assertRaises(SAXParseException, parser.parse, sio)
       
   685 
       
   686 
       
   687 def test_main():
       
   688     run_unittest(MakeParserTest,
       
   689                  SaxutilsTest,
       
   690                  XmlgenTest,
       
   691                  ExpatReaderTest,
       
   692                  ErrorReportingTest,
       
   693                  XmlReaderTest)
       
   694 
       
   695 if __name__ == "__main__":
       
   696     test_main()