blob: 948c64561f890a907c0026b645ecfc2760ef77ab [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
Guido van Rossuma8f7e592001-03-13 09:31:07 +000084import os
Barry Warsaw559f6682001-03-23 18:04:02 +000085# Filename used for testing
86if os.name == 'java':
87 # Jython disallows @ in module names
88 TESTFN = '$test'
89elif os.name != 'riscos':
90 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +000091 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +000092 if have_unicode:
93 TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
94 if os.name=="nt":
95 TESTFN_ENCODING="mbcs"
Guido van Rossuma8f7e592001-03-13 09:31:07 +000096else:
Barry Warsaw559f6682001-03-23 18:04:02 +000097 TESTFN = 'test'
Guido van Rossuma8f7e592001-03-13 09:31:07 +000098del os
99
Guido van Rossum3bead091992-01-27 17:00:37 +0000100from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +0000101
102def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000103 import os
104 if os.path.isabs(file):
105 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000106 path = sys.path
107 path = [os.path.dirname(here)] + path
108 for dn in path:
109 fn = os.path.join(dn, file)
110 if os.path.exists(fn): return fn
111 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000112
113def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000114 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000115
Skip Montanaroc955f892001-01-20 19:12:54 +0000116 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000117 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000118 """
Tim Peters983874d2001-01-19 05:59:21 +0000119
Tim Petersd2bf3b72001-01-18 02:22:22 +0000120 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000121 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000122
Tim Petersc2fe6182001-10-30 23:20:46 +0000123def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000124 """Raise TestFailed if a == b is false.
125
126 This is better than verify(a == b) because, in case of failure, the
127 error message incorporates repr(a) and repr(b) so you can see the
128 inputs.
129
130 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
131 former is tested.
132 """
133
Tim Petersc2fe6182001-10-30 23:20:46 +0000134 if not (a == b):
135 raise TestFailed, "%r == %r" % (a, b)
136
Tim Peters2f228e72001-05-13 00:19:31 +0000137def sortdict(dict):
138 "Like repr(dict), but in sorted order."
139 items = dict.items()
140 items.sort()
141 reprpairs = ["%r: %r" % pair for pair in items]
142 withcommas = ", ".join(reprpairs)
143 return "{%s}" % withcommas
144
Jeremy Hylton47793992001-02-19 15:35:26 +0000145def check_syntax(statement):
146 try:
147 compile(statement, '<string>', 'exec')
148 except SyntaxError:
149 pass
150 else:
151 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000152
153
154
155#=======================================================================
156# Preliminary PyUNIT integration.
157
158import unittest
159
160
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000161class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000162 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000163 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000164 test(result)
165 return result
166
167
Fred Drake26641032001-10-04 19:46:07 +0000168def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000169 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000170 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000171 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000172 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000173 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000174
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000175 result = runner.run(suite)
176 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000177 if len(result.errors) == 1 and not result.failures:
178 err = result.errors[0][1]
179 elif len(result.failures) == 1 and not result.errors:
180 err = result.failures[0][1]
181 else:
Fred Drake26641032001-10-04 19:46:07 +0000182 if testclass is None:
183 msg = "errors occurred; run in verbose mode for details"
184 else:
185 msg = "errors occurred in %s.%s" \
186 % (testclass.__module__, testclass.__name__)
187 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000188 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000189
Barry Warsawc10d6902001-09-20 06:30:41 +0000190
191def run_unittest(testclass):
192 """Run tests from a unittest.TestCase-derived class."""
Fred Drake26641032001-10-04 19:46:07 +0000193 run_suite(unittest.makeSuite(testclass), testclass)
Barry Warsawc10d6902001-09-20 06:30:41 +0000194
195
Tim Petersa0a62222001-09-09 06:12:01 +0000196#=======================================================================
197# doctest driver.
198
199def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000200 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000201
202 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000203 test_support's belief about verbosity on to doctest. Else doctest's
204 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000205 """
206
207 import doctest
208
209 if verbosity is None:
210 verbosity = verbose
211 else:
212 verbosity = None
213
Tim Peters342ca752001-09-25 19:13:20 +0000214 # Direct doctest output (normally just errors) to real stdout; doctest
215 # output shouldn't be compared by regrtest.
216 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000217 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000218 try:
219 f, t = doctest.testmod(module, verbose=verbosity)
220 if f:
221 raise TestFailed("%d of %d doctests failed" % (f, t))
Tim Peters17111f32001-10-03 04:08:26 +0000222 return f, t
Tim Peters342ca752001-09-25 19:13:20 +0000223 finally:
224 sys.stdout = save_stdout