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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 692 by jonathan, Wed Apr 16 14:10:10 2003 UTC revision 2654 by jan, Wed Jul 27 21:44:16 2005 UTC
# Line 1  Line 1 
1  # Copyright (c) 2002 by Intevation GmbH  # Copyright (c) 2002, 2003, 2004, 2005 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  #  #
# Line 7  Line 7 
7    
8  """  """
9  Test loading a thuban session from a file  Test loading a thuban session from a file
10    
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 time, the tests here should
20    be 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  """  """
26    
27  __version__ = "$Revision$"  __version__ = "$Revision$"
# Line 19  import unittest Line 34  import unittest
34  import support  import support
35  support.initthuban()  support.initthuban()
36    
37  from Thuban.Model.load import load_session, parse_color  import postgissupport
38  from Thuban.Model.session import Session  from xmlsupport import sax_eventlist
 from Thuban.Model.map import Map  
 from Thuban.Model.layer import Layer  
 from Thuban.Model.proj import Projection  
 from Thuban.Model.color import Color  
39    
40  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, FIELDTYPE_STRING  import dbflib
41    import shapelib
42    
43    from Thuban import internal_from_unicode
44    from Thuban.Model.save import save_session
45    from Thuban.Model.load import load_session, parse_color, LoadError, \
46         LoadCancelled
47    from Thuban.Model.color import Transparent
48  from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\  from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\
49      ClassGroupSingleton, ClassGroupDefault      ClassGroupSingleton, ClassGroupDefault
50    from Thuban.Model.postgisdb import ConnectionError
51    from Thuban.Model.table import DBFTable, MemoryTable, \
52         FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING, \
53         table_to_dbf
54    from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \
55         ALIGN_LEFT, ALIGN_RIGHT, ALIGN_BASELINE
56    
57  def filenames_equal(name1, name2):  def filenames_equal(name1, name2):
58      """Return true if the filenames name1 and name2 are equal.      """Return true if the filenames name1 and name2 are equal.
# Line 43  def filenames_equal(name1, name2): Line 66  def filenames_equal(name1, name2):
66      return os.path.normpath(name1) == os.path.normpath(name2)      return os.path.normpath(name1) == os.path.normpath(name2)
67    
68    
 contents_single_map = '''\  
 <?xml version="1.0" encoding="UTF-8"?>  
 <!DOCTYPE session SYSTEM "thuban.dtd">  
 <session title="single map&amp;layer">  
         <map title="Test Map">  
                 <projection>  
                         <parameter value="zone=26"/>  
                         <parameter value="proj=utm"/>  
                         <parameter value="ellps=clrk66"/>  
                 </projection>  
                 <layer title="My Layer" stroke_width="1" fill="None"  
                     filename="../../Data/iceland/political.shp"  
                     stroke="#000000"/>  
         </map>  
 </session>  
 '''  
69    
70  contents_classified_map_v0_2 = '''\  class LoadSessionTest(support.FileLoadTestCase):
 <?xml version="1.0" encoding="UTF-8"?>  
 <!DOCTYPE session SYSTEM "thuban.dtd">  
 <session title="single map&amp;layer">  
         <map title="Test Map">  
                 <projection>  
                         <parameter value="zone=26"/>  
                         <parameter value="proj=utm"/>  
                         <parameter value="ellps=clrk66"/>  
                 </projection>  
                 <layer title="My Layer" stroke_width="1" fill="None"  
                     filename="../../Data/iceland/political.shp"  
                     stroke="#000000">  
             <classification field="POPYREG" field_type="string">  
                 <clnull>  
                     <cldata stroke="#000000" stroke_width="1" fill="None"/>  
                 </clnull>  
                 <clpoint value="1">  
                     <cldata stroke="#000000" stroke_width="2" fill="None"/>  
                 </clpoint>  
                 <clpoint value="1">  
                     <cldata stroke="#000000" stroke_width="10" fill="None"/>  
                 </clpoint>  
             </classification>  
         </layer>  
                 <layer title="My Layer 2" stroke_width="1" fill="None"  
                     filename="../../Data/iceland/political.shp"  
                     stroke="#000000">  
             <classification field="AREA" field_type="double">  
                 <clnull>  
                     <cldata stroke="#000000" stroke_width="2" fill="None"/>  
                 </clnull>  
                 <clrange min="0" max="1">  
                     <cldata stroke="#111111" stroke_width="1" fill="None"/>  
                 </clrange>  
                 <clpoint value=".5">  
                     <cldata stroke="#000000" stroke_width="1" fill="#111111"/>  
                 </clpoint>  
                 <clrange min="-1" max="0">  
                     <cldata stroke="#000000" stroke_width="1" fill="None"/>  
                 </clrange>  
                 <clpoint value="-.5">  
                     <cldata stroke="#000000" stroke_width="1" fill="None"/>  
                 </clpoint>  
             </classification>  
         </layer>  
         </map>  
 </session>  
 '''  
71    
72  contents_test_labels = '''\      """Base class for .thuban file loading tests
73  <?xml version="1.0" encoding="UTF-8"?>  
74  <!DOCTYPE session SYSTEM "thuban.dtd">      Basically the same as the FileLoadTestCase, except that all tests
75  <session title="single map&amp;layer">      use the '.thuban' extension by default and that setUp and tearDown
76          <map title="Test Map">      handle sessions.
77                  <projection>      """
                         <parameter value="zone=26"/>  
                         <parameter value="proj=utm"/>  
                         <parameter value="ellps=clrk66"/>  
                 </projection>  
                 <layer title="My Layer" stroke_width="1" fill="None"  
                     filename="../../Data/iceland/political.shp"  
                     stroke="#000000">  
             <classification field="POPYREG" field_type="string">  
                 <clnull label="hallo">  
                     <cldata stroke="#000000" stroke_width="1" fill="None"/>  
                 </clnull>  
                 <clpoint label="welt" value="1">  
                     <cldata stroke="#000000" stroke_width="2" fill="None"/>  
                 </clpoint>  
             </classification>  
         </layer>  
     </map>  
 </session>  
 '''  
