home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 June / maximum-cd-2011-06.iso / DiscContents / LibO_3.3.1_Win_x86_install_multi.exe / libreoffice1.cab / test_sax.py < prev    next >
Encoding:
Python Source  |  2011-02-15  |  23.6 KB  |  697 lines

  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.                           "<Donald Duck & Co>")
  107.  
  108.     def test_escape_extra(self):
  109.         self.assertEquals(escape("Hei pσ deg", {"σ" : "å"}),
  110.                           "Hei på deg")
  111.  
  112.     # ===== unescape
  113.     def test_unescape_basic(self):
  114.         self.assertEquals(unescape("Donald Duck & Co"), "Donald Duck & Co")
  115.  
  116.     def test_unescape_all(self):
  117.         self.assertEquals(unescape("<Donald Duck & Co>"),
  118.                           "<Donald Duck & Co>")
  119.  
  120.     def test_unescape_extra(self):
  121.         self.assertEquals(unescape("Hei pσ deg", {"σ" : "å"}),
  122.                           "Hei på deg")
  123.  
  124.     def test_unescape_amp_extra(self):
  125.         self.assertEquals(unescape("&foo;", {"&foo;": "splat"}), "&foo;")
  126.  
  127.     # ===== quoteattr
  128.     def test_quoteattr_basic(self):
  129.         self.assertEquals(quoteattr("Donald Duck & Co"),
  130.                           '"Donald Duck & 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 "double" 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><huhei&</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=\"'"\"></e>"
  221.              "<e a=\" \"></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()
  697.