blob: 04a778bd1e81f54bcf3d06e078fcd4a931757f3a [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 Peters8dee8092001-09-25 20:05:11 +000024# _original_stdout is meant to hold stdout at the time regrtest began.
25# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
26# The point is to have some flavor of stdout the user can actually see.
27_original_stdout = None
28def record_original_stdout(stdout):
29 global _original_stdout
30 _original_stdout = stdout
31
32def get_original_stdout():
33 return _original_stdout or sys.stdout
34
Guido van Rossum3bead091992-01-27 17:00:37 +000035def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000036 try:
37 del sys.modules[name]
38 except KeyError:
39 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000040
41def forget(modname):
Fred Drake004d5e62000-10-23 17:22:08 +000042 unload(modname)
Fred Drakecd1b1dd2001-03-21 18:26:33 +000043 import os
Fred Drake004d5e62000-10-23 17:22:08 +000044 for dirname in sys.path:
45 try:
46 os.unlink(os.path.join(dirname, modname + '.pyc'))
47 except os.error:
48 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000049
Barry Warsawc0fb6052001-08-20 22:29:23 +000050def requires(resource, msg=None):
Guido van Rossumfe3f6962001-09-06 16:09:41 +000051 if use_resources is not None and resource not in use_resources:
Barry Warsawc0fb6052001-08-20 22:29:23 +000052 if msg is None:
53 msg = "Use of the `%s' resource not enabled" % resource
54 raise TestSkipped(msg)
55
Guido van Rossum35fb82a1993-01-26 13:04:43 +000056FUZZ = 1e-6
57
58def fcmp(x, y): # fuzzy comparison function
Fred Drake004d5e62000-10-23 17:22:08 +000059 if type(x) == type(0.0) or type(y) == type(0.0):
60 try:
61 x, y = coerce(x, y)
62 fuzz = (abs(x) + abs(y)) * FUZZ
63 if abs(x-y) <= fuzz:
64 return 0
65 except:
66 pass
67 elif type(x) == type(y) and type(x) in (type(()), type([])):
68 for i in range(min(len(x), len(y))):
69 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +000070 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +000071 return outcome
72 return cmp(len(x), len(y))
73 return cmp(x, y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +000074
Martin v. Löwis339d0f72001-08-17 18:39:25 +000075try:
76 unicode
77 have_unicode = 1
78except NameError:
79 have_unicode = 0
80
Guido van Rossuma8f7e592001-03-13 09:31:07 +000081import os
Barry Warsaw559f6682001-03-23 18:04:02 +000082# Filename used for testing
83if os.name == 'java':
84 # Jython disallows @ in module names
85 TESTFN = '$test'
86elif os.name != 'riscos':
87 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +000088 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +000089 if have_unicode:
90 TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
91 if os.name=="nt":
92 TESTFN_ENCODING="mbcs"
Guido van Rossuma8f7e592001-03-13 09:31:07 +000093else:
Barry Warsaw559f6682001-03-23 18:04:02 +000094 TESTFN = 'test'
Guido van Rossuma8f7e592001-03-13 09:31:07 +000095del os
96
Guido van Rossum3bead091992-01-27 17:00:37 +000097from os import unlink
Guido van Rossume26132c1998-04-23 20:13:30 +000098
99def findfile(file, here=__file__):
Fred Drake004d5e62000-10-23 17:22:08 +0000100 import os
101 if os.path.isabs(file):
102 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000103 path = sys.path
104 path = [os.path.dirname(here)] + path
105 for dn in path:
106 fn = os.path.join(dn, file)
107 if os.path.exists(fn): return fn
108 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000109
110def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000111 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000112
Skip Montanaroc955f892001-01-20 19:12:54 +0000113 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000114 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000115 """
Tim Peters983874d2001-01-19 05:59:21 +0000116
Tim Petersd2bf3b72001-01-18 02:22:22 +0000117 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000118 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000119
Tim Peters2f228e72001-05-13 00:19:31 +0000120def sortdict(dict):
121 "Like repr(dict), but in sorted order."
122 items = dict.items()
123 items.sort()
124 reprpairs = ["%r: %r" % pair for pair in items]
125 withcommas = ", ".join(reprpairs)
126 return "{%s}" % withcommas
127
Jeremy Hylton47793992001-02-19 15:35:26 +0000128def check_syntax(statement):
129 try:
130 compile(statement, '<string>', 'exec')
131 except SyntaxError:
132 pass
133 else:
134 print 'Missing SyntaxError: "%s"' % statement
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000135
136
137
138#=======================================================================
139# Preliminary PyUNIT integration.
140
141import unittest
142
143
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000144class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000145 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000146 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000147 test(result)
148 return result
149
150
Barry Warsawc10d6902001-09-20 06:30:41 +0000151def run_suite(suite):
Barry Warsawc88425e2001-09-20 06:31:22 +0000152 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000153 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000154 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000155 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000156 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000157
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000158 result = runner.run(suite)
159 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000160 if len(result.errors) == 1 and not result.failures:
161 err = result.errors[0][1]
162 elif len(result.failures) == 1 and not result.errors:
163 err = result.failures[0][1]
164 else:
165 raise TestFailed("errors occurred in %s.%s"
166 % (testclass.__module__, testclass.__name__))
Tim Peters2d84f2c2001-09-08 03:37:56 +0000167 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000168
Barry Warsawc10d6902001-09-20 06:30:41 +0000169
170def run_unittest(testclass):
171 """Run tests from a unittest.TestCase-derived class."""
172 run_suite(unittest.makeSuite(testclass))
173
174
Tim Petersa0a62222001-09-09 06:12:01 +0000175#=======================================================================
176# doctest driver.
177
178def run_doctest(module, verbosity=None):
179 """Run doctest on the given module.
180
181 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000182 test_support's belief about verbosity on to doctest. Else doctest's
183 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000184 """
185
186 import doctest
187
188 if verbosity is None:
189 verbosity = verbose
190 else:
191 verbosity = None
192
Tim Peters342ca752001-09-25 19:13:20 +0000193 # Direct doctest output (normally just errors) to real stdout; doctest
194 # output shouldn't be compared by regrtest.
195 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000196 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000197 try:
198 f, t = doctest.testmod(module, verbose=verbosity)
199 if f:
200 raise TestFailed("%d of %d doctests failed" % (f, t))
201 finally:
202 sys.stdout = save_stdout