| Antoine Pitrou | b27ddc7 | 2010-10-27 18:58:04 +0000 | [diff] [blame] | 1 | # regression test for SAX 2.0            -*- coding: utf-8 -*- | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 2 | # $Id$ | 
 | 3 |  | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 4 | from xml.sax import make_parser, ContentHandler, \ | 
| Victor Stinner | d81f9e2 | 2017-05-05 10:11:55 +0200 | [diff] [blame] | 5 |                     SAXException, SAXReaderNotAvailable, SAXParseException, \ | 
 | 6 |                     saxutils | 
| Martin v. Löwis | 962c9e7 | 2000-10-06 17:41:52 +0000 | [diff] [blame] | 7 | try: | 
 | 8 |     make_parser() | 
| Martin v. Löwis | 80670bc | 2000-10-06 21:13:23 +0000 | [diff] [blame] | 9 | except SAXReaderNotAvailable: | 
| Martin v. Löwis | 962c9e7 | 2000-10-06 17:41:52 +0000 | [diff] [blame] | 10 |     # don't try to test this module if we cannot create a parser | 
 | 11 |     raise ImportError("no XML parsers available") | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 12 | from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ | 
| Serhiy Storchaka | e9d4dc1 | 2015-04-02 20:55:46 +0300 | [diff] [blame] | 13 |                              XMLFilterBase, prepare_input_source | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 14 | from xml.sax.expatreader import create_parser | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 15 | from xml.sax.handler import feature_namespaces | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 16 | from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 17 | from cStringIO import StringIO | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 18 | import io | 
| Serhiy Storchaka | aff77f3 | 2015-04-02 23:05:23 +0300 | [diff] [blame] | 19 | import gc | 
| Serhiy Storchaka | 23298cb | 2013-02-02 12:16:22 +0200 | [diff] [blame] | 20 | import os.path | 
| Serhiy Storchaka | 8673ab9 | 2013-02-02 10:28:30 +0200 | [diff] [blame] | 21 | import shutil | 
 | 22 | import test.test_support as support | 
| Serhiy Storchaka | aff77f3 | 2015-04-02 23:05:23 +0300 | [diff] [blame] | 23 | from test.test_support import findfile, run_unittest, TESTFN | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 24 | import unittest | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 25 |  | 
| Florent Xicluna | 1b51c3d | 2010-03-13 12:41:48 +0000 | [diff] [blame] | 26 | TEST_XMLFILE = findfile("test.xml", subdir="xmltestdata") | 
 | 27 | TEST_XMLFILE_OUT = findfile("test.xml.out", subdir="xmltestdata") | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 28 |  | 
| Serhiy Storchaka | 23298cb | 2013-02-02 12:16:22 +0200 | [diff] [blame] | 29 | supports_unicode_filenames = True | 
 | 30 | if not os.path.supports_unicode_filenames: | 
 | 31 |     try: | 
 | 32 |         support.TESTFN_UNICODE.encode(support.TESTFN_ENCODING) | 
 | 33 |     except (AttributeError, UnicodeError, TypeError): | 
 | 34 |         # Either the file system encoding is None, or the file name | 
 | 35 |         # cannot be encoded in the file system encoding. | 
 | 36 |         supports_unicode_filenames = False | 
 | 37 | requires_unicode_filenames = unittest.skipUnless( | 
 | 38 |         supports_unicode_filenames, | 
 | 39 |         'Requires unicode filenames support') | 
 | 40 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 41 | ns_uri = "http://www.python.org/xml-ns/saxtest/" | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 42 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 43 | class XmlTestBase(unittest.TestCase): | 
 | 44 |     def verify_empty_attrs(self, attrs): | 
 | 45 |         self.assertRaises(KeyError, attrs.getValue, "attr") | 
 | 46 |         self.assertRaises(KeyError, attrs.getValueByQName, "attr") | 
 | 47 |         self.assertRaises(KeyError, attrs.getNameByQName, "attr") | 
 | 48 |         self.assertRaises(KeyError, attrs.getQNameByName, "attr") | 
 | 49 |         self.assertRaises(KeyError, attrs.__getitem__, "attr") | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 50 |         self.assertEqual(attrs.getLength(), 0) | 
 | 51 |         self.assertEqual(attrs.getNames(), []) | 
 | 52 |         self.assertEqual(attrs.getQNames(), []) | 
 | 53 |         self.assertEqual(len(attrs), 0) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 54 |         self.assertFalse(attrs.has_key("attr")) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 55 |         self.assertEqual(attrs.keys(), []) | 
 | 56 |         self.assertEqual(attrs.get("attrs"), None) | 
 | 57 |         self.assertEqual(attrs.get("attrs", 25), 25) | 
 | 58 |         self.assertEqual(attrs.items(), []) | 
 | 59 |         self.assertEqual(attrs.values(), []) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 60 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 61 |     def verify_empty_nsattrs(self, attrs): | 
 | 62 |         self.assertRaises(KeyError, attrs.getValue, (ns_uri, "attr")) | 
 | 63 |         self.assertRaises(KeyError, attrs.getValueByQName, "ns:attr") | 
 | 64 |         self.assertRaises(KeyError, attrs.getNameByQName, "ns:attr") | 
 | 65 |         self.assertRaises(KeyError, attrs.getQNameByName, (ns_uri, "attr")) | 
 | 66 |         self.assertRaises(KeyError, attrs.__getitem__, (ns_uri, "attr")) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 67 |         self.assertEqual(attrs.getLength(), 0) | 
 | 68 |         self.assertEqual(attrs.getNames(), []) | 
 | 69 |         self.assertEqual(attrs.getQNames(), []) | 
 | 70 |         self.assertEqual(len(attrs), 0) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 71 |         self.assertFalse(attrs.has_key((ns_uri, "attr"))) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 72 |         self.assertEqual(attrs.keys(), []) | 
 | 73 |         self.assertEqual(attrs.get((ns_uri, "attr")), None) | 
 | 74 |         self.assertEqual(attrs.get((ns_uri, "attr"), 25), 25) | 
 | 75 |         self.assertEqual(attrs.items(), []) | 
 | 76 |         self.assertEqual(attrs.values(), []) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 77 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 78 |     def verify_attrs_wattr(self, attrs): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 79 |         self.assertEqual(attrs.getLength(), 1) | 
 | 80 |         self.assertEqual(attrs.getNames(), ["attr"]) | 
 | 81 |         self.assertEqual(attrs.getQNames(), ["attr"]) | 
 | 82 |         self.assertEqual(len(attrs), 1) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 83 |         self.assertTrue(attrs.has_key("attr")) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 84 |         self.assertEqual(attrs.keys(), ["attr"]) | 
 | 85 |         self.assertEqual(attrs.get("attr"), "val") | 
 | 86 |         self.assertEqual(attrs.get("attr", 25), "val") | 
 | 87 |         self.assertEqual(attrs.items(), [("attr", "val")]) | 
 | 88 |         self.assertEqual(attrs.values(), ["val"]) | 
 | 89 |         self.assertEqual(attrs.getValue("attr"), "val") | 
 | 90 |         self.assertEqual(attrs.getValueByQName("attr"), "val") | 
 | 91 |         self.assertEqual(attrs.getNameByQName("attr"), "attr") | 
 | 92 |         self.assertEqual(attrs["attr"], "val") | 
 | 93 |         self.assertEqual(attrs.getQNameByName("attr"), "attr") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 94 |  | 
