/[thuban]/trunk/thuban/test/test_save.py
ViewVC logotype

Diff of /trunk/thuban/test/test_save.py

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

revision 1200 by jonathan, Fri Jun 13 15:04:44 2003 UTC revision 1678 by bh, Thu Aug 28 13:36:23 2003 UTC
# 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.Lib.fileutil import relative_filename
29    from Thuban.Model.save import XMLWriter, save_session, sort_data_stores
30  from Thuban.Model.session import Session  from Thuban.Model.session import Session
31  from Thuban.Model.map import Map  from Thuban.Model.map import Map
32  from Thuban.Model.layer import Layer, RasterLayer  from Thuban.Model.layer import Layer, RasterLayer
33  from Thuban.Model.proj import Projection  from Thuban.Model.proj import Projection
34    from Thuban.Model.table import DBFTable
35    from Thuban.Model.transientdb import TransientJoinedTable
36    from Thuban.Model.data import DerivedShapeStore
37    
38  from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \  from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
39      ClassGroupProperties      ClassGroupProperties
40    
41  from Thuban.Model.range import Range  from Thuban.Model.range import Range
42    
43    from Thuban.Model.postgisdb import PostGISConnection, PostGISShapeStore
44    
 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  
45    
46  class XMLWriterTest(unittest.TestCase):  class XMLWriterTest(unittest.TestCase):
47    
# Line 94  class XMLWriterTest(unittest.TestCase): Line 62  class XMLWriterTest(unittest.TestCase):
62          eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")          eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
63          eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")          eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
64    
65  class SaveSessionTest(unittest.TestCase, support.FileTestMixin):  class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
66                          xmlsupport.ValidationTest):
67    
68        dtd = "http://thuban.intevation.org/dtds/thuban-0.9.dtd"
69        thubanids = [((dtd, n), (None, "id")) for n in
70                     ["fileshapesource", "filetable", "jointable",
71                      "derivedshapesource", "dbshapesource", "dbconnection"]]
72        thubanidrefs = [((dtd, n), (None, m)) for n, m in
73                        [("layer", "shapestore"),
74                         ("jointable", "left"),
75                         ("jointable", "right"),
76                         ("derivedshapesource", "table"),
77                         ("derivedshapesource", "shapesource"),
78                         ("dbshapesource", "dbconn")]]
79        del n, m, dtd
80    
81        def tearDown(self):
82            """Call self.session.Destroy
83    
84            Test cases that create session should bind it to self.session so
85            that it gets destroyed properly
86            """
87            if hasattr(self, "session"):
88                self.session.Destroy()
89                self.session = None
90    
91      def compare_xml(self, xml1, xml2):      def compare_xml(self, xml1, xml2):
92          self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))          list1 = xmlsupport.sax_eventlist(xml1, ids = self.thubanids,
93                                             idrefs = self.thubanidrefs)
94            list2 = xmlsupport.sax_eventlist(xml2, ids = self.thubanids,
95                                             idrefs = self.thubanidrefs)
96            if list1 != list2:
97                for a, b in zip(list1, list2):
98                    if a != b:
99                        self.fail("%r != %r" % (a, b))
100    
101    
102      def testEmptySession(self):      def testEmptySession(self):
103          """Save an empty session"""          """Save an empty session"""
# Line 111  class SaveSessionTest(unittest.TestCase, Line 111  class SaveSessionTest(unittest.TestCase,
111          file.close()          file.close()
112          self.compare_xml(written_contents,          self.compare_xml(written_contents,
113                           '<?xml version="1.0" encoding="UTF-8"?>\n'                           '<?xml version="1.0" encoding="UTF-8"?>\n'
114                           '<!DOCTYPE session SYSTEM "thuban.dtd">\n'                           '<!DOCTYPE session SYSTEM "thuban-0.9.dtd">\n'
115                           '<session title="empty session">\n</session>\n')                           '<session title="empty session" '
116             'xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">'
117                             '\n</session>\n')
118    
119            self.validate_data(written_contents)
120    
121      def testSingleLayer(self):      def testSingleLayer(self):
122          """Save a session with a single map with a single layer"""          """Save a session with a single map with a single layer"""
# Line 134  class SaveSessionTest(unittest.TestCase, Line 138  class SaveSessionTest(unittest.TestCase,
138          written_contents = file.read()          written_contents = file.read()
139          file.close()          file.close()
140          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
141          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
142          <session title="single map&amp;layer">          <session title="single map&amp;layer"
143               xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
144                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
145              <map title="Test Map">              <map title="Test Map">
146                  <projection name="Unknown">                  <projection name="Unknown">
147                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
148                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
149                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
150                  </projection>                  </projection>
151                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1"
152                  fill="None" stroke="#000000" stroke_width="1" visible="%s"/>                  fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
153              </map>              </map>
154          </session>'''          </session>'''
155            
156          expected_contents = expected_template % \          expected_contents = expected_template % \
157              (os.path.join("..", "..", "Data", "iceland", "political.shp"),              (os.path.join("..", "..", "Data", "iceland", "political.shp"),
158               "true")               "true")
159    
         #print written_contents  
         #print "********************************************"  
         #print expected_contents  
