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

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

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

trunk/thuban/test/test_save.py revision 1168 by jonathan, Thu Jun 12 12:42:50 2003 UTC branches/WIP-pyshapelib-bramz/test/test_save.py revision 2734 by bramz, Thu Mar 1 12:42:59 2007 UTC
# Line 1  Line 1 
1  # Copyright (c) 2002, 2003 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 17  import os Line 17  import os
17  import unittest  import unittest
18  from StringIO import StringIO  from StringIO import StringIO
19    
20  import xml.sax  import xmlsupport
21  import xml.sax.handler  import postgissupport
 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException  
22    
23  import support  import support
24  support.initthuban()  support.initthuban()
25    
26  from Thuban.Model.save import XMLWriter, save_session  import dbflib
27    
28    from Thuban import internal_from_unicode
29    from Thuban.Lib.fileutil import relative_filename
30    from Thuban.Model.save import XMLWriter, save_session, sort_data_stores
31  from Thuban.Model.session import Session  from Thuban.Model.session import Session
32  from Thuban.Model.map import Map  from Thuban.Model.map import Map
33  from Thuban.Model.layer import Layer, RasterLayer  from Thuban.Model.layer import Layer, RasterLayer
34  from Thuban.Model.proj import Projection  from Thuban.Model.proj import Projection
35    from Thuban.Model.table import DBFTable
36    from Thuban.Model.transientdb import TransientJoinedTable
37    from Thuban.Model.data import DerivedShapeStore, SHAPETYPE_ARC
38    
39  from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \  from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
40      ClassGroupProperties      ClassGroupPattern, ClassGroupProperties
41    
42  from Thuban.Model.range import Range  from Thuban.Model.range import Range
43    
44    from Thuban.Model.postgisdb import PostGISConnection, PostGISShapeStore
45    
 class SaxEventLister(xml.sax.handler.ContentHandler):  
   
     def __init__(self):  
         self.eventlist = []  
   
     def startElementNS(self, name, qname, attrs):  
         items = attrs.items()  
         items.sort()  
         self.eventlist.append(("start", name, qname, items))  
   
     def endElementNS(self, name, qname):  
         self.eventlist.append(("end", name, qname))  
   
   
 def sax_eventlist(data):  
     """Return a list of SAX event generated for the XML data.  
     """  
     handler = SaxEventLister()  
     parser = make_parser()  
     parser.setContentHandler(handler)  
     parser.setErrorHandler(ErrorHandler())  
     parser.setFeature(xml.sax.handler.feature_namespaces, 1)  
   
     #  
     # see comment at the end of Thuban/Model/load.py  
     #  
     try:  
         parser.setFeature(xml.sax.handler.feature_validation, 0)  
         parser.setFeature(xml.sax.handler.feature_external_ges, 0)  
         parser.setFeature(xml.sax.handler.feature_external_pes, 0)  
     except SAXNotRecognizedException:  
         pass  
   
     inpsrc = xml.sax.InputSource()  
     inpsrc.setByteStream(StringIO(data))  
     parser.parse(inpsrc)  
   
     return handler.eventlist  
