/[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 957 by bh, Wed May 21 17:12:22 2003 UTC revision 1989 by bh, Fri Nov 28 12:00:54 2003 UTC
# 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, the tests here should be
20    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.color import Color  from xmlsupport import sax_eventlist
39    
40    import dbflib
41    import shapelib
42    
43    from Thuban.Model.save import save_session
44    from Thuban.Model.load import load_session, parse_color, LoadError, \
45         LoadCancelled
46    from Thuban.Model.color import Transparent
47  from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\  from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\
48      ClassGroupSingleton, ClassGroupDefault      ClassGroupSingleton, ClassGroupDefault
49    from Thuban.Model.postgisdb import ConnectionError
50    from Thuban.Model.table import DBFTable, MemoryTable, \
51         FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING, \
52         table_to_dbf
53    
54    
55  def filenames_equal(name1, name2):  def filenames_equal(name1, name2):
# Line 60  class LoadSessionTest(support.FileLoadTe Line 87  class LoadSessionTest(support.FileLoadTe
87          self.session = None          self.session = None
88    
89    
90        dtd = "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
91        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    
101        # The filenames in the tests should be understandable on all
102        # currently supported platforms so filenames is an empty list
103        filenames = []
104    
105        del n, m, dtd
106    
107        def check_format(self):
108            """Check whether the file we loaded from matches the one that
109            would be written. Call this from each test case after loading
110            the session
111            """
112            filename = self.temp_file_name(self.id() + ".roundtrip.thuban")
113            save_session(self.session, filename)
114            el1 = sax_eventlist(filename = filename, ids = self.thubanids,
115                                idrefs = self.thubanidrefs,
116                                filenames = self.filenames)
117            el2 = sax_eventlist(filename = self.filename(), ids = self.thubanids,
118                                idrefs = self.thubanidrefs,
119                                filenames = self.filenames)
120            if 0:
121                for a, b in zip(el1, el2):
122                    print a != b and "***************" or ""
123                    print a
124                    print b
125            self.assertEquals(el1, el2,
126                              "loaded file not equivalent to the saved file")
127    
128    
129  class ClassificationTest(LoadSessionTest):  class ClassificationTest(LoadSessionTest):
130    
131      """      """
# Line 98  class ClassificationTest(LoadSessionTest Line 164  class ClassificationTest(LoadSessionTest
164                  if data[CLASSES][i][GROUP_TYPE] == "default":                  if data[CLASSES][i][GROUP_TYPE] == "default":
165                      g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])                      g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])
166                  elif data[CLASSES][i][GROUP_TYPE] == "range":                  elif data[CLASSES][i][GROUP_TYPE] == "range":
167                      g = ClassGroupRange(data[CLASSES][i][GROUP_DATA][0],                      g = ClassGroupRange((data[CLASSES][i][GROUP_DATA][0],
168                                          data[CLASSES][i][GROUP_DATA][1],                                           data[CLASSES][i][GROUP_DATA][1]),
169                                          props, data[CLASSES][i][GROUP_LABEL])                                          props, data[CLASSES][i][GROUP_LABEL])
170                  elif data[CLASSES][i][GROUP_TYPE] == "single":                  elif data[CLASSES][i][GROUP_TYPE] == "single":
171                      g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],                      g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],
# Line 113  class ClassificationTest(LoadSessionTest Line 179  class ClassificationTest(LoadSessionTest
179    
180  class TestSingleLayer(LoadSessionTest):  class TestSingleLayer(LoadSessionTest):
181    
182        # Note: The use of & and non-ascii characters is deliberate. We
183        # want to test whether the loading code handles that correctly.
184      file_contents = '''\      file_contents = '''\
185  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
186  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
187  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
188          <map title="Test Map">          title="Stra\xc3\x9fen &amp; Landmarken">
189                  <projection>      <fileshapesource filetype="shapefile" id="D1"
190                          <parameter value="zone=26"/>          filename="../../Data/iceland/political.shp"/>
191                          <parameter value="proj=utm"/>      <map title="\xc3\x9cbersicht">
192                          <parameter value="ellps=clrk66"/>          <projection epsg="32627" name="WGS 84 / UTM zone 27N">
193                  </projection>              <parameter value="datum=WGS84"/>
194                  <layer title="My Layer" stroke_width="1" fill="None"              <parameter value="ellps=WGS84"/>
195                      filename="../../Data/iceland/political.shp"              <parameter value="proj=utm"/>
196                      stroke="#000000"/>              <parameter value="units=m"/>
197          </map>              <parameter value="zone=27"/>
198            </projection>
199            <layer shapestore="D1" visible="true"
200                    stroke="#000000" title="K\xc3\xbcste" stroke_width="1"
201                    fill="None"/>
202        </map>
203  </session>  </session>
204  '''  '''
205    
# Line 137  class TestSingleLayer(LoadSessionTest): Line 210  class TestSingleLayer(LoadSessionTest):
210          self.session = session          self.session = session
211    
212          # Check the title          # Check the title
213          eq(session.Title(), "single map&layer")          eq(session.Title(), "Stra\xdfen & Landmarken")
214    
215          # the session has one map.          # the session has one map.
216          maps = session.Maps()          maps = session.Maps()
# Line 145  class TestSingleLayer(LoadSessionTest): Line 218  class TestSingleLayer(LoadSessionTest):
218    
219          # Check the map's attributes          # Check the map's attributes
220          map = maps[0]          map = maps[0]
221          eq(map.Title(), "Test Map")          eq(map.Title(), "\xdcbersicht")
222            proj = map.GetProjection()
223            eq(proj.GetName(), "WGS 84 / UTM zone 27N")
224            eq(proj.EPSGCode(), "32627")
225            params = proj.GetAllParameters()
226            params.sort()
227            eq(params, ["datum=WGS84", "ellps=WGS84", "proj=utm", "units=m",
228                        "zone=27"])
229    
230          # the map has a single layer          # the map has a single layer
231          layers = map.Layers()          layers = map.Layers()
# Line 153  class TestSingleLayer(LoadSessionTest): Line 233  class TestSingleLayer(LoadSessionTest):
233    
234          # Check the layer attributes          # Check the layer attributes
235          layer = layers[0]          layer = layers[0]
236          eq(layer.Title(), "My Layer")          eq(layer.Title(), "K\xfcste")
237          self.failUnless(filenames_equal(layer.filename,          self.failUnless(filenames_equal(layer.ShapeStore().FileName(),
238                                          os.path.join(self.temp_dir(),                                          os.path.join(self.temp_dir(),
239                                                       os.pardir, os.pardir,                                                       os.pardir, os.pardir,
240                                                       "Data", "iceland",                                                       "Data", "iceland",
241                                                       "political.shp")))                                                       "political.shp")))
242          eq(layer.GetClassification().GetDefaultFill(), Color.Transparent)          eq(layer.GetClassification().GetDefaultFill(), Transparent)
243          eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")          eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")
244          eq(layer.Visible(), True)          eq(layer.Visible(), True)
245    
246            self.check_format()
247    
248          self.session.Destroy()          self.session.Destroy()
249          self.session = None          self.session = None
250    
251        def test_leak(self):
252            """Test load_session for resource leaks
253    
254  class TestLayerVisibility(LoadSessionTest):          The load_session function had a resource leak in that it created
255            cyclic references. The objects would have been eventually
256            collected by the garbage collector but too late. One symptom is
257            that when layers are removed so that the last normal reference
258            owned indirectly by the session to a shape store goes away, the
259            shape store is not actually removed from the session even though
260            the session only keeps weak references because there are still
261            references owned by the cyclic garbage.
262            """
263            session = load_session(self.filename())
264            self.session = session
265    
266            # sanity check
267            self.assertEquals(len(session.ShapeStores()), 1)
268    
269            # remove the map. The shapestore should go away too
270            session.RemoveMap(session.Maps()[0])
271            self.assertEquals(len(session.ShapeStores()), 0)
272    
273    
274    class TestNonAsciiColumnName(LoadSessionTest):
275    
276      file_contents = '''\      file_contents = '''\
277  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
278  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
279  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
280          <map title="Test Map">          title="Non ASCII column name test">
281                  <projection>      <fileshapesource filetype="shapefile" id="D1"
282                          <parameter value="zone=26"/>          filename="TestNonAsciiColumnName.shp"/>
283                          <parameter value="proj=utm"/>      <map title="map">
284                          <parameter value="ellps=clrk66"/>          <projection name="Some Projection">
285                  </projection>              <parameter value="datum=WGS84"/>
286                  <layer title="My Layer" stroke_width="1" fill="None"              <parameter value="ellps=WGS84"/>
287                      filename="../../Data/iceland/political.shp"              <parameter value="proj=utm"/>
288                      stroke="#000000" visible="false">              <parameter value="units=m"/>
289                <parameter value="zone=27"/>
290            </projection>
291            <layer shapestore="D1" visible="true"
292                    stroke="#000000" title="layer" stroke_width="1"
293                    fill="None">
294                <classification field="Fl\xc3\xa4che" field_type="double">
295                    <clnull label="">
296                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
297                    </clnull>
298                </classification>
299          </layer>          </layer>
300      </map>      </map>
301  </session>  </session>
302  '''  '''
303    
304      def test(self):      def test(self):
305            """Load a session with a single map with a single layer"""
306    
307            # Create a shapefile and a dbffile with a non-ascii column name
308            dbffile = self.temp_file_name("TestNonAsciiColumnName.dbf")
309            shpfile = self.temp_file_name("TestNonAsciiColumnName.shp")
310            dbf = dbflib.create(dbffile)
311            dbf.add_field('Fl\xe4che', dbflib.FTDouble, 10, 5)
312            dbf.write_record(0, (0.0,))
313            dbf.close()
314            shp = shapelib.create(shpfile, shapelib.SHPT_POLYGON)
315            shp.write_object(-1, shapelib.SHPObject(shapelib.SHPT_POLYGON, 1,
316                                                    [[(0,0), (10, 10), (10, 0),
317                                                      (0, 0)]]))
318            shp.close()
319    
320            try:
321                session = load_session(self.filename())
322            except ValueError, v:
323                # Usually if the field name is not decoded properly the
324                # loading fails because the field type mentioned in the file
325                # is not None as returned from the layer for a non-existing
326                # column name so we check for that and report it as failure.
327                # Other exceptions are errors in the test case.
328                if str(v) == "xml field type differs from database!":
329                    self.fail("Cannot load file with non-ascii column names")
330                else:
331                    raise
332            self.session = session
333    
334            # In case Thuban could load the file anyway (i.e. no ValueError
335            # exception in load_session()), check explicitly whether the
336            # field name was decoded properly. The test will probably lead
337            # to a UnicodeError instead of a test failure so we check that
338            # too
339            layer = session.Maps()[0].Layers()[0]
340            try:
341                self.assertEquals(layer.GetClassificationColumn(), 'Fl\xe4che')
342            except UnicodeError:
343                # FIXME: Obviously this will have to change if Thuban ever
344                # supports unicode properly.
345                self.fail("Column name was not converted to a bytestring")
346    
347            # roundtrip check
348            self.check_format()
349    
350    
351    class TestLayerVisibility(LoadSessionTest):
352    
353        file_contents = '''\
354    <?xml version="1.0" encoding="UTF-8"?>
355    <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
356    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
357            title="single map&amp;layer">
358        <fileshapesource filetype="shapefile" id="D1"
359            filename="../../Data/iceland/political.shp"/>
360        <map title="Test Map">
361            <projection name="Unknown">
362                <parameter value="zone=26"/>
363                <parameter value="proj=utm"/>
364                <parameter value="ellps=clrk66"/>
365            </projection>
366            <layer shapestore="D1" visible="false" stroke="#000000"
367                    title="My Layer" stroke_width="1" fill="None"/>
368        </map>
369    </session>
370    '''
371    
372        def test(self):
373          """Test that the visible flag is correctly loaded for a layer."""          """Test that the visible flag is correctly loaded for a layer."""
374          eq = self.assertEquals          eq = self.assertEquals
375          session = load_session(self.filename())          session = load_session(self.filename())
# Line 201  class TestLayerVisibility(LoadSessionTes Line 383  class TestLayerVisibility(LoadSessionTes
383    
384          eq(layer.Visible(), False)          eq(layer.Visible(), False)
385    
386            self.check_format()
387    
388    
389  class TestClassification(ClassificationTest):  class TestClassification(ClassificationTest):
390    
391      file_contents = '''\      file_contents = '''\
392  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
393  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
394  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
395          <map title="Test Map">          title="single map&amp;layer">
396                  <projection>      <fileshapesource filetype="shapefile" id="D138389860"
397                          <parameter value="zone=26"/>          filename="../../Data/iceland/political.shp"/>
398                          <parameter value="proj=utm"/>      <fileshapesource filetype="shapefile" id="D138504492"
399                          <parameter value="ellps=clrk66"/>          filename="../../Data/iceland/political.shp"/>
400                  </projection>      <map title="Test Map">
401                  <layer title="My Layer" stroke_width="1" fill="None"          <projection name="">
402                      filename="../../Data/iceland/political.shp"              <parameter value="zone=26"/>
403                      stroke="#000000">              <parameter value="proj=utm"/>
404                <parameter value="ellps=clrk66"/>
405            </projection>
406            <layer shapestore="D138389860" visible="true" stroke="#000000"
407                    title="My Layer" stroke_width="1" fill="None">
408              <classification field="POPYREG" field_type="string">              <classification field="POPYREG" field_type="string">
409                  <clnull>                  <clnull label="">
410                      <cldata stroke="#000000" stroke_width="1" fill="None"/>                      <cldata stroke="#000000" stroke_width="1" fill="None"/>
411                  </clnull>                  </clnull>
412                  <clpoint value="1">                  <clpoint label="" value="1">
413                      <cldata stroke="#000000" stroke_width="2" fill="None"/>                      <cldata stroke="#000000" stroke_width="2" fill="None"/>
414                  </clpoint>                  </clpoint>
415                  <clpoint value="1">                  <clpoint label="" value="1">
416                      <cldata stroke="#000000" stroke_width="10" fill="None"/>                      <cldata stroke="#000000" stroke_width="10" fill="None"/>
417                  </clpoint>                  </clpoint>
418                    <clpoint label="\xc3\x9cml\xc3\xa4uts"
419                            value="\xc3\xa4\xc3\xb6\xc3\xbc">
420                        <cldata stroke="#000000" stroke_width="1" fill="None"/>
421                    </clpoint>
422              </classification>              </classification>
423          </layer>          </layer>
424                  <layer title="My Layer 2" stroke_width="1" fill="None"          <layer shapestore="D138504492" visible="true" stroke="#000000"
425                      filename="../../Data/iceland/political.shp"                  title="My Layer 2" stroke_width="2" fill="None">
                     stroke="#000000">  
