blob: 2b09cd6801cfe48839800a41c9c28102f24bf191 [file] [log] [blame]
Lars Gustäbel96753b32000-09-24 12:24:24 +00001
2# regression test for SAX 2.0
3# $Id$
4
5from xml.sax.saxutils import XMLGenerator, escape, XMLFilterBase
6from xml.sax.expatreader import create_parser
Lars Gustäbelb7536d52000-09-24 18:53:56 +00007from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
Lars Gustäbelab647872000-09-24 18:40:52 +00008from xml.sax.handler import ContentHandler
Lars Gustäbel96753b32000-09-24 12:24:24 +00009from cStringIO import StringIO
Martin v. Löwis33315b12000-09-24 20:30:24 +000010from test_support import verbose, TestFailed, findfile
Lars Gustäbel96753b32000-09-24 12:24:24 +000011
12# ===== Utilities
13
14tests = 0
15fails = 0
16
17def confirm(outcome, name):
18 global tests, fails
19
20 tests = tests + 1
21 if outcome:
22 print "Passed", name
23 else:
24 print "Failed", name
25 fails = fails + 1
26
27# ===========================================================================
28#
29# saxutils tests
30#
31# ===========================================================================
32
33# ===== escape
34
35def test_escape_basic():
36 return escape("Donald Duck & Co") == "Donald Duck & Co"
37
38def test_escape_all():
39 return escape("<Donald Duck & Co>") == "&lt;Donald Duck &amp; Co&gt;"
40
41def test_escape_extra():
42 return escape("Hei på deg", {"å" : "&aring;"}) == "Hei p&aring; deg"
43
44# ===== XMLGenerator
45
46start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
47
48def test_xmlgen_basic():
49 result = StringIO()
50 gen = XMLGenerator(result)
51 gen.startDocument()
52 gen.startElement("doc", {})
53 gen.endElement("doc")
54 gen.endDocument()
55
56 return result.getvalue() == start + "<doc></doc>"
57
58def test_xmlgen_content():
59 result = StringIO()
60 gen = XMLGenerator(result)
61
62 gen.startDocument()
63 gen.startElement("doc", {})
64 gen.characters("huhei")
65 gen.endElement("doc")
66 gen.endDocument()
67
68 return result.getvalue() == start + "<doc>huhei</doc>"
69
70def test_xmlgen_pi():
71 result = StringIO()
72 gen = XMLGenerator(result)
73
74 gen.startDocument()
75 gen.processingInstruction("test", "data")
76 gen.startElement("doc", {})
77 gen.endElement("doc")
78 gen.endDocument()
79
80 return result.getvalue() == start + "<?test data?><doc></doc>"
81
82def test_xmlgen_content_escape():
83 result = StringIO()
84 gen = XMLGenerator(result)
85
86 gen.startDocument()
87 gen.startElement("doc", {})
88 gen.characters("<huhei&")
89 gen.endElement("doc")
90 gen.endDocument()
91
92 return result.getvalue() == start + "<doc>&lt;huhei&amp;</doc>"
93
94def test_xmlgen_ignorable():
95 result = StringIO()
96 gen = XMLGenerator(result)
97
98 gen.startDocument()
99 gen.startElement("doc", {})
100 gen.ignorableWhitespace(" ")
101 gen.endElement("doc")
102 gen.endDocument()
103
104 return result.getvalue() == start + "<doc> </doc>"
105
106ns_uri = "http://www.python.org/xml-ns/saxtest/"
107
108def test_xmlgen_ns():
109 result = StringIO()
110 gen = XMLGenerator(result)
111
112 gen.startDocument()
113 gen.startPrefixMapping("ns1", ns_uri)
Lars Gustäbel6a7768a2000-09-27 08:12:17 +0000114 gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
115 gen.endElementNS((ns_uri, "doc"), "ns1:doc")
Lars Gustäbel96753b32000-09-24 12:24:24 +0000116 gen.endPrefixMapping("ns1")
117 gen.endDocument()
118
119 return result.getvalue() == start + ('<ns1:doc xmlns:ns1="%s"></ns1:doc>' %
120 ns_uri)
121
122# ===== XMLFilterBase
123
124def test_filter_basic():
125 result = StringIO()
126 gen = XMLGenerator(result)
127 filter = XMLFilterBase()
128 filter.setContentHandler(gen)
129
130 filter.startDocument()
131 filter.startElement("doc", {})
132 filter.characters("content")
133 filter.ignorableWhitespace(" ")
134 filter.endElement("doc")
135 filter.endDocument()
136
137 return result.getvalue() == start + "<doc>content </doc>"
138
139# ===========================================================================
140#
141# expatreader tests
142#
143# ===========================================================================
144
145# ===== DTDHandler support
146
147class TestDTDHandler:
148
149 def __init__(self):
150 self._notations = []
151 self._entities = []
152
153 def notationDecl(self, name, publicId, systemId):
154 self._notations.append((name, publicId, systemId))
155
156 def unparsedEntityDecl(self, name, publicId, systemId, ndata):
157 self._entities.append((name, publicId, systemId, ndata))
158
Lars Gustäbele292a242000-09-24 20:19:45 +0000159def test_expat_dtdhandler():
160 parser = create_parser()
161 handler = TestDTDHandler()
162 parser.setDTDHandler(handler)
Lars Gustäbel96753b32000-09-24 12:24:24 +0000163
Lars Gustäbele292a242000-09-24 20:19:45 +0000164 parser.feed('<!DOCTYPE doc [\n')
165 parser.feed(' <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
166 parser.feed(' <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
167 parser.feed(']>\n')
168 parser.feed('<doc></doc>')
169 parser.close()
Lars Gustäbel96753b32000-09-24 12:24:24 +0000170
Lars Gustäbele292a242000-09-24 20:19:45 +0000171 return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
172 handler._entities == [("img", None, "expat.gif", "GIF")]
Lars Gustäbel96753b32000-09-24 12:24:24 +0000173
174# ===== EntityResolver support
175
Lars Gustäbele292a242000-09-24 20:19:45 +0000176class TestEntityResolver:
Lars Gustäbel96753b32000-09-24 12:24:24 +0000177
Lars Gustäbele292a242000-09-24 20:19:45 +0000178 def resolveEntity(self, publicId, systemId):
179 inpsrc = InputSource()
180 inpsrc.setByteStream(StringIO("<entity/>"))
181 return inpsrc
182
183def test_expat_entityresolver():
Lars Gustäbele292a242000-09-24 20:19:45 +0000184 parser = create_parser()
185 parser.setEntityResolver(TestEntityResolver())
186 result = StringIO()
187 parser.setContentHandler(XMLGenerator(result))
188
189 parser.feed('<!DOCTYPE doc [\n')
190 parser.feed(' <!ENTITY test SYSTEM "whatever">\n')
191 parser.feed(']>\n')
192 parser.feed('<doc>&test;</doc>')
193 parser.close()
194
195 return result.getvalue() == start + "<doc><entity></entity></doc>"
196
Lars Gustäbelab647872000-09-24 18:40:52 +0000197# ===== Attributes support
198
199class AttrGatherer(ContentHandler):
200
201 def startElement(self, name, attrs):
202 self._attrs = attrs
203
204 def startElementNS(self, name, qname, attrs):
205 self._attrs = attrs
206
207def test_expat_attrs_empty():
208 parser = create_parser()
209 gather = AttrGatherer()
210 parser.setContentHandler(gather)
211
212 parser.feed("<doc/>")
213 parser.close()
214
215 return verify_empty_attrs(gather._attrs)
216
217def test_expat_attrs_wattr():
218 parser = create_parser()
219 gather = AttrGatherer()
220 parser.setContentHandler(gather)
221
222 parser.feed("<doc attr='val'/>")
223 parser.close()
224
225 return verify_attrs_wattr(gather._attrs)
226
227def test_expat_nsattrs_empty():
228 parser = create_parser(1)
229 gather = AttrGatherer()
230 parser.setContentHandler(gather)
231
232 parser.feed("<doc/>")
233 parser.close()
234
235 return verify_empty_nsattrs(gather._attrs)
236
237def test_expat_nsattrs_wattr():
238 parser = create_parser(1)
239 gather = AttrGatherer()
240 parser.setContentHandler(gather)
241
242 parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
243 parser.close()
244
245 attrs = gather._attrs
246
247 return attrs.getLength() == 1 and \
248 attrs.getNames() == [(ns_uri, "attr")] and \
249 attrs.getQNames() == [] and \
250 len(attrs) == 1 and \
251 attrs.has_key((ns_uri, "attr")) and \
252 attrs.keys() == [(ns_uri, "attr")] and \
253 attrs.get((ns_uri, "attr")) == "val" and \
254 attrs.get((ns_uri, "attr"), 25) == "val" and \
255 attrs.items() == [((ns_uri, "attr"), "val")] and \
256 attrs.values() == ["val"] and \
257 attrs.getValue((ns_uri, "attr")) == "val" and \
258 attrs[(ns_uri, "attr")] == "val"
259
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000260# ===== InputSource support
261
Martin v. Löwis33315b12000-09-24 20:30:24 +0000262xml_test_out = open(findfile("test.xml.out")).read()
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000263
264def test_expat_inpsource_filename():
265 parser = create_parser()
266 result = StringIO()
267 xmlgen = XMLGenerator(result)
268
269 parser.setContentHandler(xmlgen)
Martin v. Löwis33315b12000-09-24 20:30:24 +0000270 parser.parse(findfile("test.xml"))
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000271
272 return result.getvalue() == xml_test_out
273
274def test_expat_inpsource_sysid():
275 parser = create_parser()
276 result = StringIO()
277 xmlgen = XMLGenerator(result)
278
279 parser.setContentHandler(xmlgen)
Martin v. Löwis33315b12000-09-24 20:30:24 +0000280 parser.parse(InputSource(findfile("test.xml")))
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000281
282 return result.getvalue() == xml_test_out
283
284def test_expat_inpsource_stream():
285 parser = create_parser()
286 result = StringIO()
287 xmlgen = XMLGenerator(result)
288
289 parser.setContentHandler(xmlgen)
290 inpsrc = InputSource()
Martin v. Löwis33315b12000-09-24 20:30:24 +0000291 inpsrc.setByteStream(open(findfile("test.xml")))
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000292 parser.parse(inpsrc)
293
294 return result.getvalue() == xml_test_out
295
Lars Gustäbelab647872000-09-24 18:40:52 +0000296# ===========================================================================
297#
298# xmlreader tests
299#
300# ===========================================================================
301
302# ===== AttributesImpl
303
304def verify_empty_attrs(attrs):
305 try:
306 attrs.getValue("attr")
307 gvk = 0
308 except KeyError:
309 gvk = 1
310
311 try:
312 attrs.getValueByQName("attr")
313 gvqk = 0
314 except KeyError:
315 gvqk = 1
316
317 try:
318 attrs.getNameByQName("attr")
319 gnqk = 0
320 except KeyError:
321 gnqk = 1
322
323 try:
324 attrs.getQNameByName("attr")
325 gqnk = 0
326 except KeyError:
327 gqnk = 1
328
329 try:
330 attrs["attr"]
331 gik = 0
332 except KeyError:
333 gik = 1
334
335 return attrs.getLength() == 0 and \
336 attrs.getNames() == [] and \
337 attrs.getQNames() == [] and \
338 len(attrs) == 0 and \
339 not attrs.has_key("attr") and \
340 attrs.keys() == [] and \
341 attrs.get("attrs") == None and \
342 attrs.get("attrs", 25) == 25 and \
343 attrs.items() == [] and \
344 attrs.values() == [] and \
345 gvk and gvqk and gnqk and gik and gqnk
346
347def verify_attrs_wattr(attrs):
348 return attrs.getLength() == 1 and \
349 attrs.getNames() == ["attr"] and \
350 attrs.getQNames() == ["attr"] and \
351 len(attrs) == 1 and \
352 attrs.has_key("attr") and \
353 attrs.keys() == ["attr"] and \
354 attrs.get("attr") == "val" and \
355 attrs.get("attr", 25) == "val" and \
356 attrs.items() == [("attr", "val")] and \
357 attrs.values() == ["val"] and \
358 attrs.getValue("attr") == "val" and \
359 attrs.getValueByQName("attr") == "val" and \
360 attrs.getNameByQName("attr") == "attr" and \
361 attrs["attr"] == "val" and \
362 attrs.getQNameByName("attr") == "attr"
363
364def test_attrs_empty():
365 return verify_empty_attrs(AttributesImpl({}))
366
367def test_attrs_wattr():
368 return verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
369
370# ===== AttributesImpl
371
372def verify_empty_nsattrs(attrs):
373 try:
374 attrs.getValue((ns_uri, "attr"))
375 gvk = 0
376 except KeyError:
377 gvk = 1
378
379 try:
380 attrs.getValueByQName("ns:attr")
381 gvqk = 0
382 except KeyError:
383 gvqk = 1
384
385 try:
386 attrs.getNameByQName("ns:attr")
387 gnqk = 0
388 except KeyError:
389 gnqk = 1
390
391 try:
392 attrs.getQNameByName((ns_uri, "attr"))
393 gqnk = 0
394 except KeyError:
395 gqnk = 1
396
397 try:
398 attrs[(ns_uri, "attr")]
399 gik = 0
400 except KeyError:
401 gik = 1
402
403 return attrs.getLength() == 0 and \
404 attrs.getNames() == [] and \
405 attrs.getQNames() == [] and \
406 len(attrs) == 0 and \
407 not attrs.has_key((ns_uri, "attr")) and \
408 attrs.keys() == [] and \
409 attrs.get((ns_uri, "attr")) == None and \
410 attrs.get((ns_uri, "attr"), 25) == 25 and \
411 attrs.items() == [] and \
412 attrs.values() == [] and \
413 gvk and gvqk and gnqk and gik and gqnk
414
415def test_nsattrs_empty():
416 return verify_empty_nsattrs(AttributesNSImpl({}, {}))
417
418def test_nsattrs_wattr():
419 attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
420 {(ns_uri, "attr") : "ns:attr"})
421
422 return attrs.getLength() == 1 and \
423 attrs.getNames() == [(ns_uri, "attr")] and \
424 attrs.getQNames() == ["ns:attr"] and \
425 len(attrs) == 1 and \
426 attrs.has_key((ns_uri, "attr")) and \
427 attrs.keys() == [(ns_uri, "attr")] and \
428 attrs.get((ns_uri, "attr")) == "val" and \
429 attrs.get((ns_uri, "attr"), 25) == "val" and \
430 attrs.items() == [((ns_uri, "attr"), "val")] and \
431 attrs.values() == ["val"] and \
432 attrs.getValue((ns_uri, "attr")) == "val" and \
433 attrs.getValueByQName("ns:attr") == "val" and \
434 attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
435 attrs[(ns_uri, "attr")] == "val" and \
436 attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
437
438
Lars Gustäbel96753b32000-09-24 12:24:24 +0000439# ===== Main program
440
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000441def make_test_output():
442 parser = create_parser()
443 result = StringIO()
444 xmlgen = XMLGenerator(result)
445
446 parser.setContentHandler(xmlgen)
Martin v. Löwis33315b12000-09-24 20:30:24 +0000447 parser.parse(findfile("test.xml"))
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000448
Martin v. Löwis33315b12000-09-24 20:30:24 +0000449 outf = open(findfile("test.xml.out"), "w")
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000450 outf.write(result.getvalue())
451 outf.close()
452
Lars Gustäbel96753b32000-09-24 12:24:24 +0000453items = locals().items()
454items.sort()
455for (name, value) in items:
456 if name[ : 5] == "test_":
457 confirm(value(), name)
458
459print "%d tests, %d failures" % (tests, fails)
460if fails != 0:
461 raise TestFailed, "%d of %d tests failed" % (fails, tests)