78    
79  class LoadSessionTest(unittest.TestCase, support.FileTestMixin):      file_extension = ".thuban"
80    
81      def setUp(self):      def setUp(self):
82          """Create the test files"""          """Create the test files"""
83          file = open(self.temp_file_name("load_singlelayer.thuban"), "w")          support.FileLoadTestCase.setUp(self)
         file.write(contents_single_map)  
         file.close()  
   
         file = open(self.temp_file_name("load_classified_v0_2.thuban"), "w")  
         file.write(contents_classified_map_v0_2)  
         file.close()  
   
         file = open(self.temp_file_name("load_labels.thuban"), "w")  
         file.write(contents_test_labels)  
         file.close()  
84          self.session = None          self.session = None
85    
86      def tearDown(self):      def tearDown(self):
87          if self.session is not None:          if self.session is not None:
88              self.session.Destroy()              self.session.Destroy()
89            self.session = None
90    
91    
92      def testSingleLayer(self):      dtd = "http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
93        thubanids = [((dtd, n), (None, "id")) for n in
94                     ["fileshapesource", "filetable", "jointable",
95                      "derivedshapesource"]]
96        thubanidrefs = [((dtd, n), (None, m)) for n, m in
97                        [("layer", "shapestore"),
98                         ("jointable", "left"),
99                         ("jointable", "right"),
100                         ("derivedshapesource", "table"),
101                         ("derivedshapesource", "shapesource")]]
102    
103        # The filenames in the tests should be understandable on all
104        # currently supported platforms so filenames is an empty list
105        filenames = []
106    
107        del n, m, dtd
108    
109        def check_format(self):
110            """Check whether the file we loaded from matches the one that
111            would be written. Call this from each test case after loading
112            the session
113            """
114            filename = self.temp_file_name(self.id() + ".roundtrip.thuban")
115            save_session(self.session, filename)
116            el1 = sax_eventlist(filename = filename, ids = self.thubanids,
117                                idrefs = self.thubanidrefs,
118                                filenames = self.filenames)
119            el2 = sax_eventlist(filename = self.filename(), ids = self.thubanids,
120                                idrefs = self.thubanidrefs,
121                                filenames = self.filenames)
122            if 0:
123                for a, b in zip(el1, el2):
124                    print a != b and "***************" or ""
125                    print a
126                    print b
127    
128            self.assertEquals(el1, el2,
129                              "loaded file not equivalent to the saved file")
130    
131    
132    class ClassificationTest(LoadSessionTest):
133    
134        """
135        Base class for tests that do some detailed checking of classifications
136        """
137    
138        def TestLayers(self, layers, expected):
139            TITLE = 0
140            NUM_GROUPS = 1
141            CLASSES = 2
142            GROUP_TYPE = 0
143            GROUP_DATA = 1
144            GROUP_LABEL = 2
145            GROUP_PROPS = 3
146    
147            eq = self.assertEquals
148    
149            eq(len(layers), len(expected))
150    
151            for layer, data in zip(layers, expected):
152                eq(layer.Title(), data[TITLE])
153    
154                clazz = layer.GetClassification()
155                eq(clazz.GetNumGroups(), data[NUM_GROUPS])
156                eq(clazz.GetNumGroups() + 1, len(data[CLASSES]))
157    
158                i = 0
159                for group in clazz:
160                    props = ClassGroupProperties()
161                    props.SetLineColor(
162                        parse_color(data[CLASSES][i][GROUP_PROPS][0]))
163                    props.SetLineWidth(data[CLASSES][i][GROUP_PROPS][1])
164                    props.SetFill(
165                        parse_color(data[CLASSES][i][GROUP_PROPS][2]))
166                    if len(data[CLASSES][i][GROUP_PROPS]) > 3:
167                        props.SetSize(data[CLASSES][i][GROUP_PROPS][3])
168    
169                    if data[CLASSES][i][GROUP_TYPE] == "default":
170                        g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])
171                    elif data[CLASSES][i][GROUP_TYPE] == "range":
172                        g = ClassGroupRange((data[CLASSES][i][GROUP_DATA][0],
173                                             data[CLASSES][i][GROUP_DATA][1]),
174                                            props, data[CLASSES][i][GROUP_LABEL])
175                    elif data[CLASSES][i][GROUP_TYPE] == "single":
176                        g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],
177                                              props, data[CLASSES][i][GROUP_LABEL])
178    
179                    eq(group, g)
180    
181                    i += 1
182    
183    
184    
185    class TestSingleLayer(LoadSessionTest):
186    
187        # Note: The use of &amp; and non-ascii characters is deliberate. We
188        # want to test whether the loading code handles that correctly.
189        file_contents = '''\
190    <?xml version="1.0" encoding="UTF-8"?>
191    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
192    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
193            title="Stra\xc3\x9fen &amp; Landmarken">
194        <fileshapesource filetype="shapefile" id="D1"
195            filename="../../Data/iceland/political.shp"/>
196        <map title="\xc3\x9cbersicht">
197            <projection epsg="32627" name="WGS 84 / UTM zone 27N">
198                <parameter value="datum=WGS84"/>
199                <parameter value="ellps=WGS84"/>
200                <parameter value="proj=utm"/>
201                <parameter value="units=m"/>
202                <parameter value="zone=27"/>
203            </projection>
204            <layer shapestore="D1" visible="true" title="K\xc3\xbcste">
205                <classification>
206                    <clnull label="">
207                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
208                    </clnull>
209                </classification>
210            </layer>
211        </map>
212    </session>
213    '''
214    
215        def test(self):
216          """Load a session with a single map with a single layer"""          """Load a session with a single map with a single layer"""
217          eq = self.assertEquals          eq = self.assertEquals
218          session = load_session(self.temp_file_name("load_singlelayer.thuban"))          session = load_session(self.filename())
219          self.session = session          self.session = session
220    
221          # Check the title          # Check the title
222          eq(session.Title(), "single map&layer")          eq(session.Title(), internal_from_unicode(u"Stra\xdfen & Landmarken"))
223    
224          # the session has one map.          # the session has one map.
225          maps = session.Maps()          maps = session.Maps()
# Line 172  class LoadSessionTest(unittest.TestCase, Line 227  class LoadSessionTest(unittest.TestCase,
227    
228          # Check the map's attributes          # Check the map's attributes
229          map = maps[0]          map = maps[0]
230          eq(map.Title(), "Test Map")          eq(map.Title(), internal_from_unicode(u"\xdcbersicht"))
231            proj = map.GetProjection()
232            eq(proj.GetName(), "WGS 84 / UTM zone 27N")
233            eq(proj.EPSGCode(), "32627")
234            params = proj.GetAllParameters()
235            params.sort()
236            eq(params, ["datum=WGS84", "ellps=WGS84", "proj=utm", "units=m",
237                        "zone=27"])
238    
239          # the map has a single layer          # the map has a single layer
240          layers = map.Layers()          layers = map.Layers()
# Line 180  class LoadSessionTest(unittest.TestCase, Line 242  class LoadSessionTest(unittest.TestCase,
242    
243          # Check the layer attributes          # Check the layer attributes
244          layer = layers[0]          layer = layers[0]
245          eq(layer.Title(), "My Layer")          eq(layer.Title(), internal_from_unicode(u"K\xfcste"))
246          self.failUnless(filenames_equal(layer.filename,          self.failUnless(filenames_equal(layer.ShapeStore().FileName(),
247                                          os.path.join(self.temp_dir(),                                          os.path.join(self.temp_dir(),
248                                                       os.pardir, os.pardir,                                                       os.pardir, os.pardir,
249                                                       "Data", "iceland",                                                       "Data", "iceland",
250                                                       "political.shp")))                                                       "political.shp")))
251          eq(layer.GetClassification().GetDefaultFill(), Color.Transparent)          eq(layer.GetClassification().GetDefaultFill(), Transparent)
252          eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")          eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")
253            eq(layer.Visible(), True)
254    
255            self.check_format()
256    
257          self.session.Destroy()          self.session.Destroy()
258          self.session = None          self.session = None
259    
260      def testClassification(self):      def test_leak(self):
261          """Load a session with a map and classified layers."""          """Test load_session for resource leaks
262    
263            The load_session function had a resource leak in that it created
264            cyclic references. The objects would have been eventually
265            collected by the garbage collector but too late. One symptom is
266            that when layers are removed so that the last normal reference
267            owned indirectly by the session to a shape store goes away, the
268            shape store is not actually removed from the session even though
269            the session only keeps weak references because there are still
270            references owned by the cyclic garbage.
271            """
272            session = load_session(self.filename())
273            self.session = session
274    
275            # sanity check
276            self.assertEquals(len(session.ShapeStores()), 1)
277    
278            # remove the map. The shapestore should go away too
279            session.RemoveMap(session.Maps()[0])
280            self.assertEquals(len(session.ShapeStores()), 0)
281    
282    
283    class TestNonAsciiColumnName(LoadSessionTest):
284    
285        file_contents = '''\
286    <?xml version="1.0" encoding="UTF-8"?>
287    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
288    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
289            title="Non ASCII column name test">
290        <fileshapesource filetype="shapefile" id="D1"
291            filename="TestNonAsciiColumnName.shp"/>
292        <map title="map">
293            <projection name="Some Projection">
294                <parameter value="datum=WGS84"/>
295                <parameter value="ellps=WGS84"/>
296                <parameter value="proj=utm"/>
297                <parameter value="units=m"/>
298                <parameter value="zone=27"/>
299            </projection>
300            <layer shapestore="D1" visible="true" title="layer">
301                <classification field="Fl\xc3\xa4che" field_type="double">
302                    <clnull label="">
303                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
304                    </clnull>
305                </classification>
306            </layer>
307        </map>
308    </session>
309    '''
310    
311        def test(self):
312            """Load a session with a single map with a single layer"""
313    
314            # Create a shapefile and a dbffile with a non-ascii column name
315            dbffile = self.temp_file_name("TestNonAsciiColumnName.dbf")
316            shpfile = self.temp_file_name("TestNonAsciiColumnName.shp")
317            dbf = dbflib.create(dbffile)
318            dbf.add_field('Fl\xe4che', dbflib.FTDouble, 10, 5)
319            dbf.write_record(0, (0.0,))
320            dbf.close()
321            shp = shapelib.create(shpfile, shapelib.SHPT_POLYGON)
322            shp.write_object(-1, shapelib.SHPObject(shapelib.SHPT_POLYGON, 1,
323                                                    [[(0,0), (10, 10), (10, 0),
324                                                      (0, 0)]]))
325            shp.close()
326    
327            try:
328                session = load_session(self.filename())
329            except ValueError, v:
330                # Usually if the field name is not decoded properly the
331                # loading fails because the field type mentioned in the file
332                # is not None as returned from the layer for a non-existing
333                # column name so we check for that and report it as failure.
334                # Other exceptions are errors in the test case.
335                if str(v) == "xml field type differs from database!":
336                    self.fail("Cannot load file with non-ascii column names")
337                else:
338                    raise
339            self.session = session
340    
341            # In case Thuban could load the file anyway (i.e. no ValueError
342            # exception in load_session()), check explicitly whether the
343            # field name was decoded properly. The test will probably lead
344            # to a UnicodeError instead of a test failure so we check that
345            # too
346            layer = session.Maps()[0].Layers()[0]
347            try:
348                self.assertEquals(layer.GetClassificationColumn(), 'Fl\xe4che')
349            except UnicodeError:
350                # FIXME: Obviously this will have to change if Thuban ever
351                # supports unicode properly.
352                self.fail("Column name was not converted to a bytestring")
353    
354            # roundtrip check
355            self.check_format()
356    
357    
358    class TestLayerVisibility(LoadSessionTest):
359    
360        file_contents = '''\
361    <?xml version="1.0" encoding="UTF-8"?>
362    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
363    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
364            title="single map&amp;layer">
365        <fileshapesource filetype="shapefile" id="D1"
366            filename="../../Data/iceland/political.shp"/>
367        <map title="Test Map">
368            <projection name="Unknown">
369                <parameter value="zone=26"/>
370                <parameter value="proj=utm"/>
371                <parameter value="ellps=clrk66"/>
372            </projection>
373            <layer shapestore="D1" visible="false" title="My Layer">
374                <classification>
375                    <clnull label="">
376                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
377                    </clnull>
378                </classification>
379            </layer>
380        </map>
381    </session>
382    '''
383    
384        def test(self):
385            """Test that the visible flag is correctly loaded for a layer."""
386            eq = self.assertEquals
387            session = load_session(self.filename())
388            self.session = session
389            maps = session.Maps()
390            eq(len(maps), 1)
391            map = maps[0]
392            layers = map.Layers()
393            eq(len(layers), 1)
394            layer = layers[0]
395    
396            eq(layer.Visible(), False)
397    
398            self.check_format()
399    
400    
401    class TestSymbolSize(ClassificationTest):
402    
403        file_contents = '''\
404    <?xml version="1.0" encoding="UTF-8"?>
405    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
406    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd" title="Thuban sample session">
407        <fileshapesource filetype="shapefile" id="D813968480" filename="../../Data/iceland/cultural_landmark-point.shp"/>
408        <map title="Iceland map">
409            <layer title="cultural_landmark-point" shapestore="D813968480" visible="true">
410                <classification field="CLPTLABEL" field_type="string">
411                    <clnull label="">
412                        <cldata stroke="#000000" stroke_width="1" size="3" fill="#000000"/>
413                    </clnull>
414                    <clpoint label="" value="RUINS">
415                        <cldata stroke="#000000" stroke_width="1" size="6" fill="#ffffff"/>
416                    </clpoint>
417                    <clpoint label="" value="FARM">
418                        <cldata stroke="#000000" stroke_width="1" size="9" fill="#ffff00"/>
419                    </clpoint>
420                </classification>
421            </layer>
422        </map>
423    </session>
424    '''
425    
426        def test(self):
427            """Test that the size attribute for point symbols is correctly
428            loaded for a layer."""
429            eq = self.assertEquals
430            session = load_session(self.filename())
431            self.session = session
432    
433            map = session.Maps()[0] # only one map in the sample
434    
435            expected = [("cultural_landmark-point", 2,
436                            [("default", (), "",
437                                ("#000000", 1, "#000000", 3)),
438                             ("single", "RUINS", "",
439                                ("#000000", 1, "#ffffff", 6)),
440                             ("single", "FARM", "",
441                                ("#000000", 1, "#ffff00", 9))])]
442    
443            self.TestLayers(map.Layers(), expected)
444    
445            self.check_format()
446    
447    
448    class TestClassification(ClassificationTest):
449    
450        file_contents = '''\
451    <?xml version="1.0" encoding="UTF-8"?>
452    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
453    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
454            title="single map&amp;layer">
455        <fileshapesource filetype="shapefile" id="D138389860"
456            filename="../../Data/iceland/political.shp"/>
457        <fileshapesource filetype="shapefile" id="D138504492"
458            filename="../../Data/iceland/political.shp"/>
459        <map title="Test Map">
460            <projection name="">
461                <parameter value="zone=26"/>
462                <parameter value="proj=utm"/>
463                <parameter value="ellps=clrk66"/>
464            </projection>
465            <layer shapestore="D138389860" visible="true" title="My Layer">
466                <classification field="POPYREG" field_type="string">
467                    <clnull label="">
468                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
469                    </clnull>
470                    <clpoint label="" value="1">
471                        <cldata stroke="#000000" stroke_width="2" fill="None"/>
472                    </clpoint>
473                    <clpoint label="" value="1">
474                        <cldata stroke="#000000" stroke_width="10" fill="None"/>
475                    </clpoint>
476                    <clpoint label="\xc3\x9cml\xc3\xa4uts"
477                            value="\xc3\xa4\xc3\xb6\xc3\xbc">
478                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
479                    </clpoint>
480                </classification>
481            </layer>
482            <layer shapestore="D138504492" visible="true" title="My Layer 2">
483                <classification field="AREA" field_type="double">
484                    <clnull label="">
485                        <cldata stroke="#000000" stroke_width="2" fill="None"/>
486                    </clnull>
487                    <clrange label="" range="[0;1[">
488                        <cldata stroke="#111111" stroke_width="1" fill="None"/>
489                    </clrange>
490                    <clpoint label="" value="0.5">
491                        <cldata stroke="#000000" stroke_width="1" fill="#111111"/>
492                    </clpoint>
493                    <clrange label="" range="[-1;0[">
494                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
495                    </clrange>
496                    <clpoint label="" value="-0.5">
497                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
498                    </clpoint>
499                </classification>
500            </layer>
501        </map>
502    </session>
503    '''
504    
505          session = load_session(self.temp_file_name("load_classified_v0_2.thuban"))      def test(self):
506            """Load a Thuban session with a map and classified layers."""
507            session = load_session(self.filename())
508          self.session = session          self.session = session
509    
510          map = self.session.Maps()[0] # only one map in the sample          map = self.session.Maps()[0] # only one map in the sample
511    
512          expected = [("My Layer", 2,          expected = [("My Layer", 3,
513                          [("default", (), "",                          [("default", (), "",
514                              ("#000000", 1, "None")),                              ("#000000", 1, "None")),
515                           ("single", "1", "",                           ("single", "1", "",
516                              ("#000000", 2, "None")),                              ("#000000", 2, "None")),
517                           ("single", "1", "",                           ("single", "1", "",
518                              ("#000000", 10, "None"))]),                              ("#000000", 10, "None")),
519                             ("single", internal_from_unicode(u"\xe4\xf6\xfc"),
520                              internal_from_unicode(u"\xdcml\xe4uts"),
521                                ("#000000", 1, "None"))]),
522                       ("My Layer 2", 4,                       ("My Layer 2", 4,
523                           [("default", (), "",                           [("default", (), "",
524                              ("#000000", 2, "None")),                              ("#000000", 2, "None")),
# Line 221  class LoadSessionTest(unittest.TestCase, Line 533  class LoadSessionTest(unittest.TestCase,
533    
534          self.TestLayers(map.Layers(), expected)          self.TestLayers(map.Layers(), expected)
535    
536      def TestLayers(self, layers, expected):          self.check_format()
537    
         TITLE = 0  
         NUM_GROUPS = 1  
         CLASSES = 2  
         GROUP_TYPE = 0  
         GROUP_DATA = 1  
         GROUP_LABEL = 2  
         GROUP_PROPS = 3  
538    
539    class TestLabels(ClassificationTest):
540    
541        file_contents = '''\
542    <?xml version="1.0" encoding="UTF-8"?>
543    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
544    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
545            title="single map&amp;layer">
546        <fileshapesource filetype="shapefile" id="D1"
547            filename="../../Data/iceland/political.shp"/>
548        <map title="Test Map">
549            <projection name="Unknown">
550                <parameter value="zone=26"/>
551                <parameter value="proj=utm"/>
552                <parameter value="ellps=clrk66"/>
553            </projection>
554            <layer shapestore="D1" visible="true" title="My Layer">
555                <classification field="POPYREG" field_type="string">
556                    <clnull label="hallo">
557                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
558                    </clnull>
559                    <clpoint label="welt" value="1">
560                        <cldata stroke="#000000" stroke_width="2" fill="None"/>
561                    </clpoint>
562                </classification>
563            </layer>
564        </map>
565    </session>
566    '''
567    
568        def test(self):
569            """Load a session and test for reading the group labels."""
570          eq = self.assertEquals          eq = self.assertEquals
571            session = load_session(self.filename())
572            self.session = session
573    
574          eq(len(layers), len(expected))          map = self.session.Maps()[0] # only one map in the sample
575    
576          for layer, data in zip(layers, expected):          expected = [("My Layer", 1,
577              eq(layer.Title(), data[TITLE])                          [("default", (), "hallo",
578                                ("#000000", 1, "None")),
579                             ("single", "1", "welt",
580                                ("#000000", 2, "None"))])]
581    
582              clazz = layer.GetClassification()          self.TestLayers(map.Layers(), expected)
583              eq(clazz.GetNumGroups(), data[NUM_GROUPS])          self.check_format()
             eq(clazz.GetNumGroups() + 1, len(data[CLASSES]))  
584    
             i = 0  
             for group in clazz:  
                   
                 props = ClassGroupProperties()  
                 props.SetLineColor(  
                     parse_color(data[CLASSES][i][GROUP_PROPS][0]))  
                 props.SetLineWidth(data[CLASSES][i][GROUP_PROPS][1])  
                 props.SetFill(  
                     parse_color(data[CLASSES][i][GROUP_PROPS][2]))  
585    
586                  if data[CLASSES][i][GROUP_TYPE] == "default":  class TestLayerProjection(LoadSessionTest):
                     g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])  
                 elif data[CLASSES][i][GROUP_TYPE] == "range":  
                     g = ClassGroupRange(data[CLASSES][i][GROUP_DATA][0],  
                                         data[CLASSES][i][GROUP_DATA][1],  
                                         props, data[CLASSES][i][GROUP_LABEL])  
                 elif data[CLASSES][i][GROUP_TYPE] == "single":  
                     g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],  
                                           props, data[CLASSES][i][GROUP_LABEL])  
587    
588                  eq(group, g)      file_contents = '''\
589    <?xml version="1.0" encoding="UTF-8"?>
590    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
591    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
592            title="single map&amp;layer">
593        <fileshapesource filetype="shapefile" id="D2"
594            filename="../../Data/iceland/roads-line.shp"/>
595        <fileshapesource filetype="shapefile" id="D4"
596            filename="../../Data/iceland/political.shp"/>
597        <map title="Test Map">
598            <projection name="Unknown">
599                <parameter value="zone=26"/>
600                <parameter value="proj=utm"/>
601                <parameter value="ellps=clrk66"/>
602            </projection>
603            <layer shapestore="D4" visible="true" title="My Layer">
604                <projection name="hello">
605                    <parameter value="zone=13"/>
606                    <parameter value="proj=tmerc"/>
607                    <parameter value="ellps=clrk66"/>
608                </projection>
609                <classification field="POPYREG" field_type="string">
610                    <clnull label="hallo">
611                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
612                    </clnull>
613                    <clpoint label="welt" value="1">
614                        <cldata stroke="#000000" stroke_width="2" fill="None"/>
615                    </clpoint>
616                </classification>
617            </layer>
618            <layer shapestore="D2" visible="true" title="My Layer">
619                <projection name="Unknown">
620                    <parameter value="proj=lcc"/>
621                    <parameter value="lat_1=10"/>
622                    <parameter value="lat_2=20"/>
623                    <parameter value="ellps=clrk66"/>
624                </projection>
625                <classification>
626                    <clnull label="">
627                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
628                    </clnull>
629                </classification>
630            </layer>
631        </map>
632    </session>
633    '''
634    
635                  i += 1      def test(self):
636            """Test loading layers with projections"""
637            eq = self.assertEquals
638            neq = self.assertNotEqual
639    
640      def testLabels(self):          session = load_session(self.filename())
641          """Load a session and test for reading the group labels."""          self.session = session
642    
643            map = self.session.Maps()[0] # only one map in the sample
644    
645            layers = map.Layers() # two layers in the sample
646    
647            # test layer with a named projection
648            proj = layers[0].GetProjection()
649            neq(proj, None)
650            eq(proj.GetName(), "hello")
651            eq(proj.GetParameter("proj"), "tmerc")
652            eq(proj.GetParameter("zone"), "13")
653            eq(proj.GetParameter("ellps"), "clrk66")
654    
655            # test layer with an unnamed projection
656            proj = layers[1].GetProjection()
657            neq(proj, None)
658            eq(proj.GetName(), "Unknown")
659            eq(proj.GetParameter("proj"), "lcc")
660            eq(proj.GetParameter("lat_1"), "10")
661            eq(proj.GetParameter("lat_2"), "20")
662            eq(proj.GetParameter("ellps"), "clrk66")
663    
664            self.check_format()
665    
666    
667    class TestRasterLayer(LoadSessionTest):
668    
669        file_contents = '''\
670    <?xml version="1.0" encoding="UTF-8"?>
671    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
672    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
673            title="single map&amp;layer">
674        <map title="Test Map">
675            <rasterlayer visible="false" filename="../../Data/iceland/island.tif"
676                    title="My RasterLayer" opacity="0.4" masktype="alpha"/>
677        </map>
678    </session>
679    '''
680    
681        def test(self):
682          eq = self.assertEquals          eq = self.assertEquals
683          session = load_session(self.temp_file_name("load_labels.thuban"))          neq = self.assertNotEqual
684    
685            session = load_session(self.filename())
686          self.session = session          self.session = session
687    
688          map = self.session.Maps()[0] # only one map in the sample          map = self.session.Maps()[0] # only one map in the sample
689    
690          expected = [("My Layer", 1,          layer = map.Layers()[0] # one layer in the sample
                         [("default", (), "hallo",  
                             ("#000000", 1, "None")),  
                          ("single", "1", "welt",  
                             ("#000000", 2, "None"))])]  
691    
692          self.TestLayers(map.Layers(), expected)          eq(layer.Title(), "My RasterLayer")
693            eq(layer.Opacity(), 0.4)
694            eq(layer.MaskType(), layer.MASK_ALPHA)
695    
696  if __name__ == "__main__":          self.failIf(layer.Visible())
697      unittest.main()          self.failUnless(filenames_equal(layer.GetImageFilename(),
698                                            os.path.join(self.temp_dir(),
699                                                         os.pardir, os.pardir,
700                                                         "Data", "iceland",
701                                                         "island.tif")))
702            self.check_format()
703    
704    
705    class TestJoinedTable(LoadSessionTest):
706    
707        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
708    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
709    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd" title="A Joined Table session">
710        <fileshapesource filetype="shapefile" id="D137227612"
711            filename="../../Data/iceland/roads-line.shp"/>
712        <filetable filetype="DBF" filename="load_joinedtable.dbf" id="D136171140"
713            title="Some Title"/>
714        <jointable id="D136169900" title="Joined"
715            right="D136171140" left="D137227612"
716            leftcolumn="RDLNTYPE" rightcolumn="RDTYPE"
717            jointype="LEFT OUTER"/>
718        <derivedshapesource table="D136169900" shapesource="D137227612"
719            id="D136170932"/>
720        <map title="Test Map">
721            <layer shapestore="D136170932" visible="true" title="My Layer">
722                <classification>
723                    <clnull label="">
724                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
725                    </clnull>
726                </classification>
727            </layer>
728        </map>
729    </session>
730    '''
731    
732        def setUp(self):
733            """Extend inherited method to create the dbffile for the join"""
734            LoadSessionTest.setUp(self)
735            dbffile = self.temp_file_name("load_joinedtable.dbf")
736            dbf = dbflib.create(dbffile)
737            dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
738            dbf.add_field("TEXT", dbflib.FTString, 10, 0)
739            dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
740            dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
741            dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
742            dbf.close()
743    
744        def test(self):
745            """Test loading a session containing a joined table"""
746            session = load_session(self.filename())
747            self.session = session
748    
749            tables = session.Tables()
750            self.assertEquals(len(tables), 3)
751            # FIXME: The tests shouldn't assume a certain order of the tables
752            self.assertEquals(tables[0].Title(), "Some Title")
753            self.assertEquals(tables[1].Title(), "Joined")
754            self.assertEquals(tables[1].JoinType(), "LEFT OUTER")
755            self.check_format()
756    
757    
758    class TestLabelLayer(LoadSessionTest):
759    
760        # Note that the labels deliberately contain non-ascii characters to
761        # test whether they're supported correctly.
762    
763        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
764    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
765    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd" title="Thuban sample session">
766        <fileshapesource filetype="shapefile" id="D145265052"
767            filename="../../Data/iceland/political.shp"/>
768        <fileshapesource filetype="shapefile" id="D145412868"
769            filename="../../Data/iceland/cultural_landmark-point.shp"/>
770        <map title="Iceland map">
771            <projection name="Unknown">
772                <parameter value="zone=26"/>
773                <parameter value="proj=utm"/>
774                <parameter value="ellps=clrk66"/>
775            </projection>
776            <layer shapestore="D145265052" visible="true" title="political">
777                <projection name="Geographic">
778                    <parameter value="proj=latlong"/>
779                    <parameter value="to_meter=0.017453"/>
780                    <parameter value="ellps=clrk66"/>
781                </projection>
782                <classification>
783                    <clnull label="">
784                        <cldata stroke="#000000" stroke_width="1" fill="#c0c0c0"/>
785                    </clnull>
786                </classification>
787            </layer>
788            <layer shapestore="D145412868" visible="true" title="landmarks">
789                <projection name="Geographic">
790                    <parameter value="proj=latlong"/>
791                    <parameter value="to_meter=0.017453"/>
792                    <parameter value="ellps=clrk66"/>
793                </projection>
794                <classification>
795                    <clnull label="">
796                        <cldata size="5" stroke="#000000" stroke_width="1" fill="#ffff00"/>
797                    </clnull>
798                </classification>
799            </layer>
800            <labellayer>
801                <label x="-21.5" y="64.25" text="RUINS"
802                    halign="left" valign="center"/>
803                <label x="-15.125" y="64.75" text="H\xc3\xbctte"
804                    halign="right" valign="top"/>
805            </labellayer>
806        </map>
807    </session>
808    '''
809    
810        def test(self):
811            """Test loading a session with a label layer"""
812            session = load_session(self.filename())
813            self.session = session
814    
815            label_layer = self.session.Maps()[0].LabelLayer()
816            expected_labels = [(-21.5, 64.25, "RUINS", ALIGN_LEFT, ALIGN_CENTER),
817                               (-15.125, 64.75, internal_from_unicode(u"H\xfctte"),
818                                ALIGN_RIGHT, ALIGN_TOP),
819                               ]
820            for label, values in zip(label_layer.Labels(), expected_labels):
821                self.assertEquals((label.x, label.y, label.text, label.halign,
822                                   label.valign),
823                                  values)
824            self.check_format()
825    
826    
827    class TestPostGISLayer(LoadSessionTest):
828    
829        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
830    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
831    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
832            title="unnamed session">
833        <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
834            dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
835        <dbshapesource id="D143149420" dbconn="D142684948"
836            tablename="landmarks_point_id" id_column="point_id"
837            geometry_column="the_geom" />
838        <map title="unnamed map">
839            <layer shapestore="D143149420" visible="true" stroke="#000000"
840                    title="landmarks" stroke_width="1" fill="None"/>
841        </map>
842    </session>
843    '''
844    
845        def setUp(self):
846            """Extend the inherited method to start the postgis server
847    
848            Furthermore, patch the file contents with the real postgis db
849            information
850            """
851            postgissupport.skip_if_no_postgis()
852            self.server = postgissupport.get_test_server()
853            self.postgisdb = self.server.get_default_static_data_db()
854    
855            self.file_contents = self.__class__.file_contents % {
856                "dbname": self.postgisdb.dbname,
857                "user": self.server.user_name,
858                "port": self.server.port,
859                "host": self.server.host}
860            LoadSessionTest.setUp(self)
861    
862        def test(self):
863            """Test loading a session containing a postgis shapestore"""
864            session = load_session(self.filename())
865            self.session = session
866            connections = session.DBConnections()
867            self.assertEquals(len(connections), 1)
868            conn = connections[0]
869            for attr, value in [("host", self.server.host),
870                                ("port", str(self.server.port)),
871                                ("user", self.server.user_name),
872                                ("dbname", self.postgisdb.dbname)]:
873                self.assertEquals(getattr(conn, attr), value)
874            layer = session.Maps()[0].Layers()[0]
875            self.failUnless(layer.ShapeStore().DBConnection() is conn)
876    
877    
878    class TestPostGISLayerPassword(LoadSessionTest):
879    
880        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
881    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
882    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
883            title="unnamed session">
884        <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
885            dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
886        <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
887        <map title="unnamed map">
888            <layer shapestore="D143149420" visible="true" stroke="#000000"
889                    title="landmarks" stroke_width="1" fill="None"/>
890        </map>
891    </session>
892    '''
893    
894        def setUp(self):
895            """Extend the inherited method to start the postgis server
896    
897            Furthermore, patch the file contents with the real postgis db
898            information
899            """
900            postgissupport.skip_if_no_postgis()
901            self.server = postgissupport.get_test_server()
902            self.postgisdb = self.server.get_default_static_data_db()
903    
904            self.file_contents = self.__class__.file_contents % {
905                "dbname": self.postgisdb.dbname,
906                "user": self.server.user_name,
907                "port": self.server.port,
908                "host": self.server.host}
909            LoadSessionTest.setUp(self)
910    
911            self.db_connection_callback_called = False
912            self.server.require_authentication(True)
913    
914        def tearDown(self):
915            """Extend the inherited method to switch off postgresql authentication
916            """
917            self.server.require_authentication(False)
918            LoadSessionTest.tearDown(self)
919    
920        def db_connection_callback(self, params, message):
921            """Implementation of Thuban.Model.hooks.query_db_connection_parameters
922            """
923            self.assertEquals(params,
924                              {"dbname": self.postgisdb.dbname,
925                               "user": self.server.user_name,
926                               "port": str(self.server.port),
927                               "host": self.server.host})
928            self.db_connection_callback_called = True
929            params = params.copy()
930            params["password"] = self.server.user_password
931            return params
932    
933        def test_with_callback(self):
934            """Test loading a session with postgis, authentication and a callback
935            """
936            session = load_session(self.filename(),
937                          db_connection_callback = self.db_connection_callback)
938            self.session = session
939            connections = session.DBConnections()
940            self.assertEquals(len(connections), 1)
941            conn = connections[0]
942            for attr, value in [("host", self.server.host),
943                                ("port", str(self.server.port)),
944                                ("user", self.server.user_name),
945                                ("dbname", self.postgisdb.dbname)]:
946                self.assertEquals(getattr(conn, attr), value)
947            layer = session.Maps()[0].Layers()[0]
948            self.failUnless(layer.ShapeStore().DBConnection() is conn)
949            self.failUnless(self.db_connection_callback_called)
950    
951        def test_without_callback(self):
952            """Test loading a session with postgis, authentication and no callback
953            """
954            # A password is required and there's no callback, so we should
955            # get a ConnectionError
956            self.assertRaises(ConnectionError, load_session, self.filename())
957    
958        def test_cancel(self):
959            """Test loading a session with postgis and cancelling authentication
960            """
961            def cancel(*args):
962                self.db_connection_callback_called = True
963                return None
964    
965            # If the user cancels, i.e. if the callbakc returns None, a
966            # LoadCancelled exception is raised.
967            self.assertRaises(LoadCancelled,
968                              load_session, self.filename(), cancel)
969            self.failUnless(self.db_connection_callback_called)
970    
971    
972    class TestLoadError(LoadSessionTest):
973    
974        file_contents = '''\
975    <?xml version="1.0" encoding="UTF-8"?>
976    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
977    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
978            title="single map&amp;layer">
979        <fileshapesource id="D1" filename="../../Data/iceland/political.shp"/>
980        <map title="Test Map">
981            <projection name="Unknown">
982                <parameter value="zone=26"/>
983                <parameter value="proj=utm"/>
984                <parameter value="ellps=clrk66"/>
985            </projection>
986            <layer shapestore="D1" visible="true"
987                    stroke="#000000" title="My Layer" stroke_width="1"
988                    fill="None"/>
989        </map>
990    </session>
991    '''
992    
993        def test(self):
994            """Test loading a session missing a required attribute"""
995            # Don't use assertRaises to make sure that if a session is
996            # actually returned it gets destroyed properly.
997            try:
998                self.session = load_session(self.filename())
999            except LoadError, value:
1000                # Check the actual messge in value to make sure the
1001                # LoadError really was about the missing attribute
1002                self.assertEquals(str(value),
1003                  "Element "
1004                  "(u'http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd',"
1005                  " u'fileshapesource') requires an attribute 'filetype'")
1006            else:
1007                self.fail("Missing filetype attribute doesn't raise LoadError")
1008    
1009    class Shapefile_CallBack:
1010    
1011        def __init__(self, params):
1012            """Initialize the callback return values.
1013              
1014               params must be a dictionary of the potential CB modes (keys),
1015               with lists of tuples of return values as values.
1016               Depending on the test the callback can be called multiple,
1017               each time a return value is poped from the list
1018            """
1019    
1020            self.params = params
1021    
1022    
1023        def s_cb(self, filename, mode = None, second_try= 0):
1024            if self.params.has_key(mode):
1025                return self.params[mode].pop(0)
1026            else:
1027                raise LoadError
1028            
1029    class TestAltPath(LoadSessionTest):
1030    
1031        """Test the various cases in the alternative path feature.
1032    
1033           The test checks the reasonable cases:
1034           - First recognition of a path error, fixed with user interaction.
1035           - First recognition of a path error, load cancelled.
1036           - Path error fixed from list, confirmed by user.
1037           - Path error fixed from list, changed by user.
1038           - Path error fixed from list, cancelled by user.
1039           - Path error wrongly fixed from list, manual fix forced.
1040        """
1041    
1042        file_contents = '''\
1043    <?xml version="1.0" encoding="UTF-8"?>
1044    <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
1045    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd" title="AltPath Test session">
1046        <fileshapesource filetype="shapefile" id="D1108450956" filename="../../Data/iceland/political.shp"/>
1047        <fileshapesource filetype="shapefile" id="D1108900076" filename="../Data/iceland/roads-line.shp"/>
1048        <fileshapesource filetype="shapefile" id="D1108947244" filename="../../Data/iceland/cultural_landmark-point.shp"/>
1049        <map title="not the iceland map">
1050            <layer title="political" stroke_width="1" shapestore="D1108450956" visible="true" stroke="#000000" fill="#c0c0c0"/>
1051            <layer title="roads-line" stroke_width="1" shapestore="D1108900076" visible="true" stroke="#000000" fill="None"/>
1052            <layer title="something else" stroke_width="1" shapestore="D1108947244" visible="true" stroke="#000000" fill="None"/>
1053        </map>
1054    </session>
1055    '''
1056    
1057        def checkSession(self, session):
1058            """Check if session has been loaded successfully."""
1059            
1060            eq = self.assertEquals
1061    
1062            map = session.Maps()[0]
1063            layers = map.Layers()
1064    
1065            eq("AltPath Test session", session.Title())
1066            eq("not the iceland map", map.Title())
1067            eq(3,len(layers))
1068            eq("political",layers[0].Title())
1069            eq("roads-line",layers[1].Title())
1070            eq("something else",layers[2].Title())
1071    
1072        def test_01_single_path_error_fix(self):
1073            """Test single file path error fix."""
1074            # The usual initial case
1075            s_cb = Shapefile_CallBack({
1076                        "search": [("../Data/iceland/roads-line.shp",0)],
1077                        "check": [(None, None)]})
1078            self.session = load_session(self.filename(),
1079                                        shapefile_callback =s_cb.s_cb)
1080            self.checkSession(self.session)
1081            
1082        def test_02_path_error_fix_from_list(self):
1083            """Test single file path error fix."""
1084            # This represents the usual case for "from_list"
1085            s_cb = Shapefile_CallBack({
1086                    "search": [("../Data/iceland/roads-line.shp",1)],
1087                    "check": [(os.path.abspath("../Data/iceland/roads-line.shp"),1)]
1088                   })
1089            self.session = load_session(self.filename(),
1090                                        shapefile_callback =s_cb.s_cb)
1091            self.checkSession(self.session)
1092    
1093        def test_03_single_path_error_cancelled(self):
1094            """Test alternative path cancelled."""
1095            s_cb = Shapefile_CallBack({
1096                        "search": [(None,0)],
1097                        "check": [(None, None)]})
1098            self.assertRaises(LoadCancelled,
1099                                load_session, self.filename(), None, s_cb.s_cb)
1100    
1101        def test_04_path_error_fix_from_list_cancelled(self):
1102            """Test alternative path from list cancelled."""
1103            s_cb = Shapefile_CallBack({
1104                    "search": [("../Data/iceland/roads-line.shp",1)],
1105                    "check": [(None,1)]
1106                   })
1107            self.assertRaises(LoadCancelled,
1108                                load_session, self.filename(), None, s_cb.s_cb)
1109    
1110        def test_05_path_error_fix_from_list_changed(self):
1111            """Test alternative path from list changed."""
1112            s_cb = Shapefile_CallBack({
1113                    "search": [("../Data/iceland/roads-line.shp",1)],
1114                    "check": [("../Data/iceland/roads-line.shp",0)]
1115                   })
1116            self.session = load_session(self.filename(),
1117                                        shapefile_callback =s_cb.s_cb)
1118            self.checkSession(self.session)
1119    
1120        def test_06_path_error_fix_from_list_fails(self):
1121            """Test alternative path recovery from list."""
1122            s_cb = Shapefile_CallBack({
1123                    "search": [("../wrong/iceland/roads-line.shp",1),
1124                                ("../Data/iceland/roads-line.shp",0)],
1125                    "check": [(None,None)]
1126                   })
1127            self.session = load_session(self.filename(),
1128                                        shapefile_callback =s_cb.s_cb)
1129            self.assertRaises(IndexError,
1130                                s_cb.s_cb, None, "search")
1131            
1132    
1133    
1134    if __name__ == "__main__":
1135        support.run_tests()

Legend:
Removed from v.692  
changed lines
  Added in v.2654

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26