426              <classification field="AREA" field_type="double">              <classification field="AREA" field_type="double">
427                  <clnull>                  <clnull label="">
428                      <cldata stroke="#000000" stroke_width="2" fill="None"/>                      <cldata stroke="#000000" stroke_width="2" fill="None"/>
429                  </clnull>                  </clnull>
430                  <clrange min="0" max="1">                  <clrange label="" range="[0;1[">
431                      <cldata stroke="#111111" stroke_width="1" fill="None"/>                      <cldata stroke="#111111" stroke_width="1" fill="None"/>
432                  </clrange>                  </clrange>
433                  <clpoint value=".5">                  <clpoint label="" value="0.5">
434                      <cldata stroke="#000000" stroke_width="1" fill="#111111"/>                      <cldata stroke="#000000" stroke_width="1" fill="#111111"/>
435                  </clpoint>                  </clpoint>
436                  <clrange min="-1" max="0">                  <clrange label="" range="[-1;0[">
437                      <cldata stroke="#000000" stroke_width="1" fill="None"/>                      <cldata stroke="#000000" stroke_width="1" fill="None"/>
438                  </clrange>                  </clrange>
439                  <clpoint value="-.5">                  <clpoint label="" value="-0.5">
440                      <cldata stroke="#000000" stroke_width="1" fill="None"/>                      <cldata stroke="#000000" stroke_width="1" fill="None"/>
441                  </clpoint>                  </clpoint>
442              </classification>              </classification>
443          </layer>          </layer>
444          </map>      </map>
445  </session>  </session>
446  '''  '''
447    
448      def test(self):      def test(self):
449          """Load a Thuban 0.2 session with a map and classified layers."""          """Load a Thuban session with a map and classified layers."""
450          session = load_session(self.filename())          session = load_session(self.filename())
451          self.session = session          self.session = session
452    
453          map = self.session.Maps()[0] # only one map in the sample          map = self.session.Maps()[0] # only one map in the sample
454    
455          expected = [("My Layer", 2,          expected = [("My Layer", 3,
456                          [("default", (), "",                          [("default", (), "",
457                              ("#000000", 1, "None")),                              ("#000000", 1, "None")),
458                           ("single", "1", "",                           ("single", "1", "",
459                              ("#000000", 2, "None")),                              ("#000000", 2, "None")),
460                           ("single", "1", "",                           ("single", "1", "",
461                              ("#000000", 10, "None"))]),                              ("#000000", 10, "None")),
462                             ("single", "\xe4\xf6\xfc", "\xdcml\xe4uts",
463                                ("#000000", 1, "None"))]),
464                       ("My Layer 2", 4,                       ("My Layer 2", 4,
465                           [("default", (), "",                           [("default", (), "",
466                              ("#000000", 2, "None")),                              ("#000000", 2, "None")),
# Line 284  class TestClassification(ClassificationT Line 475  class TestClassification(ClassificationT
475    
476          self.TestLayers(map.Layers(), expected)          self.TestLayers(map.Layers(), expected)
477    
478            self.check_format()
479    
480    
481  class TestLabels(ClassificationTest):  class TestLabels(ClassificationTest):
482    
483      file_contents = '''\      file_contents = '''\
484  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
485  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
486  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
487          <map title="Test Map">          title="single map&amp;layer">
488                  <projection>      <fileshapesource filetype="shapefile" id="D1"
489                          <parameter value="zone=26"/>          filename="../../Data/iceland/political.shp"/>
490                          <parameter value="proj=utm"/>      <map title="Test Map">
491                          <parameter value="ellps=clrk66"/>          <projection name="Unknown">
492                  </projection>              <parameter value="zone=26"/>
493                  <layer title="My Layer" stroke_width="1" fill="None"              <parameter value="proj=utm"/>
494                      filename="../../Data/iceland/political.shp"              <parameter value="ellps=clrk66"/>
495                      stroke="#000000">          </projection>
496            <layer shapestore="D1" visible="true" stroke="#000000"
497                    title="My Layer" stroke_width="1" fill="None">
498              <classification field="POPYREG" field_type="string">              <classification field="POPYREG" field_type="string">
499                  <clnull label="hallo">                  <clnull label="hallo">
500                      <cldata stroke="#000000" stroke_width="1" fill="None"/>                      <cldata stroke="#000000" stroke_width="1" fill="None"/>
# Line 328  class TestLabels(ClassificationTest): Line 523  class TestLabels(ClassificationTest):
523                              ("#000000", 2, "None"))])]                              ("#000000", 2, "None"))])]
524    
525          self.TestLayers(map.Layers(), expected)          self.TestLayers(map.Layers(), expected)
526            self.check_format()
527    
528    
529  class TestLayerProjection(LoadSessionTest):  class TestLayerProjection(LoadSessionTest):
530    
531      file_contents = '''\      file_contents = '''\
532  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
533  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
534  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
535          <map title="Test Map">          title="single map&amp;layer">
536                  <projection>      <fileshapesource filetype="shapefile" id="D2"
537                          <parameter value="zone=26"/>          filename="../../Data/iceland/roads-line.shp"/>
538                          <parameter value="proj=utm"/>      <fileshapesource filetype="shapefile" id="D4"
539                          <parameter value="ellps=clrk66"/>          filename="../../Data/iceland/political.shp"/>
540                  </projection>      <map title="Test Map">
541                  <layer title="My Layer" stroke_width="1" fill="None"          <projection name="Unknown">
542                      filename="../../Data/iceland/political.shp"              <parameter value="zone=26"/>
543                      stroke="#000000">              <parameter value="proj=utm"/>
544                      <projection name="hello">              <parameter value="ellps=clrk66"/>
545                          <parameter value="zone=13"/>          </projection>
546                          <parameter value="proj=tmerc"/>          <layer shapestore="D4" visible="true" stroke="#000000"
547                          <parameter value="ellps=clrk66"/>                  title="My Layer" stroke_width="1" fill="None">
548                      </projection>              <projection name="hello">
549                    <parameter value="zone=13"/>
550                    <parameter value="proj=tmerc"/>
551                    <parameter value="ellps=clrk66"/>
552                </projection>
553              <classification field="POPYREG" field_type="string">              <classification field="POPYREG" field_type="string">
554                  <clnull label="hallo">                  <clnull label="hallo">
555                      <cldata stroke="#000000" stroke_width="1" fill="None"/>                      <cldata stroke="#000000" stroke_width="1" fill="None"/>
# Line 359  class TestLayerProjection(LoadSessionTes Line 559  class TestLayerProjection(LoadSessionTes
559                  </clpoint>                  </clpoint>
560              </classification>              </classification>
561          </layer>          </layer>
562                  <layer title="My Layer" stroke_width="1" fill="None"          <layer shapestore="D2" visible="true" stroke="#000000"
563                      filename="../../Data/iceland/political.shp"                  title="My Layer" stroke_width="1" fill="None">
564                      stroke="#000000">              <projection name="Unknown">
565                      <projection>                  <parameter value="proj=lcc"/>
566                          <parameter value="proj=lcc"/>                  <parameter value="lat_1=10"/>
567                          <parameter value="ellps=clrk66"/>                  <parameter value="lat_2=20"/>
568                      </projection>                  <parameter value="ellps=clrk66"/>
569                </projection>
570          </layer>          </layer>
571      </map>      </map>
572  </session>  </session>
# Line 396  class TestLayerProjection(LoadSessionTes Line 597  class TestLayerProjection(LoadSessionTes
597          neq(proj, None)          neq(proj, None)
598          eq(proj.GetName(), "Unknown")          eq(proj.GetName(), "Unknown")
599          eq(proj.GetParameter("proj"), "lcc")          eq(proj.GetParameter("proj"), "lcc")
600            eq(proj.GetParameter("lat_1"), "10")
601            eq(proj.GetParameter("lat_2"), "20")
602          eq(proj.GetParameter("ellps"), "clrk66")          eq(proj.GetParameter("ellps"), "clrk66")
603    
604            self.check_format()
605    
606    
607  class TestRasterLayer(LoadSessionTest):  class TestRasterLayer(LoadSessionTest):
608    
609      file_contents = '''\      file_contents = '''\
610  <?xml version="1.0" encoding="UTF-8"?>  <?xml version="1.0" encoding="UTF-8"?>
611  <!DOCTYPE session SYSTEM "thuban.dtd">  <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
612  <session title="single map&amp;layer">  <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
613          <map title="Test Map">          title="single map&amp;layer">
614                  <rasterlayer title="My RasterLayer"      <map title="Test Map">
615                       filename="../../Data/iceland/island.tif"          <rasterlayer visible="false" filename="../../Data/iceland/island.tif"
616                       visible="false">                  title="My RasterLayer"/>
         </rasterlayer>  
