blob: c720f433629aa5ee60f42b2292421b93c1c793c8 [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
Barry Warsaw408b6d32002-07-30 23:27:12 +00003if __name__ != 'test.test_support':
4 raise ImportError, 'test_support must be imported from the test package'
5
Fred Drakecd1b1dd2001-03-21 18:26:33 +00006import sys
7
Fred Drake1790dd42000-07-24 06:55:00 +00008class Error(Exception):
Fred Drake004d5e62000-10-23 17:22:08 +00009 """Base class for regression test exceptions."""
Fred Drake1790dd42000-07-24 06:55:00 +000010
11class TestFailed(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000012 """Test failed."""
Fred Drake1790dd42000-07-24 06:55:00 +000013
14class TestSkipped(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000015 """Test skipped.
Fred Drake1790dd42000-07-24 06:55:00 +000016
Fred Drake004d5e62000-10-23 17:22:08 +000017 This can be raised to indicate that a test was deliberatly
18 skipped, but not because a feature wasn't available. For
19 example, if some resource can't be used, such as the network
20 appears to be unavailable, this should be raised instead of
21 TestFailed.
Fred Drake004d5e62000-10-23 17:22:08 +000022 """
Fred Drake1790dd42000-07-24 06:55:00 +000023
Barry Warsawc0fb6052001-08-20 22:29:23 +000024verbose = 1 # Flag set to 0 by regrtest.py
Guido van Rossumfe3f6962001-09-06 16:09:41 +000025use_resources = None # Flag set to [] by regrtest.py
Guido van Rossum531661c1996-12-20 02:58:22 +000026
Tim Peters8dee8092001-09-25 20:05:11 +000027# _original_stdout is meant to hold stdout at the time regrtest began.
28# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
29# The point is to have some flavor of stdout the user can actually see.
30_original_stdout = None
31def record_original_stdout(stdout):
32 global _original_stdout
33 _original_stdout = stdout
34
35def get_original_stdout():
36 return _original_stdout or sys.stdout
37
Guido van Rossum3bead091992-01-27 17:00:37 +000038def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000039 try:
40 del sys.modules[name]
41 except KeyError:
42 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000043
44def forget(modname):
Fred Drake004d5e62000-10-23 17:22:08 +000045 unload(modname)
Fred Drakecd1b1dd2001-03-21 18:26:33 +000046 import os
Fred Drake004d5e62000-10-23 17:22:08 +000047 for dirname in sys.path:
48 try:
49 os.unlink(os.path.join(dirname, modname + '.pyc'))
50 except os.error:
51 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000052
Barry Warsawc0fb6052001-08-20 22:29:23 +000053def requires(resource, msg=None):
Guido van Rossumfe3f6962001-09-06 16:09:41 +000054 if use_resources is not None and resource not in use_resources:
Barry Warsawc0fb6052001-08-20 22:29:23 +000055 if msg is None:
56 msg = "Use of the `%s' resource not enabled" % resource
57 raise TestSkipped(msg)
58
Guido van Rossum35fb82a1993-01-26 13:04:43 +000059FUZZ = 1e-6
60
61def fcmp(x, y): # fuzzy comparison function
Fred Drake004d5e62000-10-23 17:22:08 +000062 if type(x) == type(0.0) or type(y) == type(0.0):
63 try:
64 x, y = coerce(x, y)
65 fuzz = (abs(x) + abs(y)) * FUZZ
66 if abs(x-y) <= fuzz:
67 return 0
68 except:
69 pass
70 elif type(x) == type(y) and type(x) in (type(()), type([])):
71 for i in range(min(len(x), len(y))):
72 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +000073 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +000074 return outcome
75 return cmp(len(x), len(y))
76 return cmp(x, y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +000077
Martin v. Löwis339d0f72001-08-17 18:39:25 +000078try:
79 unicode
80 have_unicode = 1
81except NameError:
82 have_unicode = 0
83
Finn Bock57bc5fa2002-11-01 18:02:03 +000084is_jython = sys.platform.startswith('java')
85
Guido van Rossuma8f7e592001-03-13 09:31:07 +000086import os
Barry Warsaw559f6682001-03-23 18:04:02 +000087# Filename used for testing
88if os.name == 'java':
89 # Jython disallows @ in module names
90 TESTFN = '$test'
91elif os.name != 'riscos':
92 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +000093 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +000094 if have_unicode:
95 TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
96 if os.name=="nt":
97 TESTFN_ENCODING="mbcs"
Guido van Rossuma8f7e592001-03-13 09:31:07 +000098else:
Barry Warsaw559f6682001-03-23 18:04:02 +000099 TESTFN = 'test'
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000100del os
101
Guido van Rossum3bead091992-01-27 17:00:37 +0000102from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +0000103
104def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000105 import os
106 if os.path.isabs(file):
107 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000108 path = sys.path
109 path = [os.path.dirname(here)] + path
110 for dn in path:
111 fn = os.path.join(dn, file)
112 if os.path.exists(fn): return fn
113 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000114
115def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000116 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000117
Skip Montanaroc955f892001-01-20 19:12:54 +0000118 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000119 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000120 """
Tim Peters983874d2001-01-19 05:59:21 +0000121
Tim Petersd2bf3b72001-01-18 02:22:22 +0000122 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000123 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000124
Tim Petersc2fe6182001-10-30 23:20:46 +0000125def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000126 """Raise TestFailed if a == b is false.
127
128 This is better than verify(a == b) because, in case of failure, the
129 error message incorporates repr(a) and repr(b) so you can see the
130 inputs.
131
132 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
133 former is tested.
134 """
135
Tim Petersc2fe6182001-10-30 23:20:46 +0000136 if not (a == b):
137 raise TestFailed, "%r == %r" % (a, b)
138
Tim Peters2f228e72001-05-13 00:19:31 +0000139def sortdict(dict):
140 "Like repr(dict), but in sorted order."
141 items = dict.items()
142 items.sort()
143 reprpairs = ["%r: %r" % pair for pair in items]
144 withcommas = ", ".join(reprpairs)
145 return "{%s}" % withcommas
146
Jeremy Hylton47793992001-02-19 15:35:26 +0000147def check_syntax(statement):
148 try:
149 compile(statement, '<string>', 'exec')
150 except SyntaxError:
151 pass
152 else:
153 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000154
155
156
157#=======================================================================
158# Preliminary PyUNIT integration.
159
160import unittest
161
162
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000163class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000164 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000165 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000166 test(result)
167 return result
168
169
Fred Drake26641032001-10-04 19:46:07 +0000170def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000171 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000172 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000173 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000174 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000175 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000176
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000177 result = runner.run(suite)
178 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000179 if len(result.errors) == 1 and not result.failures:
180 err = result.errors[0][1]
181 elif len(result.failures) == 1 and not result.errors:
182 err = result.failures[0][1]
183 else:
Fred Drake26641032001-10-04 19:46:07 +0000184 if testclass is None:
185 msg = "errors occurred; run in verbose mode for details"
186 else:
187 msg = "errors occurred in %s.%s" \
188 % (testclass.__module__, testclass.__name__)
189 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000190 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000191
Barry Warsawc10d6902001-09-20 06:30:41 +0000192
193def run_unittest(testclass):
194 """Run tests from a unittest.TestCase-derived class."""
Fred Drake26641032001-10-04 19:46:07 +0000195 run_suite(unittest.makeSuite(testclass), testclass)
Barry Warsawc10d6902001-09-20 06:30:41 +0000196
197
Tim Petersa0a62222001-09-09 06:12:01 +0000198#=======================================================================
199# doctest driver.
200
201def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000202 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000203
204 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000205 test_support's belief about verbosity on to doctest. Else doctest's
206 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000207 """
208
209 import doctest
210
211 if verbosity is None:
212 verbosity = verbose
213 else:
214 verbosity = None
215
Tim Peters342ca752001-09-25 19:13:20 +0000216 # Direct doctest output (normally just errors) to real stdout; doctest
217 # output shouldn't be compared by regrtest.
218 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000219 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000220 try:
221 f, t = doctest.testmod(module, verbose=verbosity)
222 if f:
223 raise TestFailed("%d of %d doctests failed" % (f, t))
Tim Peters17111f32001-10-03 04:08:26 +0000224 return f, t
Tim Peters342ca752001-09-25 19:13:20 +0000225 finally:
226 sys.stdout = save_stdout