/[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

revision 1357 by jonathan, Wed Jul 2 09:38:27 2003 UTC revision 1845 by bh, Tue Oct 21 10:49:50 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    
 import xml.sax  
 import xml.sax.handler  
 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException  
   
20  import xmlsupport  import xmlsupport
21    import postgissupport
22    
23  import support  import support
24  support.initthuban()  support.initthuban()
# Line 43  from Thuban.Model.classification import Line 40  from Thuban.Model.classification import
40    
41  from Thuban.Model.range import Range  from Thuban.Model.range import Range
42    
43    from Thuban.Model.postgisdb import PostGISConnection, PostGISShapeStore
44    
45    
46  class XMLWriterTest(unittest.TestCase):  class XMLWriterTest(unittest.TestCase):
47    
# Line 66  class XMLWriterTest(unittest.TestCase): Line 65  class XMLWriterTest(unittest.TestCase):
65  class SaveSessionTest(unittest.TestCase, support.FileTestMixin,  class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
66                        xmlsupport.ValidationTest):                        xmlsupport.ValidationTest):
67    
68      dtd = "http://thuban.intevation.org/dtds/thuban-0.8.dtd"      dtd = "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
69      thubanids = [((dtd, n), (None, "id")) for n in      thubanids = [((dtd, n), (None, "id")) for n in
70                   ["fileshapesource", "filetable", "jointable",                   ["fileshapesource", "filetable", "jointable",
71                    "derivedshapesource"]]                    "derivedshapesource", "dbshapesource", "dbconnection"]]
72      thubanidrefs = [((dtd, n), (None, m)) for n, m in      thubanidrefs = [((dtd, n), (None, m)) for n, m in
73                      [("layer", "shapestore"),                      [("layer", "shapestore"),
74                       ("jointable", "left"),                       ("jointable", "left"),
75                       ("jointable", "right"),                       ("jointable", "right"),
76                       ("derivedshapesource", "table"),                       ("derivedshapesource", "table"),
77                       ("derivedshapesource", "shapesource")]]                       ("derivedshapesource", "shapesource"),
78                         ("dbshapesource", "dbconn")]]
79      del n, m, dtd      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          if 0:          list1 = xmlsupport.sax_eventlist(xml1, ids = self.thubanids,
93              for a, b in zip(sax_eventlist(xml1, self.thubanids,                                           idrefs = self.thubanidrefs)
94                                          self.thubanidrefs),          list2 = xmlsupport.sax_eventlist(xml2, ids = self.thubanids,
95                            sax_eventlist(xml2, self.thubanids,                                           idrefs = self.thubanidrefs)
96                                          self.thubanidrefs)):          if list1 != list2:
97                print a == b and ' ' or '*****'              for a, b in zip(list1, list2):
98                print a                  if a != b:
99                print b                      self.fail("%r != %r" % (a, b))
100          self.assertEquals(xmlsupport.sax_eventlist(xml1, ids = self.thubanids,  
                                                    idrefs = self.thubanidrefs),  
                           xmlsupport.sax_eventlist(xml2, ids = self.thubanids,  
                                                    idrefs = self.thubanidrefs))  
101    
102      def testEmptySession(self):      def testEmptySession(self):
103          """Save an empty session"""          """Save an empty session"""
# Line 104  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-0.8.dtd">\n'                           '<!DOCTYPE session SYSTEM "thuban-1.0.dtd">\n'
115                           '<session title="empty session" '                           '<session title="empty session" '
116           'xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">'           'xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">'
117                           '\n</session>\n')                           '\n</session>\n')
118    
119          self.validate_data(written_contents)          self.validate_data(written_contents)
# Line 115  class SaveSessionTest(unittest.TestCase, Line 122  class SaveSessionTest(unittest.TestCase,
122          """Save a session with a single map with a single layer"""          """Save a session with a single map with a single layer"""
123          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
124          session = Session("single map&layer")          session = Session("single map&layer")
125          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["proj=utm", "zone=27", "ellps=WGS84",
126                               "datum=WGS84", "units=m"],
127                              name = "WGS 84 / UTM zone 27N",
128                              epsg = "32627")
129          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
130          session.AddMap(map)          session.AddMap(map)
131          # use shapefile from the example data          # use shapefile from the example data
# Line 131  class SaveSessionTest(unittest.TestCase, Line 141  class SaveSessionTest(unittest.TestCase,
141          written_contents = file.read()          written_contents = file.read()
142          file.close()          file.close()
143          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
144          <!DOCTYPE session SYSTEM "thuban-0.8.dtd">          <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
145          <session title="single map&amp;layer"          <session title="single map&amp;layer"
146             xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">             xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
147              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
148              <map title="Test Map">              <map title="Test Map">
149                  <projection name="Unknown">                  <projection epsg="32627" name="WGS 84 / UTM zone 27N">
                     <parameter value="zone=26"/>  