46    
47  class XMLWriterTest(unittest.TestCase):  class XMLWriterTest(unittest.TestCase):
48    
49      def testEncode(self):      def testEncode(self):
50          """Test XMLWriter.encode"""          """Test XMLWriter.encode"""
51          writer = XMLWriter()          writer = XMLWriter()
52            eq = self.assertEquals
53    
54            eq(writer.encode("hello world"), "hello world")
55            eq(writer.encode(unicode("hello world")), unicode("hello world"))
56    
57          writer.encode("hello world")          eq(writer.encode(internal_from_unicode(u"\x80\x90\xc2\x100")),
58          writer.encode(unicode("hello world"))                           "\xc2\x80\xc2\x90\xc3\x82\x100")
59          self.assertEquals(writer.encode('&"\'<>'),          eq(writer.encode(u"\x80\x90\xc2\x100"),
60                            "&amp;&quot;&apos;&lt;&gt;")                           "\xc2\x80\xc2\x90\xc3\x82\x100")
61          self.assertEquals(writer.encode(unicode('&"\'<>')),          eq(writer.encode(u"\xFF5E"), "\xc3\xbf5E")
62                            "&amp;&quot;&apos;&lt;&gt;")  
63            eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
64            eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
65    
66    class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
67                          xmlsupport.ValidationTest):
68    
69        dtd = "http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"
70        thubanids = [((dtd, n), (None, "id")) for n in
71                     ["fileshapesource", "filetable", "jointable",
72                      "derivedshapesource", "dbshapesource", "dbconnection"]]
73        thubanidrefs = [((dtd, n), (None, m)) for n, m in
74                        [("layer", "shapestore"),
75                         ("jointable", "left"),
76                         ("jointable", "right"),
77                         ("derivedshapesource", "table"),
78                         ("derivedshapesource", "shapesource"),
79                         ("dbshapesource", "dbconn")]]
80        del n, m, dtd
81    
82  class SaveSessionTest(unittest.TestCase, support.FileTestMixin):      def tearDown(self):
83            """Call self.session.Destroy
84    
85            Test cases that create session should bind it to self.session so
86            that it gets destroyed properly
87            """
88            if hasattr(self, "session"):
89                self.session.Destroy()
90                self.session = None
91    
92      def compare_xml(self, xml1, xml2):      def compare_xml(self, xml1, xml2):
93          self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))          list1 = xmlsupport.sax_eventlist(xml1, ids = self.thubanids,
94                                             idrefs = self.thubanidrefs)
95            list2 = xmlsupport.sax_eventlist(xml2, ids = self.thubanids,
96                                             idrefs = self.thubanidrefs)
97            if list1 != list2:
98                for a, b in zip(list1, list2):
99                    if a != b:
100                        self.fail("%r != %r" % (a, b))
101    
102    
103      def testEmptySession(self):      def testEmptySession(self):
104          """Save an empty session"""          """Save an empty session"""
# Line 105  class SaveSessionTest(unittest.TestCase, Line 112  class SaveSessionTest(unittest.TestCase,
112          file.close()          file.close()
113          self.compare_xml(written_contents,          self.compare_xml(written_contents,
114                           '<?xml version="1.0" encoding="UTF-8"?>\n'                           '<?xml version="1.0" encoding="UTF-8"?>\n'
115                           '<!DOCTYPE session SYSTEM "thuban.dtd">\n'                           '<!DOCTYPE session SYSTEM "thuban-1.1.dtd">\n'
116                           '<session title="empty session">\n</session>\n')                           '<session title="empty session" '
117             'xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">'
118                             '\n</session>\n')
119    
120            self.validate_data(written_contents)
121    
122      def testSingleLayer(self):      def testSingleLayer(self):
123          """Save a session with a single map with a single layer"""          """Save a session with a single map with a single layer"""
124          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
125          session = Session("single map&layer")          session = Session("single map&layer")
126          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["proj=utm", "zone=27", "ellps=WGS84",
127                               "datum=WGS84", "units=m"],
128                              name = "WGS 84 / UTM zone 27N",
129                              epsg = "32627")
130          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
131          session.AddMap(map)          session.AddMap(map)
132          # use shapefile from the example data          # use shapefile from the example data
# Line 128  class SaveSessionTest(unittest.TestCase, Line 142  class SaveSessionTest(unittest.TestCase,
142          written_contents = file.read()          written_contents = file.read()
143          file.close()          file.close()
144          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
145          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
146          <session title="single map&amp;layer">          <session title="single map&amp;layer"
147               xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
148                <fileshapesource id="D1"
149                    filename="../../Data/iceland/political.shp"
150                    filetype="shapefile"/>
151              <map title="Test Map">              <map title="Test Map">
152                  <projection name="Unknown">                  <projection epsg="32627" name="WGS 84 / UTM zone 27N">
                     <parameter value="zone=26"/>  
