blob: 4b3839e95c26508d9b2dfc0b8a7c6e5585148df1 [file] [log] [blame]
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001"""Test case implementation"""
2
Michael Foorde6e0e262010-12-19 15:52:56 +00003import collections
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00004import sys
5import functools
6import difflib
7import pprint
8import re
9import warnings
10
Michael Foord225a0992010-02-18 20:30:09 +000011from . import result
Michael Foord98e7b762010-03-20 03:00:34 +000012from .util import (
Michael Foord4c9e91a2011-03-16 20:34:53 -040013 strclass, safe_repr, unorderable_list_difference,
14 _count_diff_all_purpose, _count_diff_hashable
Michael Foord98e7b762010-03-20 03:00:34 +000015)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000016
Michael Foord4c9e91a2011-03-16 20:34:53 -040017
Michael Foordb1aa30f2010-03-22 00:06:30 +000018__unittest = True
Michael Foordb1aa30f2010-03-22 00:06:30 +000019
Michael Foord5fe21ff2010-06-05 13:38:16 +000020
21DIFF_OMITTED = ('\nDiff is %s characters long. '
22 'Set self.maxDiff to None to see it.')
23
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000024class SkipTest(Exception):
25 """
26 Raise this exception in a test to skip it.
27
28 Usually you can use TestResult.skip() or one of the skipping decorators
29 instead of raising this directly.
30 """
31 pass
32
33class _ExpectedFailure(Exception):
34 """
35 Raise this when a test is expected to fail.
36
37 This is an implementation detail.
38 """
39
40 def __init__(self, exc_info):
41 super(_ExpectedFailure, self).__init__()
42 self.exc_info = exc_info
43
44class _UnexpectedSuccess(Exception):
45 """
46 The test was supposed to fail, but it didn't!
47 """
48 pass
49
50def _id(obj):
51 return obj
52
53def skip(reason):
54 """
55 Unconditionally skip a test.
56 """
57 def decorator(test_item):
Michael Foord53e8eea2010-03-07 20:22:12 +000058 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
59 @functools.wraps(test_item)
60 def skip_wrapper(*args, **kwargs):
61 raise SkipTest(reason)
62 test_item = skip_wrapper
63
64 test_item.__unittest_skip__ = True
65 test_item.__unittest_skip_why__ = reason
66 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000067 return decorator
68
69def skipIf(condition, reason):
70 """
71 Skip a test if the condition is true.
72 """
73 if condition:
74 return skip(reason)
75 return _id
76
77def skipUnless(condition, reason):
78 """
79 Skip a test unless the condition is true.
80 """
81 if not condition:
82 return skip(reason)
83 return _id
84
85
86def expectedFailure(func):
87 @functools.wraps(func)
88 def wrapper(*args, **kwargs):
89 try:
90 func(*args, **kwargs)
91 except Exception:
92 raise _ExpectedFailure(sys.exc_info())
93 raise _UnexpectedSuccess
94 return wrapper
95
96
97class _AssertRaisesContext(object):
98 """A context manager used to implement TestCase.assertRaises* methods."""
99
100 def __init__(self, expected, test_case, expected_regexp=None):
101 self.expected = expected
102 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000103 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000104
105 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +0000106 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000107
108 def __exit__(self, exc_type, exc_value, tb):
109 if exc_type is None:
110 try:
111 exc_name = self.expected.__name__
112 except AttributeError:
113 exc_name = str(self.expected)
114 raise self.failureException(
115 "{0} not raised".format(exc_name))
116 if not issubclass(exc_type, self.expected):
117 # let unexpected exceptions pass through
118 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000119 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000120 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000121 return True
122
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000123 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000124 if isinstance(expected_regexp, basestring):
125 expected_regexp = re.compile(expected_regexp)
126 if not expected_regexp.search(str(exc_value)):
127 raise self.failureException('"%s" does not match "%s"' %
128 (expected_regexp.pattern, str(exc_value)))
129 return True
130
131
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000132class TestCase(object):
133 """A class whose instances are single test cases.
134
135 By default, the test code itself should be placed in a method named
136 'runTest'.
137
138 If the fixture may be used for many test cases, create as
139 many test methods as are needed. When instantiating such a TestCase
140 subclass, specify in the constructor arguments the name of the test method
141 that the instance is to execute.
142
143 Test authors should subclass TestCase for their own tests. Construction
144 and deconstruction of the test's environment ('fixture') can be
145 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
146
147 If it is necessary to override the __init__ method, the base class
148 __init__ method must always be called. It is important that subclasses
149 should not change the signature of their __init__ method, since instances
150 of the classes are instantiated automatically by parts of the framework
151 in order to be run.
152 """
153
154 # This attribute determines which exception will be raised when
155 # the instance's assertion methods fail; test methods raising this
156 # exception will be deemed to have 'failed' rather than 'errored'
157
158 failureException = AssertionError
159
160 # This attribute determines whether long messages (including repr of
161 # objects used in assert methods) will be printed on failure in *addition*
162 # to any explicit message passed.
163
164 longMessage = False
165
Michael Foordae1bb9a2010-06-09 12:29:56 +0000166 # This attribute sets the maximum length of a diff in failure messages
Michael Foorde37d75f2010-06-05 12:10:52 +0000167 # by assert methods using difflib. It is looked up as an instance attribute
168 # so can be configured by individual tests if required.
Michael Foordc532c572010-06-05 23:58:40 +0000169
Michael Foorde37d75f2010-06-05 12:10:52 +0000170 maxDiff = 80*8
171
Ezio Melotti34b32d62011-04-27 09:45:46 +0300172 # If a string is longer than _diffThreshold, use normal comparison instead
173 # of difflib. See #11763.
174 _diffThreshold = 2**16
175
Michael Foord5ffa3252010-03-07 22:04:55 +0000176 # Attribute used by TestSuite for classSetUp
177
178 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000179
180 def __init__(self, methodName='runTest'):
181 """Create an instance of the class that will use the named test
182 method when executed. Raises a ValueError if the instance does
183 not have a method with the specified name.
184 """
185 self._testMethodName = methodName
186 self._resultForDoCleanups = None
187 try:
188 testMethod = getattr(self, methodName)
189 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000190 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000191 (self.__class__, methodName))
192 self._testMethodDoc = testMethod.__doc__
193 self._cleanups = []
194
195 # Map types to custom assertEqual functions that will compare
196 # instances of said type in more detail to generate a more useful
197 # error message.
Benjamin Peterson83c14fe2011-07-12 19:21:42 -0500198 self._type_equality_funcs = {}
Raymond Hettinger67a3e832011-06-25 12:16:25 +0200199 self.addTypeEqualityFunc(dict, 'assertDictEqual')
200 self.addTypeEqualityFunc(list, 'assertListEqual')
201 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
202 self.addTypeEqualityFunc(set, 'assertSetEqual')
203 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
204 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000205
206 def addTypeEqualityFunc(self, typeobj, function):
207 """Add a type specific assertEqual style function to compare a type.
208
209 This method is for use by TestCase subclasses that need to register
210 their own type equality functions to provide nicer error messages.
211
212 Args:
213 typeobj: The data type to call this function on when both values
214 are of the same type in assertEqual().
215 function: The callable taking two arguments and an optional
216 msg= argument that raises self.failureException with a
217 useful error message when the two arguments are not equal.
218 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000219 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000220
221 def addCleanup(self, function, *args, **kwargs):
222 """Add a function, with arguments, to be called when the test is
223 completed. Functions added are called on a LIFO basis and are
224 called after tearDown on test failure or success.
225
226 Cleanup items are called even if setUp fails (unlike tearDown)."""
227 self._cleanups.append((function, args, kwargs))
228
229 def setUp(self):
230 "Hook method for setting up the test fixture before exercising it."
231 pass
232
233 def tearDown(self):
234 "Hook method for deconstructing the test fixture after testing it."
235 pass
236
Michael Foord5ffa3252010-03-07 22:04:55 +0000237 @classmethod
238 def setUpClass(cls):
239 "Hook method for setting up class fixture before running tests in the class."
240
241 @classmethod
242 def tearDownClass(cls):
243 "Hook method for deconstructing the class fixture after running all tests in the class."
244
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000245 def countTestCases(self):
246 return 1
247
248 def defaultTestResult(self):
249 return result.TestResult()
250
251 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000252 """Returns a one-line description of the test, or None if no
253 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000254
Michael Foorddb43b5a2010-02-10 14:25:12 +0000255 The default implementation of this method returns the first line of
256 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000257 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000258 doc = self._testMethodDoc
259 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000260
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000261
262 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000263 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000264
265 def __eq__(self, other):
266 if type(self) is not type(other):
267 return NotImplemented
268
269 return self._testMethodName == other._testMethodName
270
271 def __ne__(self, other):
272 return not self == other
273
274 def __hash__(self):
275 return hash((type(self), self._testMethodName))
276
277 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000278 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000279
280 def __repr__(self):
281 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000282 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000283
Michael Foordae3db0a2010-02-22 23:28:32 +0000284 def _addSkip(self, result, reason):
285 addSkip = getattr(result, 'addSkip', None)
286 if addSkip is not None:
287 addSkip(self, reason)
288 else:
289 warnings.warn("TestResult has no addSkip method, skips not reported",
290 RuntimeWarning, 2)
291 result.addSuccess(self)
292
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000293 def run(self, result=None):
294 orig_result = result
295 if result is None:
296 result = self.defaultTestResult()
297 startTestRun = getattr(result, 'startTestRun', None)
298 if startTestRun is not None:
299 startTestRun()
300
301 self._resultForDoCleanups = result
302 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000303
304 testMethod = getattr(self, self._testMethodName)
305 if (getattr(self.__class__, "__unittest_skip__", False) or
306 getattr(testMethod, "__unittest_skip__", False)):
307 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000308 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000309 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
310 or getattr(testMethod, '__unittest_skip_why__', ''))
311 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000312 finally:
313 result.stopTest(self)
314 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000315 try:
316 success = False
317 try:
318 self.setUp()
319 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000320 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000321 except KeyboardInterrupt:
322 raise
323 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000324 result.addError(self, sys.exc_info())
325 else:
326 try:
327 testMethod()
Michael Foorda17f0762010-12-19 14:53:19 +0000328 except KeyboardInterrupt:
329 raise
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000330 except self.failureException:
331 result.addFailure(self, sys.exc_info())
332 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000333 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
334 if addExpectedFailure is not None:
335 addExpectedFailure(self, e.exc_info)
336 else:
337 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
338 RuntimeWarning)
339 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000340 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000341 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
342 if addUnexpectedSuccess is not None:
343 addUnexpectedSuccess(self)
344 else:
345 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
346 RuntimeWarning)
347 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000348 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000349 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000350 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000351 result.addError(self, sys.exc_info())
352 else:
353 success = True
354
355 try:
356 self.tearDown()
Michael Foorda17f0762010-12-19 14:53:19 +0000357 except KeyboardInterrupt:
358 raise
359 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000360 result.addError(self, sys.exc_info())
361 success = False
362
363 cleanUpSuccess = self.doCleanups()
364 success = success and cleanUpSuccess
365 if success:
366 result.addSuccess(self)
367 finally:
368 result.stopTest(self)
369 if orig_result is None:
370 stopTestRun = getattr(result, 'stopTestRun', None)
371 if stopTestRun is not None:
372 stopTestRun()
373
374 def doCleanups(self):
375 """Execute all cleanup functions. Normally called for you after
376 tearDown."""
377 result = self._resultForDoCleanups
378 ok = True
379 while self._cleanups:
380 function, args, kwargs = self._cleanups.pop(-1)
381 try:
382 function(*args, **kwargs)
Michael Foorda17f0762010-12-19 14:53:19 +0000383 except KeyboardInterrupt:
384 raise
385 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000386 ok = False
387 result.addError(self, sys.exc_info())
388 return ok
389
390 def __call__(self, *args, **kwds):
391 return self.run(*args, **kwds)
392
393 def debug(self):
394 """Run the test without collecting errors in a TestResult"""
395 self.setUp()
396 getattr(self, self._testMethodName)()
397 self.tearDown()
Michael Foord0fedb282010-06-08 22:44:52 +0000398 while self._cleanups:
399 function, args, kwargs = self._cleanups.pop(-1)
400 function(*args, **kwargs)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000401
402 def skipTest(self, reason):
403 """Skip this test."""
404 raise SkipTest(reason)
405
406 def fail(self, msg=None):
407 """Fail immediately, with the given message."""
408 raise self.failureException(msg)
409
410 def assertFalse(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000411 """Check that the expression is false."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000412 if expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000413 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000414 raise self.failureException(msg)
415
416 def assertTrue(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000417 """Check that the expression is true."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000418 if not expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000419 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000420 raise self.failureException(msg)
421
422 def _formatMessage(self, msg, standardMsg):
423 """Honour the longMessage attribute when generating failure messages.
424 If longMessage is False this means:
425 * Use only an explicit message if it is provided
426 * Otherwise use the standard message for the assert
427
428 If longMessage is True:
429 * Use the standard message
430 * If an explicit message is provided, plus ' : ' and the explicit message
431 """
432 if not self.longMessage:
433 return msg or standardMsg
434 if msg is None:
435 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000436 try:
437 # don't switch to '{}' formatting in Python 2.X
438 # it changes the way unicode input is handled
439 return '%s : %s' % (standardMsg, msg)
440 except UnicodeDecodeError:
441 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000442
443
444 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
445 """Fail unless an exception of class excClass is thrown
446 by callableObj when invoked with arguments args and keyword
447 arguments kwargs. If a different type of exception is
448 thrown, it will not be caught, and the test case will be
449 deemed to have suffered an error, exactly as for an
450 unexpected exception.
451
452 If called with callableObj omitted or None, will return a
453 context object used like this::
454
Michael Foordd0edec32010-02-05 22:55:09 +0000455 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000456 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000457
458 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000459 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000460 exception after the assertion::
461
462 with self.assertRaises(SomeException) as cm:
463 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000464 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000465 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000466 """
467 context = _AssertRaisesContext(excClass, self)
468 if callableObj is None:
469 return context
470 with context:
471 callableObj(*args, **kwargs)
472
473 def _getAssertEqualityFunc(self, first, second):
474 """Get a detailed comparison function for the types of the two args.
475
476 Returns: A callable accepting (first, second, msg=None) that will
477 raise a failure exception if first != second with a useful human
478 readable error message for those types.
479 """
480 #
481 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
482 # and vice versa. I opted for the conservative approach in case
483 # subclasses are not intended to be compared in detail to their super
484 # class instances using a type equality func. This means testing
485 # subtypes won't automagically use the detailed comparison. Callers
486 # should use their type specific assertSpamEqual method to compare
487 # subclasses if the detailed comparison is desired and appropriate.
488 # See the discussion in http://bugs.python.org/issue2578.
489 #
490 if type(first) is type(second):
491 asserter = self._type_equality_funcs.get(type(first))
492 if asserter is not None:
Benjamin Peterson83c14fe2011-07-12 19:21:42 -0500493 if isinstance(asserter, basestring):
494 asserter = getattr(self, asserter)
Benjamin Petersond46430b2009-11-29 22:26:26 +0000495 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000496
497 return self._baseAssertEqual
498
499 def _baseAssertEqual(self, first, second, msg=None):
500 """The default assertEqual implementation, not type specific."""
501 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000502 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000503 msg = self._formatMessage(msg, standardMsg)
504 raise self.failureException(msg)
505
506 def assertEqual(self, first, second, msg=None):
507 """Fail if the two objects are unequal as determined by the '=='
508 operator.
509 """
510 assertion_func = self._getAssertEqualityFunc(first, second)
511 assertion_func(first, second, msg=msg)
512
513 def assertNotEqual(self, first, second, msg=None):
514 """Fail if the two objects are equal as determined by the '=='
515 operator.
516 """
517 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000518 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
519 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000520 raise self.failureException(msg)
521
Michael Foorda7e08fe2010-03-27 19:10:11 +0000522
523 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000524 """Fail if the two objects are unequal as determined by their
525 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000526 (default 7) and comparing to zero, or by comparing that the
527 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000528
529 Note that decimal places (from zero) are usually not the same
530 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000531
532 If the two objects compare equal then they will automatically
533 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000534 """
Michael Foordc3f79372009-09-13 16:40:02 +0000535 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000536 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000537 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000538 if delta is not None and places is not None:
539 raise TypeError("specify delta or places not both")
540
541 if delta is not None:
542 if abs(first - second) <= delta:
543 return
544
545 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
546 safe_repr(second),
547 safe_repr(delta))
548 else:
549 if places is None:
550 places = 7
551
552 if round(abs(second-first), places) == 0:
553 return
554
Michael Foord225a0992010-02-18 20:30:09 +0000555 standardMsg = '%s != %s within %r places' % (safe_repr(first),
556 safe_repr(second),
557 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000558 msg = self._formatMessage(msg, standardMsg)
559 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000560
Michael Foorda7e08fe2010-03-27 19:10:11 +0000561 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000562 """Fail if the two objects are equal as determined by their
563 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000564 (default 7) and comparing to zero, or by comparing that the
565 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000566
567 Note that decimal places (from zero) are usually not the same
568 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000569
570 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000571 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000572 if delta is not None and places is not None:
573 raise TypeError("specify delta or places not both")
574 if delta is not None:
575 if not (first == second) and abs(first - second) > delta:
576 return
577 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
578 safe_repr(second),
579 safe_repr(delta))
580 else:
581 if places is None:
582 places = 7
583 if not (first == second) and round(abs(second-first), places) != 0:
584 return
Michael Foord225a0992010-02-18 20:30:09 +0000585 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000586 safe_repr(second),
587 places)
588
589 msg = self._formatMessage(msg, standardMsg)
590 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000591
592 # Synonyms for assertion methods
593
594 # The plurals are undocumented. Keep them that way to discourage use.
595 # Do not add more. Do not remove.
596 # Going through a deprecation cycle on these would annoy many people.
597 assertEquals = assertEqual
598 assertNotEquals = assertNotEqual
599 assertAlmostEquals = assertAlmostEqual
600 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000601 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000602
603 # These fail* assertion method names are pending deprecation and will
604 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
605 def _deprecate(original_func):
606 def deprecated_func(*args, **kwargs):
607 warnings.warn(
608 'Please use {0} instead.'.format(original_func.__name__),
609 PendingDeprecationWarning, 2)
610 return original_func(*args, **kwargs)
611 return deprecated_func
612
613 failUnlessEqual = _deprecate(assertEqual)
614 failIfEqual = _deprecate(assertNotEqual)
615 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
616 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
617 failUnless = _deprecate(assertTrue)
618 failUnlessRaises = _deprecate(assertRaises)
619 failIf = _deprecate(assertFalse)
620
Michael Foorde37d75f2010-06-05 12:10:52 +0000621 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000622 """An equality assertion for ordered sequences (like lists and tuples).
623
R. David Murray05b41712010-01-29 19:35:39 +0000624 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000625 which can be indexed, has a length, and has an equality operator.
626
627 Args:
628 seq1: The first sequence to compare.
629 seq2: The second sequence to compare.
630 seq_type: The expected datatype of the sequences, or None if no
631 datatype should be enforced.
632 msg: Optional message to use on failure instead of a list of
633 differences.
634 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000635 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000636 seq_type_name = seq_type.__name__
637 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000638 raise self.failureException('First sequence is not a %s: %s'
639 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000640 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000641 raise self.failureException('Second sequence is not a %s: %s'
642 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000643 else:
644 seq_type_name = "sequence"
645
646 differing = None
647 try:
648 len1 = len(seq1)
649 except (TypeError, NotImplementedError):
650 differing = 'First %s has no length. Non-sequence?' % (
651 seq_type_name)
652
653 if differing is None:
654 try:
655 len2 = len(seq2)
656 except (TypeError, NotImplementedError):
657 differing = 'Second %s has no length. Non-sequence?' % (
658 seq_type_name)
659
660 if differing is None:
661 if seq1 == seq2:
662 return
663
Michael Foord225a0992010-02-18 20:30:09 +0000664 seq1_repr = safe_repr(seq1)
665 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000666 if len(seq1_repr) > 30:
667 seq1_repr = seq1_repr[:30] + '...'
668 if len(seq2_repr) > 30:
669 seq2_repr = seq2_repr[:30] + '...'
670 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
671 differing = '%ss differ: %s != %s\n' % elements
672
673 for i in xrange(min(len1, len2)):
674 try:
675 item1 = seq1[i]
676 except (TypeError, IndexError, NotImplementedError):
677 differing += ('\nUnable to index element %d of first %s\n' %
678 (i, seq_type_name))
679 break
680
681 try:
682 item2 = seq2[i]
683 except (TypeError, IndexError, NotImplementedError):
684 differing += ('\nUnable to index element %d of second %s\n' %
685 (i, seq_type_name))
686 break
687
688 if item1 != item2:
689 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
690 (i, item1, item2))
691 break
692 else:
693 if (len1 == len2 and seq_type is None and
694 type(seq1) != type(seq2)):
695 # The sequences are the same, but have differing types.
696 return
697
698 if len1 > len2:
699 differing += ('\nFirst %s contains %d additional '
700 'elements.\n' % (seq_type_name, len1 - len2))
701 try:
702 differing += ('First extra element %d:\n%s\n' %
703 (len2, seq1[len2]))
704 except (TypeError, IndexError, NotImplementedError):
705 differing += ('Unable to index element %d '
706 'of first %s\n' % (len2, seq_type_name))
707 elif len1 < len2:
708 differing += ('\nSecond %s contains %d additional '
709 'elements.\n' % (seq_type_name, len2 - len1))
710 try:
711 differing += ('First extra element %d:\n%s\n' %
712 (len1, seq2[len1]))
713 except (TypeError, IndexError, NotImplementedError):
714 differing += ('Unable to index element %d '
715 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000716 standardMsg = differing
717 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000718 difflib.ndiff(pprint.pformat(seq1).splitlines(),
719 pprint.pformat(seq2).splitlines()))
Michael Foorde37d75f2010-06-05 12:10:52 +0000720 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000721 msg = self._formatMessage(msg, standardMsg)
722 self.fail(msg)
723
Michael Foorde37d75f2010-06-05 12:10:52 +0000724 def _truncateMessage(self, message, diff):
725 max_diff = self.maxDiff
Michael Foorda4412872010-06-05 11:46:59 +0000726 if max_diff is None or len(diff) <= max_diff:
727 return message + diff
Michael Foord5fe21ff2010-06-05 13:38:16 +0000728 return message + (DIFF_OMITTED % len(diff))
Michael Foorda4412872010-06-05 11:46:59 +0000729
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000730 def assertListEqual(self, list1, list2, msg=None):
731 """A list-specific equality assertion.
732
733 Args:
734 list1: The first list to compare.
735 list2: The second list to compare.
736 msg: Optional message to use on failure instead of a list of
737 differences.
738
739 """
740 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
741
742 def assertTupleEqual(self, tuple1, tuple2, msg=None):
743 """A tuple-specific equality assertion.
744
745 Args:
746 tuple1: The first tuple to compare.
747 tuple2: The second tuple to compare.
748 msg: Optional message to use on failure instead of a list of
749 differences.
750 """
751 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
752
753 def assertSetEqual(self, set1, set2, msg=None):
754 """A set-specific equality assertion.
755
756 Args:
757 set1: The first set to compare.
758 set2: The second set to compare.
759 msg: Optional message to use on failure instead of a list of
760 differences.
761
Michael Foord98e7b762010-03-20 03:00:34 +0000762 assertSetEqual uses ducktyping to support different types of sets, and
763 is optimized for sets specifically (parameters must support a
764 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000765 """
766 try:
767 difference1 = set1.difference(set2)
768 except TypeError, e:
769 self.fail('invalid type when attempting set difference: %s' % e)
770 except AttributeError, e:
771 self.fail('first argument does not support set difference: %s' % e)
772
773 try:
774 difference2 = set2.difference(set1)
775 except TypeError, e:
776 self.fail('invalid type when attempting set difference: %s' % e)
777 except AttributeError, e:
778 self.fail('second argument does not support set difference: %s' % e)
779
780 if not (difference1 or difference2):
781 return
782
783 lines = []
784 if difference1:
785 lines.append('Items in the first set but not the second:')
786 for item in difference1:
787 lines.append(repr(item))
788 if difference2:
789 lines.append('Items in the second set but not the first:')
790 for item in difference2:
791 lines.append(repr(item))
792
793 standardMsg = '\n'.join(lines)
794 self.fail(self._formatMessage(msg, standardMsg))
795
796 def assertIn(self, member, container, msg=None):
797 """Just like self.assertTrue(a in b), but with a nicer default message."""
798 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000799 standardMsg = '%s not found in %s' % (safe_repr(member),
800 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000801 self.fail(self._formatMessage(msg, standardMsg))
802
803 def assertNotIn(self, member, container, msg=None):
804 """Just like self.assertTrue(a not in b), but with a nicer default message."""
805 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000806 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
807 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000808 self.fail(self._formatMessage(msg, standardMsg))
809
810 def assertIs(self, expr1, expr2, msg=None):
811 """Just like self.assertTrue(a is b), but with a nicer default message."""
812 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000813 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000814 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000815 self.fail(self._formatMessage(msg, standardMsg))
816
817 def assertIsNot(self, expr1, expr2, msg=None):
818 """Just like self.assertTrue(a is not b), but with a nicer default message."""
819 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000820 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000821 self.fail(self._formatMessage(msg, standardMsg))
822
823 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melotti2623a372010-11-21 13:34:58 +0000824 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
825 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000826
827 if d1 != d2:
Michael Foord674648e2010-06-05 12:58:39 +0000828 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foorde37d75f2010-06-05 12:10:52 +0000829 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000830 pprint.pformat(d1).splitlines(),
831 pprint.pformat(d2).splitlines())))
Michael Foord674648e2010-06-05 12:58:39 +0000832 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000833 self.fail(self._formatMessage(msg, standardMsg))
834
835 def assertDictContainsSubset(self, expected, actual, msg=None):
836 """Checks whether actual is a superset of expected."""
837 missing = []
838 mismatched = []
839 for key, value in expected.iteritems():
840 if key not in actual:
841 missing.append(key)
842 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000843 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000844 (safe_repr(key), safe_repr(value),
845 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000846
847 if not (missing or mismatched):
848 return
849
850 standardMsg = ''
851 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000852 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
853 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000854 if mismatched:
855 if standardMsg:
856 standardMsg += '; '
857 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
858
859 self.fail(self._formatMessage(msg, standardMsg))
860
Michael Foord98e7b762010-03-20 03:00:34 +0000861 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
Michael Foorde6e0e262010-12-19 15:52:56 +0000862 """An unordered sequence specific comparison. It asserts that
863 actual_seq and expected_seq have the same element counts.
864 Equivalent to::
Michael Foord98e7b762010-03-20 03:00:34 +0000865
Michael Foorde6e0e262010-12-19 15:52:56 +0000866 self.assertEqual(Counter(iter(actual_seq)),
867 Counter(iter(expected_seq)))
Michael Foordd0edec32010-02-05 22:55:09 +0000868
Michael Foord98e7b762010-03-20 03:00:34 +0000869 Asserts that each element has the same count in both sequences.
870 Example:
871 - [0, 1, 1] and [1, 0, 1] compare equal.
872 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000873 """
Michael Foord4c9e91a2011-03-16 20:34:53 -0400874 first_seq, second_seq = list(actual_seq), list(expected_seq)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000875 with warnings.catch_warnings():
876 if sys.py3kwarning:
877 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000878 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000879 "builtin_function_or_method order comparisons",
880 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000881 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000882 try:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400883 first = collections.Counter(first_seq)
884 second = collections.Counter(second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000885 except TypeError:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400886 # Handle case with unhashable elements
887 differences = _count_diff_all_purpose(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000888 else:
Michael Foord4c9e91a2011-03-16 20:34:53 -0400889 if first == second:
Michael Foorde6e0e262010-12-19 15:52:56 +0000890 return
Michael Foord4c9e91a2011-03-16 20:34:53 -0400891 differences = _count_diff_hashable(first_seq, second_seq)
Michael Foord98e7b762010-03-20 03:00:34 +0000892
Michael Foord4c9e91a2011-03-16 20:34:53 -0400893 if differences:
894 standardMsg = 'Element counts were not equal:\n'
895 lines = ['First has %d, Second has %d: %r' % diff for diff in differences]
896 diffMsg = '\n'.join(lines)
897 standardMsg = self._truncateMessage(standardMsg, diffMsg)
898 msg = self._formatMessage(msg, standardMsg)
899 self.fail(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000900
901 def assertMultiLineEqual(self, first, second, msg=None):
902 """Assert that two multi-line strings are equal."""
Ezio Melotti2623a372010-11-21 13:34:58 +0000903 self.assertIsInstance(first, basestring,
904 'First argument is not a string')
905 self.assertIsInstance(second, basestring,
906 'Second argument is not a string')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000907
908 if first != second:
Ezio Melotti34b32d62011-04-27 09:45:46 +0300909 # don't use difflib if the strings are too long
910 if (len(first) > self._diffThreshold or
911 len(second) > self._diffThreshold):
912 self._baseAssertEqual(first, second, msg)
Michael Foord94f071c2010-07-10 13:51:42 +0000913 firstlines = first.splitlines(True)
914 secondlines = second.splitlines(True)
915 if len(firstlines) == 1 and first.strip('\r\n') == first:
916 firstlines = [first + '\n']
917 secondlines = [second + '\n']
918 standardMsg = '%s != %s' % (safe_repr(first, True),
919 safe_repr(second, True))
920 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foord674648e2010-06-05 12:58:39 +0000921 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000922 self.fail(self._formatMessage(msg, standardMsg))
923
924 def assertLess(self, a, b, msg=None):
925 """Just like self.assertTrue(a < b), but with a nicer default message."""
926 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000927 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000928 self.fail(self._formatMessage(msg, standardMsg))
929
930 def assertLessEqual(self, a, b, msg=None):
931 """Just like self.assertTrue(a <= b), but with a nicer default message."""
932 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000933 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000934 self.fail(self._formatMessage(msg, standardMsg))
935
936 def assertGreater(self, a, b, msg=None):
937 """Just like self.assertTrue(a > b), but with a nicer default message."""
938 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000939 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000940 self.fail(self._formatMessage(msg, standardMsg))
941
942 def assertGreaterEqual(self, a, b, msg=None):
943 """Just like self.assertTrue(a >= b), but with a nicer default message."""
944 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000945 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000946 self.fail(self._formatMessage(msg, standardMsg))
947
948 def assertIsNone(self, obj, msg=None):
949 """Same as self.assertTrue(obj is None), with a nicer default message."""
950 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000951 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000952 self.fail(self._formatMessage(msg, standardMsg))
953
954 def assertIsNotNone(self, obj, msg=None):
955 """Included for symmetry with assertIsNone."""
956 if obj is None:
957 standardMsg = 'unexpectedly None'
958 self.fail(self._formatMessage(msg, standardMsg))
959
Georg Brandlf895cf52009-10-01 20:59:31 +0000960 def assertIsInstance(self, obj, cls, msg=None):
961 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
962 default message."""
963 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000964 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000965 self.fail(self._formatMessage(msg, standardMsg))
966
967 def assertNotIsInstance(self, obj, cls, msg=None):
968 """Included for symmetry with assertIsInstance."""
969 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000970 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000971 self.fail(self._formatMessage(msg, standardMsg))
972
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000973 def assertRaisesRegexp(self, expected_exception, expected_regexp,
974 callable_obj=None, *args, **kwargs):
975 """Asserts that the message in a raised exception matches a regexp.
976
977 Args:
978 expected_exception: Exception class expected to be raised.
979 expected_regexp: Regexp (re pattern object or string) expected
980 to be found in error message.
981 callable_obj: Function to be called.
982 args: Extra args.
983 kwargs: Extra kwargs.
984 """
985 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
986 if callable_obj is None:
987 return context
988 with context:
989 callable_obj(*args, **kwargs)
990
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000991 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000992 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000993 if isinstance(expected_regexp, basestring):
994 expected_regexp = re.compile(expected_regexp)
995 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000996 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000997 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000998 raise self.failureException(msg)
999
Michael Foorda04c7a02010-04-02 22:55:59 +00001000 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +00001001 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +00001002 if isinstance(unexpected_regexp, basestring):
1003 unexpected_regexp = re.compile(unexpected_regexp)
1004 match = unexpected_regexp.search(text)
1005 if match:
1006 msg = msg or "Regexp matched"
1007 msg = '%s: %r matches %r in %r' % (msg,
1008 text[match.start():match.end()],
1009 unexpected_regexp.pattern,
1010 text)
1011 raise self.failureException(msg)
1012
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001013
1014class FunctionTestCase(TestCase):
1015 """A test case that wraps a test function.
1016
1017 This is useful for slipping pre-existing test functions into the
1018 unittest framework. Optionally, set-up and tidy-up functions can be
1019 supplied. As with TestCase, the tidy-up ('tearDown') function will
1020 always be called if the set-up ('setUp') function ran successfully.
1021 """
1022
1023 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1024 super(FunctionTestCase, self).__init__()
1025 self._setUpFunc = setUp
1026 self._tearDownFunc = tearDown
1027 self._testFunc = testFunc
1028 self._description = description
1029
1030 def setUp(self):
1031 if self._setUpFunc is not None:
1032 self._setUpFunc()
1033
1034 def tearDown(self):
1035 if self._tearDownFunc is not None:
1036 self._tearDownFunc()
1037
1038 def runTest(self):
1039 self._testFunc()
1040
1041 def id(self):
1042 return self._testFunc.__name__
1043
1044 def __eq__(self, other):
1045 if not isinstance(other, self.__class__):
1046 return NotImplemented
1047
1048 return self._setUpFunc == other._setUpFunc and \
1049 self._tearDownFunc == other._tearDownFunc and \
1050 self._testFunc == other._testFunc and \
1051 self._description == other._description
1052
1053 def __ne__(self, other):
1054 return not self == other
1055
1056 def __hash__(self):
1057 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1058 self._testFunc, self._description))
1059
1060 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001061 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001062 self._testFunc.__name__)
1063
1064 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001065 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001066 self._testFunc)
1067
1068 def shortDescription(self):
1069 if self._description is not None:
1070 return self._description
1071 doc = self._testFunc.__doc__
1072 return doc and doc.split("\n")[0].strip() or None