160          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
161    
162            self.validate_data(written_contents)
163    
164          layer.SetVisible(False)          layer.SetVisible(False)
165          save_session(session, filename)          save_session(session, filename)
166    
# Line 165  class SaveSessionTest(unittest.TestCase, Line 170  class SaveSessionTest(unittest.TestCase,
170          expected_contents = expected_template % \          expected_contents = expected_template % \
171              (os.path.join("..", "..", "Data", "iceland", "political.shp"),              (os.path.join("..", "..", "Data", "iceland", "political.shp"),
172               "false")               "false")
   
         #print written_contents  
         #print "********************************************"  
         #print expected_contents  
173          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
174            self.validate_data(written_contents)
175    
176          session.Destroy()          session.Destroy()
177    
178      def testLayerProjection(self):      def testLayerProjection(self):
179            """Test saving layers with projections"""
180          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
181          session = Session("single map&layer")          session = self.session = Session("single map&layer")
182          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
183          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
184          session.AddMap(map)          session.AddMap(map)
# Line 187  class SaveSessionTest(unittest.TestCase, Line 190  class SaveSessionTest(unittest.TestCase,
190          layer.SetProjection(proj)          layer.SetProjection(proj)
191          map.AddLayer(layer)          map.AddLayer(layer)
192    
193          filename = self.temp_file_name("save_singlemap.thuban")          filename = self.temp_file_name("save_layerproj.thuban")
194          save_session(session, filename)          save_session(session, filename)
         session.Destroy()  
195    
196          file = open(filename)          file = open(filename)
197          written_contents = file.read()          written_contents = file.read()
198          file.close()          file.close()
199          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
200          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
201          <session title="single map&amp;layer">          <session title="single map&amp;layer"
202               xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
203                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
204              <map title="Test Map">              <map title="Test Map">
205                  <projection name="Unknown">                  <projection name="Unknown">
206                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
207                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
208                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
209                  </projection>                  </projection>
210                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1"
211                  fill="None" stroke="#000000" stroke_width="1" visible="true">                  fill="None" stroke="#000000" stroke_width="1" visible="true">
212                      <projection name="Layer Projection">                      <projection name="Layer Projection">
213                          <parameter value="proj=lcc"/>                          <parameter value="proj=lcc"/>
# Line 218  class SaveSessionTest(unittest.TestCase, Line 222  class SaveSessionTest(unittest.TestCase,
222          #print expected_contents          #print expected_contents
223          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
224    
225                    self.validate_data(written_contents)
226    
227      def testRasterLayer(self):      def testRasterLayer(self):
228          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
229          session = Session("single map&layer")          session = Session("single map&layer")
# Line 229  class SaveSessionTest(unittest.TestCase, Line 234  class SaveSessionTest(unittest.TestCase,
234                                 os.pardir, "Data", "iceland", "island.tif")                                 os.pardir, "Data", "iceland", "island.tif")
235          layer = RasterLayer("My RasterLayer", imgfile)          layer = RasterLayer("My RasterLayer", imgfile)
236          map.AddLayer(layer)          map.AddLayer(layer)
237                                                                                    
238          filename = self.temp_file_name("save_singlemap.thuban")          filename = self.temp_file_name("%s.thuban" % self.id())
239          save_session(session, filename)          save_session(session, filename)
240          session.Destroy()          session.Destroy()
241                                                                                    
242          file = open(filename)          file = open(filename)
243          written_contents = file.read()          written_contents = file.read()
244          file.close()          file.close()
245          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
246          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
247          <session title="single map&amp;layer">          <session title="single map&amp;layer"
248               xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
249              <map title="Test Map">              <map title="Test Map">
250                  <rasterlayer title="My RasterLayer" filename="%s"                  <rasterlayer title="My RasterLayer" filename="%s"
251                               visible="true">                               visible="true">
252                  </rasterlayer>                  </rasterlayer>
253              </map>              </map>
254          </session>''' % os.path.join(os.path.dirname(__file__),          </session>''' % os.path.join(os.pardir, os.pardir, "Data", "iceland",
                                      os.pardir, "Data", "iceland",  
255                                       "island.tif")                                       "island.tif")
256          #print written_contents          #print written_contents
257          #print "********************************************"          #print "********************************************"
258          #print expected_contents          #print expected_contents
259          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
260    
261            self.validate_data(written_contents)
262    
263      def testClassifiedLayer(self):      def testClassifiedLayer(self):
264          """Save a session with a single map with a single layer          """Save a session with a single map with classifications"""
            with a classificaton.  
         """  
