blob: 8aab9de4586db6301b557189c84b878f4fbd0b94 [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'
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000100
101# Make sure we can write to TESTFN, try in /tmp if we can't
102fp = None
103try:
104 fp = open(TESTFN, 'w+')
105except IOError:
106 TMP_TESTFN = os.path.join('/tmp', TESTFN)
107 try:
108 fp = open(TMP_TESTFN, 'w+')
109 TESTFN = TMP_TESTFN
110 del TMP_TESTFN
111 except IOError:
112 print ('WARNING: tests will fail, unable to write to: %s or %s' %
113 (TESTFN, TMP_TESTFN))
114if fp is not None:
115 fp.close()
116 try:
117 os.unlink(TESTFN)
118 except:
119 pass
120del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000121
Guido van Rossum3bead091992-01-27 17:00:37 +0000122from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +0000123
124def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000125 import os
126 if os.path.isabs(file):
127 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000128 path = sys.path
129 path = [os.path.dirname(here)] + path
130 for dn in path:
131 fn = os.path.join(dn, file)
132 if os.path.exists(fn): return fn
133 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000134
135def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000136 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000137
Skip Montanaroc955f892001-01-20 19:12:54 +0000138 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000139 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000140 """
Tim Peters983874d2001-01-19 05:59:21 +0000141
Tim Petersd2bf3b72001-01-18 02:22:22 +0000142 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000143 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000144
Tim Petersc2fe6182001-10-30 23:20:46 +0000145def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000146 """Raise TestFailed if a == b is false.
147
148 This is better than verify(a == b) because, in case of failure, the
149 error message incorporates repr(a) and repr(b) so you can see the
150 inputs.
151
152 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
153 former is tested.
154 """
155
Tim Petersc2fe6182001-10-30 23:20:46 +0000156 if not (a == b):
157 raise TestFailed, "%r == %r" % (a, b)
158
Tim Peters2f228e72001-05-13 00:19:31 +0000159def sortdict(dict):
160 "Like repr(dict), but in sorted order."
161 items = dict.items()
162 items.sort()
163 reprpairs = ["%r: %r" % pair for pair in items]
164 withcommas = ", ".join(reprpairs)
165 return "{%s}" % withcommas
166
Jeremy Hylton47793992001-02-19 15:35:26 +0000167def check_syntax(statement):
168 try:
169 compile(statement, '<string>', 'exec')
170 except SyntaxError:
171 pass
172 else:
173 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000174
175
176
177#=======================================================================
178# Preliminary PyUNIT integration.
179
180import unittest
181
182
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000183class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000184 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000185 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000186 test(result)
187 return result
188
189
Fred Drake26641032001-10-04 19:46:07 +0000190def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000191 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000192 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000193 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000194 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000195 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000196
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000197 result = runner.run(suite)
198 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000199 if len(result.errors) == 1 and not result.failures:
200 err = result.errors[0][1]
201 elif len(result.failures) == 1 and not result.errors:
202 err = result.failures[0][1]
203 else:
Fred Drake26641032001-10-04 19:46:07 +0000204 if testclass is None:
205 msg = "errors occurred; run in verbose mode for details"
206 else:
207 msg = "errors occurred in %s.%s" \
208 % (testclass.__module__, testclass.__name__)
209 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000210 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000211
Barry Warsawc10d6902001-09-20 06:30:41 +0000212
213def run_unittest(testclass):
214 """Run tests from a unittest.TestCase-derived class."""
Fred Drake26641032001-10-04 19:46:07 +0000215 run_suite(unittest.makeSuite(testclass), testclass)
Barry Warsawc10d6902001-09-20 06:30:41 +0000216
217
Tim Petersa0a62222001-09-09 06:12:01 +0000218#=======================================================================
219# doctest driver.
220
221def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000222 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000223
224 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000225 test_support's belief about verbosity on to doctest. Else doctest's
226 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000227 """
228
229 import doctest
230
231 if verbosity is None:
232 verbosity = verbose
233 else:
234 verbosity = None
235
Tim Peters342ca752001-09-25 19:13:20 +0000236 # Direct doctest output (normally just errors) to real stdout; doctest
237 # output shouldn't be compared by regrtest.
238 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000239 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000240 try:
241 f, t = doctest.testmod(module, verbose=verbosity)
242 if f:
243 raise TestFailed("%d of %d doctests failed" % (f, t))
Tim Peters17111f32001-10-03 04:08:26 +0000244 return f, t
Tim Peters342ca752001-09-25 19:13:20 +0000245 finally:
246 sys.stdout = save_stdout