153                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
154                      <parameter value="ellps=clrk66"/>                      <parameter value="zone=27"/>
155                        <parameter value="ellps=WGS84"/>
156                        <parameter value="datum=WGS84"/>
157                        <parameter value="units=m"/>
158                  </projection>                  </projection>
159                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1" visible="%s">
160                  fill="None" stroke="#000000" stroke_width="1" visible="%s"/>                      <classification>
161                            <clnull label="">
162                                <cldata fill="None" stroke="#000000"
163                                    stroke_width="1"/>
164                            </clnull>
165                        </classification>
166                    </layer>
167              </map>              </map>
168          </session>'''          </session>'''
169            
170          expected_contents = expected_template % \          expected_contents = expected_template % "true"
             (os.path.join("..", "..", "Data", "iceland", "political.shp"),  
              "true")  
171    
         #print written_contents  
         #print "********************************************"  
         #print expected_contents  
172          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
173    
174            self.validate_data(written_contents)
175    
176            # Repeat with an invisible layer
177          layer.SetVisible(False)          layer.SetVisible(False)
178          save_session(session, filename)          save_session(session, filename)
179    
180          file = open(filename)          file = open(filename)
181          written_contents = file.read()          written_contents = file.read()
182          file.close()          file.close()
183          expected_contents = expected_template % \          expected_contents = expected_template % "false"
             (os.path.join("..", "..", "Data", "iceland", "political.shp"),  
              "false")  
   
         #print written_contents  
         #print "********************************************"  
         #print expected_contents  
184          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
185            self.validate_data(written_contents)
186    
187          session.Destroy()          session.Destroy()
188    
189      def testLayerProjection(self):      def testLayerProjection(self):
190            """Test saving layers with projections"""
191          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
192          session = Session("single map&layer")          session = self.session = Session("single map&layer")
193          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
194          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
195          session.AddMap(map)          session.AddMap(map)
# Line 177  class SaveSessionTest(unittest.TestCase, Line 197  class SaveSessionTest(unittest.TestCase,
197          shpfile = os.path.join(os.path.dirname(__file__),          shpfile = os.path.join(os.path.dirname(__file__),
198                                 os.pardir, "Data", "iceland", "political.shp")                                 os.pardir, "Data", "iceland", "political.shp")
199          layer = Layer("My Layer", session.OpenShapefile(shpfile))          layer = Layer("My Layer", session.OpenShapefile(shpfile))
200          proj = Projection(["proj=lcc", "ellps=clrk66"], "Layer Projection")          proj = Projection(["proj=lcc", "ellps=clrk66",
201                               "lat_1=0", "lat_2=20"],
202                              "Layer Projection")
203          layer.SetProjection(proj)          layer.SetProjection(proj)
204          map.AddLayer(layer)          map.AddLayer(layer)
205    
206          filename = self.temp_file_name("save_singlemap.thuban")          filename = self.temp_file_name("save_layerproj.thuban")
207          save_session(session, filename)          save_session(session, filename)
         session.Destroy()  
208    
209          file = open(filename)          file = open(filename)
210          written_contents = file.read()          written_contents = file.read()
211          file.close()          file.close()
212          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
213          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
214          <session title="single map&amp;layer">          <session title="single map&amp;layer"
215               xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
216                <fileshapesource id="D1"
217                    filename="../../Data/iceland/political.shp"
218                    filetype="shapefile"/>
219              <map title="Test Map">              <map title="Test Map">
220                  <projection name="Unknown">                  <projection name="Unknown">
221                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
222                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
223                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
224                  </projection>                  </projection>
225                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1" visible="true">
                 fill="None" stroke="#000000" stroke_width="1" visible="true">  
226                      <projection name="Layer Projection">                      <projection name="Layer Projection">
227                          <parameter value="proj=lcc"/>                          <parameter value="proj=lcc"/>
228                          <parameter value="ellps=clrk66"/>                          <parameter value="ellps=clrk66"/>
229                            <parameter value="lat_1=0"/>
230                            <parameter value="lat_2=20"/>
231                      </projection>                      </projection>
232                        <classification>
233                            <clnull label="">
234                                <cldata fill="None" stroke="#000000"
235                                    stroke_width="1"/>
236                            </clnull>
237                        </classification>
238                  </layer>                  </layer>
239              </map>              </map>
240          </session>''' % os.path.join("..", "..", "Data", "iceland",          </session>'''
                                      "political.shp")  
