blob: f334b5b71d1d6960526843bf494607222c298e13 [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
Antoine Pitrou38153162012-04-25 17:31:12 +02009import types
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000010import warnings
11
Michael Foord225a0992010-02-18 20:30:09 +000012from . import result
Michael Foord98e7b762010-03-20 03:00:34 +000013from .util import (
Michael Foord4c9e91a2011-03-16 20:34:53 -040014 strclass, safe_repr, unorderable_list_difference,
15 _count_diff_all_purpose, _count_diff_hashable
Michael Foord98e7b762010-03-20 03:00:34 +000016)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000017
Michael Foord4c9e91a2011-03-16 20:34:53 -040018
Michael Foordb1aa30f2010-03-22 00:06:30 +000019__unittest = True
Michael Foordb1aa30f2010-03-22 00:06:30 +000020
Michael Foord5fe21ff2010-06-05 13:38:16 +000021
22DIFF_OMITTED = ('\nDiff is %s characters long. '
23 'Set self.maxDiff to None to see it.')
24
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000025class SkipTest(Exception):
26 """
27 Raise this exception in a test to skip it.
28
29 Usually you can use TestResult.skip() or one of the skipping decorators
30 instead of raising this directly.
31 """
32 pass
33
34class _ExpectedFailure(Exception):
35 """
36 Raise this when a test is expected to fail.
37
38 This is an implementation detail.
39 """
40
41 def __init__(self, exc_info):
42 super(_ExpectedFailure, self).__init__()
43 self.exc_info = exc_info
44
45class _UnexpectedSuccess(Exception):
46 """
47 The test was supposed to fail, but it didn't!
48 """
49 pass
50
51def _id(obj):
52 return obj
53
54def skip(reason):
55 """
56 Unconditionally skip a test.
57 """
58 def decorator(test_item):
Antoine Pitrou38153162012-04-25 17:31:12 +020059 if not isinstance(test_item, (type, types.ClassType)):
Michael Foord53e8eea2010-03-07 20:22:12 +000060 @functools.wraps(test_item)
61 def skip_wrapper(*args, **kwargs):
62 raise SkipTest(reason)
63 test_item = skip_wrapper
64
65 test_item.__unittest_skip__ = True
66 test_item.__unittest_skip_why__ = reason
67 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000068 return decorator
69
70def skipIf(condition, reason):
71 """
72 Skip a test if the condition is true.
73 """
74 if condition:
75 return skip(reason)
76 return _id
77
78def skipUnless(condition, reason):
79 """
80 Skip a test unless the condition is true.
81 """
82 if not condition:
83 return skip(reason)
84 return _id
85
86
87def expectedFailure(func):
88 @functools.wraps(func)
89 def wrapper(*args, **kwargs):
90 try:
91 func(*args, **kwargs)
92 except Exception:
93 raise _ExpectedFailure(sys.exc_info())
94 raise _UnexpectedSuccess
95 return wrapper
96
97
98class _AssertRaisesContext(object):
99 """A context manager used to implement TestCase.assertRaises* methods."""
100
101 def __init__(self, expected, test_case, expected_regexp=None):
102 self.expected = expected
103 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000104 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000105
106 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +0000107 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000108
109 def __exit__(self, exc_type, exc_value, tb):
110 if exc_type is None:
111 try:
112 exc_name = self.expected.__name__
113 except AttributeError:
114 exc_name = str(self.expected)
115 raise self.failureException(
116 "{0} not raised".format(exc_name))
117 if not issubclass(exc_type, self.expected):
118 # let unexpected exceptions pass through
119 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000120 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000121 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000122 return True
123
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000124 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000125 if isinstance(expected_regexp, basestring):
126 expected_regexp = re.compile(expected_regexp)
127 if not expected_regexp.search(str(exc_value)):
128 raise self.failureException('"%s" does not match "%s"' %
129 (expected_regexp.pattern, str(exc_value)))
130 return True
131
132
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000133class TestCase(object):
134 """A class whose instances are single test cases.
135
136 By default, the test code itself should be placed in a method named
137 'runTest'.
138
139 If the fixture may be used for many test cases, create as
140 many test methods as are needed. When instantiating such a TestCase
141 subclass, specify in the constructor arguments the name of the test method
142 that the instance is to execute.
143
144 Test authors should subclass TestCase for their own tests. Construction
145 and deconstruction of the test's environment ('fixture') can be
146 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
147
148 If it is necessary to override the __init__ method, the base class
149 __init__ method must always be called. It is important that subclasses
150 should not change the signature of their __init__ method, since instances
151 of the classes are instantiated automatically by parts of the framework
152 in order to be run.
153 """
154
155 # This attribute determines which exception will be raised when
156 # the instance's assertion methods fail; test methods raising this
157 # exception will be deemed to have 'failed' rather than 'errored'
158
159 failureException = AssertionError
160
161 # This attribute determines whether long messages (including repr of
162 # objects used in assert methods) will be printed on failure in *addition*
163 # to any explicit message passed.
164
165 longMessage = False
166
Michael Foordae1bb9a2010-06-09 12:29:56 +0000167 # This attribute sets the maximum length of a diff in failure messages
Michael Foorde37d75f2010-06-05 12:10:52 +0000168 # by assert methods using difflib. It is looked up as an instance attribute
169 # so can be configured by individual tests if required.
Michael Foordc532c572010-06-05 23:58:40 +0000170
Michael Foorde37d75f2010-06-05 12:10:52 +0000171 maxDiff = 80*8
172
Ezio Melotti34b32d62011-04-27 09:45:46 +0300173 # If a string is longer than _diffThreshold, use normal comparison instead
174 # of difflib. See #11763.
175 _diffThreshold = 2**16
176
Michael Foord5ffa3252010-03-07 22:04:55 +0000177 # Attribute used by TestSuite for classSetUp
178
179 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000180
181 def __init__(self, methodName='runTest'):
182 """Create an instance of the class that will use the named test
183 method when executed. Raises a ValueError if the instance does
184 not have a method with the specified name.
185 """
186 self._testMethodName = methodName
187 self._resultForDoCleanups = None
188 try:
189 testMethod = getattr(self, methodName)
190 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000191 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000192 (self.__class__, methodName))
193 self._testMethodDoc = testMethod.__doc__
194 self._cleanups = []
195
196 # Map types to custom assertEqual functions that will compare
197 # instances of said type in more detail to generate a more useful
198 # error message.
Benjamin Peterson83c14fe2011-07-12 19:21:42 -0500199 self._type_equality_funcs = {}
Raymond Hettinger67a3e832011-06-25 12:16:25 +0200200 self.addTypeEqualityFunc(dict, 'assertDictEqual')
201 self.addTypeEqualityFunc(list, 'assertListEqual')
202 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
203 self.addTypeEqualityFunc(set, 'assertSetEqual')
204 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
205 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000206
207 def addTypeEqualityFunc(self, typeobj, function):
208 """Add a type specific assertEqual style function to compare a type.
209
210 This method is for use by TestCase subclasses that need to register
211 their own type equality functions to provide nicer error messages.
212
213 Args:
214 typeobj: The data type to call this function on when both values
215 are of the same type in assertEqual().
216 function: The callable taking two arguments and an optional
217 msg= argument that raises self.failureException with a
218 useful error message when the two arguments are not equal.
219 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000220 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000221
222 def addCleanup(self, function, *args, **kwargs):
223 """Add a function, with arguments, to be called when the test is
224 completed. Functions added are called on a LIFO basis and are
225 called after tearDown on test failure or success.
226
227 Cleanup items are called even if setUp fails (unlike tearDown)."""
228 self._cleanups.append((function, args, kwargs))
229
230 def setUp(self):
231 "Hook method for setting up the test fixture before exercising it."
232 pass
233
234 def tearDown(self):
235 "Hook method for deconstructing the test fixture after testing it."
236 pass
237
Michael Foord5ffa3252010-03-07 22:04:55 +0000238 @classmethod
239 def setUpClass(cls):
240 "Hook method for setting up class fixture before running tests in the class."
241
242 @classmethod
243 def tearDownClass(cls):
244 "Hook method for deconstructing the class fixture after running all tests in the class."
245
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000246 def countTestCases(self):
247 return 1
248
249 def defaultTestResult(self):
250 return result.TestResult()
251
252 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000253 """Returns a one-line description of the test, or None if no
254 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000255
Michael Foorddb43b5a2010-02-10 14:25:12 +0000256 The default implementation of this method returns the first line of
257 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000258 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000259 doc = self._testMethodDoc
260 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000261
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000262
263 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000264 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000265
266 def __eq__(self, other):
267 if type(self) is not type(other):
268 return NotImplemented
269
270 return self._testMethodName == other._testMethodName
271
272 def __ne__(self, other):
273 return not self == other
274
275 def __hash__(self):
276 return hash((type(self), self._testMethodName))
277
278 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000279 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000280
281 def __repr__(self):
282 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000283 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000284
Michael Foordae3db0a2010-02-22 23:28:32 +0000285 def _addSkip(self, result, reason):
286 addSkip = getattr(result, 'addSkip', None)
287 if addSkip is not None:
288 addSkip(self, reason)
289 else:
290 warnings.warn("TestResult has no addSkip method, skips not reported",
291 RuntimeWarning, 2)
292 result.addSuccess(self)
293
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000294 def run(self, result=None):
295 orig_result = result
296 if result is None:
297 result = self.defaultTestResult()
298 startTestRun = getattr(result, 'startTestRun', None)
299 if startTestRun is not None:
300 startTestRun()
301
302 self._resultForDoCleanups = result
303 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000304
305 testMethod = getattr(self, self._testMethodName)
306 if (getattr(self.__class__, "__unittest_skip__", False) or
307 getattr(testMethod, "__unittest_skip__", False)):
308 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000309 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000310 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
311 or getattr(testMethod, '__unittest_skip_why__', ''))
312 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000313 finally:
314 result.stopTest(self)
315 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000316 try:
317 success = False
318 try:
319 self.setUp()
320 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000321 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000322 except KeyboardInterrupt:
323 raise
324 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000325 result.addError(self, sys.exc_info())
326 else:
327 try:
328 testMethod()
Michael Foorda17f0762010-12-19 14:53:19 +0000329 except KeyboardInterrupt:
330 raise
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000331 except self.failureException:
332 result.addFailure(self, sys.exc_info())
333 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000334 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
335 if addExpectedFailure is not None:
336 addExpectedFailure(self, e.exc_info)
337 else:
338 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
339 RuntimeWarning)
340 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000341 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000342 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
343 if addUnexpectedSuccess is not None:
344 addUnexpectedSuccess(self)
345 else:
346 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
347 RuntimeWarning)
348 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000349 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000350 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000351 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000352 result.addError(self, sys.exc_info())
353 else:
354 success = True
355
356 try:
357 self.tearDown()
Michael Foorda17f0762010-12-19 14:53:19 +0000358 except KeyboardInterrupt:
359 raise
360 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000361 result.addError(self, sys.exc_info())
362 success = False
363
364 cleanUpSuccess = self.doCleanups()
365 success = success and cleanUpSuccess
366 if success:
367 result.addSuccess(self)
368 finally:
369 result.stopTest(self)
370 if orig_result is None:
371 stopTestRun = getattr(result, 'stopTestRun', None)
372 if stopTestRun is not None:
373 stopTestRun()
374
375 def doCleanups(self):
376 """Execute all cleanup functions. Normally called for you after
377 tearDown."""
378 result = self._resultForDoCleanups
379 ok = True
380 while self._cleanups:
381 function, args, kwargs = self._cleanups.pop(-1)
382 try:
383 function(*args, **kwargs)
Michael Foorda17f0762010-12-19 14:53:19 +0000384 except KeyboardInterrupt:
385 raise
386 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000387 ok = False
388 result.addError(self, sys.exc_info())
389 return ok
390
391 def __call__(self, *args, **kwds):
392 return self.run(*args, **kwds)
393
394 def debug(self):
395 """Run the test without collecting errors in a TestResult"""
396 self.setUp()
397 getattr(self, self._testMethodName)()
398 self.tearDown()
Michael Foord0fedb282010-06-08 22:44:52 +0000399 while self._cleanups:
400 function, args, kwargs = self._cleanups.pop(-1)
401 function(*args, **kwargs)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000402
403 def skipTest(self, reason):
404 """Skip this test."""
405 raise SkipTest(reason)
406
407 def fail(self, msg=None):
408 """Fail immediately, with the given message."""
409 raise self.failureException(msg)
410
411 def assertFalse(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000412 """Check that the expression is false."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000413 if expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000414 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000415 raise self.failureException(msg)
416
417 def assertTrue(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000418 """Check that the expression is true."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000419 if not expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000420 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000421 raise self.failureException(msg)
422
423 def _formatMessage(self, msg, standardMsg):
424 """Honour the longMessage attribute when generating failure messages.
425 If longMessage is False this means:
426 * Use only an explicit message if it is provided
427 * Otherwise use the standard message for the assert
428
429 If longMessage is True:
430 * Use the standard message
431 * If an explicit message is provided, plus ' : ' and the explicit message
432 """
433 if not self.longMessage:
434 return msg or standardMsg
435 if msg is None:
436 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000437 try:
438 # don't switch to '{}' formatting in Python 2.X
439 # it changes the way unicode input is handled
440 return '%s : %s' % (standardMsg, msg)
441 except UnicodeDecodeError:
442 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000443
444
445 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
446 """Fail unless an exception of class excClass is thrown
447 by callableObj when invoked with arguments args and keyword
448 arguments kwargs. If a different type of exception is
449 thrown, it will not be caught, and the test case will be
450 deemed to have suffered an error, exactly as for an
451 unexpected exception.
452
453 If called with callableObj omitted or None, will return a
454 context object used like this::
455
Michael Foordd0edec32010-02-05 22:55:09 +0000456 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000457 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000458
459 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000460 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000461 exception after the assertion::
462
463 with self.assertRaises(SomeException) as cm:
464 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000465 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000466 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000467 """
468 context = _AssertRaisesContext(excClass, self)
469 if callableObj is None:
470 return context
471 with context:
472 callableObj(*args, **kwargs)
473
474 def _getAssertEqualityFunc(self, first, second):
475 """Get a detailed comparison function for the types of the two args.
476
477 Returns: A callable accepting (first, second, msg=None) that will
478 raise a failure exception if first != second with a useful human
479 readable error message for those types.
480 """
481 #
482 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
483 # and vice versa. I opted for the conservative approach in case
484 # subclasses are not intended to be compared in detail to their super
485 # class instances using a type equality func. This means testing
486 # subtypes won't automagically use the detailed comparison. Callers
487 # should use their type specific assertSpamEqual method to compare
488 # subclasses if the detailed comparison is desired and appropriate.
489 # See the discussion in http://bugs.python.org/issue2578.
490 #
491 if type(first) is type(second):
492 asserter = self._type_equality_funcs.get(type(first))
493 if asserter is not None:
Benjamin Peterson83c14fe2011-07-12 19:21:42 -0500494 if isinstance(asserter, basestring):
495 asserter = getattr(self, asserter)
Benjamin Petersond46430b2009-11-29 22:26:26 +0000496 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000497
498 return self._baseAssertEqual
499
500 def _baseAssertEqual(self, first, second, msg=None):
501 """The default assertEqual implementation, not type specific."""
502 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000503 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000504 msg = self._formatMessage(msg, standardMsg)
505 raise self.failureException(msg)
506
507 def assertEqual(self, first, second, msg=None):
508 """Fail if the two objects are unequal as determined by the '=='
509 operator.
510 """
511 assertion_func = self._getAssertEqualityFunc(first, second)
512 assertion_func(first, second, msg=msg)
513
514 def assertNotEqual(self, first, second, msg=None):
515 """Fail if the two objects are equal as determined by the '=='
516 operator.
517 """
518 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000519 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
520 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000521 raise self.failureException(msg)
522
Michael Foorda7e08fe2010-03-27 19:10:11 +0000523
524 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000525 """Fail if the two objects are unequal as determined by their
526 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000527 (default 7) and comparing to zero, or by comparing that the
528 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000529
530 Note that decimal places (from zero) are usually not the same
531 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000532
533 If the two objects compare equal then they will automatically
534 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000535 """
Michael Foordc3f79372009-09-13 16:40:02 +0000536 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000537 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000538 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000539 if delta is not None and places is not None:
540 raise TypeError("specify delta or places not both")
541
542 if delta is not None:
543 if abs(first - second) <= delta:
544 return
545
546 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
547 safe_repr(second),
548 safe_repr(delta))
549 else:
550 if places is None:
551 places = 7
552
553 if round(abs(second-first), places) == 0:
554 return
555
Michael Foord225a0992010-02-18 20:30:09 +0000556 standardMsg = '%s != %s within %r places' % (safe_repr(first),
557 safe_repr(second),
558 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000559 msg = self._formatMessage(msg, standardMsg)
560 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000561
Michael Foorda7e08fe2010-03-27 19:10:11 +0000562 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000563 """Fail if the two objects are equal as determined by their
564 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000565 (default 7) and comparing to zero, or by comparing that the
566 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000567
568 Note that decimal places (from zero) are usually not the same
569 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000570
571 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000572 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000573 if delta is not None and places is not None:
574 raise TypeError("specify delta or places not both")
575 if delta is not None:
576 if not (first == second) and abs(first - second) > delta:
577 return
578 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
579 safe_repr(second),
580 safe_repr(delta))
581 else:
582 if places is None:
583 places = 7
584 if not (first == second) and round(abs(second-first), places) != 0:
585 return
Michael Foord225a0992010-02-18 20:30:09 +0000586 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000587 safe_repr(second),
588 places)
589
590 msg = self._formatMessage(msg, standardMsg)
591 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000592
593 # Synonyms for assertion methods
594
595 # The plurals are undocumented. Keep them that way to discourage use.
596 # Do not add more. Do not remove.
597 # Going through a deprecation cycle on these would annoy many people.
598 assertEquals = assertEqual
599 assertNotEquals = assertNotEqual
600 assertAlmostEquals = assertAlmostEqual
601 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000602 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000603
604 # These fail* assertion method names are pending deprecation and will
605 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
606 def _deprecate(original_func):
607 def deprecated_func(*args, **kwargs):
608 warnings.warn(
609 'Please use {0} instead.'.format(original_func.__name__),
610 PendingDeprecationWarning, 2)
611 return original_func(*args, **kwargs)
612 return deprecated_func
613
614 failUnlessEqual = _deprecate(assertEqual)
615 failIfEqual = _deprecate(assertNotEqual)
616 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
617 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
618 failUnless = _deprecate(assertTrue)
619 failUnlessRaises = _deprecate(assertRaises)
620 failIf = _deprecate(assertFalse)
621
Michael Foorde37d75f2010-06-05 12:10:52 +0000622 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000623 """An equality assertion for ordered sequences (like lists and tuples).
624
R. David Murray05b41712010-01-29 19:35:39 +0000625 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000626 which can be indexed, has a length, and has an equality operator.
627
628 Args:
629 seq1: The first sequence to compare.
630 seq2: The second sequence to compare.
631 seq_type: The expected datatype of the sequences, or None if no
632 datatype should be enforced.
633 msg: Optional message to use on failure instead of a list of
634 differences.
635 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000636 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000637 seq_type_name = seq_type.__name__
638 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000639 raise self.failureException('First sequence is not a %s: %s'
640 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000641 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000642 raise self.failureException('Second sequence is not a %s: %s'
643 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000644 else:
645 seq_type_name = "sequence"
646
647 differing = None
648 try:
649 len1 = len(seq1)
650 except (TypeError, NotImplementedError):
651 differing = 'First %s has no length. Non-sequence?' % (
652 seq_type_name)
653
654 if differing is None:
655 try:
656 len2 = len(seq2)
657 except (TypeError, NotImplementedError):
658 differing = 'Second %s has no length. Non-sequence?' % (
659 seq_type_name)
660
661 if differing is None:
662 if seq1 == seq2:
663 return
664
Michael Foord225a0992010-02-18 20:30:09 +0000665 seq1_repr = safe_repr(seq1)
666 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000667 if len(seq1_repr) > 30:
668 seq1_repr = seq1_repr[:30] + '...'
669 if len(seq2_repr) > 30:
670 seq2_repr = seq2_repr[:30] + '...'
671 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
672 differing = '%ss differ: %s != %s\n' % elements
673
674 for i in xrange(min(len1, len2)):
675 try:
676 item1 = seq1[i]
677 except (TypeError, IndexError, NotImplementedError):
678 differing += ('\nUnable to index element %d of first %s\n' %
679 (i, seq_type_name))
680 break
681
682 try:
683 item2 = seq2[i]
684 except (TypeError, IndexError, NotImplementedError):
685 differing += ('\nUnable to index element %d of second %s\n' %
686 (i, seq_type_name))
687 break
688
689 if item1 != item2:
690 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
691 (i, item1, item2))
692 break
693 else:
694 if (len1 == len2 and seq_type is None and
695 type(seq1) != type(seq2)):
696 # The sequences are the same, but have differing types.
697 return
698
699 if len1 > len2:
700 differing += ('\nFirst %s contains %d additional '
701 'elements.\n' % (seq_type_name, len1 - len2))
702 try:
703 differing += ('First extra element %d:\n%s\n' %
704 (len2, seq1[len2]))
705 except (TypeError, IndexError, NotImplementedError):
706 differing += ('Unable to index element %d '
707 'of first %s\n' % (len2, seq_type_name))
708 elif len1 < len2:
709 differing += ('\nSecond %s contains %d additional '
710 'elements.\n' % (seq_type_name, len2 - len1))
711 try:
712 differing += ('First extra element %d:\n%s\n' %
713 (len1, seq2[len1]))
714 except (TypeError, IndexError, NotImplementedError):
715 differing += ('Unable to index element %d '
716 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000717 standardMsg = differing
718 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000719 difflib.ndiff(pprint.pformat(seq1).splitlines(),
720 pprint.pformat(seq2).splitlines()))
Michael Foorde37d75f2010-06-05 12:10:52 +0000721 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000722 msg = self._formatMessage(msg, standardMsg)
723 self.fail(msg)
724
Michael Foorde37d75f2010-06-05 12:10:52 +0000725 def _truncateMessage(self, message, diff):
726 max_diff = self.maxDiff
Michael Foorda4412872010-06-05 11:46:59 +0000727 if max_diff is None or len(diff) <= max_diff:
728 return message + diff
Michael Foord5fe21ff2010-06-05 13:38:16 +0000729 return message + (DIFF_OMITTED % len(diff))
Michael Foorda4412872010-06-05 11:46:59 +0000730
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000731 def assertListEqual(self, list1, list2, msg=None):
732 """A list-specific equality assertion.
733
734 Args:
735 list1: The first list to compare.
736 list2: The second list to compare.
737 msg: Optional message to use on failure instead of a list of
738 differences.
739
740 """
741 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
742
743 def assertTupleEqual(self, tuple1, tuple2, msg=None):
744 """A tuple-specific equality assertion.
745
746 Args:
747 tuple1: The first tuple to compare.
748 tuple2: The second tuple to compare.
749 msg: Optional message to use on failure instead of a list of
750 differences.
751 """
752 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
753
754 def assertSetEqual(self, set1, set2, msg=None):
755 """A set-specific equality assertion.
756
757 Args:
758 set1: The first set to compare.
759 set2: The second set to compare.
760 msg: Optional message to use on failure instead of a list of
761 differences.
762
Michael Foord98e7b762010-03-20 03:00:34 +0000763 assertSetEqual uses ducktyping to support different types of sets, and
764 is optimized for sets specifically (parameters must support a
765 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000766 """
767 try:
768 difference1 = set1.difference(set2)
769 except TypeError, e:
770 self.fail('invalid type when attempting set difference: %s' % e)
771 except AttributeError, e:
772 self.fail('first argument does not support set difference: %s' % e)
773
774 try:
775 difference2 = set2.difference(set1)
776 except TypeError, e:
777 self.fail('invalid type when attempting set difference: %s' % e)
778 except AttributeError, e:
779 self.fail('second argument does not support set difference: %s' % e)
780
781 if not (difference1 or difference2):
782 return
783
784 lines = []
785 if difference1:
786 lines.append('Items in the first set but not the second:')
787 for item in difference1:
788 lines.append(repr(item))
789 if difference2:
790 lines.append('Items in the second set but not the first:')
791 for item in difference2:
792 lines.append(repr(item))
793
794 standardMsg = '\n'.join(lines)
795 self.fail(self._formatMessage(msg, standardMsg))
796
797 def assertIn(self, member, container, msg=None):
798 """Just like self.assertTrue(a in b), but with a nicer default message."""
799 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000800 standardMsg = '%s not 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 assertNotIn(self, member, container, msg=None):
805 """Just like self.assertTrue(a not in b), but with a nicer default message."""
806 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000807 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
808 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000809 self.fail(self._formatMessage(msg, standardMsg))
810
811 def assertIs(self, expr1, expr2, msg=None):
812 """Just like self.assertTrue(a is b), but with a nicer default message."""
813 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000814 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000815 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000816 self.fail(self._formatMessage(msg, standardMsg))
817
818 def assertIsNot(self, expr1, expr2, msg=None):
819 """Just like self.assertTrue(a is not b), but with a nicer default message."""
820 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000821 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000822 self.fail(self._formatMessage(msg, standardMsg))
823
824 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melotti2623a372010-11-21 13:34:58 +0000825 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
826 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000827
828 if d1 != d2:
Michael Foord674648e2010-06-05 12:58:39 +0000829 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foorde37d75f2010-06-05 12:10:52 +0000830 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000831 pprint.pformat(d1).splitlines(),
832 pprint.pformat(d2).splitlines())))
Michael Foord674648e2010-06-05 12:58:39 +0000833 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000834 self.fail(self._formatMessage(msg, standardMsg))
835
836 def assertDictContainsSubset(self, expected, actual, msg=None):
837 """Checks whether actual is a superset of expected."""
838 missing = []
839 mismatched = []
840 for key, value in expected.iteritems():
841 if key not in actual:
842 missing.append(key)
843 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000844 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000845 (safe_repr(key), safe_repr(value),
846 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000847
848 if not (missing or mismatched):
849 return
850
851 standardMsg = ''
852 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000853 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
854 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000855 if mismatched:
856 if standardMsg:
857 standardMsg += '; '
858 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
859
860 self.fail(self._formatMessage(msg, standardMsg))
861
Michael Foord98e7b762010-03-20 03:00:34 +0000862 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
Michael Foorde6e0e262010-12-19 15:52:56 +0000863 """An unordered sequence specific comparison. It asserts that
864 actual_seq and expected_seq have the same element counts.
865 Equivalent to::
Michael Foord98e7b762010-03-20 03:00:34 +0000866
Michael Foorde6e0e262010-12-19 15:52:56 +0000867 self.assertEqual(Counter(iter(actual_seq)),
868 Counter(iter(expected_seq)))
Michael Foordd0edec32010-02-05 22:55:09 +0000869
Michael Foord98e7b762010-03-20 03:00:34 +0000870 Asserts that each element has the same count in both sequences.
871 Example:
872 - [0, 1, 1] and [1, 0, 1] compare equal.
873 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000874 """
R David Murray69493922012-05-16 14:01:03 -0400875 first_seq, second_seq = list(expected_seq), list(actual_seq)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000876 with warnings.catch_warnings():
877 if sys.py3kwarning:
878 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000879 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000880 "builtin_function_or_method order comparisons",
881 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000882 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000883 try:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400884 first = collections.Counter(first_seq)
885 second = collections.Counter(second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000886 except TypeError:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400887 # Handle case with unhashable elements
888 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000889 else:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400890 if first == second:
Michael Foorde6e0e262010-12-19 15:52:56 +0000891 return
Michael Foord4c9e91a2011-03-16 20:34:53 -0400892 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000893
Michael Foord4c9e91a2011-03-16 20:34:53 -0400894 if differences:
895 standardMsg = 'Element counts were not equal:\n'
896 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
897 diffMsg = '\n'.join(lines)
898 standardMsg = self._truncateMessage(standardMsg, diffMsg)
899 msg = self._formatMessage(msg, standardMsg)
900 self.fail(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000901
902 def assertMultiLineEqual(self, first, second, msg=None):
903 """Assert that two multi-line strings are equal."""
Ezio Melotti2623a372010-11-21 13:34:58 +0000904 self.assertIsInstance(first, basestring,
905 'First argument is not a string')
906 self.assertIsInstance(second, basestring,
907 'Second argument is not a string')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000908
909 if first != second:
Ezio Melotti34b32d62011-04-27 09:45:46 +0300910 # don't use difflib if the strings are too long
911 if (len(first) > self._diffThreshold or
912 len(second) > self._diffThreshold):
913 self._baseAssertEqual(first, second, msg)
Michael Foord94f071c2010-07-10 13:51:42 +0000914 firstlines = first.splitlines(True)
915 secondlines = second.splitlines(True)
916 if len(firstlines) == 1 and first.strip('\r\n') == first:
917 firstlines = [first + '\n']
918 secondlines = [second + '\n']
919 standardMsg = '%s != %s' % (safe_repr(first, True),
920 safe_repr(second, True))
921 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foord674648e2010-06-05 12:58:39 +0000922 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000923 self.fail(self._formatMessage(msg, standardMsg))
924
925 def assertLess(self, a, b, msg=None):
926 """Just like self.assertTrue(a < b), but with a nicer default message."""
927 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000928 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000929 self.fail(self._formatMessage(msg, standardMsg))
930
931 def assertLessEqual(self, a, b, msg=None):
932 """Just like self.assertTrue(a <= b), but with a nicer default message."""
933 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000934 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000935 self.fail(self._formatMessage(msg, standardMsg))
936
937 def assertGreater(self, a, b, msg=None):
938 """Just like self.assertTrue(a > b), but with a nicer default message."""
939 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000940 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000941 self.fail(self._formatMessage(msg, standardMsg))
942
943 def assertGreaterEqual(self, a, b, msg=None):
944 """Just like self.assertTrue(a >= b), but with a nicer default message."""
945 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000946 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000947 self.fail(self._formatMessage(msg, standardMsg))
948
949 def assertIsNone(self, obj, msg=None):
950 """Same as self.assertTrue(obj is None), with a nicer default message."""
951 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000952 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000953 self.fail(self._formatMessage(msg, standardMsg))
954
955 def assertIsNotNone(self, obj, msg=None):
956 """Included for symmetry with assertIsNone."""
957 if obj is None:
958 standardMsg = 'unexpectedly None'
959 self.fail(self._formatMessage(msg, standardMsg))
960
Georg Brandlf895cf52009-10-01 20:59:31 +0000961 def assertIsInstance(self, obj, cls, msg=None):
962 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
963 default message."""
964 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000965 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000966 self.fail(self._formatMessage(msg, standardMsg))
967
968 def assertNotIsInstance(self, obj, cls, msg=None):
969 """Included for symmetry with assertIsInstance."""
970 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000971 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000972 self.fail(self._formatMessage(msg, standardMsg))
973
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000974 def assertRaisesRegexp(self, expected_exception, expected_regexp,
975 callable_obj=None, *args, **kwargs):
976 """Asserts that the message in a raised exception matches a regexp.
977
978 Args:
979 expected_exception: Exception class expected to be raised.
980 expected_regexp: Regexp (re pattern object or string) expected
981 to be found in error message.
982 callable_obj: Function to be called.
983 args: Extra args.
984 kwargs: Extra kwargs.
985 """
986 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
987 if callable_obj is None:
988 return context
989 with context:
990 callable_obj(*args, **kwargs)
991
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000992 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000993 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000994 if isinstance(expected_regexp, basestring):
995 expected_regexp = re.compile(expected_regexp)
996 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000997 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000998 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000999 raise self.failureException(msg)
1000
Michael Foorda04c7a02010-04-02 22:55:59 +00001001 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +00001002 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +00001003 if isinstance(unexpected_regexp, basestring):
1004 unexpected_regexp = re.compile(unexpected_regexp)
1005 match = unexpected_regexp.search(text)
1006 if match:
1007 msg = msg or "Regexp matched"
1008 msg = '%s: %r matches %r in %r' % (msg,
1009 text[match.start():match.end()],
1010 unexpected_regexp.pattern,
1011 text)
1012 raise self.failureException(msg)
1013
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001014
1015class FunctionTestCase(TestCase):
1016 """A test case that wraps a test function.
1017
1018 This is useful for slipping pre-existing test functions into the
1019 unittest framework. Optionally, set-up and tidy-up functions can be
1020 supplied. As with TestCase, the tidy-up ('tearDown') function will
1021 always be called if the set-up ('setUp') function ran successfully.
1022 """
1023
1024 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1025 super(FunctionTestCase, self).__init__()
1026 self._setUpFunc = setUp
1027 self._tearDownFunc = tearDown
1028 self._testFunc = testFunc
1029 self._description = description
1030
1031 def setUp(self):
1032 if self._setUpFunc is not None:
1033 self._setUpFunc()
1034
1035 def tearDown(self):
1036 if self._tearDownFunc is not None:
1037 self._tearDownFunc()
1038
1039 def runTest(self):
1040 self._testFunc()
1041
1042 def id(self):
1043 return self._testFunc.__name__
1044
1045 def __eq__(self, other):
1046 if not isinstance(other, self.__class__):
1047 return NotImplemented
1048
1049 return self._setUpFunc == other._setUpFunc and \
1050 self._tearDownFunc == other._tearDownFunc and \
1051 self._testFunc == other._testFunc and \
1052 self._description == other._description
1053
1054 def __ne__(self, other):
1055 return not self == other
1056
1057 def __hash__(self):
1058 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1059 self._testFunc, self._description))
1060
1061 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001062 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001063 self._testFunc.__name__)
1064
1065 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001066 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001067 self._testFunc)
1068
1069 def shortDescription(self):
1070 if self._description is not None:
1071 return self._description
1072 doc = self._testFunc.__doc__
1073 return doc and doc.split("\n")[0].strip() or None