| Serhiy Storchaka | aff77f3 | 2015-04-02 23:05:23 +0300 | [diff] [blame] | 95 |  | 
 | 96 | def xml_unicode(doc, encoding=None): | 
 | 97 |     if encoding is None: | 
 | 98 |         return doc | 
 | 99 |     return u'<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, doc) | 
 | 100 |  | 
 | 101 | def xml_bytes(doc, encoding, decl_encoding=Ellipsis): | 
 | 102 |     if decl_encoding is Ellipsis: | 
 | 103 |         decl_encoding = encoding | 
 | 104 |     return xml_unicode(doc, decl_encoding).encode(encoding, 'xmlcharrefreplace') | 
 | 105 |  | 
 | 106 | def make_xml_file(doc, encoding, decl_encoding=Ellipsis): | 
 | 107 |     if decl_encoding is Ellipsis: | 
 | 108 |         decl_encoding = encoding | 
 | 109 |     with io.open(TESTFN, 'w', encoding=encoding, errors='xmlcharrefreplace') as f: | 
 | 110 |         f.write(xml_unicode(doc, decl_encoding)) | 
 | 111 |  | 
 | 112 |  | 
 | 113 | class ParseTest(unittest.TestCase): | 
 | 114 |     data = support.u(r'<money value="$\xa3\u20ac\U0001017b">' | 
 | 115 |                      r'$\xa3\u20ac\U0001017b</money>') | 
 | 116 |  | 
 | 117 |     def tearDown(self): | 
 | 118 |         support.unlink(TESTFN) | 
 | 119 |  | 
 | 120 |     def check_parse(self, f): | 
 | 121 |         from xml.sax import parse | 
 | 122 |         result = StringIO() | 
 | 123 |         parse(f, XMLGenerator(result, 'utf-8')) | 
 | 124 |         self.assertEqual(result.getvalue(), xml_bytes(self.data, 'utf-8')) | 
 | 125 |  | 
 | 126 |     def test_parse_bytes(self): | 
 | 127 |         # UTF-8 is default encoding, US-ASCII is compatible with UTF-8, | 
 | 128 |         # UTF-16 is autodetected | 
 | 129 |         encodings = ('us-ascii', 'utf-8', 'utf-16', 'utf-16le', 'utf-16be') | 
 | 130 |         for encoding in encodings: | 
 | 131 |             self.check_parse(io.BytesIO(xml_bytes(self.data, encoding))) | 
 | 132 |             make_xml_file(self.data, encoding) | 
 | 133 |             self.check_parse(TESTFN) | 
 | 134 |             with io.open(TESTFN, 'rb') as f: | 
 | 135 |                 self.check_parse(f) | 
 | 136 |             self.check_parse(io.BytesIO(xml_bytes(self.data, encoding, None))) | 
 | 137 |             make_xml_file(self.data, encoding, None) | 
 | 138 |             self.check_parse(TESTFN) | 
 | 139 |             with io.open(TESTFN, 'rb') as f: | 
 | 140 |                 self.check_parse(f) | 
 | 141 |         # accept UTF-8 with BOM | 
 | 142 |         self.check_parse(io.BytesIO(xml_bytes(self.data, 'utf-8-sig', 'utf-8'))) | 
 | 143 |         make_xml_file(self.data, 'utf-8-sig', 'utf-8') | 
 | 144 |         self.check_parse(TESTFN) | 
 | 145 |         with io.open(TESTFN, 'rb') as f: | 
 | 146 |             self.check_parse(f) | 
 | 147 |         self.check_parse(io.BytesIO(xml_bytes(self.data, 'utf-8-sig', None))) | 
 | 148 |         make_xml_file(self.data, 'utf-8-sig', None) | 
 | 149 |         self.check_parse(TESTFN) | 
 | 150 |         with io.open(TESTFN, 'rb') as f: | 
 | 151 |             self.check_parse(f) | 
 | 152 |         # accept data with declared encoding | 
 | 153 |         self.check_parse(io.BytesIO(xml_bytes(self.data, 'iso-8859-1'))) | 
 | 154 |         make_xml_file(self.data, 'iso-8859-1') | 
 | 155 |         self.check_parse(TESTFN) | 
 | 156 |         with io.open(TESTFN, 'rb') as f: | 
 | 157 |             self.check_parse(f) | 
 | 158 |         # fail on non-UTF-8 incompatible data without declared encoding | 
 | 159 |         with self.assertRaises(SAXException): | 
 | 160 |             self.check_parse(io.BytesIO(xml_bytes(self.data, 'iso-8859-1', None))) | 
 | 161 |         make_xml_file(self.data, 'iso-8859-1', None) | 
 | 162 |         with self.assertRaises(SAXException): | 
 | 163 |             self.check_parse(TESTFN) | 
 | 164 |         with io.open(TESTFN, 'rb') as f: | 
 | 165 |             with self.assertRaises(SAXException): | 
 | 166 |                 self.check_parse(f) | 
 | 167 |  | 
 | 168 |     def test_parse_InputSource(self): | 
 | 169 |         # accept data without declared but with explicitly specified encoding | 
 | 170 |         make_xml_file(self.data, 'iso-8859-1', None) | 
 | 171 |         with io.open(TESTFN, 'rb') as f: | 
 | 172 |             input = InputSource() | 
 | 173 |             input.setByteStream(f) | 
 | 174 |             input.setEncoding('iso-8859-1') | 
 | 175 |             self.check_parse(input) | 
 | 176 |  | 
| Victor Stinner | d81f9e2 | 2017-05-05 10:11:55 +0200 | [diff] [blame] | 177 |     def test_parse_close_source(self): | 
 | 178 |         builtin_open = open | 
 | 179 |         non_local = {'fileobj': None} | 
 | 180 |  | 
 | 181 |         def mock_open(*args): | 
 | 182 |             fileobj = builtin_open(*args) | 
 | 183 |             non_local['fileobj'] = fileobj | 
 | 184 |             return fileobj | 
 | 185 |  | 
 | 186 |         with support.swap_attr(saxutils, 'open', mock_open): | 
 | 187 |             make_xml_file(self.data, 'iso-8859-1', None) | 
 | 188 |             with self.assertRaises(SAXException): | 
 | 189 |                 self.check_parse(TESTFN) | 
 | 190 |             self.assertTrue(non_local['fileobj'].closed) | 
 | 191 |  | 
| Serhiy Storchaka | aff77f3 | 2015-04-02 23:05:23 +0300 | [diff] [blame] | 192 |     def check_parseString(self, s): | 
 | 193 |         from xml.sax import parseString | 
 | 194 |         result = StringIO() | 
 | 195 |         parseString(s, XMLGenerator(result, 'utf-8')) | 
 | 196 |         self.assertEqual(result.getvalue(), xml_bytes(self.data, 'utf-8')) | 
 | 197 |  | 
 | 198 |     def test_parseString_bytes(self): | 
 | 199 |         # UTF-8 is default encoding, US-ASCII is compatible with UTF-8, | 
 | 200 |         # UTF-16 is autodetected | 
 | 201 |         encodings = ('us-ascii', 'utf-8', 'utf-16', 'utf-16le', 'utf-16be') | 
 | 202 |         for encoding in encodings: | 
 | 203 |             self.check_parseString(xml_bytes(self.data, encoding)) | 
 | 204 |             self.check_parseString(xml_bytes(self.data, encoding, None)) | 
 | 205 |         # accept UTF-8 with BOM | 
 | 206 |         self.check_parseString(xml_bytes(self.data, 'utf-8-sig', 'utf-8')) | 
 | 207 |         self.check_parseString(xml_bytes(self.data, 'utf-8-sig', None)) | 
 | 208 |         # accept data with declared encoding | 
 | 209 |         self.check_parseString(xml_bytes(self.data, 'iso-8859-1')) | 
 | 210 |         # fail on non-UTF-8 incompatible data without declared encoding | 
 | 211 |         with self.assertRaises(SAXException): | 
 | 212 |             self.check_parseString(xml_bytes(self.data, 'iso-8859-1', None)) | 
 | 213 |  | 
 | 214 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 215 | class MakeParserTest(unittest.TestCase): | 
 | 216 |     def test_make_parser2(self): | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 217 |         # Creating parsers several times in a row should succeed. | 
 | 218 |         # Testing this because there have been failures of this kind | 
 | 219 |         # before. | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 220 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 221 |         p = make_parser() | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 222 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 223 |         p = make_parser() | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 224 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 225 |         p = make_parser() | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 226 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 227 |         p = make_parser() | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 228 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 229 |         p = make_parser() | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 230 |         from xml.sax import make_parser | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 231 |         p = make_parser() | 
