/[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 723 by bh, Thu Apr 24 15:31:53 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    
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 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  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  class SaxEventLister(xml.sax.handler.ContentHandler):  from Thuban.Model.data import DerivedShapeStore
37    
38      def __init__(self):  from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
39          self.eventlist = []      ClassGroupProperties
40    
41      def startElementNS(self, name, qname, attrs):  from Thuban.Model.range import Range
42          items = attrs.items()  
43          items.sort()  from Thuban.Model.postgisdb import PostGISConnection, PostGISShapeStore
44          self.eventlist.append(("start", name, qname, items))  
45    
46      def endElementNS(self, name, qname):  class XMLWriterTest(unittest.TestCase):
47          self.eventlist.append(("end", name, qname))  
48        def testEncode(self):
49            """Test XMLWriter.encode"""
50  def sax_eventlist(data):          writer = XMLWriter()
51      """Return a list of SAX event generated for the XML data.          eq = self.assertEquals
52      """  
53      handler = SaxEventLister()          eq(writer.encode("hello world"), "hello world")
54      parser = make_parser()          eq(writer.encode(unicode("hello world")), unicode("hello world"))
55      parser.setContentHandler(handler)  
56      parser.setErrorHandler(ErrorHandler())          eq(writer.encode("\x80\x90\xc2\x100"),
57      parser.setFeature(xml.sax.handler.feature_namespaces, 1)                           "\xc2\x80\xc2\x90\xc3\x82\x100")
58            eq(writer.encode(u"\x80\x90\xc2\x100"),
59      #                           "\xc2\x80\xc2\x90\xc3\x82\x100")
60      # see comment at the end of Thuban/Model/load.py          eq(writer.encode(u"\xFF5E"), "\xc3\xbf5E")
61      #  
62      try:          eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
63          parser.setFeature(xml.sax.handler.feature_validation, 0)          eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
64          parser.setFeature(xml.sax.handler.feature_external_ges, 0)  
65          parser.setFeature(xml.sax.handler.feature_external_pes, 0)  class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
66      except SAXNotRecognizedException:                        xmlsupport.ValidationTest):
67          pass  
68        dtd = "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd"
69      inpsrc = xml.sax.InputSource()      thubanids = [((dtd, n), (None, "id")) for n in
70      inpsrc.setByteStream(StringIO(data))                   ["fileshapesource", "filetable", "jointable",
71      parser.parse(inpsrc)                    "derivedshapesource", "dbshapesource", "dbconnection"]]
72        thubanidrefs = [((dtd, n), (None, m)) for n, m in
73      return handler.eventlist                      [("layer", "shapestore"),
74                         ("jointable", "left"),
75  class SaveSessionTest(unittest.TestCase, support.FileTestMixin):                       ("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 87  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-1.0.dtd">\n'
115                           '<session title="empty session">\n</session>\n')                           '<session title="empty session" '
116             'xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.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"""
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 105  class SaveSessionTest(unittest.TestCase, Line 136  class SaveSessionTest(unittest.TestCase,
136    
137          filename = self.temp_file_name("save_singlemap.thuban")          filename = self.temp_file_name("save_singlemap.thuban")
138          save_session(session, filename)          save_session(session, filename)
139    
140            file = open(filename)
141            written_contents = file.read()
142            file.close()
143            expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
144            <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
145            <session title="single map&amp;layer"
146               xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
147                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
148                <map title="Test Map">
149                    <projection epsg="32627" name="WGS 84 / UTM zone 27N">
150                        <parameter value="proj=utm"/>
151                        <parameter value="zone=27"/>
152                        <parameter value="ellps=WGS84"/>
153                        <parameter value="datum=WGS84"/>
154                        <parameter value="units=m"/>
155                    </projection>
156                    <layer title="My Layer" shapestore="D1"
157                    fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
158                </map>
159            </session>'''
160    
161            expected_contents = expected_template % \
162                (os.path.join("..", "..", "Data", "iceland", "political.shp"),
163                 "true")
164    
165            self.compare_xml(written_contents, expected_contents)
166    
167            self.validate_data(written_contents)
168    
169            layer.SetVisible(False)
170            save_session(session, filename)
171    
172            file = open(filename)
173            written_contents = file.read()
174            file.close()
175            expected_contents = expected_template % \
176                (os.path.join("..", "..", "Data", "iceland", "political.shp"),
177                 "false")
178            self.compare_xml(written_contents, expected_contents)
179            self.validate_data(written_contents)
180    
181          session.Destroy()          session.Destroy()
182    
183        def testLayerProjection(self):
184            """Test saving layers with projections"""
185            # deliberately put an apersand in the title :)
186            session = self.session = Session("single map&layer")
187            proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
188            map = Map("Test Map", projection = proj)
189            session.AddMap(map)
190            # use shapefile from the example data
191            shpfile = os.path.join(os.path.dirname(__file__),
192                                   os.pardir, "Data", "iceland", "political.shp")
193            layer = Layer("My Layer", session.OpenShapefile(shpfile))
194            proj = Projection(["proj=lcc", "ellps=clrk66",
195                               "lat_1=0", "lat_2=20"],
196                              "Layer Projection")
197            layer.SetProjection(proj)
198            map.AddLayer(layer)
199    
200            filename = self.temp_file_name("save_layerproj.thuban")
201            save_session(session, filename)
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.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-1.0-dev.dtd">
210                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
211              <map title="Test Map">              <map title="Test Map">
212                  <projection>                  <projection name="Unknown">
213                      <parameter value="zone=26"/>                      <parameter value="zone=26"/>
214                      <parameter value="proj=utm"/>                      <parameter value="proj=utm"/>
215                      <parameter value="ellps=clrk66"/>                      <parameter value="ellps=clrk66"/>
216                  </projection>                  </projection>
217                  <layer title="My Layer" filename="%s"                  <layer title="My Layer" shapestore="D1"
218                  fill="None" stroke="#000000" stroke_width="1"/>                  fill="None" stroke="#000000" stroke_width="1" visible="true">
219                        <projection name="Layer Projection">
220                            <parameter value="proj=lcc"/>
221                            <parameter value="ellps=clrk66"/>
222                            <parameter value="lat_1=0"/>
223                            <parameter value="lat_2=20"/>
224                        </projection>
225                    </layer>
226              </map>              </map>
227          </session>''' % os.path.join("..", "..", "Data", "iceland",          </session>''' % os.path.join("..", "..", "Data", "iceland",
228                                       "political.shp")                                       "political.shp")
# Line 129  class SaveSessionTest(unittest.TestCase, Line 231  class SaveSessionTest(unittest.TestCase,
231          #print expected_contents          #print expected_contents
232          self.compare_xml(written_contents, expected_contents)          self.compare_xml(written_contents, expected_contents)
233    
234            self.validate_data(written_contents)
235    
236        def testRasterLayer(self):
237            # deliberately put an apersand in the title :)
238            session = Session("single map&layer")
239            map = Map("Test Map")
240            session.AddMap(map)
241            # use shapefile from the example data
242            imgfile = os.path.join(os.path.dirname(__file__),
243                                   os.pardir, "Data", "iceland", "island.tif")
244            layer = RasterLayer("My RasterLayer", imgfile)
245            map.AddLayer(layer)
246    
247            filename = self.temp_file_name("%s.thuban" % self.id())
248            save_session(session, filename)
249            session.Destroy()
250    
251            file = open(filename)
252            written_contents = file.read()
253            file.close()
254            expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
255            <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
256            <session title="single map&amp;layer"
257               xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
258                <map title="Test Map">
259                    <rasterlayer title="My RasterLayer" filename="%s"
260                                 visible="true">
261                    </rasterlayer>
262                </map>
263            </session>''' % os.path.join(os.pardir, os.pardir, "Data", "iceland",
264                                         "island.tif")
265            #print written_contents
266            #print "********************************************"
267            #print expected_contents
268            self.compare_xml(written_contents, expected_contents)
269    
270            self.validate_data(written_contents)
271    
272        def testClassifiedLayer(self):
273            """Save a session with a single map with classifications"""
274            # deliberately put an apersand in the title :)
275            session = Session("Map with Classifications")
276            proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
277            map = Map("Test Map", projection = proj)
278            session.AddMap(map)
279            # use shapefile from the example data
280            shpfile = os.path.join(os.path.dirname(__file__),
281                                   os.pardir, "Data", "iceland", "political.shp")
282            layer = Layer("My Layer", session.OpenShapefile(shpfile))
283            map.AddLayer(layer)
284            layer2 = Layer("My Layer", layer.ShapeStore())
285            map.AddLayer(layer2)
286    
287            clazz = layer.GetClassification()
288    
289            layer.SetClassificationColumn("AREA")
290    
291            clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
292                                                  "single"))
293            clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
294                                                  "single-text"))
295    
296            clazz.AppendGroup(ClassGroupRange((0, 42),
297                                               ClassGroupProperties(),
298                                               "range"))
299    
300            range = ClassGroupRange(Range("[0;42]"))
301            range.SetProperties(ClassGroupProperties())
302            range.SetLabel("new-range")
303            clazz.AppendGroup(range)
304    
305    
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)
317    
318            file = open(filename)
319            written_contents = file.read()
320            file.close()
321            expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
322            <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
323            <session title="Map with Classifications"
324               xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
325                <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
326                <map title="Test Map">
327                    <projection name="Unknown">
328                        <parameter value="zone=26"/>
329                        <parameter value="proj=utm"/>
330                        <parameter value="ellps=clrk66"/>
331                    </projection>
332                    <layer title="My Layer" shapestore="D1"
333                    fill="None" stroke="#000000" stroke_width="1" visible="%s">
334                        <classification field="AREA" field_type="double">
335                            <clnull label="">
336                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
337                            </clnull>
338                            <clpoint value="42" label="single">
339                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
340                            </clpoint>
341                            <clpoint value="text" label="single-text">
342                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
343                            </clpoint>
344                            <clrange range="[0;42[" label="range">
345                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
346                            </clrange>
347                            <clrange range="[0;42]" label="new-range">
348                                <cldata fill="None" stroke="#000000" stroke_width="1"/>
349                            </clrange>
350                        </classification>
351                    </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>
365            </session>'''
366    
367            expected_contents = expected_template % \
368                (os.path.join("..", "..", "Data", "iceland", "political.shp"),
369                 "true")
370    
371            #print written_contents
372            #print "********************************************"
373            #print expected_contents
374            self.compare_xml(written_contents, expected_contents)
375    
376            self.validate_data(written_contents)
377    
378            session.Destroy()
379    
380        def test_dbf_table(self):
381            """Test saving a session with a dbf table link"""
382            session = self.session = Session("a DBF Table session")
383            # use shapefile from the example data
384            dbffile = os.path.join(os.path.dirname(__file__),
385                                   os.pardir, "Data", "iceland", "political.dbf")
386            table = session.AddTable(DBFTable(dbffile))
387    
388            filename = self.temp_file_name("save_singletable.thuban")
389            save_session(session, filename)
390    
391            file = open(filename)
392            written_contents = file.read()
393            file.close()
394            expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
395            <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
396            <session title="a DBF Table session"
397               xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
398                <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
399            </session>'''
400    
401            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)
405            self.validate_data(written_contents)
406    
407        def test_joined_table(self):
408            """Test saving a session with joined table"""
409            # Create a simple table to use in the join
410            dbffile = self.temp_file_name("save_joinedtable.dbf")
411            dbf = dbflib.create(dbffile)
412            dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
413            dbf.add_field("TEXT", dbflib.FTString, 10, 0)
414            dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
415            dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
416            dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
417            dbf.close()
418    
419            # Create the session and a map
420            session = Session("A Joined Table session")
421            try:
422                map = Map("Test Map")
423                session.AddMap(map)
424    
425                # Add the dbf file to the session
426                dbftable = session.AddTable(DBFTable(dbffile))
427    
428                # Create a layer with the shapefile to use in the join
429                shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
430                                       os.pardir, "Data", "iceland",
431                                       "roads-line.shp")
432                layer = Layer("My Layer", session.OpenShapefile(shpfile))
433                map.AddLayer(layer)
434    
435                # Do the join
436                store = layer.ShapeStore()
437                #for col in store.Table().Columns():
438                #    print col.name
439                joined = TransientJoinedTable(session.TransientDB(),
440                                              store.Table(), "RDLNTYPE",
441                                              dbftable, "RDTYPE",
442                                              outer_join = True)
443                store = session.AddShapeStore(DerivedShapeStore(store, joined))
444                layer.SetShapeStore(store)
445    
446                # Save the session
447                filename = self.temp_file_name("save_joinedtable.thuban")
448                save_session(session, filename)
449    
450                # Read it back and compare
451                file = open(filename)
452                written_contents = file.read()
453                file.close()
454                expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
455                <!DOCTYPE session SYSTEM "thuban-1.0.dtd">
456                <session title="A Joined Table session"
457                 xmlns="http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd">
458                    <fileshapesource filename="%(shpfile)s"
459                                     filetype="shapefile" id="D142197204"/>
460                    <filetable filename="%(dbffile)s"
461                               title="save_joinedtable"
462                               filetype="DBF" id="D141881756"/>
463                    <jointable id="D142180284"
464                               title="Join of roads-line and save_joinedtable"
465                               leftcolumn="RDLNTYPE" left="D142197204"
466                               rightcolumn="RDTYPE" right="D141881756"
467                               jointype="LEFT OUTER" />
468                    <derivedshapesource id="D141915644"
469                                        table="D142180284"
470                                        shapesource="D142197204"/>
471                    <map title="Test Map">
472                        <layer title="My Layer"
473                               shapestore="D141915644" visible="true"
474                               stroke="#000000" stroke_width="1" fill="None"/>
475                    </map>
476                </session>'''
477    
478                expected_contents = expected_template % {
479                    "dbffile": relative_filename(self.temp_dir(), dbffile),
480                    "shpfile": relative_filename(self.temp_dir(), shpfile)
481                    }
482                self.compare_xml(written_contents, expected_contents)
483                self.validate_data(written_contents)
484            finally:
485                session.Destroy()
486                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:
544    
545        """A very simple data store that only has dependencies"""
546    
547        def __init__(self, name, *dependencies):
548            self.name = name
549            self.dependencies = dependencies
550    
551        def __repr__(self):
552            return self.name
553    
554        def Dependencies(self):
555            return self.dependencies
556    
557    
558    class TestStoreSort(unittest.TestCase):
559    
560        def check_sort(self, containers, sorted):
561            """Check whether the list of data containers is sorted"""
562            # check whether sorted is in the right order
563            seen = {}
564            for container in sorted:
565                self.failIf(id(container) in seen,
566                            "Container %r at least twice in %r" % (container,
567                                                                   sorted))
568                for dep in container.Dependencies():
569                    self.assert_(id(dep) in seen,
570                                 "Dependency %r of %r not yet seen" % (dep,
571                                                                       container))
572                seen[id(container)] = 1
573            # check whether all of containers is in sorted
574            for container in containers:
575                self.assert_(id(container) in seen,
576                             "Container %r in containers but not in sorted")
577            self.assertEquals(len(containers), len(sorted))
578    
579        def test_sort_data_stores(self):
580            """Test Thuban.Model.save.sort_data_stores"""
581            d1 = MockDataStore("d1")
582            d2 = MockDataStore("d2")
583            d3 = MockDataStore("d3", d1)
584            d4 = MockDataStore("d4", d1, d3)
585    
586            containers = [d4, d1, d2, d3]
587            self.check_sort(containers, sort_data_stores(containers))
588            containers = [d1, d3, d2, d4]
589            self.check_sort(containers, sort_data_stores(containers))
590    
591    
592    
593  if __name__ == "__main__":  if __name__ == "__main__":

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26