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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1417 - (show annotations)
Tue Jul 15 08:43:53 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/test/test_load.py
File MIME type: text/x-python
File size: 20965 byte(s)
* Thuban/Model/save.py (SessionSaver.write_classification): Encode
string values (in addition to the labels) as UTF 8

* Thuban/Model/load.py (SessionLoader.start_clpoint): Decode the
values if the field type is string

* test/test_save.py (SaveSessionTest.testClassifiedLayer): Test
saving a session with non-ascii string classification values.

* test/test_load.py (TestClassification.file_contents)
(TestClassification.test): Check for non-ascii values in string
classifications

1 # Copyright (c) 2002, 2003 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 loading a thuban session from a file
10
11 The tests in this file (test_load.py) are always be the tests for the
12 current version of the thuban file format. Tests for older versions can
13 be found in the version specific test modules, e.g. test_load_0_2 for
14 files created by Thuban 0.2.
15
16 Maintenance of the test cases:
17
18 When during a development period the file format is changed with respect
19 to the last released version for the first, the tests here should be
20 copied to the version specific test file. The round-trip tests which
21 save the session again and compare the XML files should not be copied
22 over as they only make sense here to make sure th that the files checked
23 here are actually ones that may have been written by the current thuban
24 version.
25 """
26
27 __version__ = "$Revision$"
28 # $Source$
29 # $Id$
30
31 import os
32 import unittest
33
34 import support
35 support.initthuban()
36
37 from xmlsupport import sax_eventlist
38
39 import dbflib
40
41 from Thuban.Model.save import save_session
42 from Thuban.Model.load import load_session, parse_color, LoadError
43 from Thuban.Model.color import Transparent
44 from Thuban.Model.classification import ClassGroupProperties, ClassGroupRange,\
45 ClassGroupSingleton, ClassGroupDefault
46
47
48 def filenames_equal(name1, name2):
49 """Return true if the filenames name1 and name2 are equal.
50
51 On systems where it is available, simply use os.path.samefile,
52 otherwise return whether the normalized versions of the filenames
53 according to os.path.normpath are equal.
54 """
55 if hasattr(os.path, "samefile"):
56 return os.path.samefile(name1, name2)
57 return os.path.normpath(name1) == os.path.normpath(name2)
58
59
60
61 class LoadSessionTest(support.FileLoadTestCase):
62
63 """Base class for .thuban file loading tests
64
65 Basically the same as the FileLoadTestCase, except that all tests
66 use the '.thuban' extension by default and that setUp and tearDown
67 handle sessions.
68 """
69
70 file_extension = ".thuban"
71
72 def setUp(self):
73 """Create the test files"""
74 support.FileLoadTestCase.setUp(self)
75 self.session = None
76
77 def tearDown(self):
78 if self.session is not None:
79 self.session.Destroy()
80 self.session = None
81
82
83 dtd = "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
84 thubanids = [((dtd, n), (None, "id")) for n in
85 ["fileshapesource", "filetable", "jointable",
86 "derivedshapesource"]]
87 thubanidrefs = [((dtd, n), (None, m)) for n, m in
88 [("layer", "shapestore"),
89 ("jointable", "left"),
90 ("jointable", "right"),
91 ("derivedshapesource", "table"),
92 ("derivedshapesource", "shapesource")]]
93 del n, m, dtd
94
95 def check_format(self):
96 """Check whether the file we loaded from matches the one that
97 would be written. Call this from each test case after loading
98 the session
99 """
100 filename = self.temp_file_name(self.id() + ".roundtrip.thuban")
101 save_session(self.session, filename)
102 el1 = sax_eventlist(filename = filename, ids = self.thubanids,
103 idrefs = self.thubanidrefs)
104 el2 = sax_eventlist(filename = self.filename(), ids = self.thubanids,
105 idrefs = self.thubanidrefs)
106 if 0:
107 for a, b in zip(el1, el2):
108 print a != b and "***************" or ""
109 print a
110 print b
111 self.assertEquals(el1, el2,
112 "loaded file not equivalent to the saved file")
113
114
115 class ClassificationTest(LoadSessionTest):
116
117 """
118 Base class for tests that do some detailed checking of classifications
119 """
120
121 def TestLayers(self, layers, expected):
122 TITLE = 0
123 NUM_GROUPS = 1
124 CLASSES = 2
125 GROUP_TYPE = 0
126 GROUP_DATA = 1
127 GROUP_LABEL = 2
128 GROUP_PROPS = 3
129
130 eq = self.assertEquals
131
132 eq(len(layers), len(expected))
133
134 for layer, data in zip(layers, expected):
135 eq(layer.Title(), data[TITLE])
136
137 clazz = layer.GetClassification()
138 eq(clazz.GetNumGroups(), data[NUM_GROUPS])
139 eq(clazz.GetNumGroups() + 1, len(data[CLASSES]))
140
141 i = 0
142 for group in clazz:
143 props = ClassGroupProperties()
144 props.SetLineColor(
145 parse_color(data[CLASSES][i][GROUP_PROPS][0]))
146 props.SetLineWidth(data[CLASSES][i][GROUP_PROPS][1])
147 props.SetFill(
148 parse_color(data[CLASSES][i][GROUP_PROPS][2]))
149
150 if data[CLASSES][i][GROUP_TYPE] == "default":
151 g = ClassGroupDefault(props, data[CLASSES][i][GROUP_LABEL])
152 elif data[CLASSES][i][GROUP_TYPE] == "range":
153 g = ClassGroupRange((data[CLASSES][i][GROUP_DATA][0],
154 data[CLASSES][i][GROUP_DATA][1]),
155 props, data[CLASSES][i][GROUP_LABEL])
156 elif data[CLASSES][i][GROUP_TYPE] == "single":
157 g = ClassGroupSingleton(data[CLASSES][i][GROUP_DATA],
158 props, data[CLASSES][i][GROUP_LABEL])
159
160 eq(group, g)
161
162 i += 1
163
164
165
166 class TestSingleLayer(LoadSessionTest):
167
168 file_contents = '''\
169 <?xml version="1.0" encoding="UTF-8"?>
170 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
171 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
172 title="single map&amp;layer">
173 <fileshapesource filetype="shapefile" id="D1"
174 filename="../../Data/iceland/political.shp"/>
175 <map title="Test Map">
176 <projection name="Unknown">
177 <parameter value="zone=26"/>
178 <parameter value="proj=utm"/>
179 <parameter value="ellps=clrk66"/>
180 </projection>
181 <layer shapestore="D1" visible="true"
182 stroke="#000000" title="My Layer" stroke_width="1"
183 fill="None"/>
184 </map>
185 </session>
186 '''
187
188 def test(self):
189 """Load a session with a single map with a single layer"""
190 eq = self.assertEquals
191 session = load_session(self.filename())
192 self.session = session
193
194 # Check the title
195 eq(session.Title(), "single map&layer")
196
197 # the session has one map.
198 maps = session.Maps()
199 eq(len(maps), 1)
200
201 # Check the map's attributes
202 map = maps[0]
203 eq(map.Title(), "Test Map")
204
205 # the map has a single layer
206 layers = map.Layers()
207 eq(len(layers), 1)
208
209 # Check the layer attributes
210 layer = layers[0]
211 eq(layer.Title(), "My Layer")
212 self.failUnless(filenames_equal(layer.ShapeStore().FileName(),
213 os.path.join(self.temp_dir(),
214 os.pardir, os.pardir,
215 "Data", "iceland",
216 "political.shp")))
217 eq(layer.GetClassification().GetDefaultFill(), Transparent)
218 eq(layer.GetClassification().GetDefaultLineColor().hex(), "#000000")
219 eq(layer.Visible(), True)
220
221 self.check_format()
222
223 self.session.Destroy()
224 self.session = None
225
226
227 class TestLayerVisibility(LoadSessionTest):
228
229 file_contents = '''\
230 <?xml version="1.0" encoding="UTF-8"?>
231 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
232 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
233 title="single map&amp;layer">
234 <fileshapesource filetype="shapefile" id="D1"
235 filename="../../Data/iceland/political.shp"/>
236 <map title="Test Map">
237 <projection name="Unknown">
238 <parameter value="zone=26"/>
239 <parameter value="proj=utm"/>
240 <parameter value="ellps=clrk66"/>
241 </projection>
242 <layer shapestore="D1" visible="false" stroke="#000000"
243 title="My Layer" stroke_width="1" fill="None"/>
244 </map>
245 </session>
246 '''
247
248 def test(self):
249 """Test that the visible flag is correctly loaded for a layer."""
250 eq = self.assertEquals
251 session = load_session(self.filename())
252 self.session = session
253 maps = session.Maps()
254 eq(len(maps), 1)
255 map = maps[0]
256 layers = map.Layers()
257 eq(len(layers), 1)
258 layer = layers[0]
259
260 eq(layer.Visible(), False)
261
262 self.check_format()
263
264
265 class TestClassification(ClassificationTest):
266
267 file_contents = '''\
268 <?xml version="1.0" encoding="UTF-8"?>
269 <!DOCTYPE session SYSTEM "thuban.dtd">
270 <session title="single map&amp;layer">
271 <map title="Test Map">
272 <projection>
273 <parameter value="zone=26"/>
274 <parameter value="proj=utm"/>
275 <parameter value="ellps=clrk66"/>
276 </projection>
277 <layer title="My Layer" stroke_width="1" fill="None"
278 filename="../../Data/iceland/political.shp"
279 stroke="#000000">
280 <classification field="POPYREG" field_type="string">
281 <clnull>
282 <cldata stroke="#000000" stroke_width="1" fill="None"/>
283 </clnull>
284 <clpoint value="1">
285 <cldata stroke="#000000" stroke_width="2" fill="None"/>
286 </clpoint>
287 <clpoint value="1">
288 <cldata stroke="#000000" stroke_width="10" fill="None"/>
289 </clpoint>
290 <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
291 label="\xc3\x9cml\xc3\xa4uts">
292 <cldata fill="None" stroke="#000000" stroke_width="1"/>
293 </clpoint>
294 </classification>
295 </layer>
296 <layer title="My Layer 2" stroke_width="1" fill="None"
297 filename="../../Data/iceland/political.shp"
298 stroke="#000000">
299 <classification field="AREA" field_type="double">
300 <clnull>
301 <cldata stroke="#000000" stroke_width="2" fill="None"/>
302 </clnull>
303 <clrange min="0" max="1">
304 <cldata stroke="#111111" stroke_width="1" fill="None"/>
305 </clrange>
306 <clpoint value=".5">
307 <cldata stroke="#000000" stroke_width="1" fill="#111111"/>
308 </clpoint>
309 <clrange min="-1" max="0">
310 <cldata stroke="#000000" stroke_width="1" fill="None"/>
311 </clrange>
312 <clpoint value="-.5">
313 <cldata stroke="#000000" stroke_width="1" fill="None"/>
314 </clpoint>
315 </classification>
316 </layer>
317 </map>
318 </session>
319 '''
320
321 def test(self):
322 """Load a Thuban session with a map and classified layers."""
323 session = load_session(self.filename())
324 self.session = session
325
326 map = self.session.Maps()[0] # only one map in the sample
327
328 expected = [("My Layer", 3,
329 [("default", (), "",
330 ("#000000", 1, "None")),
331 ("single", "1", "",
332 ("#000000", 2, "None")),
333 ("single", "1", "",
334 ("#000000", 10, "None")),
335 ("single", "\xe4\xf6\xfc", "\xdcml\xe4uts",
336 ("#000000", 1, "None"))]),
337 ("My Layer 2", 4,
338 [("default", (), "",
339 ("#000000", 2, "None")),
340 ("range", (0, 1), "",
341 ("#111111", 1, "None")),
342 ("single", .5, "",
343 ("#000000", 1, "#111111")),
344 ("range", (-1, 0), "",
345 ("#000000", 1, "None")),
346 ("single", -.5, "",
347 ("#000000", 1, "None"))])]
348
349 self.TestLayers(map.Layers(), expected)
350
351
352 class TestLabels(ClassificationTest):
353
354 file_contents = '''\
355 <?xml version="1.0" encoding="UTF-8"?>
356 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
357 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
358 title="single map&amp;layer">
359 <fileshapesource filetype="shapefile" id="D1"
360 filename="../../Data/iceland/political.shp"/>
361 <map title="Test Map">
362 <projection name="Unknown">
363 <parameter value="zone=26"/>
364 <parameter value="proj=utm"/>
365 <parameter value="ellps=clrk66"/>
366 </projection>
367 <layer shapestore="D1" visible="true" stroke="#000000"
368 title="My Layer" stroke_width="1" fill="None">
369 <classification field="POPYREG" field_type="string">
370 <clnull label="hallo">
371 <cldata stroke="#000000" stroke_width="1" fill="None"/>
372 </clnull>
373 <clpoint label="welt" value="1">
374 <cldata stroke="#000000" stroke_width="2" fill="None"/>
375 </clpoint>
376 </classification>
377 </layer>
378 </map>
379 </session>
380 '''
381
382 def test(self):
383 """Load a session and test for reading the group labels."""
384 eq = self.assertEquals
385 session = load_session(self.filename())
386 self.session = session
387
388 map = self.session.Maps()[0] # only one map in the sample
389
390 expected = [("My Layer", 1,
391 [("default", (), "hallo",
392 ("#000000", 1, "None")),
393 ("single", "1", "welt",
394 ("#000000", 2, "None"))])]
395
396 self.TestLayers(map.Layers(), expected)
397 self.check_format()
398
399
400 class TestLayerProjection(LoadSessionTest):
401
402 file_contents = '''\
403 <?xml version="1.0" encoding="UTF-8"?>
404 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
405 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
406 title="single map&amp;layer">
407 <fileshapesource filetype="shapefile" id="D2"
408 filename="../../Data/iceland/roads-line.shp"/>
409 <fileshapesource filetype="shapefile" id="D4"
410 filename="../../Data/iceland/political.shp"/>
411 <map title="Test Map">
412 <projection name="Unknown">
413 <parameter value="zone=26"/>
414 <parameter value="proj=utm"/>
415 <parameter value="ellps=clrk66"/>
416 </projection>
417 <layer shapestore="D4" visible="true" stroke="#000000"
418 title="My Layer" stroke_width="1" fill="None">
419 <projection name="hello">
420 <parameter value="zone=13"/>
421 <parameter value="proj=tmerc"/>
422 <parameter value="ellps=clrk66"/>
423 </projection>
424 <classification field="POPYREG" field_type="string">
425 <clnull label="hallo">
426 <cldata stroke="#000000" stroke_width="1" fill="None"/>
427 </clnull>
428 <clpoint label="welt" value="1">
429 <cldata stroke="#000000" stroke_width="2" fill="None"/>
430 </clpoint>
431 </classification>
432 </layer>
433 <layer shapestore="D2" visible="true" stroke="#000000"
434 title="My Layer" stroke_width="1" fill="None">
435 <projection name="Unknown">
436 <parameter value="proj=lcc"/>
437 <parameter value="ellps=clrk66"/>
438 </projection>
439 </layer>
440 </map>
441 </session>
442 '''
443
444 def test(self):
445 """Test loading layers with projections"""
446 eq = self.assertEquals
447 neq = self.assertNotEqual
448
449 session = load_session(self.filename())
450 self.session = session
451
452 map = self.session.Maps()[0] # only one map in the sample
453
454 layers = map.Layers() # two layers in the sample
455
456 # test layer with a named projection
457 proj = layers[0].GetProjection()
458 neq(proj, None)
459 eq(proj.GetName(), "hello")
460 eq(proj.GetParameter("proj"), "tmerc")
461 eq(proj.GetParameter("zone"), "13")
462 eq(proj.GetParameter("ellps"), "clrk66")
463
464 # test layer with an unnamed projection
465 proj = layers[1].GetProjection()
466 neq(proj, None)
467 eq(proj.GetName(), "Unknown")
468 eq(proj.GetParameter("proj"), "lcc")
469 eq(proj.GetParameter("ellps"), "clrk66")
470
471 self.check_format()
472
473
474 class TestRasterLayer(LoadSessionTest):
475
476 file_contents = '''\
477 <?xml version="1.0" encoding="UTF-8"?>
478 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
479 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
480 title="single map&amp;layer">
481 <map title="Test Map">
482 <rasterlayer visible="false" filename="../../Data/iceland/island.tif"
483 title="My RasterLayer"/>
484 </map>
485 </session>
486 '''
487
488 def test(self):
489 eq = self.assertEquals
490 neq = self.assertNotEqual
491
492 session = load_session(self.filename())
493 self.session = session
494
495 map = self.session.Maps()[0] # only one map in the sample
496
497 layer = map.Layers()[0] # one layer in the sample
498
499 eq(layer.Title(), "My RasterLayer")
500 self.failIf(layer.Visible())
501 self.failUnless(filenames_equal(layer.GetImageFilename(),
502 os.path.join(self.temp_dir(),
503 os.pardir, os.pardir,
504 "Data", "iceland",
505 "island.tif")))
506 self.check_format()
507
508
509 class TestJoinedTable(LoadSessionTest):
510
511 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
512 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
513 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd" title="A Joined Table session">
514 <fileshapesource filetype="shapefile" id="D137227612"
515 filename="../../Data/iceland/roads-line.shp"/>
516 <filetable filetype="DBF" filename="load_joinedtable.dbf" id="D136171140"
517 title="Some Title"/>
518 <jointable id="D136169900" title="Joined"
519 right="D136171140" left="D137227612"
520 leftcolumn="RDLNTYPE" rightcolumn="RDTYPE"
521 jointype="LEFT OUTER"/>
522 <derivedshapesource table="D136169900" shapesource="D137227612"
523 id="D136170932"/>
524 <map title="Test Map">
525 <layer shapestore="D136170932" visible="true" stroke="#000000"
526 title="My Layer" stroke_width="1" fill="None"/>
527 </map>
528 </session>
529 '''
530
531 def setUp(self):
532 """Extend inherited method to create the dbffile for the join"""
533 LoadSessionTest.setUp(self)
534 dbffile = self.temp_file_name("load_joinedtable.dbf")
535 dbf = dbflib.create(dbffile)
536 dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
537 dbf.add_field("TEXT", dbflib.FTString, 10, 0)
538 dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
539 dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
540 dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
541 dbf.close()
542
543 def test(self):
544 """Test loading a session containing a joined table"""
545 session = load_session(self.filename())
546 self.session = session
547
548 tables = session.Tables()
549 self.assertEquals(len(tables), 3)
550 # FIXME: The tests shouldn't assume a certain order of the tables
551 self.assertEquals(tables[0].Title(), "Some Title")
552 self.assertEquals(tables[1].Title(), "Joined")
553 self.assertEquals(tables[1].JoinType(), "LEFT OUTER")
554 self.check_format()
555
556
557 class TestLoadError(LoadSessionTest):
558
559 file_contents = '''\
560 <?xml version="1.0" encoding="UTF-8"?>
561 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
562 <session xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
563 title="single map&amp;layer">
564 <fileshapesource id="D1" filename="../../Data/iceland/political.shp"/>
565 <map title="Test Map">
566 <projection name="Unknown">
567 <parameter value="zone=26"/>
568 <parameter value="proj=utm"/>
569 <parameter value="ellps=clrk66"/>
570 </projection>
571 <layer shapestore="D1" visible="true"
572 stroke="#000000" title="My Layer" stroke_width="1"
573 fill="None"/>
574 </map>
575 </session>
576 '''
577
578 def test(self):
579 """Test loading a session missing a required attribute"""
580 # Don't use assertRaises to make sure that if a session is
581 # actually returned it gets destroyed properly.
582 try:
583 self.session = load_session(self.filename())
584 except LoadError, value:
585 pass
586 else:
587 self.fail("Missing filetype attribute doesn't raise LoadError")
588
589 if __name__ == "__main__":
590 unittest.main()

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26