blob: ca545f97efd24bba8f16b89054b3f3fd3472d16f [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
Raymond Hettinger67a3e832011-06-25 12:16:25 +0200132class _TypeEqualityDict(object):
133
134 def __init__(self, testcase):
135 self.testcase = testcase
136 self._store = {}
137
138 def __setitem__(self, key, value):
139 self._store[key] = value
140
141 def __getitem__(self, key):
142 value = self._store[key]
143 if isinstance(value, basestring):
144 return getattr(self.testcase, value)
145 return value
146
147 def get(self, key, default=None):
148 if key in self._store:
149 return self[key]
150 return default
151
152
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000153class TestCase(object):
154 """A class whose instances are single test cases.
155
156 By default, the test code itself should be placed in a method named
157 'runTest'.
158
159 If the fixture may be used for many test cases, create as
160 many test methods as are needed. When instantiating such a TestCase
161 subclass, specify in the constructor arguments the name of the test method
162 that the instance is to execute.
163
164 Test authors should subclass TestCase for their own tests. Construction
165 and deconstruction of the test's environment ('fixture') can be
166 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
167
168 If it is necessary to override the __init__ method, the base class
169 __init__ method must always be called. It is important that subclasses
170 should not change the signature of their __init__ method, since instances
171 of the classes are instantiated automatically by parts of the framework
172 in order to be run.
173 """
174
175 # This attribute determines which exception will be raised when
176 # the instance's assertion methods fail; test methods raising this
177 # exception will be deemed to have 'failed' rather than 'errored'
178
179 failureException = AssertionError
180
181 # This attribute determines whether long messages (including repr of
182 # objects used in assert methods) will be printed on failure in *addition*
183 # to any explicit message passed.
184
185 longMessage = False
186
Michael Foordae1bb9a2010-06-09 12:29:56 +0000187 # This attribute sets the maximum length of a diff in failure messages
Michael Foorde37d75f2010-06-05 12:10:52 +0000188 # by assert methods using difflib. It is looked up as an instance attribute
189 # so can be configured by individual tests if required.
Michael Foordc532c572010-06-05 23:58:40 +0000190
Michael Foorde37d75f2010-06-05 12:10:52 +0000191 maxDiff = 80*8
192
Ezio Melotti34b32d62011-04-27 09:45:46 +0300193 # If a string is longer than _diffThreshold, use normal comparison instead
194 # of difflib. See #11763.
195 _diffThreshold = 2**16
196
Michael Foord5ffa3252010-03-07 22:04:55 +0000197 # Attribute used by TestSuite for classSetUp
198
199 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000200
201 def __init__(self, methodName='runTest'):
202 """Create an instance of the class that will use the named test
203 method when executed. Raises a ValueError if the instance does
204 not have a method with the specified name.
205 """
206 self._testMethodName = methodName
207 self._resultForDoCleanups = None
208 try:
209 testMethod = getattr(self, methodName)
210 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000211 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000212 (self.__class__, methodName))
213 self._testMethodDoc = testMethod.__doc__
214 self._cleanups = []
215
216 # Map types to custom assertEqual functions that will compare
217 # instances of said type in more detail to generate a more useful
218 # error message.
Raymond Hettinger67a3e832011-06-25 12:16:25 +0200219 self._type_equality_funcs = _TypeEqualityDict(self)
220 self.addTypeEqualityFunc(dict, 'assertDictEqual')
221 self.addTypeEqualityFunc(list, 'assertListEqual')
222 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
223 self.addTypeEqualityFunc(set, 'assertSetEqual')
224 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
225 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000226
227 def addTypeEqualityFunc(self, typeobj, function):
228 """Add a type specific assertEqual style function to compare a type.
229
230 This method is for use by TestCase subclasses that need to register
231 their own type equality functions to provide nicer error messages.
232
233 Args:
234 typeobj: The data type to call this function on when both values
235 are of the same type in assertEqual().
236 function: The callable taking two arguments and an optional
237 msg= argument that raises self.failureException with a
238 useful error message when the two arguments are not equal.
239 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000240 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000241
242 def addCleanup(self, function, *args, **kwargs):
243 """Add a function, with arguments, to be called when the test is
244 completed. Functions added are called on a LIFO basis and are
245 called after tearDown on test failure or success.
246
247 Cleanup items are called even if setUp fails (unlike tearDown)."""
248 self._cleanups.append((function, args, kwargs))
249
250 def setUp(self):
251 "Hook method for setting up the test fixture before exercising it."
252 pass
253
254 def tearDown(self):
255 "Hook method for deconstructing the test fixture after testing it."
256 pass
257
Michael Foord5ffa3252010-03-07 22:04:55 +0000258 @classmethod
259 def setUpClass(cls):
260 "Hook method for setting up class fixture before running tests in the class."
261
262 @classmethod
263 def tearDownClass(cls):
264 "Hook method for deconstructing the class fixture after running all tests in the class."
265
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000266 def countTestCases(self):
267 return 1
268
269 def defaultTestResult(self):
270 return result.TestResult()
271
272 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000273 """Returns a one-line description of the test, or None if no
274 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000275
Michael Foorddb43b5a2010-02-10 14:25:12 +0000276 The default implementation of this method returns the first line of
277 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000278 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000279 doc = self._testMethodDoc
280 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000281
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000282
283 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000284 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000285
286 def __eq__(self, other):
287 if type(self) is not type(other):
288 return NotImplemented
289
290 return self._testMethodName == other._testMethodName
291
292 def __ne__(self, other):
293 return not self == other
294
295 def __hash__(self):
296 return hash((type(self), self._testMethodName))
297
298 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000299 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000300
301 def __repr__(self):
302 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000303 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000304
Michael Foordae3db0a2010-02-22 23:28:32 +0000305 def _addSkip(self, result, reason):
306 addSkip = getattr(result, 'addSkip', None)
307 if addSkip is not None:
308 addSkip(self, reason)
309 else:
310 warnings.warn("TestResult has no addSkip method, skips not reported",
311 RuntimeWarning, 2)
312 result.addSuccess(self)
313
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000314 def run(self, result=None):
315 orig_result = result
316 if result is None:
317 result = self.defaultTestResult()
318 startTestRun = getattr(result, 'startTestRun', None)
319 if startTestRun is not None:
320 startTestRun()
321
322 self._resultForDoCleanups = result
323 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000324
325 testMethod = getattr(self, self._testMethodName)
326 if (getattr(self.__class__, "__unittest_skip__", False) or
327 getattr(testMethod, "__unittest_skip__", False)):
328 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000329 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000330 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
331 or getattr(testMethod, '__unittest_skip_why__', ''))
332 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000333 finally:
334 result.stopTest(self)
335 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000336 try:
337 success = False
338 try:
339 self.setUp()
340 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000341 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000342 except KeyboardInterrupt:
343 raise
344 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000345 result.addError(self, sys.exc_info())
346 else:
347 try:
348 testMethod()
Michael Foorda17f0762010-12-19 14:53:19 +0000349 except KeyboardInterrupt:
350 raise
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000351 except self.failureException:
352 result.addFailure(self, sys.exc_info())
353 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000354 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
355 if addExpectedFailure is not None:
356 addExpectedFailure(self, e.exc_info)
357 else:
358 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
359 RuntimeWarning)
360 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000361 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000362 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
363 if addUnexpectedSuccess is not None:
364 addUnexpectedSuccess(self)
365 else:
366 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
367 RuntimeWarning)
368 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000369 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000370 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000371 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000372 result.addError(self, sys.exc_info())
373 else:
374 success = True
375
376 try:
377 self.tearDown()
Michael Foorda17f0762010-12-19 14:53:19 +0000378 except KeyboardInterrupt:
379 raise
380 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000381 result.addError(self, sys.exc_info())
382 success = False
383
384 cleanUpSuccess = self.doCleanups()
385 success = success and cleanUpSuccess
386 if success:
387 result.addSuccess(self)
388 finally:
389 result.stopTest(self)
390 if orig_result is None:
391 stopTestRun = getattr(result, 'stopTestRun', None)
392 if stopTestRun is not None:
393 stopTestRun()
394
395 def doCleanups(self):
396 """Execute all cleanup functions. Normally called for you after
397 tearDown."""
398 result = self._resultForDoCleanups
399 ok = True
400 while self._cleanups:
401 function, args, kwargs = self._cleanups.pop(-1)
402 try:
403 function(*args, **kwargs)
Michael Foorda17f0762010-12-19 14:53:19 +0000404 except KeyboardInterrupt:
405 raise
406 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000407 ok = False
408 result.addError(self, sys.exc_info())
409 return ok
410
411 def __call__(self, *args, **kwds):
412 return self.run(*args, **kwds)
413
414 def debug(self):
415 """Run the test without collecting errors in a TestResult"""
416 self.setUp()
417 getattr(self, self._testMethodName)()
418 self.tearDown()
Michael Foord0fedb282010-06-08 22:44:52 +0000419 while self._cleanups:
420 function, args, kwargs = self._cleanups.pop(-1)
421 function(*args, **kwargs)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000422
423 def skipTest(self, reason):
424 """Skip this test."""
425 raise SkipTest(reason)
426
427 def fail(self, msg=None):
428 """Fail immediately, with the given message."""
429 raise self.failureException(msg)
430
431 def assertFalse(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000432 """Check that the expression is false."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000433 if expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000434 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000435 raise self.failureException(msg)
436
437 def assertTrue(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000438 """Check that the expression is true."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000439 if not expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000440 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000441 raise self.failureException(msg)
442
443 def _formatMessage(self, msg, standardMsg):
444 """Honour the longMessage attribute when generating failure messages.
445 If longMessage is False this means:
446 * Use only an explicit message if it is provided
447 * Otherwise use the standard message for the assert
448
449 If longMessage is True:
450 * Use the standard message
451 * If an explicit message is provided, plus ' : ' and the explicit message
452 """
453 if not self.longMessage:
454 return msg or standardMsg
455 if msg is None:
456 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000457 try:
458 # don't switch to '{}' formatting in Python 2.X
459 # it changes the way unicode input is handled
460 return '%s : %s' % (standardMsg, msg)
461 except UnicodeDecodeError:
462 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000463
464
465 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
466 """Fail unless an exception of class excClass is thrown
467 by callableObj when invoked with arguments args and keyword
468 arguments kwargs. If a different type of exception is
469 thrown, it will not be caught, and the test case will be
470 deemed to have suffered an error, exactly as for an
471 unexpected exception.
472
473 If called with callableObj omitted or None, will return a
474 context object used like this::
475
Michael Foordd0edec32010-02-05 22:55:09 +0000476 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000477 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000478
479 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000480 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000481 exception after the assertion::
482
483 with self.assertRaises(SomeException) as cm:
484 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000485 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000486 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000487 """
488 context = _AssertRaisesContext(excClass, self)
489 if callableObj is None:
490 return context
491 with context:
492 callableObj(*args, **kwargs)
493
494 def _getAssertEqualityFunc(self, first, second):
495 """Get a detailed comparison function for the types of the two args.
496
497 Returns: A callable accepting (first, second, msg=None) that will
498 raise a failure exception if first != second with a useful human
499 readable error message for those types.
500 """
501 #
502 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
503 # and vice versa. I opted for the conservative approach in case
504 # subclasses are not intended to be compared in detail to their super
505 # class instances using a type equality func. This means testing
506 # subtypes won't automagically use the detailed comparison. Callers
507 # should use their type specific assertSpamEqual method to compare
508 # subclasses if the detailed comparison is desired and appropriate.
509 # See the discussion in http://bugs.python.org/issue2578.
510 #
511 if type(first) is type(second):
512 asserter = self._type_equality_funcs.get(type(first))
513 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000514 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000515
516 return self._baseAssertEqual
517
518 def _baseAssertEqual(self, first, second, msg=None):
519 """The default assertEqual implementation, not type specific."""
520 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000521 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000522 msg = self._formatMessage(msg, standardMsg)
523 raise self.failureException(msg)
524
525 def assertEqual(self, first, second, msg=None):
526 """Fail if the two objects are unequal as determined by the '=='
527 operator.
528 """
529 assertion_func = self._getAssertEqualityFunc(first, second)
530 assertion_func(first, second, msg=msg)
531
532 def assertNotEqual(self, first, second, msg=None):
533 """Fail if the two objects are equal as determined by the '=='
534 operator.
535 """
536 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000537 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
538 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000539 raise self.failureException(msg)
540
Michael Foorda7e08fe2010-03-27 19:10:11 +0000541
542 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000543 """Fail if the two objects are unequal as determined by their
544 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000545 (default 7) and comparing to zero, or by comparing that the
546 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000547
548 Note that decimal places (from zero) are usually not the same
549 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000550
551 If the two objects compare equal then they will automatically
552 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000553 """
Michael Foordc3f79372009-09-13 16:40:02 +0000554 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000555 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000556 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000557 if delta is not None and places is not None:
558 raise TypeError("specify delta or places not both")
559
560 if delta is not None:
561 if abs(first - second) <= delta:
562 return
563
564 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
565 safe_repr(second),
566 safe_repr(delta))
567 else:
568 if places is None:
569 places = 7
570
571 if round(abs(second-first), places) == 0:
572 return
573
Michael Foord225a0992010-02-18 20:30:09 +0000574 standardMsg = '%s != %s within %r places' % (safe_repr(first),
575 safe_repr(second),
576 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000577 msg = self._formatMessage(msg, standardMsg)
578 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000579
Michael Foorda7e08fe2010-03-27 19:10:11 +0000580 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000581 """Fail if the two objects are equal as determined by their
582 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000583 (default 7) and comparing to zero, or by comparing that the
584 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000585
586 Note that decimal places (from zero) are usually not the same
587 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000588
589 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000590 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000591 if delta is not None and places is not None:
592 raise TypeError("specify delta or places not both")
593 if delta is not None:
594 if not (first == second) and abs(first - second) > delta:
595 return
596 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
597 safe_repr(second),
598 safe_repr(delta))
599 else:
600 if places is None:
601 places = 7
602 if not (first == second) and round(abs(second-first), places) != 0:
603 return
Michael Foord225a0992010-02-18 20:30:09 +0000604 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000605 safe_repr(second),
606 places)
607
608 msg = self._formatMessage(msg, standardMsg)
609 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000610
611 # Synonyms for assertion methods
612
613 # The plurals are undocumented. Keep them that way to discourage use.
614 # Do not add more. Do not remove.
615 # Going through a deprecation cycle on these would annoy many people.
616 assertEquals = assertEqual
617 assertNotEquals = assertNotEqual
618 assertAlmostEquals = assertAlmostEqual
619 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000620 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000621
622 # These fail* assertion method names are pending deprecation and will
623 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
624 def _deprecate(original_func):
625 def deprecated_func(*args, **kwargs):
626 warnings.warn(
627 'Please use {0} instead.'.format(original_func.__name__),
628 PendingDeprecationWarning, 2)
629 return original_func(*args, **kwargs)
630 return deprecated_func
631
632 failUnlessEqual = _deprecate(assertEqual)
633 failIfEqual = _deprecate(assertNotEqual)
634 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
635 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
636 failUnless = _deprecate(assertTrue)
637 failUnlessRaises = _deprecate(assertRaises)
638 failIf = _deprecate(assertFalse)
639
Michael Foorde37d75f2010-06-05 12:10:52 +0000640 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000641 """An equality assertion for ordered sequences (like lists and tuples).
642
R. David Murray05b41712010-01-29 19:35:39 +0000643 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000644 which can be indexed, has a length, and has an equality operator.
645
646 Args:
647 seq1: The first sequence to compare.
648 seq2: The second sequence to compare.
649 seq_type: The expected datatype of the sequences, or None if no
650 datatype should be enforced.
651 msg: Optional message to use on failure instead of a list of
652 differences.
653 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000654 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000655 seq_type_name = seq_type.__name__
656 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000657 raise self.failureException('First sequence is not a %s: %s'
658 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000659 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000660 raise self.failureException('Second sequence is not a %s: %s'
661 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000662 else:
663 seq_type_name = "sequence"
664
665 differing = None
666 try:
667 len1 = len(seq1)
668 except (TypeError, NotImplementedError):
669 differing = 'First %s has no length. Non-sequence?' % (
670 seq_type_name)
671
672 if differing is None:
673 try:
674 len2 = len(seq2)
675 except (TypeError, NotImplementedError):
676 differing = 'Second %s has no length. Non-sequence?' % (
677 seq_type_name)
678
679 if differing is None:
680 if seq1 == seq2:
681 return
682
Michael Foord225a0992010-02-18 20:30:09 +0000683 seq1_repr = safe_repr(seq1)
684 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000685 if len(seq1_repr) > 30:
686 seq1_repr = seq1_repr[:30] + '...'
687 if len(seq2_repr) > 30:
688 seq2_repr = seq2_repr[:30] + '...'
689 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
690 differing = '%ss differ: %s != %s\n' % elements
691
692 for i in xrange(min(len1, len2)):
693 try:
694 item1 = seq1[i]
695 except (TypeError, IndexError, NotImplementedError):
696 differing += ('\nUnable to index element %d of first %s\n' %
697 (i, seq_type_name))
698 break
699
700 try:
701 item2 = seq2[i]
702 except (TypeError, IndexError, NotImplementedError):
703 differing += ('\nUnable to index element %d of second %s\n' %
704 (i, seq_type_name))
705 break
706
707 if item1 != item2:
708 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
709 (i, item1, item2))
710 break
711 else:
712 if (len1 == len2 and seq_type is None and
713 type(seq1) != type(seq2)):
714 # The sequences are the same, but have differing types.
715 return
716
717 if len1 > len2:
718 differing += ('\nFirst %s contains %d additional '
719 'elements.\n' % (seq_type_name, len1 - len2))
720 try:
721 differing += ('First extra element %d:\n%s\n' %
722 (len2, seq1[len2]))
723 except (TypeError, IndexError, NotImplementedError):
724 differing += ('Unable to index element %d '
725 'of first %s\n' % (len2, seq_type_name))
726 elif len1 < len2:
727 differing += ('\nSecond %s contains %d additional '
728 'elements.\n' % (seq_type_name, len2 - len1))
729 try:
730 differing += ('First extra element %d:\n%s\n' %
731 (len1, seq2[len1]))
732 except (TypeError, IndexError, NotImplementedError):
733 differing += ('Unable to index element %d '
734 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000735 standardMsg = differing
736 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000737 difflib.ndiff(pprint.pformat(seq1).splitlines(),
738 pprint.pformat(seq2).splitlines()))
Michael Foorde37d75f2010-06-05 12:10:52 +0000739 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000740 msg = self._formatMessage(msg, standardMsg)
741 self.fail(msg)
742
Michael Foorde37d75f2010-06-05 12:10:52 +0000743 def _truncateMessage(self, message, diff):
744 max_diff = self.maxDiff
Michael Foorda4412872010-06-05 11:46:59 +0000745 if max_diff is None or len(diff) <= max_diff:
746 return message + diff
Michael Foord5fe21ff2010-06-05 13:38:16 +0000747 return message + (DIFF_OMITTED % len(diff))
Michael Foorda4412872010-06-05 11:46:59 +0000748
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000749 def assertListEqual(self, list1, list2, msg=None):
750 """A list-specific equality assertion.
751
752 Args:
753 list1: The first list to compare.
754 list2: The second list to compare.
755 msg: Optional message to use on failure instead of a list of
756 differences.
757
758 """
759 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
760
761 def assertTupleEqual(self, tuple1, tuple2, msg=None):
762 """A tuple-specific equality assertion.
763
764 Args:
765 tuple1: The first tuple to compare.
766 tuple2: The second tuple to compare.
767 msg: Optional message to use on failure instead of a list of
768 differences.
769 """
770 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
771
772 def assertSetEqual(self, set1, set2, msg=None):
773 """A set-specific equality assertion.
774
775 Args:
776 set1: The first set to compare.
777 set2: The second set to compare.
778 msg: Optional message to use on failure instead of a list of
779 differences.
780
Michael Foord98e7b762010-03-20 03:00:34 +0000781 assertSetEqual uses ducktyping to support different types of sets, and
782 is optimized for sets specifically (parameters must support a
783 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000784 """
785 try:
786 difference1 = set1.difference(set2)
787 except TypeError, e:
788 self.fail('invalid type when attempting set difference: %s' % e)
789 except AttributeError, e:
790 self.fail('first argument does not support set difference: %s' % e)
791
792 try:
793 difference2 = set2.difference(set1)
794 except TypeError, e:
795 self.fail('invalid type when attempting set difference: %s' % e)
796 except AttributeError, e:
797 self.fail('second argument does not support set difference: %s' % e)
798
799 if not (difference1 or difference2):
800 return
801
802 lines = []
803 if difference1:
804 lines.append('Items in the first set but not the second:')
805 for item in difference1:
806 lines.append(repr(item))
807 if difference2:
808 lines.append('Items in the second set but not the first:')
809 for item in difference2:
810 lines.append(repr(item))
811
812 standardMsg = '\n'.join(lines)
813 self.fail(self._formatMessage(msg, standardMsg))
814
815 def assertIn(self, member, container, msg=None):
816 """Just like self.assertTrue(a in b), but with a nicer default message."""
817 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000818 standardMsg = '%s not found in %s' % (safe_repr(member),
819 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000820 self.fail(self._formatMessage(msg, standardMsg))
821
822 def assertNotIn(self, member, container, msg=None):
823 """Just like self.assertTrue(a not in b), but with a nicer default message."""
824 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000825 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
826 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000827 self.fail(self._formatMessage(msg, standardMsg))
828
829 def assertIs(self, expr1, expr2, msg=None):
830 """Just like self.assertTrue(a is b), but with a nicer default message."""
831 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000832 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000833 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000834 self.fail(self._formatMessage(msg, standardMsg))
835
836 def assertIsNot(self, expr1, expr2, msg=None):
837 """Just like self.assertTrue(a is not b), but with a nicer default message."""
838 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000839 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000840 self.fail(self._formatMessage(msg, standardMsg))
841
842 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melotti2623a372010-11-21 13:34:58 +0000843 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
844 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000845
846 if d1 != d2:
Michael Foord674648e2010-06-05 12:58:39 +0000847 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foorde37d75f2010-06-05 12:10:52 +0000848 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000849 pprint.pformat(d1).splitlines(),
850 pprint.pformat(d2).splitlines())))
Michael Foord674648e2010-06-05 12:58:39 +0000851 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000852 self.fail(self._formatMessage(msg, standardMsg))
853
854 def assertDictContainsSubset(self, expected, actual, msg=None):
855 """Checks whether actual is a superset of expected."""
856 missing = []
857 mismatched = []
858 for key, value in expected.iteritems():
859 if key not in actual:
860 missing.append(key)
861 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000862 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000863 (safe_repr(key), safe_repr(value),
864 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000865
866 if not (missing or mismatched):
867 return
868
869 standardMsg = ''
870 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000871 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
872 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000873 if mismatched:
874 if standardMsg:
875 standardMsg += '; '
876 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
877
878 self.fail(self._formatMessage(msg, standardMsg))
879
Michael Foord98e7b762010-03-20 03:00:34 +0000880 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
Michael Foorde6e0e262010-12-19 15:52:56 +0000881 """An unordered sequence specific comparison. It asserts that
882 actual_seq and expected_seq have the same element counts.
883 Equivalent to::
Michael Foord98e7b762010-03-20 03:00:34 +0000884
Michael Foorde6e0e262010-12-19 15:52:56 +0000885 self.assertEqual(Counter(iter(actual_seq)),
886 Counter(iter(expected_seq)))
Michael Foordd0edec32010-02-05 22:55:09 +0000887
Michael Foord98e7b762010-03-20 03:00:34 +0000888 Asserts that each element has the same count in both sequences.
889 Example:
890 - [0, 1, 1] and [1, 0, 1] compare equal.
891 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000892 """
Michael Foord4c9e91a2011-03-16 20:34:53 -0400893 first_seq, second_seq = list(actual_seq), list(expected_seq)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000894 with warnings.catch_warnings():
895 if sys.py3kwarning:
896 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000897 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000898 "builtin_function_or_method order comparisons",
899 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000900 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000901 try:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400902 first = collections.Counter(first_seq)
903 second = collections.Counter(second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000904 except TypeError:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400905 # Handle case with unhashable elements
906 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000907 else:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400908 if first == second:
Michael Foorde6e0e262010-12-19 15:52:56 +0000909 return
Michael Foord4c9e91a2011-03-16 20:34:53 -0400910 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000911
Michael Foord4c9e91a2011-03-16 20:34:53 -0400912 if differences:
913 standardMsg = 'Element counts were not equal:\n'
914 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
915 diffMsg = '\n'.join(lines)
916 standardMsg = self._truncateMessage(standardMsg, diffMsg)
917 msg = self._formatMessage(msg, standardMsg)
918 self.fail(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000919
920 def assertMultiLineEqual(self, first, second, msg=None):
921 """Assert that two multi-line strings are equal."""
Ezio Melotti2623a372010-11-21 13:34:58 +0000922 self.assertIsInstance(first, basestring,
923 'First argument is not a string')
924 self.assertIsInstance(second, basestring,
925 'Second argument is not a string')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000926
927 if first != second:
Ezio Melotti34b32d62011-04-27 09:45:46 +0300928 # don't use difflib if the strings are too long
929 if (len(first) > self._diffThreshold or
930 len(second) > self._diffThreshold):
931 self._baseAssertEqual(first, second, msg)
Michael Foord94f071c2010-07-10 13:51:42 +0000932 firstlines = first.splitlines(True)
933 secondlines = second.splitlines(True)
934 if len(firstlines) == 1 and first.strip('\r\n') == first:
935 firstlines = [first + '\n']
936 secondlines = [second + '\n']
937 standardMsg = '%s != %s' % (safe_repr(first, True),
938 safe_repr(second, True))
939 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foord674648e2010-06-05 12:58:39 +0000940 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000941 self.fail(self._formatMessage(msg, standardMsg))
942
943 def assertLess(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 less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000947 self.fail(self._formatMessage(msg, standardMsg))
948
949 def assertLessEqual(self, a, b, msg=None):
950 """Just like self.assertTrue(a <= b), but with a nicer default message."""
951 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000952 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000953 self.fail(self._formatMessage(msg, standardMsg))
954
955 def assertGreater(self, a, b, msg=None):
956 """Just like self.assertTrue(a > b), but with a nicer default message."""
957 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000958 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000959 self.fail(self._formatMessage(msg, standardMsg))
960
961 def assertGreaterEqual(self, a, b, msg=None):
962 """Just like self.assertTrue(a >= b), but with a nicer default message."""
963 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000964 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000965 self.fail(self._formatMessage(msg, standardMsg))
966
967 def assertIsNone(self, obj, msg=None):
968 """Same as self.assertTrue(obj is None), with a nicer default message."""
969 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000970 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000971 self.fail(self._formatMessage(msg, standardMsg))
972
973 def assertIsNotNone(self, obj, msg=None):
974 """Included for symmetry with assertIsNone."""
975 if obj is None:
976 standardMsg = 'unexpectedly None'
977 self.fail(self._formatMessage(msg, standardMsg))
978
Georg Brandlf895cf52009-10-01 20:59:31 +0000979 def assertIsInstance(self, obj, cls, msg=None):
980 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
981 default message."""
982 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000983 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000984 self.fail(self._formatMessage(msg, standardMsg))
985
986 def assertNotIsInstance(self, obj, cls, msg=None):
987 """Included for symmetry with assertIsInstance."""
988 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000989 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000990 self.fail(self._formatMessage(msg, standardMsg))
991
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000992 def assertRaisesRegexp(self, expected_exception, expected_regexp,
993 callable_obj=None, *args, **kwargs):
994 """Asserts that the message in a raised exception matches a regexp.
995
996 Args:
997 expected_exception: Exception class expected to be raised.
998 expected_regexp: Regexp (re pattern object or string) expected
999 to be found in error message.
1000 callable_obj: Function to be called.
1001 args: Extra args.
1002 kwargs: Extra kwargs.
1003 """
1004 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
1005 if callable_obj is None:
1006 return context
1007 with context:
1008 callable_obj(*args, **kwargs)
1009
Georg Brandlb0eb4d32010-02-07 11:34:15 +00001010 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +00001011 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +00001012 if isinstance(expected_regexp, basestring):
1013 expected_regexp = re.compile(expected_regexp)
1014 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001015 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +00001016 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001017 raise self.failureException(msg)
1018
Michael Foorda04c7a02010-04-02 22:55:59 +00001019 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +00001020 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +00001021 if isinstance(unexpected_regexp, basestring):
1022 unexpected_regexp = re.compile(unexpected_regexp)
1023 match = unexpected_regexp.search(text)
1024 if match:
1025 msg = msg or "Regexp matched"
1026 msg = '%s: %r matches %r in %r' % (msg,
1027 text[match.start():match.end()],
1028 unexpected_regexp.pattern,
1029 text)
1030 raise self.failureException(msg)
1031
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001032
1033class FunctionTestCase(TestCase):
1034 """A test case that wraps a test function.
1035
1036 This is useful for slipping pre-existing test functions into the
1037 unittest framework. Optionally, set-up and tidy-up functions can be
1038 supplied. As with TestCase, the tidy-up ('tearDown') function will
1039 always be called if the set-up ('setUp') function ran successfully.
1040 """
1041
1042 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1043 super(FunctionTestCase, self).__init__()
1044 self._setUpFunc = setUp
1045 self._tearDownFunc = tearDown
1046 self._testFunc = testFunc
1047 self._description = description
1048
1049 def setUp(self):
1050 if self._setUpFunc is not None:
1051 self._setUpFunc()
1052
1053 def tearDown(self):
1054 if self._tearDownFunc is not None:
1055 self._tearDownFunc()
1056
1057 def runTest(self):
1058 self._testFunc()
1059
1060 def id(self):
1061 return self._testFunc.__name__
1062
1063 def __eq__(self, other):
1064 if not isinstance(other, self.__class__):
1065 return NotImplemented
1066
1067 return self._setUpFunc == other._setUpFunc and \
1068 self._tearDownFunc == other._tearDownFunc and \
1069 self._testFunc == other._testFunc and \
1070 self._description == other._description
1071
1072 def __ne__(self, other):
1073 return not self == other
1074
1075 def __hash__(self):
1076 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1077 self._testFunc, self._description))
1078
1079 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001080 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001081 self._testFunc.__name__)
1082
1083 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001084 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001085 self._testFunc)
1086
1087 def shortDescription(self):
1088 if self._description is not None:
1089 return self._description
1090 doc = self._testFunc.__doc__
1091 return doc and doc.split("\n")[0].strip() or None