/[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 1375 - (hide annotations)
Tue Jul 8 10:53:05 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: 20143 byte(s)
* Resources/XML/thuban-0.9.dtd: New. This will become the DTD for
0.9.

* Thuban/Model/transientdb.py (TransientJoinedTable.JoinType):
New. Return the join type

* Thuban/Model/save.py (SessionSaver.write_session): Use new 0.9
DTD
(SessionSaver.write_data_containers): Save the join type for
joined tables

* Thuban/Model/load.py (SessionLoader.__init__): Add the new 0.9
namespace
(SessionLoader.start_jointable): Handle the jointype attribute

* test/test_load_0_8.py: New. Effectively a copy of test_load.py
as of Thuban 0.8. These are now tests to determine whether Thuban
can still read files generated by Thuban 0.8

* test/test_load.py (LoadSessionTest.dtd)
(TestSingleLayer.file_contents)
(TestLayerVisibility.file_contents, TestLabels.file_contents)
(TestLayerProjection.file_contents)
(TestRasterLayer.file_contents, TestJoinedTable.file_contents)
(TestJoinedTable.file_contents)
(TestLoadError.file_contents): Update for new DTD
(TestJoinedTable.file_contents, TestJoinedTable.setUp): Add test
for new join type attribute

* test/test_save.py (SaveSessionTest.dtd)
(SaveSessionTest.testEmptySession)
(SaveSessionTest.testSingleLayer)
(SaveSessionTest.testLayerProjection)
(SaveSessionTest.testRasterLayer)
(SaveSessionTest.testClassifiedLayer)
(SaveSessionTest.test_dbf_table)
(SaveSessionTest.test_joined_table): Update for new DTD
(SaveSessionTest.test_joined_table): Add test for new join type
attribute

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 jonathan 947 filename = self.temp_file_name("save_singlemap.thuban")
230     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 1268 </session>''' % os.path.join(os.path.dirname(__file__),
246 jonathan 947 os.pardir, "Data", "iceland",
247     "island.tif")
248     #print written_contents
249     #print "********************************************"
250     #print expected_contents
251     self.compare_xml(written_contents, expected_contents)
252 jonathan 755
253 bh 1245 self.validate_data(written_contents)
254    
255 jonathan 1168 def testClassifiedLayer(self):
256     """Save a session with a single map with a single layer
257     with a classificaton.
258     """
259     # deliberately put an apersand in the title :)
260     session = Session("single map&layer")
261     proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
262     map = Map("Test Map", projection = proj)
263     session.AddMap(map)
264     # use shapefile from the example data
265     shpfile = os.path.join(os.path.dirname(__file__),
266     os.pardir, "Data", "iceland", "political.shp")
267     layer = Layer("My Layer", session.OpenShapefile(shpfile))
268     map.AddLayer(layer)
269 jonathan 755
270 jonathan 1168 clazz = layer.GetClassification()
271    
272 jonathan 1348 clazz.SetFieldInfo("AREA", None)
273 jonathan 1168
274     clazz.AppendGroup(ClassGroupSingleton(42,
275     ClassGroupProperties(),
276     "single"))
277     clazz.AppendGroup(ClassGroupSingleton("text",
278     ClassGroupProperties(),
279     "single-text"))
280    
281 jonathan 1357 clazz.AppendGroup(ClassGroupRange((0, 42),
282 jonathan 1168 ClassGroupProperties(),
283     "range"))
284    
285     range = ClassGroupRange(Range("[0;42]"))
286     range.SetProperties(ClassGroupProperties())
287     range.SetLabel("new-range")
288     clazz.AppendGroup(range)
289    
290     filename = self.temp_file_name("save_singlemap.thuban")
291     save_session(session, filename)
292    
293     file = open(filename)
294     written_contents = file.read()
295     file.close()
296     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
297 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
298 bh 1268 <session title="single map&amp;layer"
299 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
300 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
301 jonathan 1168 <map title="Test Map">
302     <projection name="Unknown">
303     <parameter value="zone=26"/>
304     <parameter value="proj=utm"/>
305     <parameter value="ellps=clrk66"/>
306     </projection>
307 bh 1268 <layer title="My Layer" shapestore="D1"
308 jonathan 1168 fill="None" stroke="#000000" stroke_width="1" visible="%s">
309     <classification field="AREA" field_type="double">
310     <clnull label="">
311     <cldata fill="None" stroke="#000000" stroke_width="1"/>
312     </clnull>
313     <clpoint value="42" label="single">
314     <cldata fill="None" stroke="#000000" stroke_width="1"/>
315     </clpoint>
316     <clpoint value="text" label="single-text">
317     <cldata fill="None" stroke="#000000" stroke_width="1"/>
318     </clpoint>
319     <clrange range="[0;42[" label="range">
320     <cldata fill="None" stroke="#000000" stroke_width="1"/>
321     </clrange>
322     <clrange range="[0;42]" label="new-range">
323     <cldata fill="None" stroke="#000000" stroke_width="1"/>
324     </clrange>
325     </classification>
326     </layer>
327     </map>
328 bh 1245 </session>'''
329    
330 jonathan 1168 expected_contents = expected_template % \
331     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
332     "true")
333    
334     #print written_contents
335     #print "********************************************"
336     #print expected_contents
337     self.compare_xml(written_contents, expected_contents)
338    
339 bh 1245 self.validate_data(written_contents)
340    
341 jonathan 1168 session.Destroy()
342    
343 bh 1268 def test_dbf_table(self):
344     """Test saving a session with a dbf table link"""
345     session = Session("a DBF Table session")
346     # use shapefile from the example data
347     dbffile = os.path.join(os.path.dirname(__file__),
348     os.pardir, "Data", "iceland", "political.dbf")
349     table = session.AddTable(DBFTable(dbffile))
350 jonathan 1168
351 bh 1268 filename = self.temp_file_name("save_singletable.thuban")
352     save_session(session, filename)
353    
354     file = open(filename)
355     written_contents = file.read()
356     file.close()
357     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
358 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
359 bh 1268 <session title="a DBF Table session"
360 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
361 bh 1268 <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
362     </session>'''
363    
364     expected_contents = expected_template % dbffile
365     self.compare_xml(written_contents, expected_contents)
366    
367     def test_joined_table(self):
368     """Test saving a session with joined table"""
369     # Create a simple table to use in the join
370     dbffile = self.temp_file_name("save_joinedtable.dbf")
371     dbf = dbflib.create(dbffile)
372     dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
373     dbf.add_field("TEXT", dbflib.FTString, 10, 0)
374     dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
375     dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
376     dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
377     dbf.close()
378    
379     # Create the session and a map
380     session = Session("A Joined Table session")
381     try:
382     map = Map("Test Map")
383     session.AddMap(map)
384    
385     # Add the dbf file to the session
386     dbftable = session.AddTable(DBFTable(dbffile))
387    
388     # Create a layer with the shapefile to use in the join
389     shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
390     os.pardir, "Data", "iceland",
391     "roads-line.shp")
392     layer = Layer("My Layer", session.OpenShapefile(shpfile))
393     map.AddLayer(layer)
394    
395     # Do the join
396     store = layer.ShapeStore()
397     #for col in store.Table().Columns():
398     # print col.name
399     joined = TransientJoinedTable(session.TransientDB(),
400     store.Table(), "RDLNTYPE",
401 bh 1375 dbftable, "RDTYPE",
402     outer_join = True)
403 bh 1268 store = session.AddShapeStore(DerivedShapeStore(store, joined))
404     layer.SetShapeStore(store)
405    
406     # Save the session
407     filename = self.temp_file_name("save_joinedtable.thuban")
408     save_session(session, filename)
409    
410     # Read it back and compare
411     file = open(filename)
412     written_contents = file.read()
413     file.close()
414     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
415 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
416 bh 1268 <session title="A Joined Table session"
417 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
418 bh 1268 <fileshapesource filename="%(shpfile)s"
419     filetype="shapefile" id="D142197204"/>
420     <filetable filename="%(dbffile)s"
421     title="save_joinedtable"
422     filetype="DBF" id="D141881756"/>
423     <jointable id="D142180284"
424     title="Join of roads-line and save_joinedtable"
425     leftcolumn="RDLNTYPE" left="D142197204"
426 bh 1375 rightcolumn="RDTYPE" right="D141881756"
427     jointype="LEFT OUTER" />
428 bh 1268 <derivedshapesource id="D141915644"
429     table="D142180284"
430     shapesource="D142197204"/>
431     <map title="Test Map">
432     <layer title="My Layer"
433     shapestore="D141915644" visible="true"
434     stroke="#000000" stroke_width="1" fill="None"/>
435     </map>
436     </session>'''
437    
438     expected_contents = expected_template % {
439     "dbffile": relative_filename(self.temp_dir(), dbffile),
440     "shpfile": relative_filename(self.temp_dir(), shpfile)
441     }
442     self.compare_xml(written_contents, expected_contents)
443     finally:
444     session.Destroy()
445     session = None
446    
447    
448     class MockDataStore:
449    
450     """A very simple data store that only has dependencies"""
451    
452     def __init__(self, name, *dependencies):
453     self.name = name
454     self.dependencies = dependencies
455    
456     def __repr__(self):
457     return self.name
458    
459     def Dependencies(self):
460     return self.dependencies
461    
462    
463     class TestStoreSort(unittest.TestCase):
464    
465     def check_sort(self, containers, sorted):
466     """Check whether the list of data containers is sorted"""
467     # check whether sorted is in the right order
468     seen = {}
469     for container in sorted:
470     self.failIf(id(container) in seen,
471     "Container %r at least twice in %r" % (container,
472     sorted))
473     for dep in container.Dependencies():
474     self.assert_(id(dep) in seen,
475     "Dependency %r of %r not yet seen" % (dep,
476     container))
477     seen[id(container)] = 1
478     # check whether all of containers is in sorted
479     for container in containers:
480     self.assert_(id(container) in seen,
481     "Container %r in containers but not in sorted")
482     self.assertEquals(len(containers), len(sorted))
483    
484     def test_sort_data_stores(self):
485     """Test Thuban.Model.save.sort_data_stores"""
486     d1 = MockDataStore("d1")
487     d2 = MockDataStore("d2")
488     d3 = MockDataStore("d3", d1)
489     d4 = MockDataStore("d4", d1, d3)
490    
491     containers = [d4, d1, d2, d3]
492     self.check_sort(containers, sort_data_stores(containers))
493     containers = [d1, d3, d2, d4]
494     self.check_sort(containers, sort_data_stores(containers))
495    
496    
497    
498 bh 292 if __name__ == "__main__":
499     # Fake the __file__ global because it's needed by a test
500     import sys
501     __file__ = sys.argv[0]
502 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