blob: 8ff3dac74e3f8173ca7bba0977b0e90707167b7d [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
10from test_support import verbose, TestFailed
11
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)
114 gen.startElementNS((ns_uri, "doc"), "ns:doc", {})
115 gen.endElementNS((ns_uri, "doc"), "ns:doc")
116 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
159# def test_expat_dtdhandler():
160# parser = create_parser()
161# handler = TestDTDHandler()
162# parser.setDTDHandler(handler)
163
164# 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()
170
171# return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
172# handler._entities == [("img", None, "expat.gif", "GIF")]
173
174# ===== EntityResolver support
175
176# can't test this until InputSource is in place
177
Lars Gustäbelab647872000-09-24 18:40:52 +0000178# ===== Attributes support
179
180class AttrGatherer(ContentHandler):
181
182 def startElement(self, name, attrs):
183 self._attrs = attrs
184
185 def startElementNS(self, name, qname, attrs):
186 self._attrs = attrs
187
188def test_expat_attrs_empty():
189 parser = create_parser()
190 gather = AttrGatherer()
191 parser.setContentHandler(gather)
192
193 parser.feed("<doc/>")
194 parser.close()
195
196 return verify_empty_attrs(gather._attrs)
197
198def test_expat_attrs_wattr():
199 parser = create_parser()
200 gather = AttrGatherer()
201 parser.setContentHandler(gather)
202
203 parser.feed("<doc attr='val'/>")
204 parser.close()
205
206 return verify_attrs_wattr(gather._attrs)
207
208def test_expat_nsattrs_empty():
209 parser = create_parser(1)
210 gather = AttrGatherer()
211 parser.setContentHandler(gather)
212
213 parser.feed("<doc/>")
214 parser.close()
215
216 return verify_empty_nsattrs(gather._attrs)
217
218def test_expat_nsattrs_wattr():
219 parser = create_parser(1)
220 gather = AttrGatherer()
221 parser.setContentHandler(gather)
222
223 parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
224 parser.close()
225
226 attrs = gather._attrs
227
228 return attrs.getLength() == 1 and \
229 attrs.getNames() == [(ns_uri, "attr")] and \
230 attrs.getQNames() == [] and \
231 len(attrs) == 1 and \
232 attrs.has_key((ns_uri, "attr")) and \
233 attrs.keys() == [(ns_uri, "attr")] and \
234 attrs.get((ns_uri, "attr")) == "val" and \
235 attrs.get((ns_uri, "attr"), 25) == "val" and \
236 attrs.items() == [((ns_uri, "attr"), "val")] and \
237 attrs.values() == ["val"] and \
238 attrs.getValue((ns_uri, "attr")) == "val" and \
239 attrs[(ns_uri, "attr")] == "val"
240
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000241# ===== InputSource support
242
243xml_test_out = open("test.xml.out").read()
244
245def test_expat_inpsource_filename():
246 parser = create_parser()
247 result = StringIO()
248 xmlgen = XMLGenerator(result)
249
250 parser.setContentHandler(xmlgen)
251 parser.parse("test.xml")
252
253 return result.getvalue() == xml_test_out
254
255def test_expat_inpsource_sysid():
256 parser = create_parser()
257 result = StringIO()
258 xmlgen = XMLGenerator(result)
259
260 parser.setContentHandler(xmlgen)
261 parser.parse(InputSource("test.xml"))
262
263 return result.getvalue() == xml_test_out
264
265def test_expat_inpsource_stream():
266 parser = create_parser()
267 result = StringIO()
268 xmlgen = XMLGenerator(result)
269
270 parser.setContentHandler(xmlgen)
271 inpsrc = InputSource()
272 inpsrc.setByteStream(open("test.xml"))
273 parser.parse(inpsrc)
274
275 return result.getvalue() == xml_test_out
276
Lars Gustäbelab647872000-09-24 18:40:52 +0000277# ===========================================================================
278#
279# xmlreader tests
280#
281# ===========================================================================
282
283# ===== AttributesImpl
284
285def verify_empty_attrs(attrs):
286 try:
287 attrs.getValue("attr")
288 gvk = 0
289 except KeyError:
290 gvk = 1
291
292 try:
293 attrs.getValueByQName("attr")
294 gvqk = 0
295 except KeyError:
296 gvqk = 1
297
298 try:
299 attrs.getNameByQName("attr")
300 gnqk = 0
301 except KeyError:
302 gnqk = 1
303
304 try:
305 attrs.getQNameByName("attr")
306 gqnk = 0
307 except KeyError:
308 gqnk = 1
309
310 try:
311 attrs["attr"]
312 gik = 0
313 except KeyError:
314 gik = 1
315
316 return attrs.getLength() == 0 and \
317 attrs.getNames() == [] and \
318 attrs.getQNames() == [] and \
319 len(attrs) == 0 and \
320 not attrs.has_key("attr") and \
321 attrs.keys() == [] and \
322 attrs.get("attrs") == None and \
323 attrs.get("attrs", 25) == 25 and \
324 attrs.items() == [] and \
325 attrs.values() == [] and \
326 gvk and gvqk and gnqk and gik and gqnk
327
328def verify_attrs_wattr(attrs):
329 return attrs.getLength() == 1 and \
330 attrs.getNames() == ["attr"] and \
331 attrs.getQNames() == ["attr"] and \
332 len(attrs) == 1 and \
333 attrs.has_key("attr") and \
334 attrs.keys() == ["attr"] and \
335 attrs.get("attr") == "val" and \
336 attrs.get("attr", 25) == "val" and \
337 attrs.items() == [("attr", "val")] and \
338 attrs.values() == ["val"] and \
339 attrs.getValue("attr") == "val" and \
340 attrs.getValueByQName("attr") == "val" and \
341 attrs.getNameByQName("attr") == "attr" and \
342 attrs["attr"] == "val" and \
343 attrs.getQNameByName("attr") == "attr"
344
345def test_attrs_empty():
346 return verify_empty_attrs(AttributesImpl({}))
347
348def test_attrs_wattr():
349 return verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
350
351# ===== AttributesImpl
352
353def verify_empty_nsattrs(attrs):
354 try:
355 attrs.getValue((ns_uri, "attr"))
356 gvk = 0
357 except KeyError:
358 gvk = 1
359
360 try:
361 attrs.getValueByQName("ns:attr")
362 gvqk = 0
363 except KeyError:
364 gvqk = 1
365
366 try:
367 attrs.getNameByQName("ns:attr")
368 gnqk = 0
369 except KeyError:
370 gnqk = 1
371
372 try:
373 attrs.getQNameByName((ns_uri, "attr"))
374 gqnk = 0
375 except KeyError:
376 gqnk = 1
377
378 try:
379 attrs[(ns_uri, "attr")]
380 gik = 0
381 except KeyError:
382 gik = 1
383
384 return attrs.getLength() == 0 and \
385 attrs.getNames() == [] and \
386 attrs.getQNames() == [] and \
387 len(attrs) == 0 and \
388 not attrs.has_key((ns_uri, "attr")) and \
389 attrs.keys() == [] and \
390 attrs.get((ns_uri, "attr")) == None and \
391 attrs.get((ns_uri, "attr"), 25) == 25 and \
392 attrs.items() == [] and \
393 attrs.values() == [] and \
394 gvk and gvqk and gnqk and gik and gqnk
395
396def test_nsattrs_empty():
397 return verify_empty_nsattrs(AttributesNSImpl({}, {}))
398
399def test_nsattrs_wattr():
400 attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
401 {(ns_uri, "attr") : "ns:attr"})
402
403 return attrs.getLength() == 1 and \
404 attrs.getNames() == [(ns_uri, "attr")] and \
405 attrs.getQNames() == ["ns:attr"] and \
406 len(attrs) == 1 and \
407 attrs.has_key((ns_uri, "attr")) and \
408 attrs.keys() == [(ns_uri, "attr")] and \
409 attrs.get((ns_uri, "attr")) == "val" and \
410 attrs.get((ns_uri, "attr"), 25) == "val" and \
411 attrs.items() == [((ns_uri, "attr"), "val")] and \
412 attrs.values() == ["val"] and \
413 attrs.getValue((ns_uri, "attr")) == "val" and \
414 attrs.getValueByQName("ns:attr") == "val" and \
415 attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
416 attrs[(ns_uri, "attr")] == "val" and \
417 attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
418
419
Lars Gustäbel96753b32000-09-24 12:24:24 +0000420# ===== Main program
421
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000422def make_test_output():
423 parser = create_parser()
424 result = StringIO()
425 xmlgen = XMLGenerator(result)
426
427 parser.setContentHandler(xmlgen)
428 parser.parse("test.xml")
429
430 outf = open("test.xml.out", "w")
431 outf.write(result.getvalue())
432 outf.close()
433
Lars Gustäbel96753b32000-09-24 12:24:24 +0000434items = locals().items()
435items.sort()
436for (name, value) in items:
437 if name[ : 5] == "test_":
438 confirm(value(), name)
439
440print "%d tests, %d failures" % (tests, fails)
441if fails != 0:
442 raise TestFailed, "%d of %d tests failed" % (fails, tests)
Lars Gustäbelb7536d52000-09-24 18:53:56 +0000443
444make_test_output()