617      </map>      </map>
618  </session>  </session>
619  '''  '''
# Line 432  class TestRasterLayer(LoadSessionTest): Line 636  class TestRasterLayer(LoadSessionTest):
636                                                       os.pardir, os.pardir,                                                       os.pardir, os.pardir,
637                                                       "Data", "iceland",                                                       "Data", "iceland",
638                                                       "island.tif")))                                                       "island.tif")))
639            self.check_format()
640    
641    
642    class TestJoinedTable(LoadSessionTest):
643    
644        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
645    <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
646    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd" title="A Joined Table session">
647        <fileshapesource filetype="shapefile" id="D137227612"
648            filename="../../Data/iceland/roads-line.shp"/>
649        <filetable filetype="DBF" filename="load_joinedtable.dbf" id="D136171140"
650            title="Some Title"/>
651        <jointable id="D136169900" title="Joined"
652            right="D136171140" left="D137227612"
653            leftcolumn="RDLNTYPE" rightcolumn="RDTYPE"
654            jointype="LEFT OUTER"/>
655        <derivedshapesource table="D136169900" shapesource="D137227612"
656            id="D136170932"/>
657        <map title="Test Map">
658            <layer shapestore="D136170932" visible="true" stroke="#000000"
659                    title="My Layer" stroke_width="1" fill="None"/>
660        </map>
661    </session>
662    '''
663    
664        def setUp(self):
665            """Extend inherited method to create the dbffile for the join"""
666            LoadSessionTest.setUp(self)
667            dbffile = self.temp_file_name("load_joinedtable.dbf")
668            dbf = dbflib.create(dbffile)
669            dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
670            dbf.add_field("TEXT", dbflib.FTString, 10, 0)
671            dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
672            dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
673            dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
674            dbf.close()
675    
676        def test(self):
677            """Test loading a session containing a joined table"""
678            session = load_session(self.filename())
679            self.session = session
680    
681            tables = session.Tables()
682            self.assertEquals(len(tables), 3)
683            # FIXME: The tests shouldn't assume a certain order of the tables
684            self.assertEquals(tables[0].Title(), "Some Title")
685            self.assertEquals(tables[1].Title(), "Joined")
686            self.assertEquals(tables[1].JoinType(), "LEFT OUTER")
687            self.check_format()
688    
689    
690    
691    class TestPostGISLayer(LoadSessionTest):
692    
693        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
694    <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
695    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
696            title="unnamed session">
697        <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
698            dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
699        <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
700        <map title="unnamed map">
701            <layer shapestore="D143149420" visible="true" stroke="#000000"
702                    title="landmarks" stroke_width="1" fill="None"/>
703        </map>
704    </session>
705    '''
706    
707        def setUp(self):
708            """Extend the inherited method to start the postgis server
709    
710            Furthermore, patch the file contents with the real postgis db
711            information
712            """
713            postgissupport.skip_if_no_postgis()
714            self.server = postgissupport.get_test_server()
715            self.postgisdb = self.server.get_default_static_data_db()
716    
717            self.file_contents = self.__class__.file_contents % {
718                "dbname": self.postgisdb.dbname,
719                "user": self.server.user_name,
720                "port": self.server.port,
721                "host": self.server.host}
722            LoadSessionTest.setUp(self)
723    
724        def test(self):
725            """Test loading a session containing a postgis shapestore"""
726            session = load_session(self.filename())
727            self.session = session
728            connections = session.DBConnections()
729            self.assertEquals(len(connections), 1)
730            conn = connections[0]
731            for attr, value in [("host", self.server.host),
732                                ("port", str(self.server.port)),
733                                ("user", self.server.user_name),
734                                ("dbname", self.postgisdb.dbname)]:
735                self.assertEquals(getattr(conn, attr), value)
736            layer = session.Maps()[0].Layers()[0]
737            self.failUnless(layer.ShapeStore().DBConnection() is conn)
738    
739    
740    class TestPostGISLayerPassword(LoadSessionTest):
741    
742        file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
743    <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
744    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
745            title="unnamed session">
746        <dbconnection port="%(port)s" host="%(host)s" user="%(user)s"
747            dbtype="postgis" id="D142684948" dbname="%(dbname)s"/>
748        <dbshapesource tablename="landmarks" id="D143149420" dbconn="D142684948"/>
749        <map title="unnamed map">
750            <layer shapestore="D143149420" visible="true" stroke="#000000"
751                    title="landmarks" stroke_width="1" fill="None"/>
752        </map>
753    </session>
754    '''
755    
756        def setUp(self):
757            """Extend the inherited method to start the postgis server
758    
759            Furthermore, patch the file contents with the real postgis db
760            information
761            """
762            postgissupport.skip_if_no_postgis()
763            self.server = postgissupport.get_test_server()
764            self.postgisdb = self.server.get_default_static_data_db()
765    
766            self.file_contents = self.__class__.file_contents % {
767                "dbname": self.postgisdb.dbname,
768                "user": self.server.user_name,
769                "port": self.server.port,
770                "host": self.server.host}
771            LoadSessionTest.setUp(self)
772    
773            self.db_connection_callback_called = False
774            self.server.require_authentication(True)
775    
776        def tearDown(self):
777            """Extend the inherited method to switch off postgresql authentication
778            """
779            self.server.require_authentication(False)
780            LoadSessionTest.tearDown(self)
781    
782        def db_connection_callback(self, params, message):
783            """Implementation of Thuban.Model.hooks.query_db_connection_parameters
784            """
785            self.assertEquals(params,
786                              {"dbname": self.postgisdb.dbname,
787                               "user": self.server.user_name,
788                               "port": str(self.server.port),
789                               "host": self.server.host})
790            self.db_connection_callback_called = True
791            params = params.copy()
792            params["password"] = self.server.user_password
793            return params
794    
795        def test_with_callback(self):
796            """Test loading a session with postgis, authentication and a callback
797            """
798            session = load_session(self.filename(),
799                          db_connection_callback = self.db_connection_callback)
800            self.session = session
801            connections = session.DBConnections()
802            self.assertEquals(len(connections), 1)
803            conn = connections[0]
804            for attr, value in [("host", self.server.host),
805                                ("port", str(self.server.port)),
806                                ("user", self.server.user_name),
807                                ("dbname", self.postgisdb.dbname)]:
808                self.assertEquals(getattr(conn, attr), value)
809            layer = session.Maps()[0].Layers()[0]
810            self.failUnless(layer.ShapeStore().DBConnection() is conn)
811            self.failUnless(self.db_connection_callback_called)
812    
813        def test_without_callback(self):
814            """Test loading a session with postgis, authentication and no callback
815            """
816            # A password is required and there's no callback, so we should
817            # get a ConnectionError
818            self.assertRaises(ConnectionError, load_session, self.filename())
819    
820        def test_cancel(self):
821            """Test loading a session with postgis and cancelling authentication
822            """
823            def cancel(*args):
824                self.db_connection_callback_called = True
825                return None
826    
827            # If the user cancels, i.e. if the callbakc returns None, a
828            # LoadCancelled exception is raised.
829            self.assertRaises(LoadCancelled,
830                              load_session, self.filename(), cancel)
831            self.failUnless(self.db_connection_callback_called)
832    
833    
834    class TestLoadError(LoadSessionTest):
835    
836        file_contents = '''\
837    <?xml version="1.0" encoding="UTF-8"?>
838    <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
839    <session xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
840            title="single map&amp;layer">
841        <fileshapesource id="D1" filename="../../Data/iceland/political.shp"/>
842        <map title="Test Map">
843            <projection name="Unknown">
844                <parameter value="zone=26"/>
845                <parameter value="proj=utm"/>
846                <parameter value="ellps=clrk66"/>
847            </projection>
848            <layer shapestore="D1" visible="true"
849                    stroke="#000000" title="My Layer" stroke_width="1"
850                    fill="None"/>
851        </map>
852    </session>
853    '''
854    
855        def test(self):
856            """Test loading a session missing a required attribute"""
857            # Don't use assertRaises to make sure that if a session is
858            # actually returned it gets destroyed properly.
859            try:
860                self.session = load_session(self.filename())
861            except LoadError, value:
862                # Check the actual messge in value to make sure the
863                # LoadError really was about the missing attribute
864                self.assertEquals(str(value),
865                  "Element "
866                  "(u'http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd',"
867                  " u'fileshapesource') requires an attribute 'filetype'")
868            else:
869                self.fail("Missing filetype attribute doesn't raise LoadError")
870    
871  if __name__ == "__main__":  if __name__ == "__main__":
872      unittest.main()      support.run_tests()

Legend:
Removed from v.957  
changed lines
  Added in v.1989

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26