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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1263 by jonathan, Fri Jun 20 14:15:43 2003 UTC revision 1605 by bh, Tue Aug 19 11:00:40 2003 UTC
# Line 15  __version__ = "$Revision$" Line 15  __version__ = "$Revision$"
15    
16  import os, sys  import os, sys
17  import unittest  import unittest
18    import traceback
19    
20    import postgissupport
21    
22    
23  def thuban_dir():  def thuban_dir():
24      """Return the directory containing the Thuban package"""      """Return the directory containing the Thuban package"""
# Line 48  def initthuban(): Line 52  def initthuban():
52          import thubaninit          import thubaninit
53          _initthuban_done = 1          _initthuban_done = 1
54    
 def run_tests():  
     """Frontend for unittest.main that prints some additional debug information  
55    
56      After calling unittest.main, run the garbage collector and print  #
57      uncollected objects. Also print any un-unsubscribed messages.  # Special test runner and result that support skipping tests
58    #
59    
60    class SkipTest(Exception):
61        """Exception to raise in tests that are skipped for some reason
62    
63        For instance, since gdal support is optional, test cases that
64        require gdal raise this exception to indicate that they are skipped.
65        Skipped is different from failure or error in that it is expected
66        under certain circumstances.
67        """
68    
69    class ThubanTestResult(unittest._TextTestResult):
70    
71        def __init__(self, stream, descriptions, verbosity):
72            unittest._TextTestResult.__init__(self, stream, descriptions,
73                                              verbosity)
74            self.skipped_tests = {}
75    
76        def add_skipped_test(self, test, exc):
77            reason = str(exc)
78            self.skipped_tests.setdefault(reason, []).append(test)
79    
80        def count_skipped(self):
81            sum = 0
82            for tests in self.skipped_tests.values():
83                sum += len(tests)
84            return sum
85    
86        def addError(self, test, err):
87            """Extend inherited method to handle SkipTest exceptions specially
88            """
89            #print "addError", test, err
90            if isinstance(err[1], SkipTest):
91                self.add_skipped_test(test, err[1])
92                if self.showAll:
93                    self.stream.writeln("skipped")
94                elif self.dots:
95                    self.stream.write('S')
96            else:
97                unittest._TextTestResult.addError(self, test, err)
98    
99        def printErrors(self):
100            if self.skipped_tests:
101                if self.dots or self.showAll:
102                    self.stream.writeln()
103                self.stream.writeln("Skipped tests:")
104                for reason, tests in self.skipped_tests.items():
105                    self.stream.writeln("  %s:" % reason)
106                    for test in tests:
107                        self.stream.writeln("    " + test.id())
108            unittest._TextTestResult.printErrors(self)
109    
110    
111    class ThubanTestRunner(unittest.TextTestRunner):
112    
113        def _makeResult(self):
114            return ThubanTestResult(self.stream, self.descriptions, self.verbosity)
115    
116        def run(self, test):
117            result = unittest.TextTestRunner.run(self, test)
118            self.stream.writeln("skipped = %d" % result.count_skipped())
119            return result
120    
121    
122    class ThubanTestProgram(unittest.TestProgram):
123    
124        def runTests(self):
125            """Extend inherited method so that we use a ThubanTestRunner"""
126            print "ThubanTestProgram.runTests"
127            self.testRunner = ThubanTestRunner(verbosity = self.verbosity)
128            unittest.TestProgram.runTests(self)
129    
130    
131    def execute_as_testsuite(callable, *args, **kw):
132        """Call callable  with args as if it were the entry point to the test suite
133    
134        Return watever callable returns.
135    
136        This is a helper function for run_tests and runtests.py. Call
137        callable in a try-finally block and run some cleanup and print some
138        additional information in the finally block.
139    
140        The additionaly information include:
141    
142         - A list of uncollected objects (after an explicit garbage
143           collector call)
144    
145         - any unsubscribed messages
146      """      """
147      try:      try:
148          unittest.main()          return callable(*args, **kw)
149      finally:      finally:
150          # This has to be in a finally clause because unittest.main()          # This has to be in a finally clause because unittest.main()
151          # ends with a sys.exit to make sure that the process exits with          # ends with a sys.exit to make sure that the process exits with
152          # an appropriate exit code          # an appropriate exit code
153    
154            # Shutdown the postgis server if it's running
155            try:
156                postgissupport.shutdown_test_server()
157            except:
158                traceback.print_exc()
159    
160            # Print additional information
161          print_additional_summary()          print_additional_summary()
162    
163    def run_tests():
164        """Frontend for unittest.main that prints some additional debug information
165    
166        After calling unittest.main, run the garbage collector and print
167        uncollected objects. Also print any un-unsubscribed messages.
168        """
169        execute_as_testsuite(ThubanTestProgram)
170    
171    
172  def print_additional_summary():  def print_additional_summary():
173      """Print some additional summary information after tests have been run"""      """Print some additional summary information after tests have been run"""
174      print_garbage_information()      print_garbage_information()
# Line 82  def print_garbage_information(): Line 189  def print_garbage_information():
189          print gc.garbage          print gc.garbage
190      Thuban.Lib.connector._the_connector.print_connections()      Thuban.Lib.connector._the_connector.print_connections()
191    
192    #
193    
194  def create_temp_dir():  def create_temp_dir():
195      """Create a temporary directory and return its name.      """Create a temporary directory and return its name.
# Line 160  class FileLoadTestCase(unittest.TestCase Line 268  class FileLoadTestCase(unittest.TestCase
268          file.close()          file.close()
269    
270    
271  class FloatComparisonMixin(unittest.TestCase):  class FloatComparisonMixin:
272    
273      """      """
274      Mixin class for tests comparing floating point numbers.      Mixin class for tests comparing floating point numbers.
# Line 171  class FloatComparisonMixin(unittest.Test Line 279  class FloatComparisonMixin(unittest.Test
279    
280      fp_epsilon = 1e-6      fp_epsilon = 1e-6
281      fp_inf = float('1e1000')   # FIXME: hack for infinite      fp_inf = float('1e1000')   # FIXME: hack for infinite
282        
283      def assertFloatEqual(self, test, value):      def assertFloatEqual(self, test, value, epsilon = None):
284          """Assert equality of test and value with some tolerance.          """Assert equality of test and value with some tolerance.
285    
286          Assert that the absolute difference between test and value is          Assert that the absolute difference between test and value is
287          less than self.fp_epsilon.          less than self.fp_epsilon.
288          """          """
289            if epsilon is None:
290                epsilon = self.fp_epsilon
291          if abs(test) == self.fp_inf:          if abs(test) == self.fp_inf:
292              self.assertEqual(test, value)              self.assertEqual(test, value)
293          else:          else:
294              self.assert_(self.fp_epsilon > abs(test - value),              self.assert_(epsilon > abs(test - value),
295                       "abs(%g - %g) >= %g" % (test, value, self.fp_epsilon))                       "abs(%g - %g) >= %g" % (test, value, epsilon))
296    
297      def assertFloatSeqEqual(self, test, value, epsilon = None):      def assertFloatSeqEqual(self, test, value, epsilon = None):
298          """Assert equality of the sequences test and value with some tolerance.          """Assert equality of the sequences test and value with some tolerance.
# Line 191  class FloatComparisonMixin(unittest.Test Line 301  class FloatComparisonMixin(unittest.Test
301          value in test and value is less than the optional parameter          value in test and value is less than the optional parameter
302          epsilon. If epsilon is not given use self.fp_epsilon.          epsilon. If epsilon is not given use self.fp_epsilon.
303          """          """
         if epsilon is None:  
             epsilon = self.fp_epsilon  
304          for i in range(len(test)):          for i in range(len(test)):
305              self.assert_(epsilon > abs(test[i] - value[i]),              self.assertFloatEqual(test[i], value[i], epsilon)
306                           "abs(%g - %g) >= %g" % (test[i], value[i], epsilon))  
307        def assertPointListEquals(self, test, value):
308            """Assert equality of two lists of lists of tuples of float
309    
310            This assertion is usually used to compare the geometry of shapes
311            as returned by a Shape object's Points() method, hence the name.
312            """
313            for i in range(len(test)):
314                self.assertEquals(len(test[i]), len(value[i]))
315                for j in range(len(test[i])):
316                    self.assertFloatSeqEqual(test[i][j], value[i][j])
317    
318    
319  class SubscriberMixin:  class SubscriberMixin:

Legend:
Removed from v.1263  
changed lines
  Added in v.1605

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26