home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / test_sax.py < prev    next >
Text File  |  2003-12-30  |  18KB  |  661 lines

  1. # regression test for SAX 2.0            -*- coding: iso-8859-1 -*-
  2. # $Id: test_sax.py,v 1.24 2002/10/28 17:58:48 fdrake Exp $
  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 verify, verbose, TestFailed, findfile
  17. import os
  18.  
  19. # ===== Utilities
  20.  
  21. tests = 0
  22. failures = []
  23.  
  24. def confirm(outcome, name):
  25.     global tests
  26.  
  27.     tests = tests + 1
  28.     if outcome:
  29.         if verbose:
  30.             print "Failed", name
  31.     else:
  32.         failures.append(name)
  33.  
  34. def test_make_parser2():
  35.     try:
  36.         # Creating parsers several times in a row should succeed.
  37.         # Testing this because there have been failures of this kind
  38.         # before.
  39.         from xml.sax import make_parser
  40.         p = make_parser()
  41.         from xml.sax import make_parser
  42.         p = make_parser()
  43.         from xml.sax import make_parser
  44.         p = make_parser()
  45.         from xml.sax import make_parser
  46.         p = make_parser()
  47.         from xml.sax import make_parser
  48.         p = make_parser()
  49.         from xml.sax import make_parser
  50.         p = make_parser()
  51.     except:
  52.         return 0
  53.     else:
  54.         return p
  55.  
  56.  
  57. # ===========================================================================
  58. #
  59. #   saxutils tests
  60. #
  61. # ===========================================================================
  62.  
  63. # ===== escape
  64.  
  65. def test_escape_basic():
  66.     return escape("Donald Duck & Co") == "Donald Duck & Co"
  67.  
  68. def test_escape_all():
  69.     return escape("<Donald Duck & Co>") == "<Donald Duck & Co>"
  70.  
  71. def test_escape_extra():
  72.     return escape("Hei pσ deg", {"σ" : "å"}) == "Hei på deg"
  73.  
  74. # ===== unescape
  75.  
  76. def test_unescape_basic():
  77.     return unescape("Donald Duck & Co") == "Donald Duck & Co"
  78.  
  79. def test_unescape_all():
  80.     return unescape("<Donald Duck & Co>") == "<Donald Duck & Co>"
  81.  
  82. def test_unescape_extra():
  83.     return unescape("Hei pσ deg", {"σ" : "å"}) == "Hei på deg"
  84.  
  85. def test_unescape_amp_extra():
  86.     return unescape("&foo;", {"&foo;": "splat"}) == "&foo;"
  87.  
  88. # ===== quoteattr
  89.  
  90. def test_quoteattr_basic():
  91.     return quoteattr("Donald Duck & Co") == '"Donald Duck & Co"'
  92.  
  93. def test_single_quoteattr():
  94.     return (quoteattr('Includes "double" quotes')
  95.             == '\'Includes "double" quotes\'')
  96.  
  97. def test_double_quoteattr():
  98.     return (quoteattr("Includes 'single' quotes")
  99.             == "\"Includes 'single' quotes\"")
  100.  
  101. def test_single_double_quoteattr():
  102.     return (quoteattr("Includes 'single' and \"double\" quotes")
  103.             == "\"Includes 'single' and "double" quotes\"")
  104.  
  105. # ===== make_parser
  106.  
  107. def test_make_parser():
  108.     try:
  109.         # Creating a parser should succeed - it should fall back
  110.         # to the expatreader
  111.         p = make_parser(['xml.parsers.no_such_parser'])
  112.     except:
  113.         return 0
  114.     else:
  115.         return p
  116.  
  117.  
  118. # ===== XMLGenerator
  119.  
  120. start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
  121.  
  122. def test_xmlgen_basic():
  123.     result = StringIO()
  124.     gen = XMLGenerator(result)
  125.     gen.startDocument()
  126.     gen.startElement("doc", {})
  127.     gen.endElement("doc")
  128.     gen.endDocument()
  129.  
  130.     return result.getvalue() == start + "<doc></doc>"
  131.  
  132. def test_xmlgen_content():
  133.     result = StringIO()
  134.     gen = XMLGenerator(result)
  135.  
  136.     gen.startDocument()
  137.     gen.startElement("doc", {})
  138.     gen.characters("huhei")
  139.     gen.endElement("doc")
  140.     gen.endDocument()
  141.  
  142.     return result.getvalue() == start + "<doc>huhei</doc>"
  143.  
  144. def test_xmlgen_pi():
  145.     result = StringIO()
  146.     gen = XMLGenerator(result)
  147.  
  148.     gen.startDocument()
  149.     gen.processingInstruction("test", "data")
  150.     gen.startElement("doc", {})
  151.     gen.endElement("doc")
  152.     gen.endDocument()
  153.  
  154.     return result.getvalue() == start + "<?test data?><doc></doc>"
  155.  
  156. def test_xmlgen_content_escape():
  157.     result = StringIO()
  158.     gen = XMLGenerator(result)
  159.  
  160.     gen.startDocument()
  161.     gen.startElement("doc", {})
  162.     gen.characters("<huhei&")
  163.     gen.endElement("doc")
  164.     gen.endDocument()
  165.  
  166.     return result.getvalue() == start + "<doc><huhei&</doc>"
  167.  
  168. def test_xmlgen_attr_escape():
  169.     result = StringIO()
  170.     gen = XMLGenerator(result)
  171.  
  172.     gen.startDocument()
  173.     gen.startElement("doc", {"a": '"'})
  174.     gen.startElement("e", {"a": "'"})
  175.     gen.endElement("e")
  176.     gen.startElement("e", {"a": "'\""})
  177.     gen.endElement("e")
  178.     gen.endElement("doc")
  179.     gen.endDocument()
  180.  
  181.     return result.getvalue() == start \
  182.            + "<doc a='\"'><e a=\"'\"></e><e a=\"'"\"></e></doc>"
  183.  
  184. def test_xmlgen_ignorable():
  185.     result = StringIO()
  186.     gen = XMLGenerator(result)
  187.  
  188.     gen.startDocument()
  189.     gen.startElement("doc", {})
  190.     gen.ignorableWhitespace(" ")
  191.     gen.endElement("doc")
  192.     gen.endDocument()
  193.  
  194.     return result.getvalue() == start + "<doc> </doc>"
  195.  
  196. ns_uri = "http://www.python.org/xml-ns/saxtest/"
  197.  
  198. def test_xmlgen_ns():
  199.     result = StringIO()
  200.     gen = XMLGenerator(result)
  201.  
  202.     gen.startDocument()
  203.     gen.startPrefixMapping("ns1", ns_uri)
  204.     gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
  205.     # add an unqualified name
  206.     gen.startElementNS((None, "udoc"), None, {})
  207.     gen.endElementNS((None, "udoc"), None)
  208.     gen.endElementNS((ns_uri, "doc"), "ns1:doc")
  209.     gen.endPrefixMapping("ns1")
  210.     gen.endDocument()
  211.  
  212.     return result.getvalue() == start + \
  213.            ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' %
  214.                                          ns_uri)
  215.  
  216. # ===== XMLFilterBase
  217.  
  218. def test_filter_basic():
  219.     result = StringIO()
  220.     gen = XMLGenerator(result)
  221.     filter = XMLFilterBase()
  222.     filter.setContentHandler(gen)
  223.  
  224.     filter.startDocument()
  225.     filter.startElement("doc", {})
  226.     filter.characters("content")
  227.     filter.ignorableWhitespace(" ")
  228.     filter.endElement("doc")
  229.     filter.endDocument()
  230.  
  231.     return result.getvalue() == start + "<doc>content </doc>"
  232.  
  233. # ===========================================================================
  234. #
  235. #   expatreader tests
  236. #
  237. # ===========================================================================
  238.  
  239. # ===== XMLReader support
  240.  
  241. def test_expat_file():
  242.     parser = create_parser()
  243.     result = StringIO()
  244.     xmlgen = XMLGenerator(result)
  245.  
  246.     parser.setContentHandler(xmlgen)
  247.     parser.parse(open(findfile("test"+os.extsep+"xml")))
  248.  
  249.     return result.getvalue() == xml_test_out
  250.  
  251. # ===== DTDHandler support
  252.  
  253. class TestDTDHandler:
  254.  
  255.     def __init__(self):
  256.         self._notations = []
  257.         self._entities  = []
  258.  
  259.     def notationDecl(self, name, publicId, systemId):
  260.         self._notations.append((name, publicId, systemId))
  261.  
  262.     def unparsedEntityDecl(self, name, publicId, systemId, ndata):
  263.         self._entities.append((name, publicId, systemId, ndata))
  264.  
  265. def test_expat_dtdhandler():
  266.     parser = create_parser()
  267.     handler = TestDTDHandler()
  268.     parser.setDTDHandler(handler)
  269.  
  270.     parser.feed('<!DOCTYPE doc [\n')
  271.     parser.feed('  <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
  272.     parser.feed('  <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
  273.     parser.feed(']>\n')
  274.     parser.feed('<doc></doc>')
  275.     parser.close()
  276.  
  277.     return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
  278.            handler._entities == [("img", None, "expat.gif", "GIF")]
  279.  
  280. # ===== EntityResolver support
  281.  
  282. class TestEntityResolver:
  283.  
  284.     def resolveEntity(self, publicId, systemId):
  285.         inpsrc = InputSource()
  286.         inpsrc.setByteStream(StringIO("<entity/>"))
  287.         return inpsrc
  288.  
  289. def test_expat_entityresolver():
  290.     parser = create_parser()
  291.     parser.setEntityResolver(TestEntityResolver())
  292.     result = StringIO()
  293.     parser.setContentHandler(XMLGenerator(result))
  294.  
  295.     parser.feed('<!DOCTYPE doc [\n')
  296.     parser.feed('  <!ENTITY test SYSTEM "whatever">\n')
  297.     parser.feed(']>\n')
  298.     parser.feed('<doc>&test;</doc>')
  299.     parser.close()
  300.  
  301.     return result.getvalue() == start + "<doc><entity></entity></doc>"
  302.  
  303. # ===== Attributes support
  304.  
  305. class AttrGatherer(ContentHandler):
  306.  
  307.     def startElement(self, name, attrs):
  308.         self._attrs = attrs
  309.  
  310.     def startElementNS(self, name, qname, attrs):
  311.         self._attrs = attrs
  312.  
  313. def test_expat_attrs_empty():
  314.     parser = create_parser()
  315.     gather = AttrGatherer()
  316.     parser.setContentHandler(gather)
  317.  
  318.     parser.feed("<doc/>")
  319.     parser.close()
  320.  
  321.     return verify_empty_attrs(gather._attrs)
  322.  
  323. def test_expat_attrs_wattr():
  324.     parser = create_parser()
  325.     gather = AttrGatherer()
  326.     parser.setContentHandler(gather)
  327.  
  328.     parser.feed("<doc attr='val'/>")
  329.     parser.close()
  330.  
  331.     return verify_attrs_wattr(gather._attrs)
  332.  
  333. def test_expat_nsattrs_empty():
  334.     parser = create_parser(1)
  335.     gather = AttrGatherer()
  336.     parser.setContentHandler(gather)
  337.  
  338.     parser.feed("<doc/>")
  339.     parser.close()
  340.  
  341.     return verify_empty_nsattrs(gather._attrs)
  342.  
  343. def test_expat_nsattrs_wattr():
  344.     parser = create_parser(1)
  345.     gather = AttrGatherer()
  346.     parser.setContentHandler(gather)
  347.  
  348.     parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
  349.     parser.close()
  350.  
  351.     attrs = gather._attrs
  352.  
  353.     return attrs.getLength() == 1 and \
  354.            attrs.getNames() == [(ns_uri, "attr")] and \
  355.            (attrs.getQNames() == [] or attrs.getQNames() == ["ns:attr"]) and \
  356.            len(attrs) == 1 and \
  357.            attrs.has_key((ns_uri, "attr")) and \
  358.            attrs.keys() == [(ns_uri, "attr")] and \
  359.            attrs.get((ns_uri, "attr")) == "val" and \
  360.            attrs.get((ns_uri, "attr"), 25) == "val" and \
  361.            attrs.items() == [((ns_uri, "attr"), "val")] and \
  362.            attrs.values() == ["val"] and \
  363.            attrs.getValue((ns_uri, "attr")) == "val" and \
  364.            attrs[(ns_uri, "attr")] == "val"
  365.  
  366. # ===== InputSource support
  367.  
  368. xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read()
  369.  
  370. def test_expat_inpsource_filename():
  371.     parser = create_parser()
  372.     result = StringIO()
  373.     xmlgen = XMLGenerator(result)
  374.  
  375.     parser.setContentHandler(xmlgen)
  376.     parser.parse(findfile("test"+os.extsep+"xml"))
  377.  
  378.     return result.getvalue() == xml_test_out
  379.  
  380. def test_expat_inpsource_sysid():
  381.     parser = create_parser()
  382.     result = StringIO()
  383.     xmlgen = XMLGenerator(result)
  384.  
  385.     parser.setContentHandler(xmlgen)
  386.     parser.parse(InputSource(findfile("test"+os.extsep+"xml")))
  387.  
  388.     return result.getvalue() == xml_test_out
  389.  
  390. def test_expat_inpsource_stream():
  391.     parser = create_parser()
  392.     result = StringIO()
  393.     xmlgen = XMLGenerator(result)
  394.  
  395.     parser.setContentHandler(xmlgen)
  396.     inpsrc = InputSource()
  397.     inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml")))
  398.     parser.parse(inpsrc)
  399.  
  400.     return result.getvalue() == xml_test_out
  401.  
  402. # ===== IncrementalParser support
  403.  
  404. def test_expat_incremental():
  405.     result = StringIO()
  406.     xmlgen = XMLGenerator(result)
  407.     parser = create_parser()
  408.     parser.setContentHandler(xmlgen)
  409.  
  410.     parser.feed("<doc>")
  411.     parser.feed("</doc>")
  412.     parser.close()
  413.  
  414.     return result.getvalue() == start + "<doc></doc>"
  415.  
  416. def test_expat_incremental_reset():
  417.     result = StringIO()
  418.     xmlgen = XMLGenerator(result)
  419.     parser = create_parser()
  420.     parser.setContentHandler(xmlgen)
  421.  
  422.     parser.feed("<doc>")
  423.     parser.feed("text")
  424.  
  425.     result = StringIO()
  426.     xmlgen = XMLGenerator(result)
  427.     parser.setContentHandler(xmlgen)
  428.     parser.reset()
  429.  
  430.     parser.feed("<doc>")
  431.     parser.feed("text")
  432.     parser.feed("</doc>")
  433.     parser.close()
  434.  
  435.     return result.getvalue() == start + "<doc>text</doc>"
  436.  
  437. # ===== Locator support
  438.  
  439. def test_expat_locator_noinfo():
  440.     result = StringIO()
  441.     xmlgen = XMLGenerator(result)
  442.     parser = create_parser()
  443.     parser.setContentHandler(xmlgen)
  444.  
  445.     parser.feed("<doc>")
  446.     parser.feed("</doc>")
  447.     parser.close()
  448.  
  449.     return parser.getSystemId() is None and \
  450.            parser.getPublicId() is None and \
  451.            parser.getLineNumber() == 1
  452.  
  453. def test_expat_locator_withinfo():
  454.     result = StringIO()
  455.     xmlgen = XMLGenerator(result)
  456.     parser = create_parser()
  457.     parser.setContentHandler(xmlgen)
  458.     parser.parse(findfile("test.xml"))
  459.  
  460.     return parser.getSystemId() == findfile("test.xml") and \
  461.            parser.getPublicId() is None
  462.  
  463.  
  464. # ===========================================================================
  465. #
  466. #   error reporting
  467. #
  468. # ===========================================================================
  469.  
  470. def test_expat_inpsource_location():
  471.     parser = create_parser()
  472.     parser.setContentHandler(ContentHandler()) # do nothing
  473.     source = InputSource()
  474.     source.setByteStream(StringIO("<foo bar foobar>"))   #ill-formed
  475.     name = "a file name"
  476.     source.setSystemId(name)
  477.     try:
  478.         parser.parse(source)
  479.     except SAXException, e:
  480.         return e.getSystemId() == name
  481.  
  482. def test_expat_incomplete():
  483.     parser = create_parser()
  484.     parser.setContentHandler(ContentHandler()) # do nothing
  485.     try:
  486.         parser.parse(StringIO("<foo>"))
  487.     except SAXParseException:
  488.         return 1 # ok, error found
  489.     else:
  490.         return 0
  491.  
  492.  
  493. # ===========================================================================
  494. #
  495. #   xmlreader tests
  496. #
  497. # ===========================================================================
  498.  
  499. # ===== AttributesImpl
  500.  
  501. def verify_empty_attrs(attrs):
  502.     try:
  503.         attrs.getValue("attr")
  504.         gvk = 0
  505.     except KeyError:
  506.         gvk = 1
  507.  
  508.     try:
  509.         attrs.getValueByQName("attr")
  510.         gvqk = 0
  511.     except KeyError:
  512.         gvqk = 1
  513.  
  514.     try:
  515.         attrs.getNameByQName("attr")
  516.         gnqk = 0
  517.     except KeyError:
  518.         gnqk = 1
  519.  
  520.     try:
  521.         attrs.getQNameByName("attr")
  522.         gqnk = 0
  523.     except KeyError:
  524.         gqnk = 1
  525.  
  526.     try:
  527.         attrs["attr"]
  528.         gik = 0
  529.     except KeyError:
  530.         gik = 1
  531.  
  532.     return attrs.getLength() == 0 and \
  533.            attrs.getNames() == [] and \
  534.            attrs.getQNames() == [] and \
  535.            len(attrs) == 0 and \
  536.            not attrs.has_key("attr") and \
  537.            attrs.keys() == [] and \
  538.            attrs.get("attrs") is None and \
  539.            attrs.get("attrs", 25) == 25 and \
  540.            attrs.items() == [] and \
  541.            attrs.values() == [] and \
  542.            gvk and gvqk and gnqk and gik and gqnk
  543.  
  544. def verify_attrs_wattr(attrs):
  545.     return attrs.getLength() == 1 and \
  546.            attrs.getNames() == ["attr"] and \
  547.            attrs.getQNames() == ["attr"] and \
  548.            len(attrs) == 1 and \
  549.            attrs.has_key("attr") and \
  550.            attrs.keys() == ["attr"] and \
  551.            attrs.get("attr") == "val" and \
  552.            attrs.get("attr", 25) == "val" and \
  553.            attrs.items() == [("attr", "val")] and \
  554.            attrs.values() == ["val"] and \
  555.            attrs.getValue("attr") == "val" and \
  556.            attrs.getValueByQName("attr") == "val" and \
  557.            attrs.getNameByQName("attr") == "attr" and \
  558.            attrs["attr"] == "val" and \
  559.            attrs.getQNameByName("attr") == "attr"
  560.  
  561. def test_attrs_empty():
  562.     return verify_empty_attrs(AttributesImpl({}))
  563.  
  564. def test_attrs_wattr():
  565.     return verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
  566.  
  567. # ===== AttributesImpl
  568.  
  569. def verify_empty_nsattrs(attrs):
  570.     try:
  571.         attrs.getValue((ns_uri, "attr"))
  572.         gvk = 0
  573.     except KeyError:
  574.         gvk = 1
  575.  
  576.     try:
  577.         attrs.getValueByQName("ns:attr")
  578.         gvqk = 0
  579.     except KeyError:
  580.         gvqk = 1
  581.  
  582.     try:
  583.         attrs.getNameByQName("ns:attr")
  584.         gnqk = 0
  585.     except KeyError:
  586.         gnqk = 1
  587.  
  588.     try:
  589.         attrs.getQNameByName((ns_uri, "attr"))
  590.         gqnk = 0
  591.     except KeyError:
  592.         gqnk = 1
  593.  
  594.     try:
  595.         attrs[(ns_uri, "attr")]
  596.         gik = 0
  597.     except KeyError:
  598.         gik = 1
  599.  
  600.     return attrs.getLength() == 0 and \
  601.            attrs.getNames() == [] and \
  602.            attrs.getQNames() == [] and \
  603.            len(attrs) == 0 and \
  604.            not attrs.has_key((ns_uri, "attr")) and \
  605.            attrs.keys() == [] and \
  606.            attrs.get((ns_uri, "attr")) is None and \
  607.            attrs.get((ns_uri, "attr"), 25) == 25 and \
  608.            attrs.items() == [] and \
  609.            attrs.values() == [] and \
  610.            gvk and gvqk and gnqk and gik and gqnk
  611.  
  612. def test_nsattrs_empty():
  613.     return verify_empty_nsattrs(AttributesNSImpl({}, {}))
  614.  
  615. def test_nsattrs_wattr():
  616.     attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
  617.                              {(ns_uri, "attr") : "ns:attr"})
  618.  
  619.     return attrs.getLength() == 1 and \
  620.            attrs.getNames() == [(ns_uri, "attr")] and \
  621.            attrs.getQNames() == ["ns:attr"] and \
  622.            len(attrs) == 1 and \
  623.            attrs.has_key((ns_uri, "attr")) and \
  624.            attrs.keys() == [(ns_uri, "attr")] and \
  625.            attrs.get((ns_uri, "attr")) == "val" and \
  626.            attrs.get((ns_uri, "attr"), 25) == "val" and \
  627.            attrs.items() == [((ns_uri, "attr"), "val")] and \
  628.            attrs.values() == ["val"] and \
  629.            attrs.getValue((ns_uri, "attr")) == "val" and \
  630.            attrs.getValueByQName("ns:attr") == "val" and \
  631.            attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
  632.            attrs[(ns_uri, "attr")] == "val" and \
  633.            attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
  634.  
  635.  
  636. # ===== Main program
  637.  
  638. def make_test_output():
  639.     parser = create_parser()
  640.     result = StringIO()
  641.     xmlgen = XMLGenerator(result)
  642.  
  643.     parser.setContentHandler(xmlgen)
  644.     parser.parse(findfile("test"+os.extsep+"xml"))
  645.  
  646.     outf = open(findfile("test"+os.extsep+"xml"+os.extsep+"out"), "w")
  647.     outf.write(result.getvalue())
  648.     outf.close()
  649.  
  650. items = locals().items()
  651. items.sort()
  652. for (name, value) in items:
  653.     if name[ : 5] == "test_":
  654.         confirm(value(), name)
  655.  
  656. if verbose:
  657.     print "%d tests, %d failures" % (tests, len(failures))
  658. if failures:
  659.     raise TestFailed("%d of %d tests failed: %s"
  660.                      % (len(failures), tests, ", ".join(failures)))
  661.