/[thuban]/branches/WIP-pyshapelib-bramz/test/test_save.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/test/test_save.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1245 - (show annotations)
Thu Jun 19 19:29:23 2003 UTC (21 years, 8 months ago) by bh
Original Path: trunk/thuban/test/test_save.py
File MIME type: text/x-python
File size: 13268 byte(s)
Add XML validation to some of the tests. Validation will only be
done if pyRXP is installed (http://reportlab.com/xml/pyrxp.html).
To make the DTD available to the test cases it's moved into
Resources/XML

* Resources/XML/thuban.dtd: New. This is now the real Thuban DTD
for versions up to and including 0.2. Two slight changes: added an
encoding specification and fixed the comment which refered to
GRASS, not Thuban

* test/xmlsupport.py: New support module for tests involving XML.
Currently there's a mix-in class for XML validation.

* test/test_xmlsupport.py: New. Tests for the xmlsupport module

* test/test_save.py (SaveSessionTest): Derive from ValidationTest
so that we can validate the
(SaveSessionTest.testEmptySession)
(SaveSessionTest.testSingleLayer)
(SaveSessionTest.testSingleLayer)
(SaveSessionTest.testLayerProjection)
(SaveSessionTest.testRasterLayer)
(SaveSessionTest.testClassifiedLayer): Validate the generated XML

* test/runtests.py (main): Call print_additional_summary instead
of print_garbage_information

* test/support.py (resource_dir): New function to return the
"Resource" subdirectory
(print_additional_summary): New function to combine several
summary functions
(run_tests): Use print_additional_summary instead of calling
print_garbage_information directly

1 # Copyright (c) 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 """
9 Test saving a thuban session as XML
10 """
11
12 __version__ = "$Revision$"
13 # $Source$
14 # $Id$
15
16 import os
17 import unittest
18 from StringIO import StringIO
19
20 import xml.sax
21 import xml.sax.handler
22 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
23
24 import xmlsupport
25
26 import support
27 support.initthuban()
28
29 from Thuban.Model.save import XMLWriter, save_session
30 from Thuban.Model.session import Session
31 from Thuban.Model.map import Map
32 from Thuban.Model.layer import Layer, RasterLayer
33 from Thuban.Model.proj import Projection
34
35 from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
36 ClassGroupProperties
37
38 from Thuban.Model.range import Range
39
40
41 class SaxEventLister(xml.sax.handler.ContentHandler):
42
43 def __init__(self):
44 self.eventlist = []
45
46 def startElementNS(self, name, qname, attrs):
47 items = attrs.items()
48 items.sort()
49 self.eventlist.append(("start", name, qname, items))
50
51 def endElementNS(self, name, qname):
52 self.eventlist.append(("end", name, qname))
53
54
55 def sax_eventlist(data):
56 """Return a list of SAX event generated for the XML data.
57 """
58 handler = SaxEventLister()
59 parser = make_parser()
60 parser.setContentHandler(handler)
61 parser.setErrorHandler(ErrorHandler())
62 parser.setFeature(xml.sax.handler.feature_namespaces, 1)
63
64 #
65 # see comment at the end of Thuban/Model/load.py
66 #
67 try:
68 parser.setFeature(xml.sax.handler.feature_validation, 0)
69 parser.setFeature(xml.sax.handler.feature_external_ges, 0)
70 parser.setFeature(xml.sax.handler.feature_external_pes, 0)
71 except SAXNotRecognizedException:
72 pass
73
74 inpsrc = xml.sax.InputSource()
75 inpsrc.setByteStream(StringIO(data))
76 parser.parse(inpsrc)
77
78 return handler.eventlist
79
80 class XMLWriterTest(unittest.TestCase):
81
82 def testEncode(self):
83 """Test XMLWriter.encode"""
84 writer = XMLWriter()
85 eq = self.assertEquals
86
87 eq(writer.encode("hello world"), "hello world")
88 eq(writer.encode(unicode("hello world")), unicode("hello world"))
89
90 eq(writer.encode("\x80\x90\xc2\x100"),
91 "\xc2\x80\xc2\x90\xc3\x82\x100")
92 eq(writer.encode(u"\x80\x90\xc2\x100"),
93 "\xc2\x80\xc2\x90\xc3\x82\x100")
94 eq(writer.encode(u"\xFF5E"), "\xc3\xbf5E")
95
96 eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
97 eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
98
99 class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
100 xmlsupport.ValidationTest):
101
102 def compare_xml(self, xml1, xml2):
103 self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))
104
105 def testEmptySession(self):
106 """Save an empty session"""
107 session = Session("empty session")
108 filename = self.temp_file_name("save_emptysession.thuban")
109 save_session(session, filename)
110 session.Destroy()
111
112 file = open(filename)
113 written_contents = file.read()
114 file.close()
115 self.compare_xml(written_contents,
116 '<?xml version="1.0" encoding="UTF-8"?>\n'
117 '<!DOCTYPE session SYSTEM "thuban.dtd">\n'
118 '<session title="empty session">\n</session>\n')
119
120 self.validate_data(written_contents)
121
122 def testSingleLayer(self):
123 """Save a session with a single map with a single layer"""
124 # deliberately put an apersand in the title :)
125 session = Session("single map&layer")
126 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
127 map = Map("Test Map", projection = proj)
128 session.AddMap(map)
129 # use shapefile from the example data
130 shpfile = os.path.join(os.path.dirname(__file__),
131 os.pardir, "Data", "iceland", "political.shp")
132 layer = Layer("My Layer", session.OpenShapefile(shpfile))
133 map.AddLayer(layer)
134
135 filename = self.temp_file_name("save_singlemap.thuban")
136 save_session(session, filename)
137
138 file = open(filename)
139 written_contents = file.read()
140 file.close()
141 expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
142 <!DOCTYPE session SYSTEM "thuban.dtd">
143 <session title="single map&amp;layer">
144 <map title="Test Map">
145 <projection name="Unknown">
146 <parameter value="zone=26"/>
147 <parameter value="proj=utm"/>
148 <parameter value="ellps=clrk66"/>
149 </projection>
150 <layer title="My Layer" filename="%s"
151 fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
152 </map>
153 </session>'''
154
155 expected_contents = expected_template % \
156 (os.path.join("..", "..", "Data", "iceland", "political.shp"),
157 "true")
158
159 #print written_contents
160 #print "********************************************"
161 #print expected_contents
162 self.compare_xml(written_contents, expected_contents)
163
164 self.validate_data(written_contents)
165
166 layer.SetVisible(False)
167 save_session(session, filename)
168
169 file = open(filename)
170 written_contents = file.read()
171 file.close()
172 expected_contents = expected_template % \
173 (os.path.join("..", "..", "Data", "iceland", "political.shp"),
174 "false")
175
176 #print written_contents
177 #print "********************************************"
178 #print expected_contents
179 self.compare_xml(written_contents, expected_contents)
180 self.validate_data(written_contents)
181
182 session.Destroy()
183
184 def testLayerProjection(self):
185 # deliberately put an apersand in the title :)
186 session = Session("single map&layer")
187 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
188 map = Map("Test Map", projection = proj)
189 session.AddMap(map)
190 # use shapefile from the example data
191 shpfile = os.path.join(os.path.dirname(__file__),
192 os.pardir, "Data", "iceland", "political.shp")
193 layer = Layer("My Layer", session.OpenShapefile(shpfile))
194 proj = Projection(["proj=lcc", "ellps=clrk66"], "Layer Projection")
195 layer.SetProjection(proj)
196 map.AddLayer(layer)
197
198 filename = self.temp_file_name("save_singlemap.thuban")
199 save_session(session, filename)
200 session.Destroy()
201
202 file = open(filename)
203 written_contents = file.read()
204 file.close()
205 expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
206 <!DOCTYPE session SYSTEM "thuban.dtd">
207 <session title="single map&amp;layer">
208 <map title="Test Map">
209 <projection name="Unknown">
210 <parameter value="zone=26"/>
211 <parameter value="proj=utm"/>
212 <parameter value="ellps=clrk66"/>
213 </projection>
214 <layer title="My Layer" filename="%s"
215 fill="None" stroke="#000000" stroke_width="1" visible="true">
216 <projection name="Layer Projection">
217 <parameter value="proj=lcc"/>
218 <parameter value="ellps=clrk66"/>
219 </projection>
220 </layer>
221 </map>
222 </session>''' % os.path.join("..", "..", "Data", "iceland",
223 "political.shp")
224 #print written_contents
225 #print "********************************************"
226 #print expected_contents
227 self.compare_xml(written_contents, expected_contents)
228
229 self.validate_data(written_contents)
230
231 def testRasterLayer(self):
232 # deliberately put an apersand in the title :)
233 session = Session("single map&layer")
234 map = Map("Test Map")
235 session.AddMap(map)
236 # use shapefile from the example data
237 imgfile = os.path.join(os.path.dirname(__file__),
238 os.pardir, "Data", "iceland", "island.tif")
239 layer = RasterLayer("My RasterLayer", imgfile)
240 map.AddLayer(layer)
241
242 filename = self.temp_file_name("save_singlemap.thuban")
243 save_session(session, filename)
244 session.Destroy()
245
246 file = open(filename)
247 written_contents = file.read()
248 file.close()
249 expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
250 <!DOCTYPE session SYSTEM "thuban.dtd">
251 <session title="single map&amp;layer">
252 <map title="Test Map">
253 <rasterlayer title="My RasterLayer" filename="%s"
254 visible="true">
255 </rasterlayer>
256 </map>
257 </session>''' % os.path.join(os.path.dirname(__file__),
258 os.pardir, "Data", "iceland",
259 "island.tif")
260 #print written_contents
261 #print "********************************************"
262 #print expected_contents
263 self.compare_xml(written_contents, expected_contents)
264
265 self.validate_data(written_contents)
266
267 def testClassifiedLayer(self):
268 """Save a session with a single map with a single layer
269 with a classificaton.
270 """
271 # deliberately put an apersand in the title :)
272 session = Session("single map&layer")
273 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
274 map = Map("Test Map", projection = proj)
275 session.AddMap(map)
276 # use shapefile from the example data
277 shpfile = os.path.join(os.path.dirname(__file__),
278 os.pardir, "Data", "iceland", "political.shp")
279 layer = Layer("My Layer", session.OpenShapefile(shpfile))
280 map.AddLayer(layer)
281
282 clazz = layer.GetClassification()
283
284 clazz.SetField("AREA")
285
286 clazz.AppendGroup(ClassGroupSingleton(42,
287 ClassGroupProperties(),
288 "single"))
289 clazz.AppendGroup(ClassGroupSingleton("text",
290 ClassGroupProperties(),
291 "single-text"))
292
293 clazz.AppendGroup(ClassGroupRange(0, 42,
294 ClassGroupProperties(),
295 "range"))
296
297 range = ClassGroupRange(Range("[0;42]"))
298 range.SetProperties(ClassGroupProperties())
299 range.SetLabel("new-range")
300 clazz.AppendGroup(range)
301
302 filename = self.temp_file_name("save_singlemap.thuban")
303 save_session(session, filename)
304
305 file = open(filename)
306 written_contents = file.read()
307 file.close()
308 expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
309 <!DOCTYPE session SYSTEM "thuban.dtd">
310 <session title="single map&amp;layer">
311 <map title="Test Map">
312 <projection name="Unknown">
313 <parameter value="zone=26"/>
314 <parameter value="proj=utm"/>
315 <parameter value="ellps=clrk66"/>
316 </projection>
317 <layer title="My Layer" filename="%s"
318 fill="None" stroke="#000000" stroke_width="1" visible="%s">
319 <classification field="AREA" field_type="double">
320 <clnull label="">
321 <cldata fill="None" stroke="#000000" stroke_width="1"/>
322 </clnull>
323 <clpoint value="42" label="single">
324 <cldata fill="None" stroke="#000000" stroke_width="1"/>
325 </clpoint>
326 <clpoint value="text" label="single-text">
327 <cldata fill="None" stroke="#000000" stroke_width="1"/>
328 </clpoint>
329 <clrange range="[0;42[" label="range">
330 <cldata fill="None" stroke="#000000" stroke_width="1"/>
331 </clrange>
332 <clrange range="[0;42]" label="new-range">
333 <cldata fill="None" stroke="#000000" stroke_width="1"/>
334 </clrange>
335 </classification>
336 </layer>
337 </map>
338 </session>'''
339
340 expected_contents = expected_template % \
341 (os.path.join("..", "..", "Data", "iceland", "political.shp"),
342 "true")
343
344 #print written_contents
345 #print "********************************************"
346 #print expected_contents
347 self.compare_xml(written_contents, expected_contents)
348
349 self.validate_data(written_contents)
350
351 session.Destroy()
352
353
354 if __name__ == "__main__":
355 # Fake the __file__ global because it's needed by a test
356 import sys
357 __file__ = sys.argv[0]
358 support.run_tests()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26