| Tim Peters | d2bf3b7 | 2001-01-18 02:22:22 +0000 | [diff] [blame] | 232 |  | 
 | 233 |  | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 234 | # =========================================================================== | 
 | 235 | # | 
 | 236 | #   saxutils tests | 
 | 237 | # | 
 | 238 | # =========================================================================== | 
 | 239 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 240 | class SaxutilsTest(unittest.TestCase): | 
 | 241 |     # ===== escape | 
 | 242 |     def test_escape_basic(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 243 |         self.assertEqual(escape("Donald Duck & Co"), "Donald Duck & Co") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 244 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 245 |     def test_escape_all(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 246 |         self.assertEqual(escape("<Donald Duck & Co>"), | 
 | 247 |                          "<Donald Duck & Co>") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 248 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 249 |     def test_escape_extra(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 250 |         self.assertEqual(escape("Hei på deg", {"å" : "å"}), | 
 | 251 |                          "Hei på deg") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 252 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 253 |     # ===== unescape | 
 | 254 |     def test_unescape_basic(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 255 |         self.assertEqual(unescape("Donald Duck & Co"), "Donald Duck & Co") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 256 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 257 |     def test_unescape_all(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 258 |         self.assertEqual(unescape("<Donald Duck & Co>"), | 
 | 259 |                          "<Donald Duck & Co>") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 260 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 261 |     def test_unescape_extra(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 262 |         self.assertEqual(unescape("Hei på deg", {"å" : "å"}), | 
 | 263 |                          "Hei på deg") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 264 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 265 |     def test_unescape_amp_extra(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 266 |         self.assertEqual(unescape("&foo;", {"&foo;": "splat"}), "&foo;") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 267 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 268 |     # ===== quoteattr | 
 | 269 |     def test_quoteattr_basic(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 270 |         self.assertEqual(quoteattr("Donald Duck & Co"), | 
 | 271 |                          '"Donald Duck & Co"') | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 272 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 273 |     def test_single_quoteattr(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 274 |         self.assertEqual(quoteattr('Includes "double" quotes'), | 
 | 275 |                          '\'Includes "double" quotes\'') | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 276 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 277 |     def test_double_quoteattr(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 278 |         self.assertEqual(quoteattr("Includes 'single' quotes"), | 
 | 279 |                          "\"Includes 'single' quotes\"") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 280 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 281 |     def test_single_double_quoteattr(self): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 282 |         self.assertEqual(quoteattr("Includes 'single' and \"double\" quotes"), | 
 | 283 |                          "\"Includes 'single' and "double" quotes\"") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 284 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 285 |     # ===== make_parser | 
 | 286 |     def test_make_parser(self): | 
| Martin v. Löwis | 962c9e7 | 2000-10-06 17:41:52 +0000 | [diff] [blame] | 287 |         # Creating a parser should succeed - it should fall back | 
 | 288 |         # to the expatreader | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 289 |         p = make_parser(['xml.parsers.no_such_parser']) | 
| Martin v. Löwis | 962c9e7 | 2000-10-06 17:41:52 +0000 | [diff] [blame] | 290 |  | 
 | 291 |  | 
| Serhiy Storchaka | e9d4dc1 | 2015-04-02 20:55:46 +0300 | [diff] [blame] | 292 | class PrepareInputSourceTest(unittest.TestCase): | 
 | 293 |  | 
 | 294 |     def setUp(self): | 
 | 295 |         self.file = support.TESTFN | 
 | 296 |         with open(self.file, "w") as tmp: | 
 | 297 |             tmp.write("This was read from a file.") | 
 | 298 |  | 
 | 299 |     def tearDown(self): | 
 | 300 |         support.unlink(self.file) | 
 | 301 |  | 
 | 302 |     def make_byte_stream(self): | 
 | 303 |         return io.BytesIO(b"This is a byte stream.") | 
 | 304 |  | 
 | 305 |     def checkContent(self, stream, content): | 
 | 306 |         self.assertIsNotNone(stream) | 
 | 307 |         self.assertEqual(stream.read(), content) | 
 | 308 |         stream.close() | 
 | 309 |  | 
 | 310 |  | 
 | 311 |     def test_byte_stream(self): | 
 | 312 |         # If the source is an InputSource that does not have a character | 
 | 313 |         # stream but does have a byte stream, use the byte stream. | 
 | 314 |         src = InputSource(self.file) | 
 | 315 |         src.setByteStream(self.make_byte_stream()) | 
 | 316 |         prep = prepare_input_source(src) | 
 | 317 |         self.assertIsNone(prep.getCharacterStream()) | 
 | 318 |         self.checkContent(prep.getByteStream(), | 
 | 319 |                           b"This is a byte stream.") | 
 | 320 |  | 
 | 321 |     def test_system_id(self): | 
 | 322 |         # If the source is an InputSource that has neither a character | 
 | 323 |         # stream nor a byte stream, open the system ID. | 
 | 324 |         src = InputSource(self.file) | 
 | 325 |         prep = prepare_input_source(src) | 
 | 326 |         self.assertIsNone(prep.getCharacterStream()) | 
 | 327 |         self.checkContent(prep.getByteStream(), | 
 | 328 |                           b"This was read from a file.") | 
 | 329 |  | 
 | 330 |     def test_string(self): | 
 | 331 |         # If the source is a string, use it as a system ID and open it. | 
 | 332 |         prep = prepare_input_source(self.file) | 
 | 333 |         self.assertIsNone(prep.getCharacterStream()) | 
 | 334 |         self.checkContent(prep.getByteStream(), | 
 | 335 |                           b"This was read from a file.") | 
 | 336 |  | 
 | 337 |     def test_binary_file(self): | 
 | 338 |         # If the source is a binary file-like object, use it as a byte | 
 | 339 |         # stream. | 
 | 340 |         prep = prepare_input_source(self.make_byte_stream()) | 
 | 341 |         self.assertIsNone(prep.getCharacterStream()) | 
 | 342 |         self.checkContent(prep.getByteStream(), | 
 | 343 |                           b"This is a byte stream.") | 
 | 344 |  | 
 | 345 |  | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 346 | # ===== XMLGenerator | 
 | 347 |  | 
 | 348 | start = '<?xml version="1.0" encoding="iso-8859-1"?>\n' | 
 | 349 |  | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 350 | class XmlgenTest: | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 351 |     def test_xmlgen_basic(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 352 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 353 |         gen = XMLGenerator(result) | 
 | 354 |         gen.startDocument() | 
 | 355 |         gen.startElement("doc", {}) | 
 | 356 |         gen.endElement("doc") | 
 | 357 |         gen.endDocument() | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 358 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 359 |         self.assertEqual(result.getvalue(), start + "<doc></doc>") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 360 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 361 |     def test_xmlgen_content(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 362 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 363 |         gen = XMLGenerator(result) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 364 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 365 |         gen.startDocument() | 
 | 366 |         gen.startElement("doc", {}) | 
 | 367 |         gen.characters("huhei") | 
 | 368 |         gen.endElement("doc") | 
 | 369 |         gen.endDocument() | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 370 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 371 |         self.assertEqual(result.getvalue(), start + "<doc>huhei</doc>") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 372 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 373 |     def test_xmlgen_pi(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 374 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 375 |         gen = XMLGenerator(result) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 376 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 377 |         gen.startDocument() | 
 | 378 |         gen.processingInstruction("test", "data") | 
 | 379 |         gen.startElement("doc", {}) | 
 | 380 |         gen.endElement("doc") | 
 | 381 |         gen.endDocument() | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 382 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 383 |         self.assertEqual(result.getvalue(), start + "<?test data?><doc></doc>") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 384 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 385 |     def test_xmlgen_content_escape(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 386 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 387 |         gen = XMLGenerator(result) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 388 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 389 |         gen.startDocument() | 
 | 390 |         gen.startElement("doc", {}) | 
 | 391 |         gen.characters("<huhei&") | 
 | 392 |         gen.endElement("doc") | 
 | 393 |         gen.endDocument() | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 394 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 395 |         self.assertEqual(result.getvalue(), | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 396 |             start + "<doc><huhei&</doc>") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 397 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 398 |     def test_xmlgen_attr_escape(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 399 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 400 |         gen = XMLGenerator(result) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 401 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 402 |         gen.startDocument() | 
 | 403 |         gen.startElement("doc", {"a": '"'}) | 
 | 404 |         gen.startElement("e", {"a": "'"}) | 
 | 405 |         gen.endElement("e") | 
 | 406 |         gen.startElement("e", {"a": "'\""}) | 
 | 407 |         gen.endElement("e") | 
 | 408 |         gen.startElement("e", {"a": "\n\r\t"}) | 
 | 409 |         gen.endElement("e") | 
 | 410 |         gen.endElement("doc") | 
 | 411 |         gen.endDocument() | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 412 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 413 |         self.assertEqual(result.getvalue(), start + | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 414 |             ("<doc a='\"'><e a=\"'\"></e>" | 
 | 415 |              "<e a=\"'"\"></e>" | 
 | 416 |              "<e a=\"

	\"></e></doc>")) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 417 |  | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 418 |     def test_xmlgen_encoding(self): | 
 | 419 |         encodings = ('iso-8859-15', 'utf-8', | 
 | 420 |                      'utf-16be', 'utf-16le', | 
 | 421 |                      'utf-32be', 'utf-32le') | 
 | 422 |         for encoding in encodings: | 
 | 423 |             result = self.ioclass() | 
 | 424 |             gen = XMLGenerator(result, encoding=encoding) | 
 | 425 |  | 
 | 426 |             gen.startDocument() | 
 | 427 |             gen.startElement("doc", {"a": u'\u20ac'}) | 
 | 428 |             gen.characters(u"\u20ac") | 
 | 429 |             gen.endElement("doc") | 
 | 430 |             gen.endDocument() | 
 | 431 |  | 
 | 432 |             self.assertEqual(result.getvalue(), ( | 
 | 433 |                 u'<?xml version="1.0" encoding="%s"?>\n' | 
 | 434 |                 u'<doc a="\u20ac">\u20ac</doc>' % encoding | 
 | 435 |                 ).encode(encoding, 'xmlcharrefreplace')) | 
 | 436 |  | 
 | 437 |     def test_xmlgen_unencodable(self): | 
 | 438 |         result = self.ioclass() | 
 | 439 |         gen = XMLGenerator(result, encoding='ascii') | 
 | 440 |  | 
 | 441 |         gen.startDocument() | 
 | 442 |         gen.startElement("doc", {"a": u'\u20ac'}) | 
 | 443 |         gen.characters(u"\u20ac") | 
 | 444 |         gen.endElement("doc") | 
 | 445 |         gen.endDocument() | 
 | 446 |  | 
 | 447 |         self.assertEqual(result.getvalue(), | 
 | 448 |                 '<?xml version="1.0" encoding="ascii"?>\n' | 
 | 449 |                 '<doc a="€">€</doc>') | 
 | 450 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 451 |     def test_xmlgen_ignorable(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 452 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 453 |         gen = XMLGenerator(result) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 454 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 455 |         gen.startDocument() | 
 | 456 |         gen.startElement("doc", {}) | 
 | 457 |         gen.ignorableWhitespace(" ") | 
 | 458 |         gen.endElement("doc") | 
 | 459 |         gen.endDocument() | 
| Fred Drake | c9fadf9 | 2001-08-07 19:17:06 +0000 | [diff] [blame] | 460 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 461 |         self.assertEqual(result.getvalue(), start + "<doc> </doc>") | 
| Fred Drake | c9fadf9 | 2001-08-07 19:17:06 +0000 | [diff] [blame] | 462 |  | 
| Serhiy Storchaka | 7423903 | 2013-05-12 17:29:34 +0300 | [diff] [blame] | 463 |     def test_xmlgen_encoding_bytes(self): | 
 | 464 |         encodings = ('iso-8859-15', 'utf-8', | 
 | 465 |                      'utf-16be', 'utf-16le', | 
 | 466 |                      'utf-32be', 'utf-32le') | 
 | 467 |         for encoding in encodings: | 
 | 468 |             result = self.ioclass() | 
 | 469 |             gen = XMLGenerator(result, encoding=encoding) | 
 | 470 |  | 
 | 471 |             gen.startDocument() | 
 | 472 |             gen.startElement("doc", {"a": u'\u20ac'}) | 
 | 473 |             gen.characters(u"\u20ac".encode(encoding)) | 
 | 474 |             gen.ignorableWhitespace(" ".encode(encoding)) | 
 | 475 |             gen.endElement("doc") | 
 | 476 |             gen.endDocument() | 
 | 477 |  | 
 | 478 |             self.assertEqual(result.getvalue(), ( | 
 | 479 |                 u'<?xml version="1.0" encoding="%s"?>\n' | 
 | 480 |                 u'<doc a="\u20ac">\u20ac </doc>' % encoding | 
 | 481 |                 ).encode(encoding, 'xmlcharrefreplace')) | 
 | 482 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 483 |     def test_xmlgen_ns(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 484 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 485 |         gen = XMLGenerator(result) | 
| Fred Drake | c9fadf9 | 2001-08-07 19:17:06 +0000 | [diff] [blame] | 486 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 487 |         gen.startDocument() | 
 | 488 |         gen.startPrefixMapping("ns1", ns_uri) | 
 | 489 |         gen.startElementNS((ns_uri, "doc"), "ns1:doc", {}) | 
 | 490 |         # add an unqualified name | 
 | 491 |         gen.startElementNS((None, "udoc"), None, {}) | 
 | 492 |         gen.endElementNS((None, "udoc"), None) | 
 | 493 |         gen.endElementNS((ns_uri, "doc"), "ns1:doc") | 
 | 494 |         gen.endPrefixMapping("ns1") | 
 | 495 |         gen.endDocument() | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 496 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 497 |         self.assertEqual(result.getvalue(), start + \ | 
| Martin v. Löwis | cf0a1cc | 2000-10-03 22:35:29 +0000 | [diff] [blame] | 498 |            ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' % | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 499 |                                          ns_uri)) | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 500 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 501 |     def test_1463026_1(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 502 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 503 |         gen = XMLGenerator(result) | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 504 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 505 |         gen.startDocument() | 
 | 506 |         gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'}) | 
 | 507 |         gen.endElementNS((None, 'a'), 'a') | 
 | 508 |         gen.endDocument() | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 509 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 510 |         self.assertEqual(result.getvalue(), start+'<a b="c"></a>') | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 511 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 512 |     def test_1463026_2(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 513 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 514 |         gen = XMLGenerator(result) | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 515 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 516 |         gen.startDocument() | 
 | 517 |         gen.startPrefixMapping(None, 'qux') | 
 | 518 |         gen.startElementNS(('qux', 'a'), 'a', {}) | 
 | 519 |         gen.endElementNS(('qux', 'a'), 'a') | 
 | 520 |         gen.endPrefixMapping(None) | 
 | 521 |         gen.endDocument() | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 522 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 523 |         self.assertEqual(result.getvalue(), start+'<a xmlns="qux"></a>') | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 524 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 525 |     def test_1463026_3(self): | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 526 |         result = self.ioclass() | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 527 |         gen = XMLGenerator(result) | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 528 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 529 |         gen.startDocument() | 
 | 530 |         gen.startPrefixMapping('my', 'qux') | 
 | 531 |         gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'}) | 
 | 532 |         gen.endElementNS(('qux', 'a'), 'a') | 
 | 533 |         gen.endPrefixMapping('my') | 
 | 534 |         gen.endDocument() | 
| Martin v. Löwis | 2bad58f | 2007-02-12 12:21:10 +0000 | [diff] [blame] | 535 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 536 |         self.assertEqual(result.getvalue(), | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 537 |             start+'<my:a xmlns:my="qux" b="c"></my:a>') | 
| Tim Peters | ea5962f | 2007-03-12 18:07:52 +0000 | [diff] [blame] | 538 |  | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 539 |     def test_5027_1(self): | 
 | 540 |         # The xml prefix (as in xml:lang below) is reserved and bound by | 
 | 541 |         # definition to http://www.w3.org/XML/1998/namespace.  XMLGenerator had | 
| Andrew Svetlov | 4bb142b | 2012-12-18 21:27:37 +0200 | [diff] [blame] | 542 |         # a bug whereby a KeyError is raised because this namespace is missing | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 543 |         # from a dictionary. | 
 | 544 |         # | 
 | 545 |         # This test demonstrates the bug by parsing a document. | 
 | 546 |         test_xml = StringIO( | 
 | 547 |             '<?xml version="1.0"?>' | 
 | 548 |             '<a:g1 xmlns:a="http://example.com/ns">' | 
 | 549 |              '<a:g2 xml:lang="en">Hello</a:g2>' | 
 | 550 |             '</a:g1>') | 
 | 551 |  | 
 | 552 |         parser = make_parser() | 
 | 553 |         parser.setFeature(feature_namespaces, True) | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 554 |         result = self.ioclass() | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 555 |         gen = XMLGenerator(result) | 
 | 556 |         parser.setContentHandler(gen) | 
 | 557 |         parser.parse(test_xml) | 
 | 558 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 559 |         self.assertEqual(result.getvalue(), | 
 | 560 |                          start + ( | 
 | 561 |                          '<a:g1 xmlns:a="http://example.com/ns">' | 
 | 562 |                           '<a:g2 xml:lang="en">Hello</a:g2>' | 
 | 563 |                          '</a:g1>')) | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 564 |  | 
 | 565 |     def test_5027_2(self): | 
 | 566 |         # The xml prefix (as in xml:lang below) is reserved and bound by | 
 | 567 |         # definition to http://www.w3.org/XML/1998/namespace.  XMLGenerator had | 
| Andrew Svetlov | 4bb142b | 2012-12-18 21:27:37 +0200 | [diff] [blame] | 568 |         # a bug whereby a KeyError is raised because this namespace is missing | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 569 |         # from a dictionary. | 
 | 570 |         # | 
 | 571 |         # This test demonstrates the bug by direct manipulation of the | 
 | 572 |         # XMLGenerator. | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 573 |         result = self.ioclass() | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 574 |         gen = XMLGenerator(result) | 
 | 575 |  | 
 | 576 |         gen.startDocument() | 
 | 577 |         gen.startPrefixMapping('a', 'http://example.com/ns') | 
 | 578 |         gen.startElementNS(('http://example.com/ns', 'g1'), 'g1', {}) | 
 | 579 |         lang_attr = {('http://www.w3.org/XML/1998/namespace', 'lang'): 'en'} | 
 | 580 |         gen.startElementNS(('http://example.com/ns', 'g2'), 'g2', lang_attr) | 
 | 581 |         gen.characters('Hello') | 
 | 582 |         gen.endElementNS(('http://example.com/ns', 'g2'), 'g2') | 
 | 583 |         gen.endElementNS(('http://example.com/ns', 'g1'), 'g1') | 
 | 584 |         gen.endPrefixMapping('a') | 
 | 585 |         gen.endDocument() | 
 | 586 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 587 |         self.assertEqual(result.getvalue(), | 
 | 588 |                          start + ( | 
 | 589 |                          '<a:g1 xmlns:a="http://example.com/ns">' | 
 | 590 |                           '<a:g2 xml:lang="en">Hello</a:g2>' | 
 | 591 |                          '</a:g1>')) | 
| Antoine Pitrou | 7f08102 | 2010-10-27 18:43:21 +0000 | [diff] [blame] | 592 |  | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 593 |     def test_no_close_file(self): | 
 | 594 |         result = self.ioclass() | 
 | 595 |         def func(out): | 
 | 596 |             gen = XMLGenerator(out) | 
 | 597 |             gen.startDocument() | 
 | 598 |             gen.startElement("doc", {}) | 
 | 599 |         func(result) | 
 | 600 |         self.assertFalse(result.closed) | 
 | 601 |  | 
| Serhiy Storchaka | 93bfe7d | 2013-02-25 13:31:29 +0200 | [diff] [blame] | 602 |     def test_xmlgen_fragment(self): | 
 | 603 |         result = self.ioclass() | 
 | 604 |         gen = XMLGenerator(result) | 
 | 605 |  | 
 | 606 |         # Don't call gen.startDocument() | 
 | 607 |         gen.startElement("foo", {"a": "1.0"}) | 
 | 608 |         gen.characters("Hello") | 
 | 609 |         gen.endElement("foo") | 
 | 610 |         gen.startElement("bar", {"b": "2.0"}) | 
 | 611 |         gen.endElement("bar") | 
 | 612 |         # Don't call gen.endDocument() | 
 | 613 |  | 
 | 614 |         self.assertEqual(result.getvalue(), | 
 | 615 |                          '<foo a="1.0">Hello</foo><bar b="2.0"></bar>') | 
 | 616 |  | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 617 | class StringXmlgenTest(XmlgenTest, unittest.TestCase): | 
 | 618 |     ioclass = StringIO | 
 | 619 |  | 
 | 620 | class BytesIOXmlgenTest(XmlgenTest, unittest.TestCase): | 
 | 621 |     ioclass = io.BytesIO | 
 | 622 |  | 
 | 623 | class WriterXmlgenTest(XmlgenTest, unittest.TestCase): | 
 | 624 |     class ioclass(list): | 
 | 625 |         write = list.append | 
 | 626 |         closed = False | 
 | 627 |  | 
 | 628 |         def getvalue(self): | 
 | 629 |             return b''.join(self) | 
 | 630 |  | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 631 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 632 | class XMLFilterBaseTest(unittest.TestCase): | 
 | 633 |     def test_filter_basic(self): | 
 | 634 |         result = StringIO() | 
 | 635 |         gen = XMLGenerator(result) | 
 | 636 |         filter = XMLFilterBase() | 
 | 637 |         filter.setContentHandler(gen) | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 638 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 639 |         filter.startDocument() | 
 | 640 |         filter.startElement("doc", {}) | 
 | 641 |         filter.characters("content") | 
 | 642 |         filter.ignorableWhitespace(" ") | 
 | 643 |         filter.endElement("doc") | 
 | 644 |         filter.endDocument() | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 645 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 646 |         self.assertEqual(result.getvalue(), start + "<doc>content </doc>") | 
| Lars Gustäbel | 96753b3 | 2000-09-24 12:24:24 +0000 | [diff] [blame] | 647 |  | 
 | 648 | # =========================================================================== | 
 | 649 | # | 
 | 650 | #   expatreader tests | 
 | 651 | # | 
 | 652 | # =========================================================================== | 
 | 653 |  | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 654 | xml_test_out = open(TEST_XMLFILE_OUT).read() | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 655 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 656 | class ExpatReaderTest(XmlTestBase): | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 657 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 658 |     # ===== XMLReader support | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 659 |  | 
| Serhiy Storchaka | e9d4dc1 | 2015-04-02 20:55:46 +0300 | [diff] [blame] | 660 |     def test_expat_binary_file(self): | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 661 |         parser = create_parser() | 
 | 662 |         result = StringIO() | 
 | 663 |         xmlgen = XMLGenerator(result) | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 664 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 665 |         parser.setContentHandler(xmlgen) | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 666 |         parser.parse(open(TEST_XMLFILE)) | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 667 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 668 |         self.assertEqual(result.getvalue(), xml_test_out) | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 669 |  | 
| Serhiy Storchaka | 23298cb | 2013-02-02 12:16:22 +0200 | [diff] [blame] | 670 |     @requires_unicode_filenames | 
| Serhiy Storchaka | 8673ab9 | 2013-02-02 10:28:30 +0200 | [diff] [blame] | 671 |     def test_expat_file_unicode(self): | 
 | 672 |         fname = support.TESTFN_UNICODE | 
 | 673 |         shutil.copyfile(TEST_XMLFILE, fname) | 
 | 674 |         self.addCleanup(support.unlink, fname) | 
 | 675 |  | 
 | 676 |         parser = create_parser() | 
 | 677 |         result = StringIO() | 
 | 678 |         xmlgen = XMLGenerator(result) | 
 | 679 |  | 
 | 680 |         parser.setContentHandler(xmlgen) | 
 | 681 |         parser.parse(open(fname)) | 
 | 682 |  | 
 | 683 |         self.assertEqual(result.getvalue(), xml_test_out) | 
 | 684 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 685 |     # ===== DTDHandler support | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 686 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 687 |     class TestDTDHandler: | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 688 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 689 |         def __init__(self): | 
 | 690 |             self._notations = [] | 
 | 691 |             self._entities  = [] | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 692 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 693 |         def notationDecl(self, name, publicId, systemId): | 
 | 694 |             self._notations.append((name, publicId, systemId)) | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 695 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 696 |         def unparsedEntityDecl(self, name, publicId, systemId, ndata): | 
 | 697 |             self._entities.append((name, publicId, systemId, ndata)) | 
| Lars Gustäbel | b7536d5 | 2000-09-24 18:53:56 +0000 | [diff] [blame] | 698 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 699 |     def test_expat_dtdhandler(self): | 
 | 700 |         parser = create_parser() | 
 | 701 |         handler = self.TestDTDHandler() | 
 | 702 |         parser.setDTDHandler(handler) | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 703 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 704 |         parser.feed('<!DOCTYPE doc [\n') | 
 | 705 |         parser.feed('  <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n') | 
 | 706 |         parser.feed('  <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n') | 
 | 707 |         parser.feed(']>\n') | 
 | 708 |         parser.feed('<doc></doc>') | 
 | 709 |         parser.close() | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 710 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 711 |         self.assertEqual(handler._notations, | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 712 |             [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)]) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 713 |         self.assertEqual(handler._entities, [("img", None, "expat.gif", "GIF")]) | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 714 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 715 |     # ===== EntityResolver support | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 716 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 717 |     class TestEntityResolver: | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 718 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 719 |         def resolveEntity(self, publicId, systemId): | 
 | 720 |             inpsrc = InputSource() | 
 | 721 |             inpsrc.setByteStream(StringIO("<entity/>")) | 
 | 722 |             return inpsrc | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 723 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 724 |     def test_expat_entityresolver(self): | 
 | 725 |         parser = create_parser() | 
 | 726 |         parser.setEntityResolver(self.TestEntityResolver()) | 
 | 727 |         result = StringIO() | 
 | 728 |         parser.setContentHandler(XMLGenerator(result)) | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 729 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 730 |         parser.feed('<!DOCTYPE doc [\n') | 
 | 731 |         parser.feed('  <!ENTITY test SYSTEM "whatever">\n') | 
 | 732 |         parser.feed(']>\n') | 
 | 733 |         parser.feed('<doc>&test;</doc>') | 
 | 734 |         parser.close() | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 735 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 736 |         self.assertEqual(result.getvalue(), start + | 
 | 737 |                          "<doc><entity></entity></doc>") | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 738 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 739 |     # ===== Attributes support | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 740 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 741 |     class AttrGatherer(ContentHandler): | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 742 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 743 |         def startElement(self, name, attrs): | 
 | 744 |             self._attrs = attrs | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 745 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 746 |         def startElementNS(self, name, qname, attrs): | 
 | 747 |             self._attrs = attrs | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 748 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 749 |     def test_expat_attrs_empty(self): | 
 | 750 |         parser = create_parser() | 
 | 751 |         gather = self.AttrGatherer() | 
 | 752 |         parser.setContentHandler(gather) | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 753 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 754 |         parser.feed("<doc/>") | 
 | 755 |         parser.close() | 
| Lars Gustäbel | 2fc5294 | 2000-10-24 15:35:07 +0000 | [diff] [blame] | 756 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 757 |         self.verify_empty_attrs(gather._attrs) | 
| Martin v. Löwis | 80670bc | 2000-10-06 21:13:23 +0000 | [diff] [blame] | 758 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 759 |     def test_expat_attrs_wattr(self): | 
 | 760 |         parser = create_parser() | 
 | 761 |         gather = self.AttrGatherer() | 
 | 762 |         parser.setContentHandler(gather) | 
 | 763 |  | 
 | 764 |         parser.feed("<doc attr='val'/>") | 
 | 765 |         parser.close() | 
 | 766 |  | 
 | 767 |         self.verify_attrs_wattr(gather._attrs) | 
 | 768 |  | 
 | 769 |     def test_expat_nsattrs_empty(self): | 
 | 770 |         parser = create_parser(1) | 
 | 771 |         gather = self.AttrGatherer() | 
 | 772 |         parser.setContentHandler(gather) | 
 | 773 |  | 
 | 774 |         parser.feed("<doc/>") | 
 | 775 |         parser.close() | 
 | 776 |  | 
 | 777 |         self.verify_empty_nsattrs(gather._attrs) | 
 | 778 |  | 
 | 779 |     def test_expat_nsattrs_wattr(self): | 
 | 780 |         parser = create_parser(1) | 
 | 781 |         gather = self.AttrGatherer() | 
 | 782 |         parser.setContentHandler(gather) | 
 | 783 |  | 
 | 784 |         parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri) | 
 | 785 |         parser.close() | 
 | 786 |  | 
 | 787 |         attrs = gather._attrs | 
 | 788 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 789 |         self.assertEqual(attrs.getLength(), 1) | 
 | 790 |         self.assertEqual(attrs.getNames(), [(ns_uri, "attr")]) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 791 |         self.assertTrue((attrs.getQNames() == [] or | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 792 |                          attrs.getQNames() == ["ns:attr"])) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 793 |         self.assertEqual(len(attrs), 1) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 794 |         self.assertTrue(attrs.has_key((ns_uri, "attr"))) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 795 |         self.assertEqual(attrs.get((ns_uri, "attr")), "val") | 
 | 796 |         self.assertEqual(attrs.get((ns_uri, "attr"), 25), "val") | 
 | 797 |         self.assertEqual(attrs.items(), [((ns_uri, "attr"), "val")]) | 
 | 798 |         self.assertEqual(attrs.values(), ["val"]) | 
 | 799 |         self.assertEqual(attrs.getValue((ns_uri, "attr")), "val") | 
 | 800 |         self.assertEqual(attrs[(ns_uri, "attr")], "val") | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 801 |  | 
 | 802 |     # ===== InputSource support | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 803 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 804 |     def test_expat_inpsource_filename(self): | 
 | 805 |         parser = create_parser() | 
 | 806 |         result = StringIO() | 
 | 807 |         xmlgen = XMLGenerator(result) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 808 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 809 |         parser.setContentHandler(xmlgen) | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 810 |         parser.parse(TEST_XMLFILE) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 811 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 812 |         self.assertEqual(result.getvalue(), xml_test_out) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 813 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 814 |     def test_expat_inpsource_sysid(self): | 
 | 815 |         parser = create_parser() | 
 | 816 |         result = StringIO() | 
 | 817 |         xmlgen = XMLGenerator(result) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 818 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 819 |         parser.setContentHandler(xmlgen) | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 820 |         parser.parse(InputSource(TEST_XMLFILE)) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 821 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 822 |         self.assertEqual(result.getvalue(), xml_test_out) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 823 |  | 
| Serhiy Storchaka | 23298cb | 2013-02-02 12:16:22 +0200 | [diff] [blame] | 824 |     @requires_unicode_filenames | 
| Serhiy Storchaka | 8673ab9 | 2013-02-02 10:28:30 +0200 | [diff] [blame] | 825 |     def test_expat_inpsource_sysid_unicode(self): | 
 | 826 |         fname = support.TESTFN_UNICODE | 
 | 827 |         shutil.copyfile(TEST_XMLFILE, fname) | 
 | 828 |         self.addCleanup(support.unlink, fname) | 
 | 829 |  | 
 | 830 |         parser = create_parser() | 
 | 831 |         result = StringIO() | 
 | 832 |         xmlgen = XMLGenerator(result) | 
 | 833 |  | 
 | 834 |         parser.setContentHandler(xmlgen) | 
 | 835 |         parser.parse(InputSource(fname)) | 
 | 836 |  | 
 | 837 |         self.assertEqual(result.getvalue(), xml_test_out) | 
 | 838 |  | 
| Serhiy Storchaka | e9d4dc1 | 2015-04-02 20:55:46 +0300 | [diff] [blame] | 839 |     def test_expat_inpsource_byte_stream(self): | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 840 |         parser = create_parser() | 
 | 841 |         result = StringIO() | 
 | 842 |         xmlgen = XMLGenerator(result) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 843 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 844 |         parser.setContentHandler(xmlgen) | 
 | 845 |         inpsrc = InputSource() | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 846 |         inpsrc.setByteStream(open(TEST_XMLFILE)) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 847 |         parser.parse(inpsrc) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 848 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 849 |         self.assertEqual(result.getvalue(), xml_test_out) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 850 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 851 |     # ===== IncrementalParser support | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 852 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 853 |     def test_expat_incremental(self): | 
 | 854 |         result = StringIO() | 
 | 855 |         xmlgen = XMLGenerator(result) | 
 | 856 |         parser = create_parser() | 
 | 857 |         parser.setContentHandler(xmlgen) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 858 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 859 |         parser.feed("<doc>") | 
 | 860 |         parser.feed("</doc>") | 
 | 861 |         parser.close() | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 862 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 863 |         self.assertEqual(result.getvalue(), start + "<doc></doc>") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 864 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 865 |     def test_expat_incremental_reset(self): | 
 | 866 |         result = StringIO() | 
 | 867 |         xmlgen = XMLGenerator(result) | 
 | 868 |         parser = create_parser() | 
 | 869 |         parser.setContentHandler(xmlgen) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 870 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 871 |         parser.feed("<doc>") | 
 | 872 |         parser.feed("text") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 873 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 874 |         result = StringIO() | 
 | 875 |         xmlgen = XMLGenerator(result) | 
 | 876 |         parser.setContentHandler(xmlgen) | 
 | 877 |         parser.reset() | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 878 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 879 |         parser.feed("<doc>") | 
 | 880 |         parser.feed("text") | 
 | 881 |         parser.feed("</doc>") | 
 | 882 |         parser.close() | 
 | 883 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 884 |         self.assertEqual(result.getvalue(), start + "<doc>text</doc>") | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 885 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 886 |     # ===== Locator support | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 887 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 888 |     def test_expat_locator_noinfo(self): | 
 | 889 |         result = StringIO() | 
 | 890 |         xmlgen = XMLGenerator(result) | 
 | 891 |         parser = create_parser() | 
 | 892 |         parser.setContentHandler(xmlgen) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 893 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 894 |         parser.feed("<doc>") | 
 | 895 |         parser.feed("</doc>") | 
 | 896 |         parser.close() | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 897 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 898 |         self.assertEqual(parser.getSystemId(), None) | 
 | 899 |         self.assertEqual(parser.getPublicId(), None) | 
 | 900 |         self.assertEqual(parser.getLineNumber(), 1) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 901 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 902 |     def test_expat_locator_withinfo(self): | 
 | 903 |         result = StringIO() | 
 | 904 |         xmlgen = XMLGenerator(result) | 
 | 905 |         parser = create_parser() | 
 | 906 |         parser.setContentHandler(xmlgen) | 
| Florent Xicluna | 13ba1a1 | 2010-03-13 11:18:49 +0000 | [diff] [blame] | 907 |         parser.parse(TEST_XMLFILE) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 908 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 909 |         self.assertEqual(parser.getSystemId(), TEST_XMLFILE) | 
 | 910 |         self.assertEqual(parser.getPublicId(), None) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 911 |  | 
| Serhiy Storchaka | 23298cb | 2013-02-02 12:16:22 +0200 | [diff] [blame] | 912 |     @requires_unicode_filenames | 
| Serhiy Storchaka | 8673ab9 | 2013-02-02 10:28:30 +0200 | [diff] [blame] | 913 |     def test_expat_locator_withinfo_unicode(self): | 
 | 914 |         fname = support.TESTFN_UNICODE | 
 | 915 |         shutil.copyfile(TEST_XMLFILE, fname) | 
 | 916 |         self.addCleanup(support.unlink, fname) | 
 | 917 |  | 
 | 918 |         result = StringIO() | 
 | 919 |         xmlgen = XMLGenerator(result) | 
 | 920 |         parser = create_parser() | 
 | 921 |         parser.setContentHandler(xmlgen) | 
 | 922 |         parser.parse(fname) | 
 | 923 |  | 
 | 924 |         self.assertEqual(parser.getSystemId(), fname) | 
 | 925 |         self.assertEqual(parser.getPublicId(), None) | 
 | 926 |  | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 927 |  | 
| Martin v. Löwis | 80670bc | 2000-10-06 21:13:23 +0000 | [diff] [blame] | 928 | # =========================================================================== | 
 | 929 | # | 
 | 930 | #   error reporting | 
 | 931 | # | 
 | 932 | # =========================================================================== | 
 | 933 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 934 | class ErrorReportingTest(unittest.TestCase): | 
 | 935 |     def test_expat_inpsource_location(self): | 
 | 936 |         parser = create_parser() | 
 | 937 |         parser.setContentHandler(ContentHandler()) # do nothing | 
 | 938 |         source = InputSource() | 
 | 939 |         source.setByteStream(StringIO("<foo bar foobar>"))   #ill-formed | 
 | 940 |         name = "a file name" | 
 | 941 |         source.setSystemId(name) | 
 | 942 |         try: | 
 | 943 |             parser.parse(source) | 
 | 944 |             self.fail() | 
 | 945 |         except SAXException, e: | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 946 |             self.assertEqual(e.getSystemId(), name) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 947 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 948 |     def test_expat_incomplete(self): | 
 | 949 |         parser = create_parser() | 
 | 950 |         parser.setContentHandler(ContentHandler()) # do nothing | 
 | 951 |         self.assertRaises(SAXParseException, parser.parse, StringIO("<foo>")) | 
| Serhiy Storchaka | 3234abb | 2015-05-06 09:35:52 +0300 | [diff] [blame] | 952 |         self.assertEqual(parser.getColumnNumber(), 5) | 
 | 953 |         self.assertEqual(parser.getLineNumber(), 1) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 954 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 955 |     def test_sax_parse_exception_str(self): | 
 | 956 |         # pass various values from a locator to the SAXParseException to | 
 | 957 |         # make sure that the __str__() doesn't fall apart when None is | 
 | 958 |         # passed instead of an integer line and column number | 
 | 959 |         # | 
 | 960 |         # use "normal" values for the locator: | 
 | 961 |         str(SAXParseException("message", None, | 
 | 962 |                               self.DummyLocator(1, 1))) | 
 | 963 |         # use None for the line number: | 
 | 964 |         str(SAXParseException("message", None, | 
 | 965 |                               self.DummyLocator(None, 1))) | 
 | 966 |         # use None for the column number: | 
 | 967 |         str(SAXParseException("message", None, | 
 | 968 |                               self.DummyLocator(1, None))) | 
 | 969 |         # use None for both: | 
 | 970 |         str(SAXParseException("message", None, | 
 | 971 |                               self.DummyLocator(None, None))) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 972 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 973 |     class DummyLocator: | 
 | 974 |         def __init__(self, lineno, colno): | 
 | 975 |             self._lineno = lineno | 
 | 976 |             self._colno = colno | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 977 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 978 |         def getPublicId(self): | 
 | 979 |             return "pubid" | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 980 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 981 |         def getSystemId(self): | 
 | 982 |             return "sysid" | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 983 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 984 |         def getLineNumber(self): | 
 | 985 |             return self._lineno | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 986 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 987 |         def getColumnNumber(self): | 
 | 988 |             return self._colno | 
| Martin v. Löwis | 80670bc | 2000-10-06 21:13:23 +0000 | [diff] [blame] | 989 |  | 
| Lars Gustäbel | ab64787 | 2000-09-24 18:40:52 +0000 | [diff] [blame] | 990 | # =========================================================================== | 
 | 991 | # | 
 | 992 | #   xmlreader tests | 
 | 993 | # | 
 | 994 | # =========================================================================== | 
 | 995 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 996 | class XmlReaderTest(XmlTestBase): | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 997 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 998 |     # ===== AttributesImpl | 
 | 999 |     def test_attrs_empty(self): | 
 | 1000 |         self.verify_empty_attrs(AttributesImpl({})) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1001 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1002 |     def test_attrs_wattr(self): | 
 | 1003 |         self.verify_attrs_wattr(AttributesImpl({"attr" : "val"})) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1004 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1005 |     def test_nsattrs_empty(self): | 
 | 1006 |         self.verify_empty_nsattrs(AttributesNSImpl({}, {})) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1007 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1008 |     def test_nsattrs_wattr(self): | 
 | 1009 |         attrs = AttributesNSImpl({(ns_uri, "attr") : "val"}, | 
 | 1010 |                                  {(ns_uri, "attr") : "ns:attr"}) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1011 |  | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 1012 |         self.assertEqual(attrs.getLength(), 1) | 
 | 1013 |         self.assertEqual(attrs.getNames(), [(ns_uri, "attr")]) | 
 | 1014 |         self.assertEqual(attrs.getQNames(), ["ns:attr"]) | 
 | 1015 |         self.assertEqual(len(attrs), 1) | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1016 |         self.assertTrue(attrs.has_key((ns_uri, "attr"))) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 1017 |         self.assertEqual(attrs.keys(), [(ns_uri, "attr")]) | 
 | 1018 |         self.assertEqual(attrs.get((ns_uri, "attr")), "val") | 
 | 1019 |         self.assertEqual(attrs.get((ns_uri, "attr"), 25), "val") | 
 | 1020 |         self.assertEqual(attrs.items(), [((ns_uri, "attr"), "val")]) | 
 | 1021 |         self.assertEqual(attrs.values(), ["val"]) | 
 | 1022 |         self.assertEqual(attrs.getValue((ns_uri, "attr")), "val") | 
 | 1023 |         self.assertEqual(attrs.getValueByQName("ns:attr"), "val") | 
 | 1024 |         self.assertEqual(attrs.getNameByQName("ns:attr"), (ns_uri, "attr")) | 
 | 1025 |         self.assertEqual(attrs[(ns_uri, "attr")], "val") | 
 | 1026 |         self.assertEqual(attrs.getQNameByName((ns_uri, "attr")), "ns:attr") | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 1027 |  | 
| Lars Gustäbel | ab64787 | 2000-09-24 18:40:52 +0000 | [diff] [blame] | 1028 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1029 |     # During the development of Python 2.5, an attempt to move the "xml" | 
 | 1030 |     # package implementation to a new package ("xmlcore") proved painful. | 
 | 1031 |     # The goal of this change was to allow applications to be able to | 
 | 1032 |     # obtain and rely on behavior in the standard library implementation | 
 | 1033 |     # of the XML support without needing to be concerned about the | 
 | 1034 |     # availability of the PyXML implementation. | 
 | 1035 |     # | 
 | 1036 |     # While the existing import hackery in Lib/xml/__init__.py can cause | 
 | 1037 |     # PyXML's _xmlpus package to supplant the "xml" package, that only | 
 | 1038 |     # works because either implementation uses the "xml" package name for | 
 | 1039 |     # imports. | 
 | 1040 |     # | 
 | 1041 |     # The move resulted in a number of problems related to the fact that | 
 | 1042 |     # the import machinery's "package context" is based on the name that's | 
 | 1043 |     # being imported rather than the __name__ of the actual package | 
 | 1044 |     # containment; it wasn't possible for the "xml" package to be replaced | 
 | 1045 |     # by a simple module that indirected imports to the "xmlcore" package. | 
 | 1046 |     # | 
 | 1047 |     # The following two tests exercised bugs that were introduced in that | 
 | 1048 |     # attempt.  Keeping these tests around will help detect problems with | 
 | 1049 |     # other attempts to provide reliable access to the standard library's | 
 | 1050 |     # implementation of the XML support. | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1051 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1052 |     def test_sf_1511497(self): | 
 | 1053 |         # Bug report: http://www.python.org/sf/1511497 | 
 | 1054 |         import sys | 
 | 1055 |         old_modules = sys.modules.copy() | 
 | 1056 |         for modname in sys.modules.keys(): | 
 | 1057 |             if modname.startswith("xml."): | 
 | 1058 |                 del sys.modules[modname] | 
 | 1059 |         try: | 
 | 1060 |             import xml.sax.expatreader | 
 | 1061 |             module = xml.sax.expatreader | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 1062 |             self.assertEqual(module.__name__, "xml.sax.expatreader") | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1063 |         finally: | 
 | 1064 |             sys.modules.update(old_modules) | 
| Neal Norwitz | 0d4c06e | 2007-04-25 06:30:05 +0000 | [diff] [blame] | 1065 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1066 |     def test_sf_1513611(self): | 
 | 1067 |         # Bug report: http://www.python.org/sf/1513611 | 
 | 1068 |         sio = StringIO("invalid") | 
 | 1069 |         parser = make_parser() | 
 | 1070 |         from xml.sax import SAXParseException | 
 | 1071 |         self.assertRaises(SAXParseException, parser.parse, sio) | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 1072 |  | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 1073 |  | 
| Neal Norwitz | ab364c4 | 2008-03-28 07:36:31 +0000 | [diff] [blame] | 1074 | def test_main(): | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1075 |     run_unittest(MakeParserTest, | 
| Serhiy Storchaka | aff77f3 | 2015-04-02 23:05:23 +0300 | [diff] [blame] | 1076 |                  ParseTest, | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1077 |                  SaxutilsTest, | 
| Serhiy Storchaka | e9d4dc1 | 2015-04-02 20:55:46 +0300 | [diff] [blame] | 1078 |                  PrepareInputSourceTest, | 
| Serhiy Storchaka | f898038 | 2013-02-10 14:26:08 +0200 | [diff] [blame] | 1079 |                  StringXmlgenTest, | 
 | 1080 |                  BytesIOXmlgenTest, | 
 | 1081 |                  WriterXmlgenTest, | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1082 |                  ExpatReaderTest, | 
 | 1083 |                  ErrorReportingTest, | 
 | 1084 |                  XmlReaderTest) | 
| Fred Drake | fbdeaad | 2006-07-29 16:56:15 +0000 | [diff] [blame] | 1085 |  | 
| Collin Winter | d28fcbc | 2007-03-28 23:34:06 +0000 | [diff] [blame] | 1086 | if __name__ == "__main__": | 
| Neal Norwitz | ab364c4 | 2008-03-28 07:36:31 +0000 | [diff] [blame] | 1087 |     test_main() |