150                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
151                      <parameter value="ellps=clrk66"/>                      <parameter value="zone=27"/>
152                        <parameter value="ellps=WGS84"/>
153                        <parameter value="datum=WGS84"/>
154                        <parameter value="units=m"/>
155                  </projection>                  </projection>
156                  <layer title="My Layer" shapestore="D1"                  <layer title="My Layer" shapestore="D1"
157                  fill="None" stroke="#000000" stroke_width="1" visible="%s"/>                  fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
# Line 171  class SaveSessionTest(unittest.TestCase, Line 183  class SaveSessionTest(unittest.TestCase,
183      def testLayerProjection(self):      def testLayerProjection(self):
184          """Test saving layers with projections"""          """Test saving layers with projections"""
185          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
186          session = Session("single map&layer")          session = self.session = Session("single map&layer")
187          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
188          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
189          session.AddMap(map)          session.AddMap(map)
# Line 179  class SaveSessionTest(unittest.TestCase, Line 191  class SaveSessionTest(unittest.TestCase,
191          shpfile = os.path.join(os.path.dirname(__file__),          shpfile = os.path.join(os.path.dirname(__file__),
192                                 os.pardir, "Data", "iceland", "political.shp")                                 os.pardir, "Data", "iceland", "political.shp")
193          layer = Layer("My Layer", session.OpenShapefile(shpfile))          layer = Layer("My Layer", session.OpenShapefile(shpfile))
194          proj = Projection(["proj=lcc", "ellps=clrk66"], "Layer Projection")          proj = Projection(["proj=lcc", "ellps=clrk66",
195                               "lat_1=0", "lat_2=20"],
196                              "Layer Projection")
197          layer.SetProjection(proj)          layer.SetProjection(proj)
198          map.AddLayer(layer)          map.AddLayer(layer)
199    
200          filename = self.temp_file_name("save_layerproj.thuban")          filename = self.temp_file_name("save_layerproj.thuban")
201          save_session(session, filename)          save_session(session, filename)
         session.Destroy()  
