blob: 81695330d2574e3d317170941a2edb89eec1ee93 [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
Tim Petersb4ee4eb2002-12-04 03:26:57 +000053def is_resource_enabled(resource):
54 return use_resources is not None and resource in use_resources
55
Barry Warsawc0fb6052001-08-20 22:29:23 +000056def requires(resource, msg=None):
Tim Petersb4ee4eb2002-12-04 03:26:57 +000057 if not is_resource_enabled(resource):
Barry Warsawc0fb6052001-08-20 22:29:23 +000058 if msg is None:
59 msg = "Use of the `%s' resource not enabled" % resource
60 raise TestSkipped(msg)
61
Guido van Rossum35fb82a1993-01-26 13:04:43 +000062FUZZ = 1e-6
63
64def fcmp(x, y): # fuzzy comparison function
Fred Drake004d5e62000-10-23 17:22:08 +000065 if type(x) == type(0.0) or type(y) == type(0.0):
66 try:
67 x, y = coerce(x, y)
68 fuzz = (abs(x) + abs(y)) * FUZZ
69 if abs(x-y) <= fuzz:
70 return 0
71 except:
72 pass
73 elif type(x) == type(y) and type(x) in (type(()), type([])):
74 for i in range(min(len(x), len(y))):
75 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +000076 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +000077 return outcome
78 return cmp(len(x), len(y))
79 return cmp(x, y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +000080
Martin v. Löwis339d0f72001-08-17 18:39:25 +000081try:
82 unicode
83 have_unicode = 1
84except NameError:
85 have_unicode = 0
86
Finn Bock57bc5fa2002-11-01 18:02:03 +000087is_jython = sys.platform.startswith('java')
88
Guido van Rossuma8f7e592001-03-13 09:31:07 +000089import os
Barry Warsaw559f6682001-03-23 18:04:02 +000090# Filename used for testing
91if os.name == 'java':
92 # Jython disallows @ in module names
93 TESTFN = '$test'
94elif os.name != 'riscos':
95 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +000096 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +000097 if have_unicode:
Martin v. Löwis2411a2d2002-11-09 19:57:26 +000098 if isinstance('', unicode):
99 # python -U
100 # XXX perhaps unicode() should accept Unicode strings?
101 TESTFN_UNICODE="@test-\xe0\xf2"
102 else:
103 TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000104 if os.name=="nt":
105 TESTFN_ENCODING="mbcs"
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000106else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000107 TESTFN = 'test'
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000108
109# Make sure we can write to TESTFN, try in /tmp if we can't
110fp = None
111try:
112 fp = open(TESTFN, 'w+')
113except IOError:
114 TMP_TESTFN = os.path.join('/tmp', TESTFN)
115 try:
116 fp = open(TMP_TESTFN, 'w+')
117 TESTFN = TMP_TESTFN
118 del TMP_TESTFN
119 except IOError:
Tim Peters3de75262002-11-09 05:26:15 +0000120 print ('WARNING: tests will fail, unable to write to: %s or %s' %
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000121 (TESTFN, TMP_TESTFN))
122if fp is not None:
123 fp.close()
124 try:
125 os.unlink(TESTFN)
126 except:
127 pass
128del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000129
Guido van Rossum3bead091992-01-27 17:00:37 +0000130from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +0000131
132def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000133 import os
134 if os.path.isabs(file):
135 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000136 path = sys.path
137 path = [os.path.dirname(here)] + path
138 for dn in path:
139 fn = os.path.join(dn, file)
140 if os.path.exists(fn): return fn
141 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000142
143def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000144 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000145
Skip Montanaroc955f892001-01-20 19:12:54 +0000146 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000147 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000148 """
Tim Peters983874d2001-01-19 05:59:21 +0000149
Tim Petersd2bf3b72001-01-18 02:22:22 +0000150 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000151 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000152
Tim Petersc2fe6182001-10-30 23:20:46 +0000153def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000154 """Raise TestFailed if a == b is false.
155
156 This is better than verify(a == b) because, in case of failure, the
157 error message incorporates repr(a) and repr(b) so you can see the
158 inputs.
159
160 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
161 former is tested.
162 """
163
Tim Petersc2fe6182001-10-30 23:20:46 +0000164 if not (a == b):
165 raise TestFailed, "%r == %r" % (a, b)
166
Tim Peters2f228e72001-05-13 00:19:31 +0000167def sortdict(dict):
168 "Like repr(dict), but in sorted order."
169 items = dict.items()
170 items.sort()
171 reprpairs = ["%r: %r" % pair for pair in items]
172 withcommas = ", ".join(reprpairs)
173 return "{%s}" % withcommas
174
Jeremy Hylton47793992001-02-19 15:35:26 +0000175def check_syntax(statement):
176 try:
177 compile(statement, '<string>', 'exec')
178 except SyntaxError:
179 pass
180 else:
181 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000182
183
184
185#=======================================================================
186# Preliminary PyUNIT integration.
187
188import unittest
189
190
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000191class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000192 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000193 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000194 test(result)
195 return result
196
197
Fred Drake26641032001-10-04 19:46:07 +0000198def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000199 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000200 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000201 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000202 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000203 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000204
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000205 result = runner.run(suite)
206 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000207 if len(result.errors) == 1 and not result.failures:
208 err = result.errors[0][1]
209 elif len(result.failures) == 1 and not result.errors:
210 err = result.failures[0][1]
211 else:
Fred Drake26641032001-10-04 19:46:07 +0000212 if testclass is None:
213 msg = "errors occurred; run in verbose mode for details"
214 else:
215 msg = "errors occurred in %s.%s" \
216 % (testclass.__module__, testclass.__name__)
217 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000218 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000219
Barry Warsawc10d6902001-09-20 06:30:41 +0000220
221def run_unittest(testclass):
222 """Run tests from a unittest.TestCase-derived class."""
Fred Drake26641032001-10-04 19:46:07 +0000223 run_suite(unittest.makeSuite(testclass), testclass)
Barry Warsawc10d6902001-09-20 06:30:41 +0000224
225
Tim Petersa0a62222001-09-09 06:12:01 +0000226#=======================================================================
227# doctest driver.
228
229def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000230 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000231
232 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000233 test_support's belief about verbosity on to doctest. Else doctest's
234 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000235 """
236
237 import doctest
238
239 if verbosity is None:
240 verbosity = verbose
241 else:
242 verbosity = None
243
Tim Peters342ca752001-09-25 19:13:20 +0000244 # Direct doctest output (normally just errors) to real stdout; doctest
245 # output shouldn't be compared by regrtest.
246 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000247 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000248 try:
249 f, t = doctest.testmod(module, verbose=verbosity)
250 if f:
251 raise TestFailed("%d of %d doctests failed" % (f, t))
Tim Peters17111f32001-10-03 04:08:26 +0000252 return f, t
Tim Peters342ca752001-09-25 19:13:20 +0000253 finally:
254 sys.stdout = save_stdout