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