202    
203          file = open(filename)          file = open(filename)
204          written_contents = file.read()          written_contents = file.read()
205          file.close()          file.close()
206          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
207          <!DOCTYPE session SYSTEM "thuban-0.8.dtd">          <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
208          <session title="single map&amp;layer"          <session title="single map&amp;layer"
209             xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">             xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
210              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
211              <map title="Test Map">              <map title="Test Map">
212                  <projection name="Unknown">                  <projection name="Unknown">
# Line 206  class SaveSessionTest(unittest.TestCase, Line 219  class SaveSessionTest(unittest.TestCase,
219                      <projection name="Layer Projection">                      <projection name="Layer Projection">
220                          <parameter value="proj=lcc"/>                          <parameter value="proj=lcc"/>
221                          <parameter value="ellps=clrk66"/>                          <parameter value="ellps=clrk66"/>
222                            <parameter value="lat_1=0"/>
223                            <parameter value="lat_2=20"/>
224                      </projection>                      </projection>
225                  </layer>                  </layer>
226              </map>              </map>
# Line 229  class SaveSessionTest(unittest.TestCase, Line 244  class SaveSessionTest(unittest.TestCase,
244          layer = RasterLayer("My RasterLayer", imgfile)          layer = RasterLayer("My RasterLayer", imgfile)
245          map.AddLayer(layer)          map.AddLayer(layer)
246    
247          filename = self.temp_file_name("save_singlemap.thuban")          filename = self.temp_file_name("%s.thuban" % self.id())
248          save_session(session, filename)          save_session(session, filename)
249          session.Destroy()          session.Destroy()
250    
# Line 237  class SaveSessionTest(unittest.TestCase, Line 252  class SaveSessionTest(unittest.TestCase,
252          written_contents = file.read()          written_contents = file.read()
253          file.close()          file.close()
254          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>          expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
255          <!DOCTYPE session SYSTEM "thuban-0.8.dtd">          <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
256          <session title="single map&amp;layer"          <session title="single map&amp;layer"
257             xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">             xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
258              <map title="Test Map">              <map title="Test Map">
259                  <rasterlayer title="My RasterLayer" filename="%s"                  <rasterlayer title="My RasterLayer" filename="%s"
260                               visible="true">                               visible="true">
261                  </rasterlayer>                  </rasterlayer>
262              </map>              </map>
263          </session>''' % os.path.join(os.path.dirname(__file__),          </session>''' % os.path.join(os.pardir, os.pardir, "Data", "iceland",
                                      os.pardir, "Data", "iceland",  
264                                       "island.tif")                                       "island.tif")
265          #print written_contents          #print written_contents
266          #print "********************************************"          #print "********************************************"
# Line 256  class SaveSessionTest(unittest.TestCase, Line 270  class SaveSessionTest(unittest.TestCase,
270          self.validate_data(written_contents)          self.validate_data(written_contents)
271    
272      def testClassifiedLayer(self):      def testClassifiedLayer(self):
273          """Save a session with a single map with a single layer          """Save a session with a single map with classifications"""
            with a classificaton.  
         """  
274          # deliberately put an apersand in the title :)          # deliberately put an apersand in the title :)
275          session = Session("single map&layer")          session = Session("Map with Classifications")
276          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])          proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
277          map = Map("Test Map", projection = proj)          map = Map("Test Map", projection = proj)
278          session.AddMap(map)          session.AddMap(map)
# Line 269  class SaveSessionTest(unittest.TestCase, Line 281  class SaveSessionTest(unittest.TestCase,
281                                 os.pardir, "Data", "iceland", "political.shp")                                 os.pardir, "Data", "iceland", "political.shp")
282          layer = Layer("My Layer", session.OpenShapefile(shpfile))          layer = Layer("My Layer", session.OpenShapefile(shpfile))
283          map.AddLayer(layer)          map.AddLayer(layer)
284            layer2 = Layer("My Layer", layer.ShapeStore())
285            map.AddLayer(layer2)
286    
287          clazz = layer.GetClassification()          clazz = layer.GetClassification()
288    
289          clazz.SetFieldInfo("AREA", None)          layer.SetClassificationColumn("AREA")
290    
291          clazz.AppendGroup(ClassGroupSingleton(42,          clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
292                                             ClassGroupProperties(),                                                "single"))
293                                             "single"))          clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
294          clazz.AppendGroup(ClassGroupSingleton("text",                                                "single-text"))
                                            ClassGroupProperties(),  
                                            "single-text"))  