241          #print written_contents          #print written_contents
242          #print "********************************************"          #print "********************************************"
243          #print expected_contents          #print expected_contents
244          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
245    
246                    self.validate_data(written_contents)
247    
248      def testRasterLayer(self):      def testRasterLayer(self):
249          # deliberately put an apersand in the title :)  
250          session = Session("single map&layer")          MASK_NONE = RasterLayer.MASK_NONE
251          map = Map("Test Map")          MASK_BIT = RasterLayer.MASK_BIT
252          session.AddMap(map)          MASK_ALPHA = RasterLayer.MASK_ALPHA
253          # use shapefile from the example data  
254          imgfile = os.path.join(os.path.dirname(__file__),          for opacity, masktype, opname, maskname in \
255                                 os.pardir, "Data", "iceland", "island.tif")              [(1,  MASK_BIT,   '', ''),
256          layer = RasterLayer("My RasterLayer", imgfile)               (.2, MASK_BIT,   'opacity="0.2"', ''),
257          map.AddLayer(layer)               (1,  MASK_ALPHA, '',              'masktype="alpha"'),
258                                                                                                 (.5, MASK_ALPHA, 'opacity="0.5"', 'masktype="alpha"'),
259          filename = self.temp_file_name("save_singlemap.thuban")               (1,  MASK_NONE,  '',              'masktype="none"'),
260          save_session(session, filename)               (0,  MASK_NONE,  'opacity="0"',   'masktype="none"') ]:
261          session.Destroy()  
262                                                                                    
263          file = open(filename)              # deliberately put an apersand in the title :)
264          written_contents = file.read()              session = Session("single map&layer")
265          file.close()              map = Map("Test Map")
266          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>              session.AddMap(map)
267          <!DOCTYPE session SYSTEM "thuban.dtd">              # use shapefile from the example data
268          <session title="single map&amp;layer">              imgfile = os.path.join(os.path.dirname(__file__),
269              <map title="Test Map">                                     os.pardir, "Data", "iceland", "island.tif")
270                  <rasterlayer title="My RasterLayer" filename="%s"              layer = RasterLayer("My RasterLayer", imgfile)
271                               visible="true">  
272                  </rasterlayer>              layer.SetOpacity(opacity)
273              </map>              layer.SetMaskType(masktype)
274          </session>''' % os.path.join(os.path.dirname(__file__),  
275                                       os.pardir, "Data", "iceland",              map.AddLayer(layer)
276                                       "island.tif")  
277          #print written_contents              filename = self.temp_file_name("%s.thuban" % self.id())
278          #print "********************************************"              save_session(session, filename)
279          #print expected_contents              session.Destroy()
280          self.compare_xml(written_contents, expected_contents)  
281                file = open(filename)
282                written_contents = file.read()
283                file.close()
284                expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
285                <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
286                <session title="single map&amp;layer"
287                   xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
288                    <map title="Test Map">
289                        <rasterlayer title="My RasterLayer"
290                                filename="../../Data/iceland/island.tif"
291                                visible="true" %s %s>
292                        </rasterlayer>
293                    </map>
294                </session>''' % (opname, maskname)
295                #print written_contents
296                #print "********************************************"
297                #print expected_contents
298                self.compare_xml(written_contents, expected_contents)
299    
300                self.validate_data(written_contents)
301    
302      def testClassifiedLayer(self):      def testClassifiedLayer(self):
303          """Save a session with a single map with a single layer          """Save a session with a single map with classifications"""
            with a classificaton.  
         """  
