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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1976 - (hide annotations)
Tue Nov 25 14:26:08 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/test/test_load.py
File MIME type: text/x-python
File size: 32961 byte(s)
(TestClassification.test): Add the missing
round trip test.
(TestClassification.file_contents): Update to the newest file
format

1 bh 765 # 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 loading a thuban session from a file
10 bh 1247
11     The tests in this file (test_load.py) are always be the tests for the
12     current version of the thuban file format. Tests for older versions can
13     be found in the version specific test modules, e.g. test_load_0_2 for
14     files created by Thuban 0.2.
15    
16     Maintenance of the test cases:
17    
18     When during a development period the file format is changed with respect
19     to the last released version for the first, the tests here should be
20 bh 1257 copied to the version specific test file. The round-trip tests which
21     save the session again and compare the XML files should not be copied
22     over as they only make sense here to make sure th that the files checked
23     here are actually ones that may have been written by the current thuban
24     version.
25 bh 292 """
26    
27     __version__ = "$Revision$"
28     # $Source$
29     # $Id$
30    
31     import os
32     import unittest
33    
34     import support
35     support.initthuban()
36    
37 bh 1646 import postgissupport
38 bh 1257 from xmlsupport import sax_eventlist
39 bh 1268
40     import dbflib
41 bh 1970 import shapelib
42 bh 1268
43 bh 1257 from Thuban.Model.save import save_session
44 bh 1646 from Thuban.Model.load import load_session, parse_color, LoadError, \
45     LoadCancelled
46 jonathan 1350 from Thuban.Model.color import Transparent
47 jonathan 684 from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\
48     ClassGroupSingleton, ClassGroupDefault
49 bh 1646 from Thuban.Model.postgisdb import ConnectionError
50 bh 1970 from Thuban.Model.table import DBFTable, MemoryTable, \
51     FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING, \
52     table_to_dbf
53 jonathan 684
54 bh 1970
55 bh 292 def filenames_equal(name1, name2):
56     """Return true if the filenames name1 and name2 are equal.
57    
58     On systems where it is available, simply use os.path.samefile,
59     otherwise return whether the normalized versions of the filenames
60     according to os.path.normpath are equal.
61     """
62     if hasattr(os.path, "samefile"):
63     return os.path.samefile(name1, name2)
64     return os.path.normpath(name1) == os.path.normpath(name2)
65    
66    
67 bh 957
68     class LoadSessionTest(support.FileLoadTestCase):
69    
70     """Base class for .thuban file loading tests
71    
72     Basically the same as the FileLoadTestCase, except that all tests
73     use the '.thuban' extension by default and that setUp and tearDown
74     handle sessions.
75     """
76    
77     file_extension = ".thuban"
78    
79     def setUp(self):
80     """Create the test files"""
81     support.FileLoadTestCase.setUp(self)
82     self.session = None
83    
84     def tearDown(self):
85     if self.session is not None:
86     self.session.Destroy()
87     self.session = None
88    
89 bh 1268
90 bh 1846 dtd = "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
91 bh 1268 thubanids = [((dtd, n), (None, "id")) for n in
92     ["fileshapesource", "filetable", "jointable",
93     "derivedshapesource"]]
94     thubanidrefs = [((dtd, n), (None, m)) for n, m in
95     [("layer", "shapestore"),
96     ("jointable", "left"),
97     ("jointable", "right"),
98     ("derivedshapesource", "table"),
99     ("derivedshapesource", "shapesource")]]
100 bh 1683 filenames = [((dtd, n), (None, m)) for n, m in
101     [("fileshapesource", "filename"),
102     ("rasterlayer", "filename"),
103     ("filetable", "filename")]]
104 bh 1268 del n, m, dtd
105    
106 bh 1257 def check_format(self):
107     """Check whether the file we loaded from matches the one that
108     would be written. Call this from each test case after loading
109     the session
110     """
111     filename = self.temp_file_name(self.id() + ".roundtrip.thuban")
112     save_session(self.session, filename)
113 bh 1268 el1 = sax_eventlist(filename = filename, ids = self.thubanids,
114 bh 1683 idrefs = self.thubanidrefs,
115     filenames = self.filenames)
116 bh 1268 el2 = sax_eventlist(filename = self.filename(), ids = self.thubanids,
117 bh 1683 idrefs = self.thubanidrefs,
118     filenames = self.filenames)
119 bh 1268 if 0:
120     for a, b in zip(el1, el2):
121     print a != b and "***************" or ""
122     print a
123     print b
124     self.assertEquals(el1, el2,
125     "loaded file not equivalent to the saved file")
126 bh 957
127 bh 1257
128 bh 957 class ClassificationTest(LoadSessionTest):
129    
130     """
131     Base class for tests that do some detailed checking of classifications
132     """
133    
134     def TestLayers(self, layers, expected):
135     TITLE = 0
136     NUM_GROUPS = 1
137     CLASSES = 2
138     GROUP_TYPE = 0
139     GROUP_DATA = 1
140     GROUP_LABEL = 2
141     GROUP_PROPS = 3
142    
143     eq = self.assertEquals
144    
145     eq(len(layers), len(expected))
146    
147     for layer, data in zip(layers, expected):
148     eq(layer.Title(), data[TITLE])
149    
150     clazz = layer.GetClassification()
151     eq(clazz.GetNumGroups(), data[NUM_GROUPS])
152     eq(clazz.GetNumGroups() + 1, len(data[CLASSES]))
153    
154     i = 0
155     for group in clazz:
156     props = ClassGroupProperties()
157     props.SetLineColor(
158     parse_color(data[CLASSES][i][GROUP_PROPS][0]))
159     props.SetLineWidth(data[CLASSES][i][GROUP_PROPS][1])
160     props.SetFill(
161     parse_color(data[CLASSES][i][GROUP_PROPS][2]))
162    
163     if data[CLASSES][i][GROUP_TYPE] == "default":
164     g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])
165     elif data[CLASSES][i][GROUP_TYPE] == "range":
166 jonathan 1357 g = ClassGroupRange((data[CLASSES][i][GROUP_DATA][0],
167     data[CLASSES][i][GROUP_DATA][1]),
168 bh 957 props, data[CLASSES][i][GROUP_LABEL])
169     elif data[CLASSES][i][GROUP_TYPE] == "single":
170     g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],
171     props, data[CLASSES][i][GROUP_LABEL])
172    
173     eq(group, g)
174    
175     i += 1
176    
177    
178    
179     class TestSingleLayer(LoadSessionTest):
180    
181 bh 1846 # Note: The use of &amp; and non-ascii characters is deliberate. We
182     # want to test whether the loading code handles that correctly.
183 bh 957 file_contents = '''\
184 bh 292 <?xml version="1.0" encoding="UTF-8"?>
185 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
186     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
187 bh 1848 title="Stra\xc3\x9fen &amp; Landmarken">
188 bh 1268 <fileshapesource filetype="shapefile" id="D1"
189     filename="../../Data/iceland/political.shp"/>
190 bh 1848 <map title="\xc3\x9cbersicht">
191 bh 1846 <projection epsg="32627" name="WGS 84 / UTM zone 27N">
192     <parameter value="datum=WGS84"/>
193     <parameter value="ellps=WGS84"/>
194 bh 1268 <parameter value="proj=utm"/>
195 bh 1846 <parameter value="units=m"/>
196     <parameter value="zone=27"/>
197 bh 1268 </projection>
198     <layer shapestore="D1" visible="true"
199 bh 1848 stroke="#000000" title="K\xc3\xbcste" stroke_width="1"
200 bh 1268 fill="None"/>
201     </map>
202 bh 292 </session>
203     '''
204    
205 bh 957 def test(self):
206     """Load a session with a single map with a single layer"""
207     eq = self.assertEquals
208     session = load_session(self.filename())
209     self.session = session
210    
211     # Check the title
212 bh 1848 eq(session.Title(), "Stra\xdfen & Landmarken")
213 bh 957
214     # the session has one map.
215     maps = session.Maps()
216     eq(len(maps), 1)
217    
218     # Check the map's attributes
219     map = maps[0]
220 bh 1848 eq(map.Title(), "\xdcbersicht")
221 bh 1846 proj = map.GetProjection()
222     eq(proj.GetName(), "WGS 84 / UTM zone 27N")
223     eq(proj.EPSGCode(), "32627")
224     params = proj.GetAllParameters()
225     params.sort()
226     eq(params, ["datum=WGS84", "ellps=WGS84", "proj=utm", "units=m",
227     "zone=27"])
228 bh 957
229     # the map has a single layer
230     layers = map.Layers()
231     eq(len(layers), 1)
232    
233     # Check the layer attributes
234     layer = layers[0]
235 bh 1848 eq(layer.Title(), "K\xfcste")
236 bh 1219 self.failUnless(filenames_equal(layer.ShapeStore().FileName(),
237 bh 957 os.path.join(self.temp_dir(),
238     os.pardir, os.pardir,
239     "Data", "iceland",
240     "political.shp")))
241 jonathan 1347 eq(layer.GetClassification().GetDefaultFill(), Transparent)
242 bh 957 eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")
243     eq(layer.Visible(), True)
244    
245 bh 1257 self.check_format()
246    
247 bh 957 self.session.Destroy()
248     self.session = None
249    
250 bh 1931 def test_leak(self):
251     """Test load_session for resource leaks
252 bh 957
253 bh 1931 The load_session function had a resource leak in that it created
254     cyclic references. The objects would have been eventually
255     collected by the garbage collector but too late. One symptom is
256     that when layers are removed so that the last normal reference
257     owned indirectly by the session to a shape store goes away, the
258     shape store is not actually removed from the session even though
259     the session only keeps weak references because there are still
260     references owned by the cyclic garbage.
261     """
262     session = load_session(self.filename())
263     self.session = session
264    
265     # sanity check
266     self.assertEquals(len(session.ShapeStores()), 1)
267    
268     # remove the map. The shapestore should go away too
269     session.RemoveMap(session.Maps()[0])
270     self.assertEquals(len(session.ShapeStores()), 0)
271    
272    
273 bh 1970 class TestNonAsciiColumnName(LoadSessionTest):
274    
275     file_contents = '''\
276     <?xml version="1.0" encoding="UTF-8"?>
277     <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
278     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
279     title="Non ASCII column name test">
280     <fileshapesource filetype="shapefile" id="D1"
281     filename="TestNonAsciiColumnName.shp"/>
282     <map title="map">
283     <projection name="Some Projection">
284     <parameter value="datum=WGS84"/>
285     <parameter value="ellps=WGS84"/>
286     <parameter value="proj=utm"/>
287     <parameter value="units=m"/>
288     <parameter value="zone=27"/>
289     </projection>
290     <layer shapestore="D1" visible="true"
291     stroke="#000000" title="layer" stroke_width="1"
292     fill="None">
293     <classification field="Fl\xc3\xa4che" field_type="double">
294     <clnull label="">
295     <cldata stroke="#000000" stroke_width="1" fill="None"/>
296     </clnull>
297     </classification>
298     </layer>
299     </map>
300     </session>
301     '''
302    
303     def test(self):
304     """Load a session with a single map with a single layer"""
305    
306     # Create a shapefile and a dbffile with a non-ascii column name
307     dbffile = self.temp_file_name("TestNonAsciiColumnName.dbf")
308     shpfile = self.temp_file_name("TestNonAsciiColumnName.shp")
309     dbf = dbflib.create(dbffile)
310     dbf.add_field('Fl\xe4che', dbflib.FTDouble, 10, 5)
311     dbf.write_record(0, (0.0,))
312     dbf.close()
313     shp = shapelib.create(shpfile, shapelib.SHPT_POLYGON)
314     shp.write_object(-1, shapelib.SHPObject(shapelib.SHPT_POLYGON, 1,
315     [[(0,0), (10, 10), (10, 0),
316     (0, 0)]]))
317     shp.close()
318    
319     try:
320     session = load_session(self.filename())
321     except ValueError, v:
322     # Usually if the field name is not decoded properly the
323     # loading fails because the field type mentioned in the file
324     # is not None as returned from the layer for a non-existing
325     # column name so we check for that and report it as failure.
326     # Other exceptions are errors in the test case.
327     if str(v) == "xml field type differs from database!":
328     self.fail("Cannot load file with non-ascii column names")
329     else:
330     raise
331     self.session = session
332    
333     # In case Thuban could load the file anyway (i.e. no ValueError
334     # exception in load_session()), check explicitly whether the
335     # field name was decoded properly. The test will probably lead
336     # to a UnicodeError instead of a test failure so we check that
337     # too
338     layer = session.Maps()[0].Layers()[0]
339     try:
340     self.assertEquals(layer.GetClassificationColumn(), 'Fl\xe4che')
341     except UnicodeError:
342     # FIXME: Obviously this will have to change if Thuban ever
343     # supports unicode properly.
344     self.fail("Column name was not converted to a bytestring")
345    
346     # roundtrip check
347     self.check_format()
348    
349    
350 bh 957 class TestLayerVisibility(LoadSessionTest):
351    
352     file_contents = '''\
353 jonathan 690 <?xml version="1.0" encoding="UTF-8"?>
354 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
355     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
356 bh 1268 title="single map&amp;layer">
357     <fileshapesource filetype="shapefile" id="D1"
358     filename="../../Data/iceland/political.shp"/>
359     <map title="Test Map">
360     <projection name="Unknown">
361     <parameter value="zone=26"/>
362     <parameter value="proj=utm"/>
363     <parameter value="ellps=clrk66"/>
364     </projection>
365     <layer shapestore="D1" visible="false" stroke="#000000"
366     title="My Layer" stroke_width="1" fill="None"/>
367 bh 957 </map>
368     </session>
369     '''
370    
371     def test(self):
372     """Test that the visible flag is correctly loaded for a layer."""
373     eq = self.assertEquals
374     session = load_session(self.filename())
375     self.session = session
376     maps = session.Maps()
377     eq(len(maps), 1)
378     map = maps[0]
379     layers = map.Layers()
380     eq(len(layers), 1)
381     layer = layers[0]
382    
383     eq(layer.Visible(), False)
384    
385 bh 1257 self.check_format()
386 bh 957
387    
388     class TestClassification(ClassificationTest):
389    
390     file_contents = '''\
391     <?xml version="1.0" encoding="UTF-8"?>
392 bh 1976 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
393     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
394     title="single map&amp;layer">
395     <fileshapesource filetype="shapefile" id="D138389860"
396     filename="../../Data/iceland/political.shp"/>
397     <fileshapesource filetype="shapefile" id="D138504492"
398     filename="../../Data/iceland/political.shp"/>
399     <map title="Test Map">
400     <projection name="">
401     <parameter value="zone=26"/>
402     <parameter value="proj=utm"/>
403     <parameter value="ellps=clrk66"/>
404     </projection>
405     <layer shapestore="D138389860" visible="true" stroke="#000000"
406     title="My Layer" stroke_width="1" fill="None">
407 jonathan 690 <classification field="POPYREG" field_type="string">
408 bh 1976 <clnull label="">
409 jonathan 690 <cldata stroke="#000000" stroke_width="1" fill="None"/>
410     </clnull>
411 bh 1976 <clpoint label="" value="1">
412 jonathan 690 <cldata stroke="#000000" stroke_width="2" fill="None"/>
413     </clpoint>
414 bh 1976 <clpoint label="" value="1">
415 jonathan 690 <cldata stroke="#000000" stroke_width="10" fill="None"/>
416     </clpoint>
417 bh 1976 <clpoint label="\xc3\x9cml\xc3\xa4uts"
418     value="\xc3\xa4\xc3\xb6\xc3\xbc">
419     <cldata stroke="#000000" stroke_width="1" fill="None"/>
420 bh 1417 </clpoint>
421 jonathan 690 </classification>
422     </layer>
423 bh 1976 <layer shapestore="D138504492" visible="true" stroke="#000000"
424     title="My Layer 2" stroke_width="2" fill="None">
425 jonathan 690 <classification field="AREA" field_type="double">
426 bh 1976 <clnull label="">
427 jonathan 690 <cldata stroke="#000000" stroke_width="2" fill="None"/>
428     </clnull>
429 bh 1976 <clrange label="" range="[0;1[">
430 jonathan 692 <cldata stroke="#111111" stroke_width="1" fill="None"/>
431 jonathan 690 </clrange>
432 bh 1976 <clpoint label="" value="0.5">
433 jonathan 692 <cldata stroke="#000000" stroke_width="1" fill="#111111"/>
434 jonathan 690 </clpoint>
435 bh 1976 <clrange label="" range="[-1;0[">
436 jonathan 690 <cldata stroke="#000000" stroke_width="1" fill="None"/>
437     </clrange>
438 bh 1976 <clpoint label="" value="-0.5">
439 jonathan 690 <cldata stroke="#000000" stroke_width="1" fill="None"/>
440     </clpoint>
441     </classification>
442     </layer>
443 bh 1976 </map>
444 jonathan 690 </session>
445     '''
446 bh 292
447 bh 957 def test(self):
448 bh 1247 """Load a Thuban session with a map and classified layers."""
449 bh 957 session = load_session(self.filename())
450     self.session = session
451    
452     map = self.session.Maps()[0] # only one map in the sample
453    
454 bh 1417 expected = [("My Layer", 3,
455 bh 957 [("default", (), "",
456     ("#000000", 1, "None")),
457     ("single", "1", "",
458     ("#000000", 2, "None")),
459     ("single", "1", "",
460 bh 1417 ("#000000", 10, "None")),
461     ("single", "\xe4\xf6\xfc", "\xdcml\xe4uts",
462     ("#000000", 1, "None"))]),
463 bh 957 ("My Layer 2", 4,
464     [("default", (), "",
465     ("#000000", 2, "None")),
466     ("range", (0, 1), "",
467     ("#111111", 1, "None")),
468     ("single", .5, "",
469     ("#000000", 1, "#111111")),
470     ("range", (-1, 0), "",
471     ("#000000", 1, "None")),
472     ("single", -.5, "",
473     ("#000000", 1, "None"))])]
474    
475     self.TestLayers(map.Layers(), expected)
476    
477 bh 1976 self.check_format()
478 bh 957
479 bh 1976
480 bh 957 class TestLabels(ClassificationTest):
481    
482     file_contents = '''\
483 jonathan 690 <?xml version="1.0" encoding="UTF-8"?>
484 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
485     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
486 bh 1268 title="single map&amp;layer">
487     <fileshapesource filetype="shapefile" id="D1"
488     filename="../../Data/iceland/political.shp"/>
489     <map title="Test Map">
490     <projection name="Unknown">
491     <parameter value="zone=26"/>
492     <parameter value="proj=utm"/>
493     <parameter value="ellps=clrk66"/>
494     </projection>
495     <layer shapestore="D1" visible="true" stroke="#000000"
496     title="My Layer" stroke_width="1" fill="None">
497 jonathan 690 <classification field="POPYREG" field_type="string">
498     <clnull label="hallo">
499     <cldata stroke="#000000" stroke_width="1" fill="None"/>
500     </clnull>
501     <clpoint label="welt" value="1">
502     <cldata stroke="#000000" stroke_width="2" fill="None"/>
503     </clpoint>
504     </classification>
505     </layer>
506     </map>
507     </session>
508     '''
509    
510 bh 957 def test(self):
511     """Load a session and test for reading the group labels."""
512     eq = self.assertEquals
513     session = load_session(self.filename())
514     self.session = session
515    
516     map = self.session.Maps()[0] # only one map in the sample
517    
518     expected = [("My Layer", 1,
519     [("default", (), "hallo",
520     ("#000000", 1, "None")),
521     ("single", "1", "welt",
522     ("#000000", 2, "None"))])]
523    
524     self.TestLayers(map.Layers(), expected)
525 bh 1257 self.check_format()
526 bh 957
527    
528     class TestLayerProjection(LoadSessionTest):
529    
530     file_contents = '''\
531 jonathan 746 <?xml version="1.0" encoding="UTF-8"?>
532 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
533     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
534 bh 1268 title="single map&amp;layer">
535     <fileshapesource filetype="shapefile" id="D2"
536     filename="../../Data/iceland/roads-line.shp"/>
537     <fileshapesource filetype="shapefile" id="D4"
538     filename="../../Data/iceland/political.shp"/>
539     <map title="Test Map">
540     <projection name="Unknown">
541     <parameter value="zone=26"/>
542     <parameter value="proj=utm"/>
543     <parameter value="ellps=clrk66"/>
544     </projection>
545     <layer shapestore="D4" visible="true" stroke="#000000"
546     title="My Layer" stroke_width="1" fill="None">
547     <projection name="hello">
548     <parameter value="zone=13"/>
549     <parameter value="proj=tmerc"/>
550     <parameter value="ellps=clrk66"/>
551     </projection>
552 jonathan 746 <classification field="POPYREG" field_type="string">
553     <clnull label="hallo">
554     <cldata stroke="#000000" stroke_width="1" fill="None"/>
555     </clnull>
556     <clpoint label="welt" value="1">
557     <cldata stroke="#000000" stroke_width="2" fill="None"/>
558     </clpoint>
559     </classification>
560     </layer>
561 bh 1268 <layer shapestore="D2" visible="true" stroke="#000000"
562     title="My Layer" stroke_width="1" fill="None">
563     <projection name="Unknown">
564     <parameter value="proj=lcc"/>
565 bh 1687 <parameter value="lat_1=10"/>
566     <parameter value="lat_2=20"/>
567 bh 1268 <parameter value="ellps=clrk66"/>
568     </projection>
569 jonathan 746 </layer>
570     </map>
571     </session>
572     '''
573    
574 bh 957 def test(self):
575     """Test loading layers with projections"""
576 bh 292 eq = self.assertEquals
577 jonathan 746 neq = self.assertNotEqual
578    
579 bh 957 session = load_session(self.filename())
580 jonathan 746 self.session = session
581    
582     map = self.session.Maps()[0] # only one map in the sample
583    
584     layers = map.Layers() # two layers in the sample
585    
586     # test layer with a named projection
587     proj = layers[0].GetProjection()
588     neq(proj, None)
589     eq(proj.GetName(), "hello")
590     eq(proj.GetParameter("proj"), "tmerc")
591     eq(proj.GetParameter("zone"), "13")
592     eq(proj.GetParameter("ellps"), "clrk66")
593    
594     # test layer with an unnamed projection
595     proj = layers[1].GetProjection()
596     neq(proj, None)
597     eq(proj.GetName(), "Unknown")
598     eq(proj.GetParameter("proj"), "lcc")
599 bh 1687 eq(proj.GetParameter("lat_1"), "10")
600     eq(proj.GetParameter("lat_2"), "20")
601 jonathan 746 eq(proj.GetParameter("ellps"), "clrk66")
602    
603 bh 1257 self.check_format()
604 bh 957
605 bh 1257
606 bh 957 class TestRasterLayer(LoadSessionTest):
607    
608     file_contents = '''\
609     <?xml version="1.0" encoding="UTF-8"?>
610 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
611     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
612 bh 1268 title="single map&amp;layer">
613     <map title="Test Map">
614     <rasterlayer visible="false" filename="../../Data/iceland/island.tif"
615     title="My RasterLayer"/>
616 bh 957 </map>
617     </session>
618     '''
619    
620     def test(self):
621 jonathan 947 eq = self.assertEquals
622     neq = self.assertNotEqual
623    
624 bh 957 session = load_session(self.filename())
625 jonathan 947 self.session = session
626    
627     map = self.session.Maps()[0] # only one map in the sample
628    
629     layer = map.Layers()[0] # one layer in the sample
630    
631     eq(layer.Title(), "My RasterLayer")
632     self.failIf(layer.Visible())
633     self.failUnless(filenames_equal(layer.GetImageFilename(),
634     os.path.join(self.temp_dir(),
635     os.pardir, os.pardir,
636     "Data", "iceland",
637     "island.tif")))
638 bh 1257 self.check_format()
639 jonathan 947
640 bh 1268
641     class TestJoinedTable(LoadSessionTest):
642    
643     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
644 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
645     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd" title="A Joined Table session">
646 bh 1282 <fileshapesource filetype="shapefile" id="D137227612"
647     filename="../../Data/iceland/roads-line.shp"/>
648     <filetable filetype="DBF" filename="load_joinedtable.dbf" id="D136171140"
649     title="Some Title"/>
650 bh 1375 <jointable id="D136169900" title="Joined"
651     right="D136171140" left="D137227612"
652     leftcolumn="RDLNTYPE" rightcolumn="RDTYPE"
653     jointype="LEFT OUTER"/>
654 bh 1282 <derivedshapesource table="D136169900" shapesource="D137227612"
655     id="D136170932"/>
656 bh 1268 <map title="Test Map">
657 bh 1282 <layer shapestore="D136170932" visible="true" stroke="#000000"
658     title="My Layer" stroke_width="1" fill="None"/>
659 bh 1268 </map>
660 bh 1282 </session>
661     '''
662 bh 1268
663     def setUp(self):
664     """Extend inherited method to create the dbffile for the join"""
665     LoadSessionTest.setUp(self)
666     dbffile = self.temp_file_name("load_joinedtable.dbf")
667     dbf = dbflib.create(dbffile)
668     dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
669     dbf.add_field("TEXT", dbflib.FTString, 10, 0)
670     dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
671     dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
672     dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
673     dbf.close()
674    
675     def test(self):
676     """Test loading a session containing a joined table"""
677     session = load_session(self.filename())
678     self.session = session
679    
680     tables = session.Tables()
681     self.assertEquals(len(tables), 3)
682     # FIXME: The tests shouldn't assume a certain order of the tables
683     self.assertEquals(tables[0].Title(), "Some Title")
684     self.assertEquals(tables[1].Title(), "Joined")
685 bh 1375 self.assertEquals(tables[1].JoinType(), "LEFT OUTER")
686 bh 1282 self.check_format()
687 bh 1268
688    
689 bh 1646
690     class TestPostGISLayer(LoadSessionTest):
691    
692     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
693 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
694     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
695 bh 1646 title="unnamed session">
696     <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
697     dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
698     <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
699     <map title="unnamed map">
700     <layer shapestore="D143149420" visible="true" stroke="#000000"
701     title="landmarks" stroke_width="1" fill="None"/>
702     </map>
703     </session>
704     '''
705    
706     def setUp(self):
707     """Extend the inherited method to start the postgis server
708    
709     Furthermore, patch the file contents with the real postgis db
710     information
711     """
712     postgissupport.skip_if_no_postgis()
713     self.server = postgissupport.get_test_server()
714     self.postgisdb = self.server.get_default_static_data_db()
715    
716     self.file_contents = self.__class__.file_contents % {
717     "dbname": self.postgisdb.dbname,
718     "user": self.server.user_name,
719     "port": self.server.port,
720     "host": self.server.host}
721     LoadSessionTest.setUp(self)
722    
723     def test(self):
724     """Test loading a session containing a postgis shapestore"""
725     session = load_session(self.filename())
726     self.session = session
727     connections = session.DBConnections()
728     self.assertEquals(len(connections), 1)
729     conn = connections[0]
730     for attr, value in [("host", self.server.host),
731     ("port", str(self.server.port)),
732     ("user", self.server.user_name),
733     ("dbname", self.postgisdb.dbname)]:
734     self.assertEquals(getattr(conn, attr), value)
735     layer = session.Maps()[0].Layers()[0]
736     self.failUnless(layer.ShapeStore().DBConnection() is conn)
737    
738    
739     class TestPostGISLayerPassword(LoadSessionTest):
740    
741     file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
742 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
743     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
744 bh 1646 title="unnamed session">
745     <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
746     dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
747     <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
748     <map title="unnamed map">
749     <layer shapestore="D143149420" visible="true" stroke="#000000"
750     title="landmarks" stroke_width="1" fill="None"/>
751     </map>
752     </session>
753     '''
754    
755     def setUp(self):
756     """Extend the inherited method to start the postgis server
757    
758     Furthermore, patch the file contents with the real postgis db
759     information
760     """
761     postgissupport.skip_if_no_postgis()
762     self.server = postgissupport.get_test_server()
763     self.postgisdb = self.server.get_default_static_data_db()
764    
765     self.file_contents = self.__class__.file_contents % {
766     "dbname": self.postgisdb.dbname,
767     "user": self.server.user_name,
768     "port": self.server.port,
769     "host": self.server.host}
770     LoadSessionTest.setUp(self)
771    
772     self.db_connection_callback_called = False
773     self.server.require_authentication(True)
774    
775     def tearDown(self):
776     """Extend the inherited method to switch off postgresql authentication
777     """
778     self.server.require_authentication(False)
779     LoadSessionTest.tearDown(self)
780    
781     def db_connection_callback(self, params, message):
782     """Implementation of Thuban.Model.hooks.query_db_connection_parameters
783     """
784     self.assertEquals(params,
785     {"dbname": self.postgisdb.dbname,
786     "user": self.server.user_name,
787     "port": str(self.server.port),
788     "host": self.server.host})
789     self.db_connection_callback_called = True
790     params = params.copy()
791     params["password"] = self.server.user_password
792     return params
793    
794     def test_with_callback(self):
795     """Test loading a session with postgis, authentication and a callback
796     """
797     session = load_session(self.filename(),
798     db_connection_callback = self.db_connection_callback)
799     self.session = session
800     connections = session.DBConnections()
801     self.assertEquals(len(connections), 1)
802     conn = connections[0]
803     for attr, value in [("host", self.server.host),
804     ("port", str(self.server.port)),
805     ("user", self.server.user_name),
806     ("dbname", self.postgisdb.dbname)]:
807     self.assertEquals(getattr(conn, attr), value)
808     layer = session.Maps()[0].Layers()[0]
809     self.failUnless(layer.ShapeStore().DBConnection() is conn)
810     self.failUnless(self.db_connection_callback_called)
811    
812     def test_without_callback(self):
813     """Test loading a session with postgis, authentication and no callback
814     """
815     # A password is required and there's no callback, so we should
816     # get a ConnectionError
817     self.assertRaises(ConnectionError, load_session, self.filename())
818    
819     def test_cancel(self):
820     """Test loading a session with postgis and cancelling authentication
821     """
822     def cancel(*args):
823     self.db_connection_callback_called = True
824     return None
825    
826     # If the user cancels, i.e. if the callbakc returns None, a
827     # LoadCancelled exception is raised.
828     self.assertRaises(LoadCancelled,
829     load_session, self.filename(), cancel)
830     self.failUnless(self.db_connection_callback_called)
831    
832    
833 bh 1268 class TestLoadError(LoadSessionTest):
834    
835     file_contents = '''\
836     <?xml version="1.0" encoding="UTF-8"?>
837 bh 1846 <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
838     <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
839 bh 1268 title="single map&amp;layer">
840     <fileshapesource id="D1" filename="../../Data/iceland/political.shp"/>
841     <map title="Test Map">
842     <projection name="Unknown">
843     <parameter value="zone=26"/>
844     <parameter value="proj=utm"/>
845     <parameter value="ellps=clrk66"/>
846     </projection>
847     <layer shapestore="D1" visible="true"
848     stroke="#000000" title="My Layer" stroke_width="1"
849     fill="None"/>
850     </map>
851     </session>
852     '''
853    
854     def test(self):
855     """Test loading a session missing a required attribute"""
856     # Don't use assertRaises to make sure that if a session is
857     # actually returned it gets destroyed properly.
858     try:
859     self.session = load_session(self.filename())
860     except LoadError, value:
861 bh 1642 # Check the actual messge in value to make sure the
862     # LoadError really was about the missing attribute
863     self.assertEquals(str(value),
864     "Element "
865 bh 1846 "(u'http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd',"
866 bh 1642 " u'fileshapesource') requires an attribute 'filetype'")
867 bh 1268 else:
868     self.fail("Missing filetype attribute doesn't raise LoadError")
869    
870 bh 292 if __name__ == "__main__":
871 bh 1683 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