home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / TEST_SAX.PY < prev    next >
Encoding:
Python Source  |  2000-10-06  |  14.3 KB  |  513 lines

  1.  
  2. # regression test for SAX 2.0
  3. # $Id: test_sax.py,v 1.10 2000/10/06 21:13:22 loewis Exp $
  4.  
  5. from xml.sax import make_parser, ContentHandler, \
  6.                     SAXException, SAXReaderNotAvailable, SAXParseException
  7. try:
  8.     make_parser()
  9. except SAXReaderNotAvailable:
  10.     # don't try to test this module if we cannot create a parser
  11.     raise ImportError("no XML parsers available")
  12. from xml.sax.saxutils import XMLGenerator, escape, 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_support import verbose, TestFailed, findfile
  17.  
  18. # ===== Utilities
  19.  
  20. tests = 0
  21. fails = 0
  22.  
  23. def confirm(outcome, name):
  24.     global tests, fails
  25.  
  26.     tests = tests + 1
  27.     if outcome:
  28.         print "Passed", name
  29.     else:
  30.         print "Failed", name
  31.         fails = fails + 1
  32.  
  33. # ===========================================================================
  34. #
  35. #   saxutils tests
  36. #
  37. # ===========================================================================
  38.  
  39. # ===== escape
  40.  
  41. def test_escape_basic():
  42.     return escape("Donald Duck & Co") == "Donald Duck & Co"
  43.  
  44. def test_escape_all():
  45.     return escape("<Donald Duck & Co>") == "<Donald Duck & Co>"
  46.  
  47. def test_escape_extra():
  48.     return escape("Hei pσ deg", {"σ" : "å"}) == "Hei på deg"
  49.  
  50. def test_make_parser():
  51.     try:
  52.         # Creating a parser should succeed - it should fall back
  53.         # to the expatreader
  54.         p = make_parser(['xml.parsers.no_such_parser'])
  55.     except:
  56.         return 0
  57.     else:
  58.         return p
  59.  
  60.  
  61. # ===== XMLGenerator
  62.  
  63. start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
  64.  
  65. def test_xmlgen_basic():
  66.     result = StringIO()
  67.     gen = XMLGenerator(result)
  68.     gen.startDocument()
  69.     gen.startElement("doc", {})
  70.     gen.endElement("doc")
  71.     gen.endDocument()
  72.  
  73.     return result.getvalue() == start + "<doc></doc>"
  74.  
  75. def test_xmlgen_content():
  76.     result = StringIO()
  77.     gen = XMLGenerator(result)
  78.     
  79.     gen.startDocument()
  80.     gen.startElement("doc", {})
  81.     gen.characters("huhei")
  82.     gen.endElement("doc")
  83.     gen.endDocument()
  84.  
  85.     return result.getvalue() == start + "<doc>huhei</doc>"
  86.  
  87. def test_xmlgen_pi():
  88.     result = StringIO()
  89.     gen = XMLGenerator(result)
  90.     
  91.     gen.startDocument()
  92.     gen.processingInstruction("test", "data")
  93.     gen.startElement("doc", {})
  94.     gen.endElement("doc")
  95.     gen.endDocument()
  96.  
  97.     return result.getvalue() == start + "<?test data?><doc></doc>"
  98.  
  99. def test_xmlgen_content_escape():
  100.     result = StringIO()
  101.     gen = XMLGenerator(result)
  102.     
  103.     gen.startDocument()
  104.     gen.startElement("doc", {})
  105.     gen.characters("<huhei&")
  106.     gen.endElement("doc")
  107.     gen.endDocument()
  108.  
  109.     return result.getvalue() == start + "<doc><huhei&</doc>"
  110.  
  111. def test_xmlgen_ignorable():
  112.     result = StringIO()
  113.     gen = XMLGenerator(result)
  114.     
  115.     gen.startDocument()
  116.     gen.startElement("doc", {})
  117.     gen.ignorableWhitespace(" ")
  118.     gen.endElement("doc")
  119.     gen.endDocument()
  120.  
  121.     return result.getvalue() == start + "<doc> </doc>"
  122.  
  123. ns_uri = "http://www.python.org/xml-ns/saxtest/"
  124.  
  125. def test_xmlgen_ns():
  126.     result = StringIO()
  127.     gen = XMLGenerator(result)
  128.     
  129.     gen.startDocument()
  130.     gen.startPrefixMapping("ns1", ns_uri)
  131.     gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
  132.     # add an unqualified name
  133.     gen.startElementNS((None, "udoc"), None, {})
  134.     gen.endElementNS((None, "udoc"), None)
  135.     gen.endElementNS((ns_uri, "doc"), "ns1:doc")
  136.     gen.endPrefixMapping("ns1")
  137.     gen.endDocument()
  138.  
  139.     return result.getvalue() == start + \
  140.            ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' %
  141.                                          ns_uri)
  142.  
  143. # ===== XMLFilterBase
  144.  
  145. def test_filter_basic():
  146.     result = StringIO()
  147.     gen = XMLGenerator(result)
  148.     filter = XMLFilterBase()
  149.     filter.setContentHandler(gen)
  150.     
  151.     filter.startDocument()
  152.     filter.startElement("doc", {})
  153.     filter.characters("content")
  154.     filter.ignorableWhitespace(" ")
  155.     filter.endElement("doc")
  156.     filter.endDocument()
  157.  
  158.     return result.getvalue() == start + "<doc>content </doc>"
  159.  
  160. # ===========================================================================
  161. #
  162. #   expatreader tests
  163. #
  164. # ===========================================================================
  165.  
  166. # ===== DTDHandler support
  167.  
  168. class TestDTDHandler:
  169.  
  170.     def __init__(self):
  171.         self._notations = []
  172.         self._entities  = []
  173.     
  174.     def notationDecl(self, name, publicId, systemId):
  175.         self._notations.append((name, publicId, systemId))
  176.  
  177.     def unparsedEntityDecl(self, name, publicId, systemId, ndata):
  178.         self._entities.append((name, publicId, systemId, ndata))
  179.  
  180. def test_expat_dtdhandler():
  181.     parser = create_parser()
  182.     handler = TestDTDHandler()
  183.     parser.setDTDHandler(handler)
  184.  
  185.     parser.feed('<!DOCTYPE doc [\n')
  186.     parser.feed('  <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
  187.     parser.feed('  <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
  188.     parser.feed(']>\n')
  189.     parser.feed('<doc></doc>')
  190.     parser.close()
  191.  
  192.     return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
  193.            handler._entities == [("img", None, "expat.gif", "GIF")]
  194.  
  195. # ===== EntityResolver support
  196.  
  197. class TestEntityResolver:
  198.  
  199.     def resolveEntity(self, publicId, systemId):
  200.         inpsrc = InputSource()
  201.         inpsrc.setByteStream(StringIO("<entity/>"))
  202.         return inpsrc
  203.  
  204. def test_expat_entityresolver():
  205.     parser = create_parser()
  206.     parser.setEntityResolver(TestEntityResolver())
  207.     result = StringIO()
  208.     parser.setContentHandler(XMLGenerator(result))
  209.  
  210.     parser.feed('<!DOCTYPE doc [\n')
  211.     parser.feed('  <!ENTITY test SYSTEM "whatever">\n')
  212.     parser.feed(']>\n')
  213.     parser.feed('<doc>&test;</doc>')
  214.     parser.close()
  215.  
  216.     return result.getvalue() == start + "<doc><entity></entity></doc>"
  217.     
  218. # ===== Attributes support
  219.  
  220. class AttrGatherer(ContentHandler):
  221.  
  222.     def startElement(self, name, attrs):
  223.         self._attrs = attrs
  224.  
  225.     def startElementNS(self, name, qname, attrs):
  226.         self._attrs = attrs
  227.         
  228. def test_expat_attrs_empty():
  229.     parser = create_parser()
  230.     gather = AttrGatherer()
  231.     parser.setContentHandler(gather)
  232.  
  233.     parser.feed("<doc/>")
  234.     parser.close()
  235.  
  236.     return verify_empty_attrs(gather._attrs)
  237.  
  238. def test_expat_attrs_wattr():
  239.     parser = create_parser()
  240.     gather = AttrGatherer()
  241.     parser.setContentHandler(gather)
  242.  
  243.     parser.feed("<doc attr='val'/>")
  244.     parser.close()
  245.  
  246.     return verify_attrs_wattr(gather._attrs)
  247.  
  248. def test_expat_nsattrs_empty():
  249.     parser = create_parser(1)
  250.     gather = AttrGatherer()
  251.     parser.setContentHandler(gather)
  252.  
  253.     parser.feed("<doc/>")
  254.     parser.close()
  255.  
  256.     return verify_empty_nsattrs(gather._attrs)
  257.  
  258. def test_expat_nsattrs_wattr():
  259.     parser = create_parser(1)
  260.     gather = AttrGatherer()
  261.     parser.setContentHandler(gather)
  262.  
  263.     parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
  264.     parser.close()
  265.  
  266.     attrs = gather._attrs
  267.     
  268.     return attrs.getLength() == 1 and \
  269.            attrs.getNames() == [(ns_uri, "attr")] and \
  270.            attrs.getQNames() == [] and \
  271.            len(attrs) == 1 and \
  272.            attrs.has_key((ns_uri, "attr")) and \
  273.            attrs.keys() == [(ns_uri, "attr")] and \
  274.            attrs.get((ns_uri, "attr")) == "val" and \
  275.            attrs.get((ns_uri, "attr"), 25) == "val" and \
  276.            attrs.items() == [((ns_uri, "attr"), "val")] and \
  277.            attrs.values() == ["val"] and \
  278.            attrs.getValue((ns_uri, "attr")) == "val" and \
  279.            attrs[(ns_uri, "attr")] == "val"
  280.  
  281. # ===== InputSource support
  282.  
  283. xml_test_out = open(findfile("test.xml.out")).read()
  284.  
  285. def test_expat_inpsource_filename():
  286.     parser = create_parser()
  287.     result = StringIO()
  288.     xmlgen = XMLGenerator(result)
  289.  
  290.     parser.setContentHandler(xmlgen)
  291.     parser.parse(findfile("test.xml"))
  292.  
  293.     return result.getvalue() == xml_test_out
  294.  
  295. def test_expat_inpsource_sysid():
  296.     parser = create_parser()
  297.     result = StringIO()
  298.     xmlgen = XMLGenerator(result)
  299.  
  300.     parser.setContentHandler(xmlgen)
  301.     parser.parse(InputSource(findfile("test.xml")))
  302.  
  303.     return result.getvalue() == xml_test_out
  304.  
  305. def test_expat_inpsource_stream():
  306.     parser = create_parser()
  307.     result = StringIO()
  308.     xmlgen = XMLGenerator(result)
  309.  
  310.     parser.setContentHandler(xmlgen)
  311.     inpsrc = InputSource()
  312.     inpsrc.setByteStream(open(findfile("test.xml")))
  313.     parser.parse(inpsrc)
  314.  
  315.     return result.getvalue() == xml_test_out
  316.  
  317.  
  318. # ===========================================================================
  319. #
  320. #   error reporting
  321. #
  322. # ===========================================================================
  323.  
  324. def test_expat_inpsource_location():
  325.     parser = create_parser()
  326.     parser.setContentHandler(ContentHandler()) # do nothing
  327.     source = InputSource()
  328.     source.setByteStream(StringIO("<foo bar foobar>"))   #ill-formed
  329.     name = "a file name"
  330.     source.setSystemId(name)
  331.     try:
  332.         parser.parse(source)
  333.     except SAXException, e:
  334.         return e.getSystemId() == name
  335.  
  336. def test_expat_incomplete():
  337.     parser = create_parser()
  338.     parser.setContentHandler(ContentHandler()) # do nothing
  339.     try:
  340.         parser.parse(StringIO("<foo>"))
  341.     except SAXParseException:
  342.         return 1 # ok, error found
  343.     else:
  344.         return 0
  345.  
  346.  
  347. # ===========================================================================
  348. #
  349. #   xmlreader tests
  350. #
  351. # ===========================================================================
  352.  
  353. # ===== AttributesImpl
  354.  
  355. def verify_empty_attrs(attrs):
  356.     try:
  357.         attrs.getValue("attr")
  358.         gvk = 0
  359.     except KeyError:
  360.         gvk = 1
  361.  
  362.     try:
  363.         attrs.getValueByQName("attr")
  364.         gvqk = 0
  365.     except KeyError:
  366.         gvqk = 1
  367.  
  368.     try:
  369.         attrs.getNameByQName("attr")
  370.         gnqk = 0
  371.     except KeyError:
  372.         gnqk = 1
  373.  
  374.     try:
  375.         attrs.getQNameByName("attr")
  376.         gqnk = 0
  377.     except KeyError:
  378.         gqnk = 1
  379.         
  380.     try:
  381.         attrs["attr"]
  382.         gik = 0
  383.     except KeyError:
  384.         gik = 1
  385.         
  386.     return attrs.getLength() == 0 and \
  387.            attrs.getNames() == [] and \
  388.            attrs.getQNames() == [] and \
  389.            len(attrs) == 0 and \
  390.            not attrs.has_key("attr") and \
  391.            attrs.keys() == [] and \
  392.            attrs.get("attrs") == None and \
  393.            attrs.get("attrs", 25) == 25 and \
  394.            attrs.items() == [] and \
  395.            attrs.values() == [] and \
  396.            gvk and gvqk and gnqk and gik and gqnk
  397.  
  398. def verify_attrs_wattr(attrs):
  399.     return attrs.getLength() == 1 and \
  400.            attrs.getNames() == ["attr"] and \
  401.            attrs.getQNames() == ["attr"] and \
  402.            len(attrs) == 1 and \
  403.            attrs.has_key("attr") and \
  404.            attrs.keys() == ["attr"] and \
  405.            attrs.get("attr") == "val" and \
  406.            attrs.get("attr", 25) == "val" and \
  407.            attrs.items() == [("attr", "val")] and \
  408.            attrs.values() == ["val"] and \
  409.            attrs.getValue("attr") == "val" and \
  410.            attrs.getValueByQName("attr") == "val" and \
  411.            attrs.getNameByQName("attr") == "attr" and \
  412.            attrs["attr"] == "val" and \
  413.            attrs.getQNameByName("attr") == "attr"
  414.  
  415. def test_attrs_empty():
  416.     return verify_empty_attrs(AttributesImpl({}))
  417.  
  418. def test_attrs_wattr():
  419.     return verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
  420.  
  421. # ===== AttributesImpl
  422.  
  423. def verify_empty_nsattrs(attrs):
  424.     try:
  425.         attrs.getValue((ns_uri, "attr"))
  426.         gvk = 0
  427.     except KeyError:
  428.         gvk = 1
  429.  
  430.     try:
  431.         attrs.getValueByQName("ns:attr")
  432.         gvqk = 0
  433.     except KeyError:
  434.         gvqk = 1
  435.  
  436.     try:
  437.         attrs.getNameByQName("ns:attr")
  438.         gnqk = 0
  439.     except KeyError:
  440.         gnqk = 1
  441.  
  442.     try:
  443.         attrs.getQNameByName((ns_uri, "attr"))
  444.         gqnk = 0
  445.     except KeyError:
  446.         gqnk = 1
  447.         
  448.     try:
  449.         attrs[(ns_uri, "attr")]
  450.         gik = 0
  451.     except KeyError:
  452.         gik = 1
  453.         
  454.     return attrs.getLength() == 0 and \
  455.            attrs.getNames() == [] and \
  456.            attrs.getQNames() == [] and \
  457.            len(attrs) == 0 and \
  458.            not attrs.has_key((ns_uri, "attr")) and \
  459.            attrs.keys() == [] and \
  460.            attrs.get((ns_uri, "attr")) == None and \
  461.            attrs.get((ns_uri, "attr"), 25) == 25 and \
  462.            attrs.items() == [] and \
  463.            attrs.values() == [] and \
  464.            gvk and gvqk and gnqk and gik and gqnk
  465.  
  466. def test_nsattrs_empty():
  467.     return verify_empty_nsattrs(AttributesNSImpl({}, {}))
  468.  
  469. def test_nsattrs_wattr():
  470.     attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
  471.                              {(ns_uri, "attr") : "ns:attr"})
  472.     
  473.     return attrs.getLength() == 1 and \
  474.            attrs.getNames() == [(ns_uri, "attr")] and \
  475.            attrs.getQNames() == ["ns:attr"] and \
  476.            len(attrs) == 1 and \
  477.            attrs.has_key((ns_uri, "attr")) and \
  478.            attrs.keys() == [(ns_uri, "attr")] and \
  479.            attrs.get((ns_uri, "attr")) == "val" and \
  480.            attrs.get((ns_uri, "attr"), 25) == "val" and \
  481.            attrs.items() == [((ns_uri, "attr"), "val")] and \
  482.            attrs.values() == ["val"] and \
  483.            attrs.getValue((ns_uri, "attr")) == "val" and \
  484.            attrs.getValueByQName("ns:attr") == "val" and \
  485.            attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
  486.            attrs[(ns_uri, "attr")] == "val" and \
  487.            attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
  488.         
  489.  
  490. # ===== Main program
  491.  
  492. def make_test_output():
  493.     parser = create_parser()
  494.     result = StringIO()
  495.     xmlgen = XMLGenerator(result)
  496.  
  497.     parser.setContentHandler(xmlgen)
  498.     parser.parse(findfile("test.xml"))
  499.  
  500.     outf = open(findfile("test.xml.out"), "w")
  501.     outf.write(result.getvalue())
  502.     outf.close()
  503.  
  504. items = locals().items()
  505. items.sort()
  506. for (name, value) in items:
  507.     if name[ : 5] == "test_":
  508.         confirm(value(), name)
  509.  
  510. print "%d tests, %d failures" % (tests, fails)
  511. if fails != 0:
  512.     raise TestFailed, "%d of %d tests failed" % (fails, tests)
  513.