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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2642 - (show annotations)
Fri Jul 1 20:49:04 2005 UTC (19 years, 8 months ago) by bh
Original Path: trunk/thuban/test/test_save.py
File MIME type: text/x-python
File size: 24916 byte(s)
First step towards unicode.  With this roughly we're at step 1
string_representation.txt

* Doc/technotes/string_representation.txt: New.  Document how
strings are represented in Thuban and how to get to a Unicode
Thuban.

* Thuban/__init__.py (set_internal_encoding)
(unicode_from_internal, internal_from_unicode): New. The first few
functions for the internal string representation

* Thuban/UI/about.py (unicodeToLocale): Removed.  Use
internal_from_unicode instead.

* Thuban/UI/__init__.py (install_wx_translation): Determine the
encoding to use for the internal string representation.  Also,
change the translation function to return strings in internal
representation even on unicode builds of wxPython

* Thuban/Model/load.py (SessionLoader.check_attrs): Decode
filenames too.
(SessionLoader.start_clrange): Use check_attrs to decode and check
the attributes.

* Thuban/Model/xmlreader.py (XMLReader.encode): Use
internal_from_unicode to convert unicode strings.

* Thuban/Model/xmlwriter.py (XMLWriter.encode): Use
unicode_from_internal when applicable

* test/runtests.py (main): New command line option:
internal-encoding to specify the internal string encoding to use
in the tests.

* test/support.py (initthuban): Set the internal encoding to
latin-1

* test/test_load.py (TestSingleLayer.test, TestClassification.test)
(TestLabelLayer.test): Use the internal string representation when
dealing with non-ascii characters

* test/test_load_1_0.py (TestSingleLayer.test)
(TestClassification.test, TestLabelLayer.test): Use the internal
string representation when dealing with non-ascii characters

* test/test_load_0_9.py (TestSingleLayer.test)
(TestClassification.test): Use the internal string representation
when dealing with non-ascii characters

* test/test_load_0_8.py (TestUnicodeStrings.test): Use the
internal string representation when dealing with non-ascii
characters

* test/test_save.py (XMLWriterTest.testEncode)
(SaveSessionTest.testClassifiedLayer): Use the internal string
representation when dealing with non-ascii characters where
applicable

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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26