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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1245 - (show annotations)
Thu Jun 19 19:29:23 2003 UTC (21 years, 8 months ago) by bh
Original Path: trunk/thuban/test/support.py
File MIME type: text/x-python
File size: 8015 byte(s)
Add XML validation to some of the tests. Validation will only be
done if pyRXP is installed (http://reportlab.com/xml/pyrxp.html).
To make the DTD available to the test cases it's moved into
Resources/XML

* Resources/XML/thuban.dtd: New. This is now the real Thuban DTD
for versions up to and including 0.2. Two slight changes: added an
encoding specification and fixed the comment which refered to
GRASS, not Thuban

* test/xmlsupport.py: New support module for tests involving XML.
Currently there's a mix-in class for XML validation.

* test/test_xmlsupport.py: New. Tests for the xmlsupport module

* test/test_save.py (SaveSessionTest): Derive from ValidationTest
so that we can validate the
(SaveSessionTest.testEmptySession)
(SaveSessionTest.testSingleLayer)
(SaveSessionTest.testSingleLayer)
(SaveSessionTest.testLayerProjection)
(SaveSessionTest.testRasterLayer)
(SaveSessionTest.testClassifiedLayer): Validate the generated XML

* test/runtests.py (main): Call print_additional_summary instead
of print_garbage_information

* test/support.py (resource_dir): New function to return the
"Resource" subdirectory
(print_additional_summary): New function to combine several
summary functions
(run_tests): Use print_additional_summary instead of calling
print_garbage_information directly

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 Support classes and function for the test suite
10 """
11
12 __version__ = "$Revision$"
13 # $Source$
14 # $Id$
15
16 import os, sys
17 import unittest
18
19 def thuban_dir():
20 """Return the directory containing the Thuban package"""
21 thisdir = os.path.dirname(__file__)
22 return os.path.join(thisdir, os.pardir)
23
24 def resource_dir():
25 return os.path.join(thuban_dir(), "Resources")
26
27 def add_thuban_dir_to_path():
28 """Insert the Thuban directory at the beginning of the python path.
29
30 If it's already part of the path, remove later occurrences.
31 """
32 dir = thuban_dir()
33 while 1:
34 try:
35 sys.path.remove(dir)
36 except ValueError:
37 break
38 sys.path.insert(0, dir)
39
40
41 _initthuban_done = 0
42 def initthuban():
43 """Initialize the interpreter for using Thuban modules
44 """
45 global _initthuban_done
46 if not _initthuban_done:
47 add_thuban_dir_to_path()
48 import thubaninit
49 _initthuban_done = 1
50
51 def run_tests():
52 """Frontend for unittest.main that prints some additional debug information
53
54 After calling unittest.main, run the garbage collector and print
55 uncollected objects. Also print any un-unsubscribed messages.
56 """
57 try:
58 unittest.main()
59 finally:
60 # This has to be in a finally clause because unittest.main()
61 # ends with a sys.exit to make sure that the process exits with
62 # an appropriate exit code
63 print_additional_summary()
64
65 def print_additional_summary():
66 """Print some additional summary information after tests have been run"""
67 print_garbage_information()
68 import xmlsupport
69 xmlsupport.print_summary_message()
70
71 def print_garbage_information():
72 """Print information about things that haven't been cleaned up.
73
74 Run the garbage collector and print uncollected objects. Also print
75 any un-unsubscribed messages.
76 """
77 import gc, Thuban.Lib.connector
78 gc.collect()
79 if gc.garbage:
80 print
81 print "There are %d uncollected objects:" % len(gc.garbage)
82 print gc.garbage
83 Thuban.Lib.connector._the_connector.print_connections()
84
85
86 def create_temp_dir():
87 """Create a temporary directory and return its name.
88
89 The temporary directory is always called temp and is created in the
90 directory where support module is located.
91
92 If the temp directory already exists, just return the name.
93 """
94 name = os.path.abspath(os.path.join(os.path.dirname(__file__), "temp"))
95
96 # if the directory already exists, we're done
97 if os.path.isdir(name):
98 return name
99
100 # create the directory
101 os.mkdir(name)
102 return name
103
104
105 class FileTestMixin:
106
107 """Mixin class for tests that use files in the temporary directory
108 """
109
110 def temp_file_name(self, basename):
111 """Return the full name of the file named basename in the temp. dir"""
112 return os.path.join(create_temp_dir(), basename)
113
114 def temp_dir(self):
115 """Return the name of the directory for the temporary files"""
116 return create_temp_dir()
117
118
119
120 class FileLoadTestCase(unittest.TestCase, FileTestMixin):
121
122 """Base class for test case that test loading files.
123
124 This base class provides some common infrastructure for testing the
125 reading of files.
126
127 Each test case should be its own class derived from this one. There
128 is one file associated with each class. The contents are defined by
129 the file_contents class attribute and its name by the filename
130 method.
131
132 Derived classes usually only have to provide appropriate values for
133 the file_contents and file_extension class attributes.
134 """
135
136 file_contents = None
137 file_extension = ""
138
139 def filename(self):
140 """Return the name of the test file to use.
141
142 The default implementation simply calls self.volatile_file_name
143 with a basename derived from the class name by stripping off a
144 leading 'test_' and appending self.file_extension.
145 """
146 name = self.__class__.__name__
147 if name.startswith("test_"):
148 name = name[5:]
149 return self.temp_file_name(name + self.file_extension)
150
151 def setUp(self):
152 """Create the volatile file for the test.
153
154 Write self.contents (which should be a string) to the file named
155 by self.filename().
156 """
157 filename = self.filename()
158 file = open(filename, "w")
159 file.write(self.file_contents)
160 file.close()
161
162
163 class FloatComparisonMixin:
164
165 """
166 Mixin class for tests comparing floating point numbers.
167
168 This class provides a few methods for testing floating point
169 operations.
170 """
171
172 fp_epsilon = 1e-6
173
174 def assertFloatEqual(self, test, value):
175 """Assert equality of test and value with some tolerance.
176
177 Assert that the absolute difference between test and value is
178 less than self.fp_epsilon.
179 """
180 self.assert_(self.fp_epsilon > abs(test - value),
181 "abs(%g - %g) >= %g" % (test, value, self.fp_epsilon))
182
183 def assertFloatSeqEqual(self, test, value, epsilon = None):
184 """Assert equality of the sequences test and value with some tolerance.
185
186 Assert that the absolute difference between each corresponding
187 value in test and value is less than the optional parameter
188 epsilon. If epsilon is not given use self.fp_epsilon.
189 """
190 if epsilon is None:
191 epsilon = self.fp_epsilon
192 for i in range(len(test)):
193 self.assert_(epsilon > abs(test[i] - value[i]),
194 "abs(%g - %g) >= %g" % (test[i], value[i], epsilon))
195
196
197 class SubscriberMixin:
198
199 """Mixin class for tests for messages sent through the Connector
200
201 The SubscriberMixin has some methods that can be used as subscribers
202 of events that when called append information about the message into
203 a list of messages received.
204
205 A derived class should call the clear_messages() method in both its
206 setUp and tearDown methods to clear the list of messages received.
207 """
208
209 def clear_messages(self):
210 """Clear the list of received messages.
211
212 Call this at least in the tests setUp and tearDown methods. It's
213 important to do it in tearDown too because otherwise there may
214 be cyclic references.
215 """
216 self.received_messages = []
217
218 def subscribe_no_params(self):
219 """Method for subscriptions without parameters.
220
221 Add an empty tuple to the list of received messages.
222 """
223 self.received_messages.append(())
224
225 def subscribe_with_params(self, *args):
226 """Method for subscriptions with parameters.
227
228 Append the tuple will all arguments to this function (except for
229 the self argument) to the list of received messages.
230 """
231 self.received_messages.append(args)
232
233 def check_messages(self, messages):
234 """Check whether the messages received match the list messages"""
235 self.assertEquals(messages, self.received_messages)
236
237 class FloatTestCase(unittest.TestCase):
238 """TestCase with methods for testing floating point values"""
239
240 fp_epsilon = 1e-6
241 fp_inf = float('1e1000') # FIXME: hack for infinite
242
243 def assertFloatEqual(self, first, second, msg=None):
244 """Fail if one float is greater than the other + fp_epsilon"""
245 if abs(first) == self.fp_inf:
246 self.assertEqual(first, second, msg)
247 else:
248 self.assert_(self.fp_epsilon > abs(first - second), msg)
249

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26