blob: d2a485f73b4a5e02f317db64ae82d9ec1b0f5658 [file] [log] [blame]
Fred Drake1790dd42000-07-24 06:55:00 +00001"""Supporting definitions for the Python regression test."""
Guido van Rossum3bead091992-01-27 17:00:37 +00002
Fred Drakecd1b1dd2001-03-21 18:26:33 +00003import sys
4
Fred Drake1790dd42000-07-24 06:55:00 +00005class Error(Exception):
Fred Drake004d5e62000-10-23 17:22:08 +00006 """Base class for regression test exceptions."""
Fred Drake1790dd42000-07-24 06:55:00 +00007
8class TestFailed(Error):
Fred Drake004d5e62000-10-23 17:22:08 +00009 """Test failed."""
Fred Drake1790dd42000-07-24 06:55:00 +000010
11class TestSkipped(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000012 """Test skipped.
Fred Drake1790dd42000-07-24 06:55:00 +000013
Fred Drake004d5e62000-10-23 17:22:08 +000014 This can be raised to indicate that a test was deliberatly
15 skipped, but not because a feature wasn't available. For
16 example, if some resource can't be used, such as the network
17 appears to be unavailable, this should be raised instead of
18 TestFailed.
Fred Drake004d5e62000-10-23 17:22:08 +000019 """
Fred Drake1790dd42000-07-24 06:55:00 +000020
Barry Warsawc0fb6052001-08-20 22:29:23 +000021verbose = 1 # Flag set to 0 by regrtest.py
Guido van Rossumfe3f6962001-09-06 16:09:41 +000022use_resources = None # Flag set to [] by regrtest.py
Guido van Rossum531661c1996-12-20 02:58:22 +000023
Tim Petersa0a62222001-09-09 06:12:01 +000024# _output_comparison controls whether regrtest will try to compare stdout
25# with an expected-output file. For straight regrtests, it should.
26# The doctest driver should set_output_comparison(0) for the duration, and
27# restore the old value when it's done.
28# Note that this control is in addition to verbose mode: output will be
29# compared if and only if _output_comparison is true and verbose mode is
30# not in effect.
31_output_comparison = 1
32
33def set_output_comparison(newvalue):
34 global _output_comparison
35 oldvalue = _output_comparison
36 _output_comparison = newvalue
37 return oldvalue
38
39# regrtest's interface to _output_comparison.
40def suppress_output_comparison():
41 return not _output_comparison
42
43
Guido van Rossum3bead091992-01-27 17:00:37 +000044def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000045 try:
46 del sys.modules[name]
47 except KeyError:
48 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000049
50def forget(modname):
Fred Drake004d5e62000-10-23 17:22:08 +000051 unload(modname)
Fred Drakecd1b1dd2001-03-21 18:26:33 +000052 import os
Fred Drake004d5e62000-10-23 17:22:08 +000053 for dirname in sys.path:
54 try:
55 os.unlink(os.path.join(dirname, modname + '.pyc'))
56 except os.error:
57 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000058
Barry Warsawc0fb6052001-08-20 22:29:23 +000059def requires(resource, msg=None):
Guido van Rossumfe3f6962001-09-06 16:09:41 +000060 if use_resources is not None and resource not in use_resources:
Barry Warsawc0fb6052001-08-20 22:29:23 +000061 if msg is None:
62 msg = "Use of the `%s' resource not enabled" % resource
63 raise TestSkipped(msg)
64
Guido van Rossum35fb82a1993-01-26 13:04:43 +000065FUZZ = 1e-6
66
67def fcmp(x, y): # fuzzy comparison function
Fred Drake004d5e62000-10-23 17:22:08 +000068 if type(x) == type(0.0) or type(y) == type(0.0):
69 try:
70 x, y = coerce(x, y)
71 fuzz = (abs(x) + abs(y)) * FUZZ
72 if abs(x-y) <= fuzz:
73 return 0
74 except:
75 pass
76 elif type(x) == type(y) and type(x) in (type(()), type([])):
77 for i in range(min(len(x), len(y))):
78 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +000079 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +000080 return outcome
81 return cmp(len(x), len(y))
82 return cmp(x, y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +000083
Martin v. Löwis339d0f72001-08-17 18:39:25 +000084try:
85 unicode
86 have_unicode = 1
87except NameError:
88 have_unicode = 0
89
Guido van Rossuma8f7e592001-03-13 09:31:07 +000090import os
Barry Warsaw559f6682001-03-23 18:04:02 +000091# Filename used for testing
92if os.name == 'java':
93 # Jython disallows @ in module names
94 TESTFN = '$test'
95elif os.name != 'riscos':
96 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +000097 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +000098 if have_unicode:
99 TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
100 if os.name=="nt":
101 TESTFN_ENCODING="mbcs"
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000102else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000103 TESTFN = 'test'
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000104del os
105
Guido van Rossum3bead091992-01-27 17:00:37 +0000106from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +0000107
108def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000109 import os
110 if os.path.isabs(file):
111 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000112 path = sys.path
113 path = [os.path.dirname(here)] + path
114 for dn in path:
115 fn = os.path.join(dn, file)
116 if os.path.exists(fn): return fn
117 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000118
119def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000120 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000121
Skip Montanaroc955f892001-01-20 19:12:54 +0000122 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000123 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000124 """
Tim Peters983874d2001-01-19 05:59:21 +0000125
Tim Petersd2bf3b72001-01-18 02:22:22 +0000126 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000127 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000128
Tim Peters2f228e72001-05-13 00:19:31 +0000129def sortdict(dict):
130 "Like repr(dict), but in sorted order."
131 items = dict.items()
132 items.sort()
133 reprpairs = ["%r: %r" % pair for pair in items]
134 withcommas = ", ".join(reprpairs)
135 return "{%s}" % withcommas
136
Jeremy Hylton47793992001-02-19 15:35:26 +0000137def check_syntax(statement):
138 try:
139 compile(statement, '<string>', 'exec')
140 except SyntaxError:
141 pass
142 else:
143 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000144
145
146
147#=======================================================================
148# Preliminary PyUNIT integration.
149
150import unittest
151
152
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000153class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000154 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000155 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000156 test(result)
157 return result
158
159
Barry Warsawc10d6902001-09-20 06:30:41 +0000160def run_suite(suite):
Barry Warsawc88425e2001-09-20 06:31:22 +0000161 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000162 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000163 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000164 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000165 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000166
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000167 result = runner.run(suite)
168 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000169 if len(result.errors) == 1 and not result.failures:
170 err = result.errors[0][1]
171 elif len(result.failures) == 1 and not result.errors:
172 err = result.failures[0][1]
173 else:
174 raise TestFailed("errors occurred in %s.%s"
175 % (testclass.__module__, testclass.__name__))
Tim Peters2d84f2c2001-09-08 03:37:56 +0000176 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000177
Barry Warsawc10d6902001-09-20 06:30:41 +0000178
179def run_unittest(testclass):
180 """Run tests from a unittest.TestCase-derived class."""
181 run_suite(unittest.makeSuite(testclass))
182
183
Tim Petersa0a62222001-09-09 06:12:01 +0000184#=======================================================================
185# doctest driver.
186
187def run_doctest(module, verbosity=None):
188 """Run doctest on the given module.
189
190 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000191 test_support's belief about verbosity on to doctest. Else doctest's
192 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000193 """
194
195 import doctest
196
197 if verbosity is None:
198 verbosity = verbose
199 else:
200 verbosity = None
201
202 oldvalue = set_output_comparison(0)
203 try:
204 f, t = doctest.testmod(module, verbose=verbosity)
205 if f:
206 raise TestFailed("%d of %d doctests failed" % (f, t))
207 finally:
208 set_output_comparison(oldvalue)