304          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
305          session = Session("single map&layer")          session = Session("Map with Classifications")
306          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
307          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
308          session.AddMap(map)          session.AddMap(map)
# Line 261  class SaveSessionTest(unittest.TestCase, Line 311  class SaveSessionTest(unittest.TestCase,
311                                 os.pardir, "Data", "iceland", "political.shp")                                 os.pardir, "Data", "iceland", "political.shp")
312          layer = Layer("My Layer", session.OpenShapefile(shpfile))          layer = Layer("My Layer", session.OpenShapefile(shpfile))
313          map.AddLayer(layer)          map.AddLayer(layer)
314            layer2 = Layer("My Layer", layer.ShapeStore())
315            map.AddLayer(layer2)
316    
317          clazz = layer.GetClassification()          clazz = layer.GetClassification()
318    
319          clazz.SetField("AREA")          layer.SetClassificationColumn("AREA")
320    
321          clazz.AppendGroup(ClassGroupSingleton(42,          clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
322                                             ClassGroupProperties(),                                                "single"))
323                                             "single"))          clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
324          clazz.AppendGroup(ClassGroupSingleton("text",                                                "single-text"))
                                            ClassGroupProperties(),  
                                            "single-text"))  
325    
326          clazz.AppendGroup(ClassGroupRange(0, 42,          clazz.AppendGroup(ClassGroupRange((0, 42),
327                                             ClassGroupProperties(),                                             ClassGroupProperties(),
328                                             "range"))                                             "range"))
329    
# Line 282  class SaveSessionTest(unittest.TestCase, Line 332  class SaveSessionTest(unittest.TestCase,
332          range.SetLabel("new-range")          range.SetLabel("new-range")
333          clazz.AppendGroup(range)          clazz.AppendGroup(range)
334    
335          filename = self.temp_file_name("save_singlemap.thuban")  
336            clazz = layer2.GetClassification()
337            layer2.SetClassificationColumn("POPYCOUN")
338    
339            # Classification with Latin 1 text
340            clazz.AppendGroup(ClassGroupSingleton(
341                internal_from_unicode(u'\xe4\xf6\xfc'), # ae, oe, ue
342                ClassGroupProperties(),
343                internal_from_unicode(u'\xdcml\xe4uts'))) # Uemlaeuts
344    
345            # Pattern
346            clazz.AppendGroup(ClassGroupPattern("BUI", ClassGroupProperties(),
347                                                "pattern"))
348    
349            filename = self.temp_file_name("%s.thuban" % self.id())
350          save_session(session, filename)          save_session(session, filename)
351    
352          file = open(filename)          file = open(filename)
353          written_contents = file.read()          written_contents = file.read()
354          file.close()          file.close()
355          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
356          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
357          <session title="single map&amp;layer">          <session title="Map with Classifications"
358               xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
359                <fileshapesource id="D1"
360                    filename="../../Data/iceland/political.shp"
361                    filetype="shapefile"/>
362              <map title="Test Map">              <map title="Test Map">
363                  <projection name="Unknown">                  <projection name="Unknown">
364                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
365                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
366                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
367                  </projection>                  </projection>
368                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1" visible="true">
                 fill="None" stroke="#000000" stroke_width="1" visible="%s">  
369                      <classification field="AREA" field_type="double">                      <classification field="AREA" field_type="double">
370                          <clnull label="">                          <clnull label="">
371                              <cldata fill="None" stroke="#000000" stroke_width="1"/>                              <cldata fill="None" stroke="#000000" stroke_width="1"/>
# Line 317  class SaveSessionTest(unittest.TestCase, Line 384  class SaveSessionTest(unittest.TestCase,
384                          </clrange>                          </clrange>
385                      </classification>                      </classification>
386                  </layer>                  </layer>
387                    <layer title="My Layer" shapestore="D1" visible="true">
388                        <classification field="POPYCOUN" field_type="string">
389                            <clnull label="">
390                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
391                            </clnull>
392                            <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
393                                 label="\xc3\x9cml\xc3\xa4uts">
394                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
395                            </clpoint>
396                            <clpattern pattern="BUI" label="pattern">
397                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
398                            </clpattern>
399                        </classification>
400                    </layer>
401              </map>              </map>
402          </session>'''          </session>'''
           
         expected_contents = expected_template % \  
             (os.path.join("..", "..", "Data", "iceland", "political.shp"),  
              "true")  
