/[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 1375 - (show 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 # 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 import dbflib
30
31 from Thuban.Lib.fileutil import relative_filename
32 from Thuban.Model.save import XMLWriter, save_session, sort_data_stores
33 from Thuban.Model.session import Session
34 from Thuban.Model.map import Map
35 from Thuban.Model.layer import Layer, RasterLayer
36 from Thuban.Model.proj import Projection
37 from Thuban.Model.table import DBFTable
38 from Thuban.Model.transientdb import TransientJoinedTable
39 from Thuban.Model.data import DerivedShapeStore
40
41 from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
42 ClassGroupProperties
43
44 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 eq = self.assertEquals
53
54 eq(writer.encode("hello world"), "hello world")
55 eq(writer.encode(unicode("hello world")), unicode("hello world"))
56
57 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
63 eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
64 eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
65
66 class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
67 xmlsupport.ValidationTest):
68
69 dtd = "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
70 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 def compare_xml(self, xml1, xml2):
82 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
91
92 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 '<!DOCTYPE session SYSTEM "thuban-0.9.dtd">\n'
105 '<session title="empty session" '
106 'xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">'
107 '\n</session>\n')
108
109 self.validate_data(written_contents)
110
111 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 layer = Layer("My Layer", session.OpenShapefile(shpfile))
122 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 expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
131 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
132 <session title="single map&amp;layer"
133 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
134 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
135 <map title="Test Map">
136 <projection name="Unknown">
137 <parameter value="zone=26"/>
138 <parameter value="proj=utm"/>
139 <parameter value="ellps=clrk66"/>
140 </projection>
141 <layer title="My Layer" shapestore="D1"
142 fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
143 </map>
144 </session>'''
145
146 expected_contents = expected_template % \
147 (os.path.join("..", "..", "Data", "iceland", "political.shp"),
148 "true")
149
150 self.compare_xml(written_contents, expected_contents)
151
152 self.validate_data(written_contents)
153
154 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 self.validate_data(written_contents)
165
166 session.Destroy()
167
168 def testLayerProjection(self):
169 """Test saving layers with projections"""
170 # 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
183 filename = self.temp_file_name("save_layerproj.thuban")
184 save_session(session, filename)
185 session.Destroy()
186
187 file = open(filename)
188 written_contents = file.read()
189 file.close()
190 expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
191 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
192 <session title="single map&amp;layer"
193 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
194 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
195 <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 <layer title="My Layer" shapestore="D1"
202 fill="None" stroke="#000000" stroke_width="1" visible="true">
203 <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 self.validate_data(written_contents)
217
218 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
229 filename = self.temp_file_name("save_singlemap.thuban")
230 save_session(session, filename)
231 session.Destroy()
232
233 file = open(filename)
234 written_contents = file.read()
235 file.close()
236 expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
237 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
238 <session title="single map&amp;layer"
239 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
240 <map title="Test Map">
241 <rasterlayer title="My RasterLayer" filename="%s"
242 visible="true">
243 </rasterlayer>
244 </map>
245 </session>''' % os.path.join(os.path.dirname(__file__),
246 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
253 self.validate_data(written_contents)
254
255 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
270 clazz = layer.GetClassification()
271
272 clazz.SetFieldInfo("AREA", None)
273
274 clazz.AppendGroup(ClassGroupSingleton(42,
275 ClassGroupProperties(),
276 "single"))
277 clazz.AppendGroup(ClassGroupSingleton("text",
278 ClassGroupProperties(),
279 "single-text"))
280
281 clazz.AppendGroup(ClassGroupRange((0, 42),
282 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 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
298 <session title="single map&amp;layer"
299 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
300 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
301 <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 <layer title="My Layer" shapestore="D1"
308 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 </session>'''
329
330 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 self.validate_data(written_contents)
340
341 session.Destroy()
342
343 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
351 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 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
359 <session title="a DBF Table session"
360 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
361 <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 dbftable, "RDTYPE",
402 outer_join = True)
403 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 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
416 <session title="A Joined Table session"
417 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
418 <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 rightcolumn="RDTYPE" right="D141881756"
427 jointype="LEFT OUTER" />
428 <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 if __name__ == "__main__":
499 # Fake the __file__ global because it's needed by a test
500 import sys
501 __file__ = sys.argv[0]
502 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