blob: ecb6a3e419431caaca302711101ad4b522b91808 [file] [log] [blame]
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001"""Test case implementation"""
2
Michael Foorde6e0e262010-12-19 15:52:56 +00003import collections
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00004import sys
5import functools
6import difflib
7import pprint
8import re
9import warnings
10
Michael Foord225a0992010-02-18 20:30:09 +000011from . import result
Michael Foord98e7b762010-03-20 03:00:34 +000012from .util import (
Michael Foord4c9e91a2011-03-16 20:34:53 -040013 strclass, safe_repr, unorderable_list_difference,
14 _count_diff_all_purpose, _count_diff_hashable
Michael Foord98e7b762010-03-20 03:00:34 +000015)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000016
Michael Foord4c9e91a2011-03-16 20:34:53 -040017
Michael Foordb1aa30f2010-03-22 00:06:30 +000018__unittest = True
Michael Foordb1aa30f2010-03-22 00:06:30 +000019
Michael Foord5fe21ff2010-06-05 13:38:16 +000020
21DIFF_OMITTED = ('\nDiff is %s characters long. '
22 'Set self.maxDiff to None to see it.')
23
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000024class SkipTest(Exception):
25 """
26 Raise this exception in a test to skip it.
27
28 Usually you can use TestResult.skip() or one of the skipping decorators
29 instead of raising this directly.
30 """
31 pass
32
33class _ExpectedFailure(Exception):
34 """
35 Raise this when a test is expected to fail.
36
37 This is an implementation detail.
38 """
39
40 def __init__(self, exc_info):
41 super(_ExpectedFailure, self).__init__()
42 self.exc_info = exc_info
43
44class _UnexpectedSuccess(Exception):
45 """
46 The test was supposed to fail, but it didn't!
47 """
48 pass
49
50def _id(obj):
51 return obj
52
53def skip(reason):
54 """
55 Unconditionally skip a test.
56 """
57 def decorator(test_item):
Michael Foord53e8eea2010-03-07 20:22:12 +000058 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
59 @functools.wraps(test_item)
60 def skip_wrapper(*args, **kwargs):
61 raise SkipTest(reason)
62 test_item = skip_wrapper
63
64 test_item.__unittest_skip__ = True
65 test_item.__unittest_skip_why__ = reason
66 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000067 return decorator
68
69def skipIf(condition, reason):
70 """
71 Skip a test if the condition is true.
72 """
73 if condition:
74 return skip(reason)
75 return _id
76
77def skipUnless(condition, reason):
78 """
79 Skip a test unless the condition is true.
80 """
81 if not condition:
82 return skip(reason)
83 return _id
84
85
86def expectedFailure(func):
87 @functools.wraps(func)
88 def wrapper(*args, **kwargs):
89 try:
90 func(*args, **kwargs)
91 except Exception:
92 raise _ExpectedFailure(sys.exc_info())
93 raise _UnexpectedSuccess
94 return wrapper
95
96
97class _AssertRaisesContext(object):
98 """A context manager used to implement TestCase.assertRaises* methods."""
99
100 def __init__(self, expected, test_case, expected_regexp=None):
101 self.expected = expected
102 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000103 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000104
105 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +0000106 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000107
108 def __exit__(self, exc_type, exc_value, tb):
109 if exc_type is None:
110 try:
111 exc_name = self.expected.__name__
112 except AttributeError:
113 exc_name = str(self.expected)
114 raise self.failureException(
115 "{0} not raised".format(exc_name))
116 if not issubclass(exc_type, self.expected):
117 # let unexpected exceptions pass through
118 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000119 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000120 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000121 return True
122
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000123 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000124 if isinstance(expected_regexp, basestring):
125 expected_regexp = re.compile(expected_regexp)
126 if not expected_regexp.search(str(exc_value)):
127 raise self.failureException('"%s" does not match "%s"' %
128 (expected_regexp.pattern, str(exc_value)))
129 return True
130
131
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000132class TestCase(object):
133 """A class whose instances are single test cases.
134
135 By default, the test code itself should be placed in a method named
136 'runTest'.
137
138 If the fixture may be used for many test cases, create as
139 many test methods as are needed. When instantiating such a TestCase
140 subclass, specify in the constructor arguments the name of the test method
141 that the instance is to execute.
142
143 Test authors should subclass TestCase for their own tests. Construction
144 and deconstruction of the test's environment ('fixture') can be
145 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
146
147 If it is necessary to override the __init__ method, the base class
148 __init__ method must always be called. It is important that subclasses
149 should not change the signature of their __init__ method, since instances
150 of the classes are instantiated automatically by parts of the framework
151 in order to be run.
152 """
153
154 # This attribute determines which exception will be raised when
155 # the instance's assertion methods fail; test methods raising this
156 # exception will be deemed to have 'failed' rather than 'errored'
157
158 failureException = AssertionError
159
160 # This attribute determines whether long messages (including repr of
161 # objects used in assert methods) will be printed on failure in *addition*
162 # to any explicit message passed.
163
164 longMessage = False
165
Michael Foordae1bb9a2010-06-09 12:29:56 +0000166 # This attribute sets the maximum length of a diff in failure messages
Michael Foorde37d75f2010-06-05 12:10:52 +0000167 # by assert methods using difflib. It is looked up as an instance attribute
168 # so can be configured by individual tests if required.
Michael Foordc532c572010-06-05 23:58:40 +0000169
Michael Foorde37d75f2010-06-05 12:10:52 +0000170 maxDiff = 80*8
171
Michael Foord5ffa3252010-03-07 22:04:55 +0000172 # Attribute used by TestSuite for classSetUp
173
174 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000175
176 def __init__(self, methodName='runTest'):
177 """Create an instance of the class that will use the named test
178 method when executed. Raises a ValueError if the instance does
179 not have a method with the specified name.
180 """
181 self._testMethodName = methodName
182 self._resultForDoCleanups = None
183 try:
184 testMethod = getattr(self, methodName)
185 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000186 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000187 (self.__class__, methodName))
188 self._testMethodDoc = testMethod.__doc__
189 self._cleanups = []
190
191 # Map types to custom assertEqual functions that will compare
192 # instances of said type in more detail to generate a more useful
193 # error message.
194 self._type_equality_funcs = {}
195 self.addTypeEqualityFunc(dict, self.assertDictEqual)
196 self.addTypeEqualityFunc(list, self.assertListEqual)
197 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
198 self.addTypeEqualityFunc(set, self.assertSetEqual)
199 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foordfe6349c2010-02-08 22:41:16 +0000200 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000201
202 def addTypeEqualityFunc(self, typeobj, function):
203 """Add a type specific assertEqual style function to compare a type.
204
205 This method is for use by TestCase subclasses that need to register
206 their own type equality functions to provide nicer error messages.
207
208 Args:
209 typeobj: The data type to call this function on when both values
210 are of the same type in assertEqual().
211 function: The callable taking two arguments and an optional
212 msg= argument that raises self.failureException with a
213 useful error message when the two arguments are not equal.
214 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000215 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000216
217 def addCleanup(self, function, *args, **kwargs):
218 """Add a function, with arguments, to be called when the test is
219 completed. Functions added are called on a LIFO basis and are
220 called after tearDown on test failure or success.
221
222 Cleanup items are called even if setUp fails (unlike tearDown)."""
223 self._cleanups.append((function, args, kwargs))
224
225 def setUp(self):
226 "Hook method for setting up the test fixture before exercising it."
227 pass
228
229 def tearDown(self):
230 "Hook method for deconstructing the test fixture after testing it."
231 pass
232
Michael Foord5ffa3252010-03-07 22:04:55 +0000233 @classmethod
234 def setUpClass(cls):
235 "Hook method for setting up class fixture before running tests in the class."
236
237 @classmethod
238 def tearDownClass(cls):
239 "Hook method for deconstructing the class fixture after running all tests in the class."
240
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000241 def countTestCases(self):
242 return 1
243
244 def defaultTestResult(self):
245 return result.TestResult()
246
247 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000248 """Returns a one-line description of the test, or None if no
249 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000250
Michael Foorddb43b5a2010-02-10 14:25:12 +0000251 The default implementation of this method returns the first line of
252 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000253 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000254 doc = self._testMethodDoc
255 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000256
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000257
258 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000259 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000260
261 def __eq__(self, other):
262 if type(self) is not type(other):
263 return NotImplemented
264
265 return self._testMethodName == other._testMethodName
266
267 def __ne__(self, other):
268 return not self == other
269
270 def __hash__(self):
271 return hash((type(self), self._testMethodName))
272
273 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000274 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000275
276 def __repr__(self):
277 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000278 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000279
Michael Foordae3db0a2010-02-22 23:28:32 +0000280 def _addSkip(self, result, reason):
281 addSkip = getattr(result, 'addSkip', None)
282 if addSkip is not None:
283 addSkip(self, reason)
284 else:
285 warnings.warn("TestResult has no addSkip method, skips not reported",
286 RuntimeWarning, 2)
287 result.addSuccess(self)
288
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000289 def run(self, result=None):
290 orig_result = result
291 if result is None:
292 result = self.defaultTestResult()
293 startTestRun = getattr(result, 'startTestRun', None)
294 if startTestRun is not None:
295 startTestRun()
296
297 self._resultForDoCleanups = result
298 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000299
300 testMethod = getattr(self, self._testMethodName)
301 if (getattr(self.__class__, "__unittest_skip__", False) or
302 getattr(testMethod, "__unittest_skip__", False)):
303 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000304 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000305 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
306 or getattr(testMethod, '__unittest_skip_why__', ''))
307 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000308 finally:
309 result.stopTest(self)
310 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000311 try:
312 success = False
313 try:
314 self.setUp()
315 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000316 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000317 except KeyboardInterrupt:
318 raise
319 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000320 result.addError(self, sys.exc_info())
321 else:
322 try:
323 testMethod()
Michael Foorda17f0762010-12-19 14:53:19 +0000324 except KeyboardInterrupt:
325 raise
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000326 except self.failureException:
327 result.addFailure(self, sys.exc_info())
328 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000329 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
330 if addExpectedFailure is not None:
331 addExpectedFailure(self, e.exc_info)
332 else:
333 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
334 RuntimeWarning)
335 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000336 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000337 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
338 if addUnexpectedSuccess is not None:
339 addUnexpectedSuccess(self)
340 else:
341 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
342 RuntimeWarning)
343 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000344 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000345 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000346 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000347 result.addError(self, sys.exc_info())
348 else:
349 success = True
350
351 try:
352 self.tearDown()
Michael Foorda17f0762010-12-19 14:53:19 +0000353 except KeyboardInterrupt:
354 raise
355 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000356 result.addError(self, sys.exc_info())
357 success = False
358
359 cleanUpSuccess = self.doCleanups()
360 success = success and cleanUpSuccess
361 if success:
362 result.addSuccess(self)
363 finally:
364 result.stopTest(self)
365 if orig_result is None:
366 stopTestRun = getattr(result, 'stopTestRun', None)
367 if stopTestRun is not None:
368 stopTestRun()
369
370 def doCleanups(self):
371 """Execute all cleanup functions. Normally called for you after
372 tearDown."""
373 result = self._resultForDoCleanups
374 ok = True
375 while self._cleanups:
376 function, args, kwargs = self._cleanups.pop(-1)
377 try:
378 function(*args, **kwargs)
Michael Foorda17f0762010-12-19 14:53:19 +0000379 except KeyboardInterrupt:
380 raise
381 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000382 ok = False
383 result.addError(self, sys.exc_info())
384 return ok
385
386 def __call__(self, *args, **kwds):
387 return self.run(*args, **kwds)
388
389 def debug(self):
390 """Run the test without collecting errors in a TestResult"""
391 self.setUp()
392 getattr(self, self._testMethodName)()
393 self.tearDown()
Michael Foord0fedb282010-06-08 22:44:52 +0000394 while self._cleanups:
395 function, args, kwargs = self._cleanups.pop(-1)
396 function(*args, **kwargs)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000397
398 def skipTest(self, reason):
399 """Skip this test."""
400 raise SkipTest(reason)
401
402 def fail(self, msg=None):
403 """Fail immediately, with the given message."""
404 raise self.failureException(msg)
405
406 def assertFalse(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000407 """Check that the expression is false."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000408 if expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000409 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000410 raise self.failureException(msg)
411
412 def assertTrue(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000413 """Check that the expression is true."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000414 if not expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000415 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000416 raise self.failureException(msg)
417
418 def _formatMessage(self, msg, standardMsg):
419 """Honour the longMessage attribute when generating failure messages.
420 If longMessage is False this means:
421 * Use only an explicit message if it is provided
422 * Otherwise use the standard message for the assert
423
424 If longMessage is True:
425 * Use the standard message
426 * If an explicit message is provided, plus ' : ' and the explicit message
427 """
428 if not self.longMessage:
429 return msg or standardMsg
430 if msg is None:
431 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000432 try:
433 # don't switch to '{}' formatting in Python 2.X
434 # it changes the way unicode input is handled
435 return '%s : %s' % (standardMsg, msg)
436 except UnicodeDecodeError:
437 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000438
439
440 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
441 """Fail unless an exception of class excClass is thrown
442 by callableObj when invoked with arguments args and keyword
443 arguments kwargs. If a different type of exception is
444 thrown, it will not be caught, and the test case will be
445 deemed to have suffered an error, exactly as for an
446 unexpected exception.
447
448 If called with callableObj omitted or None, will return a
449 context object used like this::
450
Michael Foordd0edec32010-02-05 22:55:09 +0000451 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000452 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000453
454 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000455 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000456 exception after the assertion::
457
458 with self.assertRaises(SomeException) as cm:
459 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000460 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000461 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000462 """
463 context = _AssertRaisesContext(excClass, self)
464 if callableObj is None:
465 return context
466 with context:
467 callableObj(*args, **kwargs)
468
469 def _getAssertEqualityFunc(self, first, second):
470 """Get a detailed comparison function for the types of the two args.
471
472 Returns: A callable accepting (first, second, msg=None) that will
473 raise a failure exception if first != second with a useful human
474 readable error message for those types.
475 """
476 #
477 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
478 # and vice versa. I opted for the conservative approach in case
479 # subclasses are not intended to be compared in detail to their super
480 # class instances using a type equality func. This means testing
481 # subtypes won't automagically use the detailed comparison. Callers
482 # should use their type specific assertSpamEqual method to compare
483 # subclasses if the detailed comparison is desired and appropriate.
484 # See the discussion in http://bugs.python.org/issue2578.
485 #
486 if type(first) is type(second):
487 asserter = self._type_equality_funcs.get(type(first))
488 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000489 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000490
491 return self._baseAssertEqual
492
493 def _baseAssertEqual(self, first, second, msg=None):
494 """The default assertEqual implementation, not type specific."""
495 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000496 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000497 msg = self._formatMessage(msg, standardMsg)
498 raise self.failureException(msg)
499
500 def assertEqual(self, first, second, msg=None):
501 """Fail if the two objects are unequal as determined by the '=='
502 operator.
503 """
504 assertion_func = self._getAssertEqualityFunc(first, second)
505 assertion_func(first, second, msg=msg)
506
507 def assertNotEqual(self, first, second, msg=None):
508 """Fail if the two objects are equal as determined by the '=='
509 operator.
510 """
511 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000512 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
513 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000514 raise self.failureException(msg)
515
Michael Foorda7e08fe2010-03-27 19:10:11 +0000516
517 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000518 """Fail if the two objects are unequal as determined by their
519 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000520 (default 7) and comparing to zero, or by comparing that the
521 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000522
523 Note that decimal places (from zero) are usually not the same
524 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000525
526 If the two objects compare equal then they will automatically
527 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000528 """
Michael Foordc3f79372009-09-13 16:40:02 +0000529 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000530 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000531 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000532 if delta is not None and places is not None:
533 raise TypeError("specify delta or places not both")
534
535 if delta is not None:
536 if abs(first - second) <= delta:
537 return
538
539 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
540 safe_repr(second),
541 safe_repr(delta))
542 else:
543 if places is None:
544 places = 7
545
546 if round(abs(second-first), places) == 0:
547 return
548
Michael Foord225a0992010-02-18 20:30:09 +0000549 standardMsg = '%s != %s within %r places' % (safe_repr(first),
550 safe_repr(second),
551 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000552 msg = self._formatMessage(msg, standardMsg)
553 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000554
Michael Foorda7e08fe2010-03-27 19:10:11 +0000555 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000556 """Fail if the two objects are equal as determined by their
557 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000558 (default 7) and comparing to zero, or by comparing that the
559 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000560
561 Note that decimal places (from zero) are usually not the same
562 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000563
564 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000565 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000566 if delta is not None and places is not None:
567 raise TypeError("specify delta or places not both")
568 if delta is not None:
569 if not (first == second) and abs(first - second) > delta:
570 return
571 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
572 safe_repr(second),
573 safe_repr(delta))
574 else:
575 if places is None:
576 places = 7
577 if not (first == second) and round(abs(second-first), places) != 0:
578 return
Michael Foord225a0992010-02-18 20:30:09 +0000579 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000580 safe_repr(second),
581 places)
582
583 msg = self._formatMessage(msg, standardMsg)
584 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000585
586 # Synonyms for assertion methods
587
588 # The plurals are undocumented. Keep them that way to discourage use.
589 # Do not add more. Do not remove.
590 # Going through a deprecation cycle on these would annoy many people.
591 assertEquals = assertEqual
592 assertNotEquals = assertNotEqual
593 assertAlmostEquals = assertAlmostEqual
594 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000595 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000596
597 # These fail* assertion method names are pending deprecation and will
598 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
599 def _deprecate(original_func):
600 def deprecated_func(*args, **kwargs):
601 warnings.warn(
602 'Please use {0} instead.'.format(original_func.__name__),
603 PendingDeprecationWarning, 2)
604 return original_func(*args, **kwargs)
605 return deprecated_func
606
607 failUnlessEqual = _deprecate(assertEqual)
608 failIfEqual = _deprecate(assertNotEqual)
609 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
610 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
611 failUnless = _deprecate(assertTrue)
612 failUnlessRaises = _deprecate(assertRaises)
613 failIf = _deprecate(assertFalse)
614
Michael Foorde37d75f2010-06-05 12:10:52 +0000615 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000616 """An equality assertion for ordered sequences (like lists and tuples).
617
R. David Murray05b41712010-01-29 19:35:39 +0000618 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000619 which can be indexed, has a length, and has an equality operator.
620
621 Args:
622 seq1: The first sequence to compare.
623 seq2: The second sequence to compare.
624 seq_type: The expected datatype of the sequences, or None if no
625 datatype should be enforced.
626 msg: Optional message to use on failure instead of a list of
627 differences.
628 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000629 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000630 seq_type_name = seq_type.__name__
631 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000632 raise self.failureException('First sequence is not a %s: %s'
633 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000634 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000635 raise self.failureException('Second sequence is not a %s: %s'
636 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000637 else:
638 seq_type_name = "sequence"
639
640 differing = None
641 try:
642 len1 = len(seq1)
643 except (TypeError, NotImplementedError):
644 differing = 'First %s has no length. Non-sequence?' % (
645 seq_type_name)
646
647 if differing is None:
648 try:
649 len2 = len(seq2)
650 except (TypeError, NotImplementedError):
651 differing = 'Second %s has no length. Non-sequence?' % (
652 seq_type_name)
653
654 if differing is None:
655 if seq1 == seq2:
656 return
657
Michael Foord225a0992010-02-18 20:30:09 +0000658 seq1_repr = safe_repr(seq1)
659 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000660 if len(seq1_repr) > 30:
661 seq1_repr = seq1_repr[:30] + '...'
662 if len(seq2_repr) > 30:
663 seq2_repr = seq2_repr[:30] + '...'
664 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
665 differing = '%ss differ: %s != %s\n' % elements
666
667 for i in xrange(min(len1, len2)):
668 try:
669 item1 = seq1[i]
670 except (TypeError, IndexError, NotImplementedError):
671 differing += ('\nUnable to index element %d of first %s\n' %
672 (i, seq_type_name))
673 break
674
675 try:
676 item2 = seq2[i]
677 except (TypeError, IndexError, NotImplementedError):
678 differing += ('\nUnable to index element %d of second %s\n' %
679 (i, seq_type_name))
680 break
681
682 if item1 != item2:
683 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
684 (i, item1, item2))
685 break
686 else:
687 if (len1 == len2 and seq_type is None and
688 type(seq1) != type(seq2)):
689 # The sequences are the same, but have differing types.
690 return
691
692 if len1 > len2:
693 differing += ('\nFirst %s contains %d additional '
694 'elements.\n' % (seq_type_name, len1 - len2))
695 try:
696 differing += ('First extra element %d:\n%s\n' %
697 (len2, seq1[len2]))
698 except (TypeError, IndexError, NotImplementedError):
699 differing += ('Unable to index element %d '
700 'of first %s\n' % (len2, seq_type_name))
701 elif len1 < len2:
702 differing += ('\nSecond %s contains %d additional '
703 'elements.\n' % (seq_type_name, len2 - len1))
704 try:
705 differing += ('First extra element %d:\n%s\n' %
706 (len1, seq2[len1]))
707 except (TypeError, IndexError, NotImplementedError):
708 differing += ('Unable to index element %d '
709 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000710 standardMsg = differing
711 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000712 difflib.ndiff(pprint.pformat(seq1).splitlines(),
713 pprint.pformat(seq2).splitlines()))
Michael Foorde37d75f2010-06-05 12:10:52 +0000714 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000715 msg = self._formatMessage(msg, standardMsg)
716 self.fail(msg)
717
Michael Foorde37d75f2010-06-05 12:10:52 +0000718 def _truncateMessage(self, message, diff):
719 max_diff = self.maxDiff
Michael Foorda4412872010-06-05 11:46:59 +0000720 if max_diff is None or len(diff) <= max_diff:
721 return message + diff
Michael Foord5fe21ff2010-06-05 13:38:16 +0000722 return message + (DIFF_OMITTED % len(diff))
Michael Foorda4412872010-06-05 11:46:59 +0000723
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000724 def assertListEqual(self, list1, list2, msg=None):
725 """A list-specific equality assertion.
726
727 Args:
728 list1: The first list to compare.
729 list2: The second list to compare.
730 msg: Optional message to use on failure instead of a list of
731 differences.
732
733 """
734 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
735
736 def assertTupleEqual(self, tuple1, tuple2, msg=None):
737 """A tuple-specific equality assertion.
738
739 Args:
740 tuple1: The first tuple to compare.
741 tuple2: The second tuple to compare.
742 msg: Optional message to use on failure instead of a list of
743 differences.
744 """
745 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
746
747 def assertSetEqual(self, set1, set2, msg=None):
748 """A set-specific equality assertion.
749
750 Args:
751 set1: The first set to compare.
752 set2: The second set to compare.
753 msg: Optional message to use on failure instead of a list of
754 differences.
755
Michael Foord98e7b762010-03-20 03:00:34 +0000756 assertSetEqual uses ducktyping to support different types of sets, and
757 is optimized for sets specifically (parameters must support a
758 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000759 """
760 try:
761 difference1 = set1.difference(set2)
762 except TypeError, e:
763 self.fail('invalid type when attempting set difference: %s' % e)
764 except AttributeError, e:
765 self.fail('first argument does not support set difference: %s' % e)
766
767 try:
768 difference2 = set2.difference(set1)
769 except TypeError, e:
770 self.fail('invalid type when attempting set difference: %s' % e)
771 except AttributeError, e:
772 self.fail('second argument does not support set difference: %s' % e)
773
774 if not (difference1 or difference2):
775 return
776
777 lines = []
778 if difference1:
779 lines.append('Items in the first set but not the second:')
780 for item in difference1:
781 lines.append(repr(item))
782 if difference2:
783 lines.append('Items in the second set but not the first:')
784 for item in difference2:
785 lines.append(repr(item))
786
787 standardMsg = '\n'.join(lines)
788 self.fail(self._formatMessage(msg, standardMsg))
789
790 def assertIn(self, member, container, msg=None):
791 """Just like self.assertTrue(a in b), but with a nicer default message."""
792 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000793 standardMsg = '%s not found in %s' % (safe_repr(member),
794 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000795 self.fail(self._formatMessage(msg, standardMsg))
796
797 def assertNotIn(self, member, container, msg=None):
798 """Just like self.assertTrue(a not in b), but with a nicer default message."""
799 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000800 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
801 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000802 self.fail(self._formatMessage(msg, standardMsg))
803
804 def assertIs(self, expr1, expr2, msg=None):
805 """Just like self.assertTrue(a is b), but with a nicer default message."""
806 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000807 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000808 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000809 self.fail(self._formatMessage(msg, standardMsg))
810
811 def assertIsNot(self, expr1, expr2, msg=None):
812 """Just like self.assertTrue(a is not b), but with a nicer default message."""
813 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000814 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000815 self.fail(self._formatMessage(msg, standardMsg))
816
817 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melotti2623a372010-11-21 13:34:58 +0000818 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
819 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000820
821 if d1 != d2:
Michael Foord674648e2010-06-05 12:58:39 +0000822 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foorde37d75f2010-06-05 12:10:52 +0000823 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000824 pprint.pformat(d1).splitlines(),
825 pprint.pformat(d2).splitlines())))
Michael Foord674648e2010-06-05 12:58:39 +0000826 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000827 self.fail(self._formatMessage(msg, standardMsg))
828
829 def assertDictContainsSubset(self, expected, actual, msg=None):
830 """Checks whether actual is a superset of expected."""
831 missing = []
832 mismatched = []
833 for key, value in expected.iteritems():
834 if key not in actual:
835 missing.append(key)
836 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000837 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000838 (safe_repr(key), safe_repr(value),
839 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000840
841 if not (missing or mismatched):
842 return
843
844 standardMsg = ''
845 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000846 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
847 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000848 if mismatched:
849 if standardMsg:
850 standardMsg += '; '
851 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
852
853 self.fail(self._formatMessage(msg, standardMsg))
854
Michael Foord98e7b762010-03-20 03:00:34 +0000855 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
Michael Foorde6e0e262010-12-19 15:52:56 +0000856 """An unordered sequence specific comparison. It asserts that
857 actual_seq and expected_seq have the same element counts.
858 Equivalent to::
Michael Foord98e7b762010-03-20 03:00:34 +0000859
Michael Foorde6e0e262010-12-19 15:52:56 +0000860 self.assertEqual(Counter(iter(actual_seq)),
861 Counter(iter(expected_seq)))
Michael Foordd0edec32010-02-05 22:55:09 +0000862
Michael Foord98e7b762010-03-20 03:00:34 +0000863 Asserts that each element has the same count in both sequences.
864 Example:
865 - [0, 1, 1] and [1, 0, 1] compare equal.
866 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000867 """
Michael Foord4c9e91a2011-03-16 20:34:53 -0400868 first_seq, second_seq = list(actual_seq), list(expected_seq)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000869 with warnings.catch_warnings():
870 if sys.py3kwarning:
871 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000872 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000873 "builtin_function_or_method order comparisons",
874 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000875 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000876 try:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400877 first = collections.Counter(first_seq)
878 second = collections.Counter(second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000879 except TypeError:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400880 # Handle case with unhashable elements
881 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000882 else:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400883 if first == second:
Michael Foorde6e0e262010-12-19 15:52:56 +0000884 return
Michael Foord4c9e91a2011-03-16 20:34:53 -0400885 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000886
Michael Foord4c9e91a2011-03-16 20:34:53 -0400887 if differences:
888 standardMsg = 'Element counts were not equal:\n'
889 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
890 diffMsg = '\n'.join(lines)
891 standardMsg = self._truncateMessage(standardMsg, diffMsg)
892 msg = self._formatMessage(msg, standardMsg)
893 self.fail(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000894
895 def assertMultiLineEqual(self, first, second, msg=None):
896 """Assert that two multi-line strings are equal."""
Ezio Melotti2623a372010-11-21 13:34:58 +0000897 self.assertIsInstance(first, basestring,
898 'First argument is not a string')
899 self.assertIsInstance(second, basestring,
900 'Second argument is not a string')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000901
902 if first != second:
Michael Foord94f071c2010-07-10 13:51:42 +0000903 firstlines = first.splitlines(True)
904 secondlines = second.splitlines(True)
905 if len(firstlines) == 1 and first.strip('\r\n') == first:
906 firstlines = [first + '\n']
907 secondlines = [second + '\n']
908 standardMsg = '%s != %s' % (safe_repr(first, True),
909 safe_repr(second, True))
910 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foord674648e2010-06-05 12:58:39 +0000911 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000912 self.fail(self._formatMessage(msg, standardMsg))
913
914 def assertLess(self, a, b, msg=None):
915 """Just like self.assertTrue(a < b), but with a nicer default message."""
916 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000917 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000918 self.fail(self._formatMessage(msg, standardMsg))
919
920 def assertLessEqual(self, a, b, msg=None):
921 """Just like self.assertTrue(a <= b), but with a nicer default message."""
922 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000923 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000924 self.fail(self._formatMessage(msg, standardMsg))
925
926 def assertGreater(self, a, b, msg=None):
927 """Just like self.assertTrue(a > b), but with a nicer default message."""
928 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000929 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000930 self.fail(self._formatMessage(msg, standardMsg))
931
932 def assertGreaterEqual(self, a, b, msg=None):
933 """Just like self.assertTrue(a >= b), but with a nicer default message."""
934 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000935 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000936 self.fail(self._formatMessage(msg, standardMsg))
937
938 def assertIsNone(self, obj, msg=None):
939 """Same as self.assertTrue(obj is None), with a nicer default message."""
940 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000941 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000942 self.fail(self._formatMessage(msg, standardMsg))
943
944 def assertIsNotNone(self, obj, msg=None):
945 """Included for symmetry with assertIsNone."""
946 if obj is None:
947 standardMsg = 'unexpectedly None'
948 self.fail(self._formatMessage(msg, standardMsg))
949
Georg Brandlf895cf52009-10-01 20:59:31 +0000950 def assertIsInstance(self, obj, cls, msg=None):
951 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
952 default message."""
953 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000954 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000955 self.fail(self._formatMessage(msg, standardMsg))
956
957 def assertNotIsInstance(self, obj, cls, msg=None):
958 """Included for symmetry with assertIsInstance."""
959 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000960 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000961 self.fail(self._formatMessage(msg, standardMsg))
962
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000963 def assertRaisesRegexp(self, expected_exception, expected_regexp,
964 callable_obj=None, *args, **kwargs):
965 """Asserts that the message in a raised exception matches a regexp.
966
967 Args:
968 expected_exception: Exception class expected to be raised.
969 expected_regexp: Regexp (re pattern object or string) expected
970 to be found in error message.
971 callable_obj: Function to be called.
972 args: Extra args.
973 kwargs: Extra kwargs.
974 """
975 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
976 if callable_obj is None:
977 return context
978 with context:
979 callable_obj(*args, **kwargs)
980
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000981 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000982 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000983 if isinstance(expected_regexp, basestring):
984 expected_regexp = re.compile(expected_regexp)
985 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000986 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000987 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000988 raise self.failureException(msg)
989
Michael Foorda04c7a02010-04-02 22:55:59 +0000990 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000991 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +0000992 if isinstance(unexpected_regexp, basestring):
993 unexpected_regexp = re.compile(unexpected_regexp)
994 match = unexpected_regexp.search(text)
995 if match:
996 msg = msg or "Regexp matched"
997 msg = '%s: %r matches %r in %r' % (msg,
998 text[match.start():match.end()],
999 unexpected_regexp.pattern,
1000 text)
1001 raise self.failureException(msg)
1002
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001003
1004class FunctionTestCase(TestCase):
1005 """A test case that wraps a test function.
1006
1007 This is useful for slipping pre-existing test functions into the
1008 unittest framework. Optionally, set-up and tidy-up functions can be
1009 supplied. As with TestCase, the tidy-up ('tearDown') function will
1010 always be called if the set-up ('setUp') function ran successfully.
1011 """
1012
1013 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1014 super(FunctionTestCase, self).__init__()
1015 self._setUpFunc = setUp
1016 self._tearDownFunc = tearDown
1017 self._testFunc = testFunc
1018 self._description = description
1019
1020 def setUp(self):
1021 if self._setUpFunc is not None:
1022 self._setUpFunc()
1023
1024 def tearDown(self):
1025 if self._tearDownFunc is not None:
1026 self._tearDownFunc()
1027
1028 def runTest(self):
1029 self._testFunc()
1030
1031 def id(self):
1032 return self._testFunc.__name__
1033
1034 def __eq__(self, other):
1035 if not isinstance(other, self.__class__):
1036 return NotImplemented
1037
1038 return self._setUpFunc == other._setUpFunc and \
1039 self._tearDownFunc == other._tearDownFunc and \
1040 self._testFunc == other._testFunc and \
1041 self._description == other._description
1042
1043 def __ne__(self, other):
1044 return not self == other
1045
1046 def __hash__(self):
1047 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1048 self._testFunc, self._description))
1049
1050 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001051 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001052 self._testFunc.__name__)
1053
1054 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001055 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001056 self._testFunc)
1057
1058 def shortDescription(self):
1059 if self._description is not None:
1060 return self._description
1061 doc = self._testFunc.__doc__
1062 return doc and doc.split("\n")[0].strip() or None