403    
404          #print written_contents          #print written_contents
405          #print "********************************************"          #print "********************************************"
406          #print expected_contents          #print expected_contents
407          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
408    
409            self.validate_data(written_contents)
410    
411          session.Destroy()          session.Destroy()
412    
413        def test_dbf_table(self):
414            """Test saving a session with a dbf table link"""
415            session = self.session = Session("a DBF Table session")
416            # use shapefile from the example data
417            dbffile = os.path.join(os.path.dirname(__file__),
418                                   os.pardir, "Data", "iceland", "political.dbf")
419            table = session.AddTable(DBFTable(dbffile))
420    
421            filename = self.temp_file_name("save_singletable.thuban")
422            save_session(session, filename)
423    
424            file = open(filename)
425            written_contents = file.read()
426            file.close()
427            expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
428            <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
429            <session title="a DBF Table session"
430               xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
431                <filetable id="D1" filename="../../Data/iceland/political.dbf"
432                    filetype="DBF" title="political"/>
433            </session>'''
434    
435            self.compare_xml(written_contents, expected_contents)
436            self.validate_data(written_contents)
437    
438        def test_joined_table(self):
439            """Test saving a session with joined table"""
440            # Create a simple table to use in the join
441            dbffile = self.temp_file_name("save_joinedtable.dbf")
442            dbf = dbflib.create(dbffile)
443            dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
444            dbf.add_field("TEXT", dbflib.FTString, 10, 0)
445            dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
446            dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
447            dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
448            dbf.close()
449    
450            # Create the session and a map
451            session = Session("A Joined Table session")
452            try:
453                map = Map("Test Map")
454                session.AddMap(map)
455    
456                # Add the dbf file to the session
457                dbftable = session.AddTable(DBFTable(dbffile))
458    
459                # Create a layer with the shapefile to use in the join
460                shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
461                                       os.pardir, "Data", "iceland",
462                                       "roads-line.shp")
463                layer = Layer("My Layer", session.OpenShapefile(shpfile))
464                map.AddLayer(layer)
465    
466                # Do the join
467                store = layer.ShapeStore()
468                #for col in store.Table().Columns():
469                #    print col.name
470                joined = TransientJoinedTable(session.TransientDB(),
471                                              store.Table(), "RDLNTYPE",
472                                              dbftable, "RDTYPE",
473                                              outer_join = True)
474                store = session.AddShapeStore(DerivedShapeStore(store, joined))
475                layer.SetShapeStore(store)
476    
477                # Save the session
478                filename = self.temp_file_name("save_joinedtable.thuban")
479                save_session(session, filename)
480    
481                # Read it back and compare
482                file = open(filename)
483                written_contents = file.read()
484                file.close()
485                expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
486                <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
487                <session title="A Joined Table session"
488                 xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
489                    <fileshapesource filename="../../Data/iceland/roads-line.shp"
490                                     filetype="shapefile" id="D142197204"/>
491                    <filetable filename="save_joinedtable.dbf"
492                               title="save_joinedtable"
493                               filetype="DBF" id="D141881756"/>
494                    <jointable id="D142180284"
495                               title="Join of roads-line and save_joinedtable"
496                               leftcolumn="RDLNTYPE" left="D142197204"
497                               rightcolumn="RDTYPE" right="D141881756"
498                               jointype="LEFT OUTER" />
499                    <derivedshapesource id="D141915644"
500                                        table="D142180284"
501                                        shapesource="D142197204"/>
502                    <map title="Test Map">
503                        <layer title="My Layer"
504                               shapestore="D141915644" visible="true">
505                            <classification>
506                                <clnull label="">
507                                    <cldata fill="None" stroke="#000000"
508                                            stroke_width="1"/>
509                                </clnull>
510                            </classification>
511                        </layer>
512                    </map>
513                </session>'''
514    
515                self.compare_xml(written_contents, expected_contents)
516                self.validate_data(written_contents)
517            finally:
518                session.Destroy()
519                session = None
520    
521    
522        def test_save_postgis(self):
523            """Test saving a session with a postgis connection"""
524    
525            class NonConnection(PostGISConnection):
526                """connection class that doesn't actually connect """
527                def connect(self):
528                    pass
529    
530            class NonConnectionStore(PostGISShapeStore):
531                """Shapestore that doesn't try to access the server"""
532                def _fetch_table_information(self):
533                    # pretend that we've found a geometry column
534                    self.geometry_column = "the_geom"
535                    # pretend this is a ARC shape type.
536                    self.shape_type = SHAPETYPE_ARC
537                def IDColumn(self):
538                    """Return an object with a name attribute with value 'gid'"""
539                    class dummycol:
540                        name = "gid"
541                    return dummycol
542    
543            session = Session("A PostGIS Session")
544            try:
545                dbconn = NonConnection(dbname="plugh", host="xyzzy", port="42",
546                                       user="grue")
547                session.AddDBConnection(dbconn)
548                map = Map("Test Map")
549                session.AddMap(map)
550                store = NonConnectionStore(dbconn, "roads")
551                session.AddShapeStore(store)
552                layer = Layer("Roads to Nowhere", store)
553                map.AddLayer(layer)
554    
555                # Save the session
556                filename = self.temp_file_name(self.id() + ".thuban")
557                save_session(session, filename)
558    
559                # Read it back and compare
560                file = open(filename)
561                written = file.read()
562                file.close()
563                expected = '''<?xml version="1.0" encoding="UTF-8"?>
564                <!DOCTYPE session SYSTEM "thuban-1.1.dtd">
565                <session title="A PostGIS Session"
566                 xmlns="http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd">
567                    <dbconnection id="DB"
568                                  dbtype="postgis" dbname="plugh"
569                                  host="xyzzy" port="42"
570                                  user="grue"/>
571                    <dbshapesource id="roads" dbconn="DB" tablename="roads"
572                                   id_column="gid" geometry_column="the_geom"/>
573                    <map title="Test Map">
574                        <layer title="Roads to Nowhere"
575                               shapestore="roads" visible="true">
576                            <classification>
577                                <clnull label="">
578                                    <cldata fill="None" stroke="#000000"
579                                        stroke_width="1"/>
580                                </clnull>
581                            </classification>
582                        </layer>
583                    </map>
584                </session>'''
585                self.compare_xml(written, expected)
586                self.validate_data(written)
587            finally:
588                session.Destroy()
589    
590    
591    class MockDataStore:
592    
593        """A very simple data store that only has dependencies"""
594    
595        def __init__(self, name, *dependencies):
596            self.name = name
597            self.dependencies = dependencies
598    
599        def __repr__(self):
600            return self.name
601    
602        def Dependencies(self):
603            return self.dependencies
604    
605    
606    class TestStoreSort(unittest.TestCase):
607    
608        def check_sort(self, containers, sorted):
609            """Check whether the list of data containers is sorted"""
610            # check whether sorted is in the right order
611            seen = {}
612            for container in sorted:
613                self.failIf(id(container) in seen,
614                            "Container %r at least twice in %r" % (container,
615                                                                   sorted))
616                for dep in container.Dependencies():
617                    self.assert_(id(dep) in seen,
618                                 "Dependency %r of %r not yet seen" % (dep,
619                                                                       container))
620                seen[id(container)] = 1
621            # check whether all of containers is in sorted
622            for container in containers:
623                self.assert_(id(container) in seen,
624                             "Container %r in containers but not in sorted")
625            self.assertEquals(len(containers), len(sorted))
626    
627        def test_sort_data_stores(self):
628            """Test Thuban.Model.save.sort_data_stores"""
629            d1 = MockDataStore("d1")
630            d2 = MockDataStore("d2")
631            d3 = MockDataStore("d3", d1)
632            d4 = MockDataStore("d4", d1, d3)
633    
634            containers = [d4, d1, d2, d3]
635            self.check_sort(containers, sort_data_stores(containers))
636            containers = [d1, d3, d2, d4]
637            self.check_sort(containers, sort_data_stores(containers))
638    
639    
640    
641  if __name__ == "__main__":  if __name__ == "__main__":
642      # Fake the __file__ global because it's needed by a test      # Fake the __file__ global because it's needed by a test

Legend:
Removed from v.1168  
changed lines
  Added in v.2734

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26