265          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
266          session = Session("single map&layer")          session = Session("Map with Classifications")
267          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
268          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
269          session.AddMap(map)          session.AddMap(map)
# Line 267  class SaveSessionTest(unittest.TestCase, Line 272  class SaveSessionTest(unittest.TestCase,
272                                 os.pardir, "Data", "iceland", "political.shp")                                 os.pardir, "Data", "iceland", "political.shp")
273          layer = Layer("My Layer", session.OpenShapefile(shpfile))          layer = Layer("My Layer", session.OpenShapefile(shpfile))
274          map.AddLayer(layer)          map.AddLayer(layer)
275            layer2 = Layer("My Layer", layer.ShapeStore())
276            map.AddLayer(layer2)
277    
278          clazz = layer.GetClassification()          clazz = layer.GetClassification()
279    
280          clazz.SetField("AREA")          layer.SetClassificationColumn("AREA")
281    
282          clazz.AppendGroup(ClassGroupSingleton(42,          clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
283                                             ClassGroupProperties(),                                                "single"))
284                                             "single"))          clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
285          clazz.AppendGroup(ClassGroupSingleton("text",                                                "single-text"))
                                            ClassGroupProperties(),  
                                            "single-text"))  
286    
287          clazz.AppendGroup(ClassGroupRange(0, 42,          clazz.AppendGroup(ClassGroupRange((0, 42),
288                                             ClassGroupProperties(),                                             ClassGroupProperties(),
289                                             "range"))                                             "range"))
290    
# Line 288  class SaveSessionTest(unittest.TestCase, Line 293  class SaveSessionTest(unittest.TestCase,
293          range.SetLabel("new-range")          range.SetLabel("new-range")
294          clazz.AppendGroup(range)          clazz.AppendGroup(range)
295    
296          filename = self.temp_file_name("save_singlemap.thuban")  
297            clazz = layer2.GetClassification()
298            layer2.SetClassificationColumn("POPYCOUN")
299    
300            # Classification with Latin 1 text
301            clazz.AppendGroup(ClassGroupSingleton('\xe4\xf6\xfc', # ae, oe, ue
302                                                  ClassGroupProperties(),
303                                                  '\xdcml\xe4uts')) # Uemlaeuts
304    
305    
306            filename = self.temp_file_name("%s.thuban" % self.id())
307          save_session(session, filename)          save_session(session, filename)
308    
309          file = open(filename)          file = open(filename)
310          written_contents = file.read()          written_contents = file.read()
311          file.close()          file.close()
312          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
313          <!DOCTYPE session SYSTEM "thuban.dtd">          <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
314          <session title="single map&amp;layer">          <session title="Map with Classifications"
315               xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
316                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
317              <map title="Test Map">              <map title="Test Map">
318                  <projection name="Unknown">                  <projection name="Unknown">
319                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
320                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
321                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
322                  </projection>                  </projection>
323                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1"
324                  fill="None" stroke="#000000" stroke_width="1" visible="%s">                  fill="None" stroke="#000000" stroke_width="1" visible="%s">
325                      <classification field="AREA" field_type="double">                      <classification field="AREA" field_type="double">
326                          <clnull label="">                          <clnull label="">
# Line 323  class SaveSessionTest(unittest.TestCase, Line 340  class SaveSessionTest(unittest.TestCase,
340                          </clrange>                          </clrange>
341                      </classification>                      </classification>
342                  </layer>                  </layer>
343                    <layer title="My Layer" shapestore="D1"
344                    fill="None" stroke="#000000" stroke_width="1" visible="true">
345                        <classification field="POPYCOUN" field_type="string">
346                            <clnull label="">
347                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
348                            </clnull>
349                            <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
350                                 label="\xc3\x9cml\xc3\xa4uts">
351                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
352                            </clpoint>
353                        </classification>
354                    </layer>
355              </map>              </map>
356          </session>'''          </session>'''
357            
358          expected_contents = expected_template % \          expected_contents = expected_template % \
359              (os.path.join("..", "..", "Data", "iceland", "political.shp"),              (os.path.join("..", "..", "Data", "iceland", "political.shp"),
360               "true")               "true")
# Line 335  class SaveSessionTest(unittest.TestCase, Line 364  class SaveSessionTest(unittest.TestCase,
364          #print expected_contents          #print expected_contents
365          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
366    
367            self.validate_data(written_contents)
368    
369          session.Destroy()          session.Destroy()
370    
371        def test_dbf_table(self):
372            """Test saving a session with a dbf table link"""
373            session = self.session = Session("a DBF Table session")
374            # use shapefile from the example data
375            dbffile = os.path.join(os.path.dirname(__file__),
376                                   os.pardir, "Data", "iceland", "political.dbf")
377            table = session.AddTable(DBFTable(dbffile))
378    
379            filename = self.temp_file_name("save_singletable.thuban")
380            save_session(session, filename)
381    
382            file = open(filename)
383            written_contents = file.read()
384            file.close()
385            expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
386            <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
387            <session title="a DBF Table session"
388               xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
389                <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
390            </session>'''
391    
392            expected_contents = (expected_template
393                                 % os.path.join(os.pardir, os.pardir, "Data",
394                                                "iceland", "political.dbf"))
395            self.compare_xml(written_contents, expected_contents)
396            self.validate_data(written_contents)
397    
398        def test_joined_table(self):
399            """Test saving a session with joined table"""
400            # Create a simple table to use in the join
401            dbffile = self.temp_file_name("save_joinedtable.dbf")
402            dbf = dbflib.create(dbffile)
403            dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
404            dbf.add_field("TEXT", dbflib.FTString, 10, 0)
405            dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
406            dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
407            dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
408            dbf.close()
409    
410            # Create the session and a map
411            session = Session("A Joined Table session")
412            try:
413                map = Map("Test Map")
414                session.AddMap(map)
415    
416                # Add the dbf file to the session
417                dbftable = session.AddTable(DBFTable(dbffile))
418    
419                # Create a layer with the shapefile to use in the join
420                shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
421                                       os.pardir, "Data", "iceland",
422                                       "roads-line.shp")
423                layer = Layer("My Layer", session.OpenShapefile(shpfile))
424                map.AddLayer(layer)
425    
426                # Do the join
427                store = layer.ShapeStore()
428                #for col in store.Table().Columns():
429                #    print col.name
430                joined = TransientJoinedTable(session.TransientDB(),
431                                              store.Table(), "RDLNTYPE",
432                                              dbftable, "RDTYPE",
433                                              outer_join = True)
434                store = session.AddShapeStore(DerivedShapeStore(store, joined))
435                layer.SetShapeStore(store)
436    
437                # Save the session
438                filename = self.temp_file_name("save_joinedtable.thuban")
439                save_session(session, filename)
440    
441                # Read it back and compare
442                file = open(filename)
443                written_contents = file.read()
444                file.close()
445                expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
446                <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
447                <session title="A Joined Table session"
448                 xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
449                    <fileshapesource filename="%(shpfile)s"
450                                     filetype="shapefile" id="D142197204"/>
451                    <filetable filename="%(dbffile)s"
452                               title="save_joinedtable"
453                               filetype="DBF" id="D141881756"/>
454                    <jointable id="D142180284"
455                               title="Join of roads-line and save_joinedtable"
456                               leftcolumn="RDLNTYPE" left="D142197204"
457                               rightcolumn="RDTYPE" right="D141881756"
458                               jointype="LEFT OUTER" />
459                    <derivedshapesource id="D141915644"
460                                        table="D142180284"
461                                        shapesource="D142197204"/>
462                    <map title="Test Map">
463                        <layer title="My Layer"
464                               shapestore="D141915644" visible="true"
465                               stroke="#000000" stroke_width="1" fill="None"/>
466                    </map>
467                </session>'''
468    
469                expected_contents = expected_template % {
470                    "dbffile": relative_filename(self.temp_dir(), dbffile),
471                    "shpfile": relative_filename(self.temp_dir(), shpfile)
472                    }
473                self.compare_xml(written_contents, expected_contents)
474                self.validate_data(written_contents)
475            finally:
476                session.Destroy()
477                session = None
478    
479    
480        def test_save_postgis(self):
481            """Test saving a session with a postgis connection"""
482    
483            class NonConnection(PostGISConnection):
484                """connection class that doesn't actually connect """
485                def connect(self):
486                    pass
487    
488            class NonConnectionStore(PostGISShapeStore):
489                """Shapestore that doesn't try to access the server"""
490                def _fetch_table_information(self):
491                    pass
492    
493            session = Session("A PostGIS Session")
494            try:
495                dbconn = NonConnection(dbname="plugh", host="xyzzy", port="42",
496                                       user="grue")
497                session.AddDBConnection(dbconn)
498                map = Map("Test Map")
499                session.AddMap(map)
500                store = NonConnectionStore(dbconn, "roads")
501                session.AddShapeStore(store)
502                layer = Layer("Roads to Nowhere", store)
503                map.AddLayer(layer)
504    
505                # Save the session
506                filename = self.temp_file_name(self.id() + ".thuban")
507                save_session(session, filename)
508    
509                # Read it back and compare
510                file = open(filename)
511                written = file.read()
512                file.close()
513                expected = '''<?xml version="1.0" encoding="UTF-8"?>
514                <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
515                <session title="A PostGIS Session"
516                 xmlns="http://thuban.intevation.org/dtds/thuban-0.9.dtd">
517                    <dbconnection id="DB"
518                                  dbtype="postgis" dbname="plugh"
519                                  host="xyzzy" port="42"
520                                  user="grue"/>
521                    <dbshapesource id="roads" dbconn="DB" tablename="roads"/>
522                    <map title="Test Map">
523                        <layer title="Roads to Nowhere"
524                               shapestore="roads" visible="true"
525                               stroke="#000000" stroke_width="1" fill="None"/>
526                    </map>
527                </session>'''
528                self.compare_xml(written, expected)
529                self.validate_data(written)
530            finally:
531                session.Destroy()
532    
533    
534    class MockDataStore:
535    
536        """A very simple data store that only has dependencies"""
537    
538        def __init__(self, name, *dependencies):
539            self.name = name
540            self.dependencies = dependencies
541    
542        def __repr__(self):
543            return self.name
544    
545        def Dependencies(self):
546            return self.dependencies
547    
548    
549    class TestStoreSort(unittest.TestCase):
550    
551        def check_sort(self, containers, sorted):
552            """Check whether the list of data containers is sorted"""
553            # check whether sorted is in the right order
554            seen = {}
555            for container in sorted:
556                self.failIf(id(container) in seen,
557                            "Container %r at least twice in %r" % (container,
558                                                                   sorted))
559                for dep in container.Dependencies():
560                    self.assert_(id(dep) in seen,
561                                 "Dependency %r of %r not yet seen" % (dep,
562                                                                       container))
563                seen[id(container)] = 1
564            # check whether all of containers is in sorted
565            for container in containers:
566                self.assert_(id(container) in seen,
567                             "Container %r in containers but not in sorted")
568            self.assertEquals(len(containers), len(sorted))
569    
570        def test_sort_data_stores(self):
571            """Test Thuban.Model.save.sort_data_stores"""
572            d1 = MockDataStore("d1")
573            d2 = MockDataStore("d2")
574            d3 = MockDataStore("d3", d1)
575            d4 = MockDataStore("d4", d1, d3)
576    
577            containers = [d4, d1, d2, d3]
578            self.check_sort(containers, sort_data_stores(containers))
579            containers = [d1, d3, d2, d4]
580            self.check_sort(containers, sort_data_stores(containers))
581    
582    
583    
584  if __name__ == "__main__":  if __name__ == "__main__":
585      # 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.1200  
changed lines
  Added in v.1678

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26