295    
296          clazz.AppendGroup(ClassGroupRange((0, 42),          clazz.AppendGroup(ClassGroupRange((0, 42),
297                                             ClassGroupProperties(),                                             ClassGroupProperties(),
# Line 290  class SaveSessionTest(unittest.TestCase, Line 302  class SaveSessionTest(unittest.TestCase,
302          range.SetLabel("new-range")          range.SetLabel("new-range")
303          clazz.AppendGroup(range)          clazz.AppendGroup(range)
304    
305          filename = self.temp_file_name("save_singlemap.thuban")  
306            clazz = layer2.GetClassification()
307            layer2.SetClassificationColumn("POPYCOUN")
308    
309            # Classification with Latin 1 text
310            clazz.AppendGroup(ClassGroupSingleton('\xe4\xf6\xfc', # ae, oe, ue
311                                                  ClassGroupProperties(),
312                                                  '\xdcml\xe4uts')) # Uemlaeuts
313    
314    
315            filename = self.temp_file_name("%s.thuban" % self.id())
316          save_session(session, filename)          save_session(session, filename)
317    
318          file = open(filename)          file = open(filename)
319          written_contents = file.read()          written_contents = file.read()
320          file.close()          file.close()
321          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
322          <!DOCTYPE session SYSTEM "thuban-0.8.dtd">          <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
323          <session title="single map&amp;layer"          <session title="Map with Classifications"
324             xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">             xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
325              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>              <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
326              <map title="Test Map">              <map title="Test Map">
327                  <projection name="Unknown">                  <projection name="Unknown">
# Line 327  class SaveSessionTest(unittest.TestCase, Line 349  class SaveSessionTest(unittest.TestCase,
349                          </clrange>                          </clrange>
350                      </classification>                      </classification>
351                  </layer>                  </layer>
352                    <layer title="My Layer" shapestore="D1"
353                    fill="None" stroke="#000000" stroke_width="1" visible="true">
354                        <classification field="POPYCOUN" field_type="string">
355                            <clnull label="">
356                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
357                            </clnull>
358                            <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
359                                 label="\xc3\x9cml\xc3\xa4uts">
360                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
361                            </clpoint>
362                        </classification>
363                    </layer>
364              </map>              </map>
365          </session>'''          </session>'''
366    
# Line 345  class SaveSessionTest(unittest.TestCase, Line 379  class SaveSessionTest(unittest.TestCase,
379    
380      def test_dbf_table(self):      def test_dbf_table(self):
381          """Test saving a session with a dbf table link"""          """Test saving a session with a dbf table link"""
382          session = Session("a DBF Table session")          session = self.session = Session("a DBF Table session")
383          # use shapefile from the example data          # use shapefile from the example data
384          dbffile = os.path.join(os.path.dirname(__file__),          dbffile = os.path.join(os.path.dirname(__file__),
385                                 os.pardir, "Data", "iceland", "political.dbf")                                 os.pardir, "Data", "iceland", "political.dbf")
# Line 358  class SaveSessionTest(unittest.TestCase, Line 392  class SaveSessionTest(unittest.TestCase,
392          written_contents = file.read()          written_contents = file.read()
393          file.close()          file.close()
394          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>          expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
395          <!DOCTYPE session SYSTEM "thuban-0.8.dtd">          <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
396          <session title="a DBF Table session"          <session title="a DBF Table session"
397             xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">             xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
398              <filetable id="D1" filename="%s" filetype="DBF" title="political"/>              <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
399          </session>'''          </session>'''
400    
401          expected_contents = expected_template % dbffile          expected_contents = (expected_template
402                                 % os.path.join(os.pardir, os.pardir, "Data",
403                                                "iceland", "political.dbf"))
404          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
405            self.validate_data(written_contents)
406    
407      def test_joined_table(self):      def test_joined_table(self):
408          """Test saving a session with joined table"""          """Test saving a session with joined table"""
# Line 401  class SaveSessionTest(unittest.TestCase, Line 438  class SaveSessionTest(unittest.TestCase,
438              #    print col.name              #    print col.name
439              joined = TransientJoinedTable(session.TransientDB(),              joined = TransientJoinedTable(session.TransientDB(),
440                                            store.Table(), "RDLNTYPE",                                            store.Table(), "RDLNTYPE",
441                                            dbftable, "RDTYPE")                                            dbftable, "RDTYPE",
442                                              outer_join = True)
443              store = session.AddShapeStore(DerivedShapeStore(store, joined))              store = session.AddShapeStore(DerivedShapeStore(store, joined))
444              layer.SetShapeStore(store)              layer.SetShapeStore(store)
445    
# Line 414  class SaveSessionTest(unittest.TestCase, Line 452  class SaveSessionTest(unittest.TestCase,
452              written_contents = file.read()              written_contents = file.read()
453              file.close()              file.close()
454              expected_template = '''<?xml version="1.0" encoding="UTF-8"?>              expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
455              <!DOCTYPE session SYSTEM "thuban-0.8.dtd">              <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
456              <session title="A Joined Table session"              <session title="A Joined Table session"
457               xmlns="http://thuban.intevation.org/dtds/thuban-0.8.dtd">               xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
458                  <fileshapesource filename="%(shpfile)s"                  <fileshapesource filename="%(shpfile)s"
459                                   filetype="shapefile" id="D142197204"/>                                   filetype="shapefile" id="D142197204"/>
460                  <filetable filename="%(dbffile)s"                  <filetable filename="%(dbffile)s"
# Line 425  class SaveSessionTest(unittest.TestCase, Line 463  class SaveSessionTest(unittest.TestCase,
463                  <jointable id="D142180284"                  <jointable id="D142180284"
464                             title="Join of roads-line and save_joinedtable"                             title="Join of roads-line and save_joinedtable"
465                             leftcolumn="RDLNTYPE" left="D142197204"                             leftcolumn="RDLNTYPE" left="D142197204"
466                             rightcolumn="RDTYPE" right="D141881756"/>                             rightcolumn="RDTYPE" right="D141881756"
467                               jointype="LEFT OUTER" />
468                  <derivedshapesource id="D141915644"                  <derivedshapesource id="D141915644"
469                                      table="D142180284"                                      table="D142180284"
470                                      shapesource="D142197204"/>                                      shapesource="D142197204"/>
# Line 441  class SaveSessionTest(unittest.TestCase, Line 480  class SaveSessionTest(unittest.TestCase,
480                  "shpfile": relative_filename(self.temp_dir(), shpfile)                  "shpfile": relative_filename(self.temp_dir(), shpfile)
481                  }                  }
482              self.compare_xml(written_contents, expected_contents)              self.compare_xml(written_contents, expected_contents)
483                self.validate_data(written_contents)
484          finally:          finally:
485              session.Destroy()              session.Destroy()
486              session = None              session = None
487    
488    
489        def test_save_postgis(self):
490            """Test saving a session with a postgis connection"""
491    
492            class NonConnection(PostGISConnection):
493                """connection class that doesn't actually connect """
494                def connect(self):
495                    pass
496    
497            class NonConnectionStore(PostGISShapeStore):
498                """Shapestore that doesn't try to access the server"""
499                def _fetch_table_information(self):
500                    pass
501    
502            session = Session("A PostGIS Session")
503            try:
504                dbconn = NonConnection(dbname="plugh", host="xyzzy", port="42",
505                                       user="grue")
506                session.AddDBConnection(dbconn)
507                map = Map("Test Map")
508                session.AddMap(map)
509                store = NonConnectionStore(dbconn, "roads")
510                session.AddShapeStore(store)
511                layer = Layer("Roads to Nowhere", store)
512                map.AddLayer(layer)
513    
514                # Save the session
515                filename = self.temp_file_name(self.id() + ".thuban")
516                save_session(session, filename)
517    
518                # Read it back and compare
519                file = open(filename)
520                written = file.read()
521                file.close()
522                expected = '''<?xml version="1.0" encoding="UTF-8"?>
523                <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
524                <session title="A PostGIS Session"
525                 xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
526                    <dbconnection id="DB"
527                                  dbtype="postgis" dbname="plugh"
528                                  host="xyzzy" port="42"
529                                  user="grue"/>
530                    <dbshapesource id="roads" dbconn="DB" tablename="roads"/>
531                    <map title="Test Map">
532                        <layer title="Roads to Nowhere"
533                               shapestore="roads" visible="true"
534                               stroke="#000000" stroke_width="1" fill="None"/>
535                    </map>
536                </session>'''
537                self.compare_xml(written, expected)
538                self.validate_data(written)
539            finally:
540                session.Destroy()
541    
542    
543  class MockDataStore:  class MockDataStore:
544    
545      """A very simple data store that only has dependencies"""      """A very simple data store that only has dependencies"""

Legend:
Removed from v.1357  
changed lines
  Added in v.1845

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26