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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1599 - (hide annotations)
Mon Aug 18 12:45:28 2003 UTC (21 years, 6 months ago) by bh
Original Path: trunk/thuban/test/test_save.py
File MIME type: text/x-python
File size: 21244 byte(s)
Fix some bugs in Thuban and the test suite that were uncovered by
changes introduced in Python 2.3:

* Thuban/Model/table.py (DBFTable.__init__): Make sure the
filename is an absolute name

* Thuban/Model/layer.py (RasterLayer.__init__): Make sure the
filename is an absolute name

* test/test_save.py (SaveSessionTest.testRasterLayer): Use a
unique filename to save to and use the correct relative filename
in the expected output.
(SaveSessionTest.test_dbf_table): Use the correct relative
filename in the expected output.

* test/test_layer.py (TestLayer.test_raster_layer): Update the
test to check whether the filename is absolute.

1 bh 723 # Copyright (c) 2002, 2003 by Intevation GmbH
2 bh 292 # 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 jonathan 530 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
23 bh 292
24 bh 1245 import xmlsupport
25    
26 bh 292 import support
27     support.initthuban()
28    
29 bh 1268 import dbflib
30    
31     from Thuban.Lib.fileutil import relative_filename
32     from Thuban.Model.save import XMLWriter, save_session, sort_data_stores
33 bh 292 from Thuban.Model.session import Session
34     from Thuban.Model.map import Map
35 jonathan 947 from Thuban.Model.layer import Layer, RasterLayer
36 bh 292 from Thuban.Model.proj import Projection
37 bh 1268 from Thuban.Model.table import DBFTable
38     from Thuban.Model.transientdb import TransientJoinedTable
39     from Thuban.Model.data import DerivedShapeStore
40 bh 292
41 jonathan 1168 from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
42     ClassGroupProperties
43 bh 292
44 jonathan 1168 from Thuban.Model.range import Range
45    
46    
47     class XMLWriterTest(unittest.TestCase):
48    
49     def testEncode(self):
50     """Test XMLWriter.encode"""
51     writer = XMLWriter()
52 jonathan 1200 eq = self.assertEquals
53 jonathan 1168
54 jonathan 1200 eq(writer.encode("hello world"), "hello world")
55     eq(writer.encode(unicode("hello world")), unicode("hello world"))
56 jonathan 1173
57 jonathan 1200 eq(writer.encode("\x80\x90\xc2\x100"),
58     "\xc2\x80\xc2\x90\xc3\x82\x100")
59     eq(writer.encode(u"\x80\x90\xc2\x100"),
60     "\xc2\x80\xc2\x90\xc3\x82\x100")
61     eq(writer.encode(u"\xFF5E"), "\xc3\xbf5E")
62 jonathan 1173
63 jonathan 1200 eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
64     eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
65 jonathan 1168
66 bh 1245 class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
67     xmlsupport.ValidationTest):
68 bh 292
69 bh 1375 dtd = "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
70 bh 1268 thubanids = [((dtd, n), (None, "id")) for n in
71     ["fileshapesource", "filetable", "jointable",
72     "derivedshapesource"]]
73     thubanidrefs = [((dtd, n), (None, m)) for n, m in
74     [("layer", "shapestore"),
75     ("jointable", "left"),
76     ("jointable", "right"),
77     ("derivedshapesource", "table"),
78     ("derivedshapesource", "shapesource")]]
79     del n, m, dtd
80    
81 bh 292 def compare_xml(self, xml1, xml2):
82 bh 1375 list1 = xmlsupport.sax_eventlist(xml1, ids = self.thubanids,
83     idrefs = self.thubanidrefs)
84     list2 = xmlsupport.sax_eventlist(xml2, ids = self.thubanids,
85     idrefs = self.thubanidrefs)
86     if list1 != list2:
87     for a, b in zip(list1, list2):
88     if a != b:
89     self.fail("%r != %r" % (a, b))
90 bh 292
91 bh 1375
92 bh 292 def testEmptySession(self):
93     """Save an empty session"""
94     session = Session("empty session")
95     filename = self.temp_file_name("save_emptysession.thuban")
96     save_session(session, filename)
97     session.Destroy()
98    
99     file = open(filename)
100     written_contents = file.read()
101     file.close()
102     self.compare_xml(written_contents,
103     '<?xml version="1.0" encoding="UTF-8"?>\n'
104 bh 1375 '<!DOCTYPE session SYSTEM "thuban-0.9.dtd">\n'
105 bh 1268 '<session title="empty session" '
106 bh 1375 'xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">'
107 bh 1268 '\n</session>\n')
108 bh 292
109 bh 1245 self.validate_data(written_contents)
110    
111 bh 292 def testSingleLayer(self):
112     """Save a session with a single map with a single layer"""
113     # deliberately put an apersand in the title :)
114     session = Session("single map&layer")
115     proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
116     map = Map("Test Map", projection = proj)
117     session.AddMap(map)
118     # use shapefile from the example data
119     shpfile = os.path.join(os.path.dirname(__file__),
120     os.pardir, "Data", "iceland", "political.shp")
121 bh 723 layer = Layer("My Layer", session.OpenShapefile(shpfile))
122 bh 292 map.AddLayer(layer)
123    
124     filename = self.temp_file_name("save_singlemap.thuban")
125     save_session(session, filename)
126    
127     file = open(filename)
128     written_contents = file.read()
129     file.close()
130 jonathan 775 expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
131 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
132 bh 1268 <session title="single map&amp;layer"
133 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
134 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
135 bh 292 <map title="Test Map">
136 jonathan 755 <projection name="Unknown">
137 bh 292 <parameter value="zone=26"/>
138     <parameter value="proj=utm"/>
139     <parameter value="ellps=clrk66"/>
140     </projection>
141 bh 1268 <layer title="My Layer" shapestore="D1"
142 jonathan 775 fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
143 bh 292 </map>
144 bh 1268 </session>'''
145    
146 jonathan 775 expected_contents = expected_template % \
147     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
148     "true")
149    
150 bh 292 self.compare_xml(written_contents, expected_contents)
151    
152 bh 1245 self.validate_data(written_contents)
153    
154 jonathan 775 layer.SetVisible(False)
155     save_session(session, filename)
156    
157     file = open(filename)
158     written_contents = file.read()
159     file.close()
160     expected_contents = expected_template % \
161     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
162     "false")
163     self.compare_xml(written_contents, expected_contents)
164 bh 1245 self.validate_data(written_contents)
165 jonathan 775
166     session.Destroy()
167    
168 jonathan 755 def testLayerProjection(self):
169 bh 1268 """Test saving layers with projections"""
170 jonathan 755 # deliberately put an apersand in the title :)
171     session = Session("single map&layer")
172     proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
173     map = Map("Test Map", projection = proj)
174     session.AddMap(map)
175     # use shapefile from the example data
176     shpfile = os.path.join(os.path.dirname(__file__),
177     os.pardir, "Data", "iceland", "political.shp")
178     layer = Layer("My Layer", session.OpenShapefile(shpfile))
179     proj = Projection(["proj=lcc", "ellps=clrk66"], "Layer Projection")
180     layer.SetProjection(proj)
181     map.AddLayer(layer)
182 bh 292
183 bh 1268 filename = self.temp_file_name("save_layerproj.thuban")
184 jonathan 755 save_session(session, filename)
185     session.Destroy()
186 bh 292
187 jonathan 755 file = open(filename)
188     written_contents = file.read()
189     file.close()
190     expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
191 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
192 bh 1268 <session title="single map&amp;layer"
193 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
194 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
195 jonathan 755 <map title="Test Map">
196     <projection name="Unknown">
197     <parameter value="zone=26"/>
198     <parameter value="proj=utm"/>
199     <parameter value="ellps=clrk66"/>
200     </projection>
201 bh 1268 <layer title="My Layer" shapestore="D1"
202 jonathan 775 fill="None" stroke="#000000" stroke_width="1" visible="true">
203 jonathan 755 <projection name="Layer Projection">
204     <parameter value="proj=lcc"/>
205     <parameter value="ellps=clrk66"/>
206     </projection>
207     </layer>
208     </map>
209     </session>''' % os.path.join("..", "..", "Data", "iceland",
210     "political.shp")
211     #print written_contents
212     #print "********************************************"
213     #print expected_contents
214     self.compare_xml(written_contents, expected_contents)
215    
216 bh 1245 self.validate_data(written_contents)
217    
218 jonathan 947 def testRasterLayer(self):
219     # deliberately put an apersand in the title :)
220     session = Session("single map&layer")
221     map = Map("Test Map")
222     session.AddMap(map)
223     # use shapefile from the example data
224     imgfile = os.path.join(os.path.dirname(__file__),
225     os.pardir, "Data", "iceland", "island.tif")
226     layer = RasterLayer("My RasterLayer", imgfile)
227     map.AddLayer(layer)
228 bh 1245
229 bh 1599 filename = self.temp_file_name("%s.thuban" % self.id())
230 jonathan 947 save_session(session, filename)
231     session.Destroy()
232 bh 1245
233 jonathan 947 file = open(filename)
234     written_contents = file.read()
235     file.close()
236     expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
237 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
238 bh 1268 <session title="single map&amp;layer"
239 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
240 jonathan 947 <map title="Test Map">
241 bh 1268 <rasterlayer title="My RasterLayer" filename="%s"
242 jonathan 947 visible="true">
243     </rasterlayer>
244     </map>
245 bh 1599 </session>''' % os.path.join(os.pardir, os.pardir, "Data", "iceland",
246 jonathan 947 "island.tif")
247     #print written_contents
248     #print "********************************************"
249     #print expected_contents
250     self.compare_xml(written_contents, expected_contents)
251 jonathan 755
252 bh 1245 self.validate_data(written_contents)
253    
254 jonathan 1168 def testClassifiedLayer(self):
255 bh 1417 """Save a session with a single map with classifications"""
256 jonathan 1168 # deliberately put an apersand in the title :)
257 bh 1417 session = Session("Map with Classifications")
258 jonathan 1168 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
259     map = Map("Test Map", projection = proj)
260     session.AddMap(map)
261     # use shapefile from the example data
262     shpfile = os.path.join(os.path.dirname(__file__),
263     os.pardir, "Data", "iceland", "political.shp")
264     layer = Layer("My Layer", session.OpenShapefile(shpfile))
265     map.AddLayer(layer)
266 bh 1417 layer2 = Layer("My Layer", layer.ShapeStore())
267     map.AddLayer(layer2)
268 jonathan 755
269 jonathan 1168 clazz = layer.GetClassification()
270    
271 bh 1452 layer.SetClassificationColumn("AREA")
272 jonathan 1168
273 bh 1417 clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
274     "single"))
275     clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
276     "single-text"))
277 jonathan 1168
278 jonathan 1357 clazz.AppendGroup(ClassGroupRange((0, 42),
279 jonathan 1168 ClassGroupProperties(),
280     "range"))
281    
282     range = ClassGroupRange(Range("[0;42]"))
283     range.SetProperties(ClassGroupProperties())
284     range.SetLabel("new-range")
285     clazz.AppendGroup(range)
286    
287 bh 1417
288     clazz = layer2.GetClassification()
289 bh 1452 layer2.SetClassificationColumn("POPYCOUN")
290 bh 1417
291     # Classification with Latin 1 text
292     clazz.AppendGroup(ClassGroupSingleton('\xe4\xf6\xfc', # ae, oe, ue
293     ClassGroupProperties(),
294     '\xdcml\xe4uts')) # Uemlaeuts
295    
296    
297     filename = self.temp_file_name("%s.thuban" % self.id())
298 jonathan 1168 save_session(session, filename)
299    
300     file = open(filename)
301     written_contents = file.read()
302     file.close()
303     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
304 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
305 bh 1417 <session title="Map with Classifications"
306 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
307 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
308 jonathan 1168 <map title="Test Map">
309     <projection name="Unknown">
310     <parameter value="zone=26"/>
311     <parameter value="proj=utm"/>
312     <parameter value="ellps=clrk66"/>
313     </projection>
314 bh 1268 <layer title="My Layer" shapestore="D1"
315 jonathan 1168 fill="None" stroke="#000000" stroke_width="1" visible="%s">
316     <classification field="AREA" field_type="double">
317     <clnull label="">
318     <cldata fill="None" stroke="#000000" stroke_width="1"/>
319     </clnull>
320     <clpoint value="42" label="single">
321     <cldata fill="None" stroke="#000000" stroke_width="1"/>
322     </clpoint>
323     <clpoint value="text" label="single-text">
324     <cldata fill="None" stroke="#000000" stroke_width="1"/>
325     </clpoint>
326     <clrange range="[0;42[" label="range">
327     <cldata fill="None" stroke="#000000" stroke_width="1"/>
328     </clrange>
329     <clrange range="[0;42]" label="new-range">
330     <cldata fill="None" stroke="#000000" stroke_width="1"/>
331     </clrange>
332     </classification>
333     </layer>
334 bh 1417 <layer title="My Layer" shapestore="D1"
335     fill="None" stroke="#000000" stroke_width="1" visible="true">
336     <classification field="POPYCOUN" field_type="string">
337     <clnull label="">
338     <cldata fill="None" stroke="#000000" stroke_width="1"/>
339     </clnull>
340     <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
341     label="\xc3\x9cml\xc3\xa4uts">
342     <cldata fill="None" stroke="#000000" stroke_width="1"/>
343     </clpoint>
344     </classification>
345     </layer>
346 jonathan 1168 </map>
347 bh 1245 </session>'''
348    
349 jonathan 1168 expected_contents = expected_template % \
350     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
351     "true")
352    
353     #print written_contents
354     #print "********************************************"
355     #print expected_contents
356     self.compare_xml(written_contents, expected_contents)
357    
358 bh 1245 self.validate_data(written_contents)
359    
360 jonathan 1168 session.Destroy()
361    
362 bh 1268 def test_dbf_table(self):
363     """Test saving a session with a dbf table link"""
364     session = Session("a DBF Table session")
365     # use shapefile from the example data
366     dbffile = os.path.join(os.path.dirname(__file__),
367     os.pardir, "Data", "iceland", "political.dbf")
368     table = session.AddTable(DBFTable(dbffile))
369 jonathan 1168
370 bh 1268 filename = self.temp_file_name("save_singletable.thuban")
371     save_session(session, filename)
372    
373     file = open(filename)
374     written_contents = file.read()
375     file.close()
376     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
377 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
378 bh 1268 <session title="a DBF Table session"
379 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
380 bh 1268 <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
381     </session>'''
382    
383 bh 1599 expected_contents = (expected_template
384     % os.path.join(os.pardir, os.pardir, "Data",
385     "iceland", "political.dbf"))
386 bh 1268 self.compare_xml(written_contents, expected_contents)
387    
388     def test_joined_table(self):
389     """Test saving a session with joined table"""
390     # Create a simple table to use in the join
391     dbffile = self.temp_file_name("save_joinedtable.dbf")
392     dbf = dbflib.create(dbffile)
393     dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
394     dbf.add_field("TEXT", dbflib.FTString, 10, 0)
395     dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
396     dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
397     dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
398     dbf.close()
399    
400     # Create the session and a map
401     session = Session("A Joined Table session")
402     try:
403     map = Map("Test Map")
404     session.AddMap(map)
405    
406     # Add the dbf file to the session
407     dbftable = session.AddTable(DBFTable(dbffile))
408    
409     # Create a layer with the shapefile to use in the join
410     shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
411     os.pardir, "Data", "iceland",
412     "roads-line.shp")
413     layer = Layer("My Layer", session.OpenShapefile(shpfile))
414     map.AddLayer(layer)
415    
416     # Do the join
417     store = layer.ShapeStore()
418     #for col in store.Table().Columns():
419     # print col.name
420     joined = TransientJoinedTable(session.TransientDB(),
421     store.Table(), "RDLNTYPE",
422 bh 1375 dbftable, "RDTYPE",
423     outer_join = True)
424 bh 1268 store = session.AddShapeStore(DerivedShapeStore(store, joined))
425     layer.SetShapeStore(store)
426    
427     # Save the session
428     filename = self.temp_file_name("save_joinedtable.thuban")
429     save_session(session, filename)
430    
431     # Read it back and compare
432     file = open(filename)
433     written_contents = file.read()
434     file.close()
435     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
436 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
437 bh 1268 <session title="A Joined Table session"
438 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
439 bh 1268 <fileshapesource filename="%(shpfile)s"
440     filetype="shapefile" id="D142197204"/>
441     <filetable filename="%(dbffile)s"
442     title="save_joinedtable"
443     filetype="DBF" id="D141881756"/>
444     <jointable id="D142180284"
445     title="Join of roads-line and save_joinedtable"
446     leftcolumn="RDLNTYPE" left="D142197204"
447 bh 1375 rightcolumn="RDTYPE" right="D141881756"
448     jointype="LEFT OUTER" />
449 bh 1268 <derivedshapesource id="D141915644"
450     table="D142180284"
451     shapesource="D142197204"/>
452     <map title="Test Map">
453     <layer title="My Layer"
454     shapestore="D141915644" visible="true"
455     stroke="#000000" stroke_width="1" fill="None"/>
456     </map>
457     </session>'''
458    
459     expected_contents = expected_template % {
460     "dbffile": relative_filename(self.temp_dir(), dbffile),
461     "shpfile": relative_filename(self.temp_dir(), shpfile)
462     }
463     self.compare_xml(written_contents, expected_contents)
464     finally:
465     session.Destroy()
466     session = None
467    
468    
469     class MockDataStore:
470    
471     """A very simple data store that only has dependencies"""
472    
473     def __init__(self, name, *dependencies):
474     self.name = name
475     self.dependencies = dependencies
476    
477     def __repr__(self):
478     return self.name
479    
480     def Dependencies(self):
481     return self.dependencies
482    
483    
484     class TestStoreSort(unittest.TestCase):
485    
486     def check_sort(self, containers, sorted):
487     """Check whether the list of data containers is sorted"""
488     # check whether sorted is in the right order
489     seen = {}
490     for container in sorted:
491     self.failIf(id(container) in seen,
492     "Container %r at least twice in %r" % (container,
493     sorted))
494     for dep in container.Dependencies():
495     self.assert_(id(dep) in seen,
496     "Dependency %r of %r not yet seen" % (dep,
497     container))
498     seen[id(container)] = 1
499     # check whether all of containers is in sorted
500     for container in containers:
501     self.assert_(id(container) in seen,
502     "Container %r in containers but not in sorted")
503     self.assertEquals(len(containers), len(sorted))
504    
505     def test_sort_data_stores(self):
506     """Test Thuban.Model.save.sort_data_stores"""
507     d1 = MockDataStore("d1")
508     d2 = MockDataStore("d2")
509     d3 = MockDataStore("d3", d1)
510     d4 = MockDataStore("d4", d1, d3)
511    
512     containers = [d4, d1, d2, d3]
513     self.check_sort(containers, sort_data_stores(containers))
514     containers = [d1, d3, d2, d4]
515     self.check_sort(containers, sort_data_stores(containers))
516    
517    
518    
519 bh 292 if __name__ == "__main__":
520     # Fake the __file__ global because it's needed by a test
521     import sys
522     __file__ = sys.argv[0]
523 bh 723 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