| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1 | """Test case implementation""" | 
 | 2 |  | 
 | 3 | import sys | 
 | 4 | import functools | 
 | 5 | import difflib | 
 | 6 | import pprint | 
 | 7 | import re | 
 | 8 | import warnings | 
| Raymond Hettinger | 6e165b3 | 2010-11-27 09:31:37 +0000 | [diff] [blame] | 9 | import collections | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 10 |  | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 11 | from . import result | 
 | 12 | from .util import (strclass, safe_repr, sorted_list_difference, | 
| Raymond Hettinger | 93e233d | 2010-12-24 10:02:22 +0000 | [diff] [blame] | 13 |                    unorderable_list_difference, _count_diff_all_purpose, | 
 | 14 |                    _count_diff_hashable) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 15 |  | 
| Benjamin Peterson | dccc1fc | 2010-03-22 00:15:53 +0000 | [diff] [blame] | 16 | __unittest = True | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 17 |  | 
| Michael Foord | 9dad32e | 2010-06-05 13:49:56 +0000 | [diff] [blame] | 18 |  | 
 | 19 | DIFF_OMITTED = ('\nDiff is %s characters long. ' | 
 | 20 |                  'Set self.maxDiff to None to see it.') | 
 | 21 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 22 | class SkipTest(Exception): | 
 | 23 |     """ | 
 | 24 |     Raise this exception in a test to skip it. | 
 | 25 |  | 
 | 26 |     Usually you can use TestResult.skip() or one of the skipping decorators | 
 | 27 |     instead of raising this directly. | 
 | 28 |     """ | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 29 |  | 
 | 30 | class _ExpectedFailure(Exception): | 
 | 31 |     """ | 
 | 32 |     Raise this when a test is expected to fail. | 
 | 33 |  | 
 | 34 |     This is an implementation detail. | 
 | 35 |     """ | 
 | 36 |  | 
 | 37 |     def __init__(self, exc_info): | 
 | 38 |         super(_ExpectedFailure, self).__init__() | 
 | 39 |         self.exc_info = exc_info | 
 | 40 |  | 
 | 41 | class _UnexpectedSuccess(Exception): | 
 | 42 |     """ | 
 | 43 |     The test was supposed to fail, but it didn't! | 
 | 44 |     """ | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 45 |  | 
 | 46 |  | 
 | 47 | class _Outcome(object): | 
 | 48 |     def __init__(self): | 
 | 49 |         self.success = True | 
 | 50 |         self.skipped = None | 
 | 51 |         self.unexpectedSuccess = None | 
 | 52 |         self.expectedFailure = None | 
 | 53 |         self.errors = [] | 
 | 54 |         self.failures = [] | 
 | 55 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 56 |  | 
 | 57 | def _id(obj): | 
 | 58 |     return obj | 
 | 59 |  | 
 | 60 | def skip(reason): | 
 | 61 |     """ | 
 | 62 |     Unconditionally skip a test. | 
 | 63 |     """ | 
 | 64 |     def decorator(test_item): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 65 |         if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): | 
 | 66 |             @functools.wraps(test_item) | 
 | 67 |             def skip_wrapper(*args, **kwargs): | 
 | 68 |                 raise SkipTest(reason) | 
 | 69 |             test_item = skip_wrapper | 
 | 70 |  | 
 | 71 |         test_item.__unittest_skip__ = True | 
 | 72 |         test_item.__unittest_skip_why__ = reason | 
 | 73 |         return test_item | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 74 |     return decorator | 
 | 75 |  | 
 | 76 | def skipIf(condition, reason): | 
 | 77 |     """ | 
 | 78 |     Skip a test if the condition is true. | 
 | 79 |     """ | 
 | 80 |     if condition: | 
 | 81 |         return skip(reason) | 
 | 82 |     return _id | 
 | 83 |  | 
 | 84 | def skipUnless(condition, reason): | 
 | 85 |     """ | 
 | 86 |     Skip a test unless the condition is true. | 
 | 87 |     """ | 
 | 88 |     if not condition: | 
 | 89 |         return skip(reason) | 
 | 90 |     return _id | 
 | 91 |  | 
 | 92 |  | 
 | 93 | def expectedFailure(func): | 
 | 94 |     @functools.wraps(func) | 
 | 95 |     def wrapper(*args, **kwargs): | 
 | 96 |         try: | 
 | 97 |             func(*args, **kwargs) | 
 | 98 |         except Exception: | 
 | 99 |             raise _ExpectedFailure(sys.exc_info()) | 
 | 100 |         raise _UnexpectedSuccess | 
 | 101 |     return wrapper | 
 | 102 |  | 
 | 103 |  | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 104 | class _AssertRaisesBaseContext(object): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 105 |  | 
 | 106 |     def __init__(self, expected, test_case, callable_obj=None, | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 107 |                   expected_regex=None): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 108 |         self.expected = expected | 
 | 109 |         self.failureException = test_case.failureException | 
 | 110 |         if callable_obj is not None: | 
 | 111 |             try: | 
 | 112 |                 self.obj_name = callable_obj.__name__ | 
 | 113 |             except AttributeError: | 
 | 114 |                 self.obj_name = str(callable_obj) | 
 | 115 |         else: | 
 | 116 |             self.obj_name = None | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 117 |         if isinstance(expected_regex, (bytes, str)): | 
 | 118 |             expected_regex = re.compile(expected_regex) | 
 | 119 |         self.expected_regex = expected_regex | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 120 |  | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 121 |  | 
 | 122 | class _AssertRaisesContext(_AssertRaisesBaseContext): | 
 | 123 |     """A context manager used to implement TestCase.assertRaises* methods.""" | 
 | 124 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 125 |     def __enter__(self): | 
| Ezio Melotti | 4900823 | 2010-02-08 21:57:48 +0000 | [diff] [blame] | 126 |         return self | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 127 |  | 
 | 128 |     def __exit__(self, exc_type, exc_value, tb): | 
 | 129 |         if exc_type is None: | 
 | 130 |             try: | 
 | 131 |                 exc_name = self.expected.__name__ | 
 | 132 |             except AttributeError: | 
 | 133 |                 exc_name = str(self.expected) | 
 | 134 |             if self.obj_name: | 
 | 135 |                 raise self.failureException("{0} not raised by {1}" | 
 | 136 |                     .format(exc_name, self.obj_name)) | 
 | 137 |             else: | 
 | 138 |                 raise self.failureException("{0} not raised" | 
 | 139 |                     .format(exc_name)) | 
 | 140 |         if not issubclass(exc_type, self.expected): | 
 | 141 |             # let unexpected exceptions pass through | 
 | 142 |             return False | 
| Ezio Melotti | 4900823 | 2010-02-08 21:57:48 +0000 | [diff] [blame] | 143 |         # store exception, without traceback, for later retrieval | 
 | 144 |         self.exception = exc_value.with_traceback(None) | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 145 |         if self.expected_regex is None: | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 146 |             return True | 
 | 147 |  | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 148 |         expected_regex = self.expected_regex | 
 | 149 |         if not expected_regex.search(str(exc_value)): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 150 |             raise self.failureException('"%s" does not match "%s"' % | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 151 |                      (expected_regex.pattern, str(exc_value))) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 152 |         return True | 
 | 153 |  | 
 | 154 |  | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 155 | class _AssertWarnsContext(_AssertRaisesBaseContext): | 
 | 156 |     """A context manager used to implement TestCase.assertWarns* methods.""" | 
 | 157 |  | 
 | 158 |     def __enter__(self): | 
 | 159 |         # The __warningregistry__'s need to be in a pristine state for tests | 
 | 160 |         # to work properly. | 
 | 161 |         for v in sys.modules.values(): | 
 | 162 |             if getattr(v, '__warningregistry__', None): | 
 | 163 |                 v.__warningregistry__ = {} | 
 | 164 |         self.warnings_manager = warnings.catch_warnings(record=True) | 
 | 165 |         self.warnings = self.warnings_manager.__enter__() | 
 | 166 |         warnings.simplefilter("always", self.expected) | 
 | 167 |         return self | 
 | 168 |  | 
 | 169 |     def __exit__(self, exc_type, exc_value, tb): | 
 | 170 |         self.warnings_manager.__exit__(exc_type, exc_value, tb) | 
 | 171 |         if exc_type is not None: | 
 | 172 |             # let unexpected exceptions pass through | 
 | 173 |             return | 
 | 174 |         try: | 
 | 175 |             exc_name = self.expected.__name__ | 
 | 176 |         except AttributeError: | 
 | 177 |             exc_name = str(self.expected) | 
 | 178 |         first_matching = None | 
 | 179 |         for m in self.warnings: | 
 | 180 |             w = m.message | 
 | 181 |             if not isinstance(w, self.expected): | 
 | 182 |                 continue | 
 | 183 |             if first_matching is None: | 
 | 184 |                 first_matching = w | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 185 |             if (self.expected_regex is not None and | 
 | 186 |                 not self.expected_regex.search(str(w))): | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 187 |                 continue | 
 | 188 |             # store warning for later retrieval | 
 | 189 |             self.warning = w | 
 | 190 |             self.filename = m.filename | 
 | 191 |             self.lineno = m.lineno | 
 | 192 |             return | 
 | 193 |         # Now we simply try to choose a helpful failure message | 
 | 194 |         if first_matching is not None: | 
 | 195 |             raise self.failureException('"%s" does not match "%s"' % | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 196 |                      (self.expected_regex.pattern, str(first_matching))) | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 197 |         if self.obj_name: | 
 | 198 |             raise self.failureException("{0} not triggered by {1}" | 
 | 199 |                 .format(exc_name, self.obj_name)) | 
 | 200 |         else: | 
 | 201 |             raise self.failureException("{0} not triggered" | 
 | 202 |                 .format(exc_name)) | 
 | 203 |  | 
 | 204 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 205 | class TestCase(object): | 
 | 206 |     """A class whose instances are single test cases. | 
 | 207 |  | 
 | 208 |     By default, the test code itself should be placed in a method named | 
 | 209 |     'runTest'. | 
 | 210 |  | 
 | 211 |     If the fixture may be used for many test cases, create as | 
 | 212 |     many test methods as are needed. When instantiating such a TestCase | 
 | 213 |     subclass, specify in the constructor arguments the name of the test method | 
 | 214 |     that the instance is to execute. | 
 | 215 |  | 
 | 216 |     Test authors should subclass TestCase for their own tests. Construction | 
 | 217 |     and deconstruction of the test's environment ('fixture') can be | 
 | 218 |     implemented by overriding the 'setUp' and 'tearDown' methods respectively. | 
 | 219 |  | 
 | 220 |     If it is necessary to override the __init__ method, the base class | 
 | 221 |     __init__ method must always be called. It is important that subclasses | 
 | 222 |     should not change the signature of their __init__ method, since instances | 
 | 223 |     of the classes are instantiated automatically by parts of the framework | 
 | 224 |     in order to be run. | 
 | 225 |     """ | 
 | 226 |  | 
 | 227 |     # This attribute determines which exception will be raised when | 
 | 228 |     # the instance's assertion methods fail; test methods raising this | 
 | 229 |     # exception will be deemed to have 'failed' rather than 'errored' | 
 | 230 |  | 
 | 231 |     failureException = AssertionError | 
 | 232 |  | 
 | 233 |     # This attribute determines whether long messages (including repr of | 
 | 234 |     # objects used in assert methods) will be printed on failure in *addition* | 
 | 235 |     # to any explicit message passed. | 
 | 236 |  | 
| Michael Foord | 5074df6 | 2010-12-03 00:53:09 +0000 | [diff] [blame] | 237 |     longMessage = True | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 238 |  | 
| Michael Foord | c41d141 | 2010-06-10 16:17:07 +0000 | [diff] [blame] | 239 |     # This attribute sets the maximum length of a diff in failure messages | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 240 |     # by assert methods using difflib. It is looked up as an instance attribute | 
 | 241 |     # so can be configured by individual tests if required. | 
| Michael Foord | d50a6b9 | 2010-06-05 23:59:34 +0000 | [diff] [blame] | 242 |  | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 243 |     maxDiff = 80*8 | 
 | 244 |  | 
| Ezio Melotti | edd117f | 2011-04-27 10:20:38 +0300 | [diff] [blame] | 245 |     # If a string is longer than _diffThreshold, use normal comparison instead | 
 | 246 |     # of difflib.  See #11763. | 
 | 247 |     _diffThreshold = 2**16 | 
 | 248 |  | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 249 |     # Attribute used by TestSuite for classSetUp | 
 | 250 |  | 
 | 251 |     _classSetupFailed = False | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 252 |  | 
 | 253 |     def __init__(self, methodName='runTest'): | 
 | 254 |         """Create an instance of the class that will use the named test | 
 | 255 |            method when executed. Raises a ValueError if the instance does | 
 | 256 |            not have a method with the specified name. | 
 | 257 |         """ | 
 | 258 |         self._testMethodName = methodName | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 259 |         self._outcomeForDoCleanups = None | 
| Michael Foord | 32e1d83 | 2011-01-03 17:00:11 +0000 | [diff] [blame] | 260 |         self._testMethodDoc = 'No test' | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 261 |         try: | 
 | 262 |             testMethod = getattr(self, methodName) | 
 | 263 |         except AttributeError: | 
| Michael Foord | 32e1d83 | 2011-01-03 17:00:11 +0000 | [diff] [blame] | 264 |             if methodName != 'runTest': | 
 | 265 |                 # we allow instantiation with no explicit method name | 
 | 266 |                 # but not an *incorrect* or missing method name | 
 | 267 |                 raise ValueError("no such test method in %s: %s" % | 
 | 268 |                       (self.__class__, methodName)) | 
 | 269 |         else: | 
 | 270 |             self._testMethodDoc = testMethod.__doc__ | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 271 |         self._cleanups = [] | 
 | 272 |  | 
 | 273 |         # Map types to custom assertEqual functions that will compare | 
 | 274 |         # instances of said type in more detail to generate a more useful | 
 | 275 |         # error message. | 
| Benjamin Peterson | 34b2b26 | 2011-07-12 19:21:42 -0500 | [diff] [blame] | 276 |         self._type_equality_funcs = {} | 
| Michael Foord | 8ca6d98 | 2010-11-20 15:34:26 +0000 | [diff] [blame] | 277 |         self.addTypeEqualityFunc(dict, 'assertDictEqual') | 
 | 278 |         self.addTypeEqualityFunc(list, 'assertListEqual') | 
 | 279 |         self.addTypeEqualityFunc(tuple, 'assertTupleEqual') | 
 | 280 |         self.addTypeEqualityFunc(set, 'assertSetEqual') | 
 | 281 |         self.addTypeEqualityFunc(frozenset, 'assertSetEqual') | 
 | 282 |         self.addTypeEqualityFunc(str, 'assertMultiLineEqual') | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 283 |  | 
 | 284 |     def addTypeEqualityFunc(self, typeobj, function): | 
 | 285 |         """Add a type specific assertEqual style function to compare a type. | 
 | 286 |  | 
 | 287 |         This method is for use by TestCase subclasses that need to register | 
 | 288 |         their own type equality functions to provide nicer error messages. | 
 | 289 |  | 
 | 290 |         Args: | 
 | 291 |             typeobj: The data type to call this function on when both values | 
 | 292 |                     are of the same type in assertEqual(). | 
 | 293 |             function: The callable taking two arguments and an optional | 
 | 294 |                     msg= argument that raises self.failureException with a | 
 | 295 |                     useful error message when the two arguments are not equal. | 
 | 296 |         """ | 
| Benjamin Peterson | 8f326b2 | 2009-12-13 02:10:36 +0000 | [diff] [blame] | 297 |         self._type_equality_funcs[typeobj] = function | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 298 |  | 
 | 299 |     def addCleanup(self, function, *args, **kwargs): | 
 | 300 |         """Add a function, with arguments, to be called when the test is | 
 | 301 |         completed. Functions added are called on a LIFO basis and are | 
 | 302 |         called after tearDown on test failure or success. | 
 | 303 |  | 
 | 304 |         Cleanup items are called even if setUp fails (unlike tearDown).""" | 
 | 305 |         self._cleanups.append((function, args, kwargs)) | 
 | 306 |  | 
 | 307 |     def setUp(self): | 
 | 308 |         "Hook method for setting up the test fixture before exercising it." | 
 | 309 |         pass | 
 | 310 |  | 
 | 311 |     def tearDown(self): | 
 | 312 |         "Hook method for deconstructing the test fixture after testing it." | 
 | 313 |         pass | 
 | 314 |  | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 315 |     @classmethod | 
 | 316 |     def setUpClass(cls): | 
 | 317 |         "Hook method for setting up class fixture before running tests in the class." | 
 | 318 |  | 
 | 319 |     @classmethod | 
 | 320 |     def tearDownClass(cls): | 
 | 321 |         "Hook method for deconstructing the class fixture after running all tests in the class." | 
 | 322 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 323 |     def countTestCases(self): | 
 | 324 |         return 1 | 
 | 325 |  | 
 | 326 |     def defaultTestResult(self): | 
 | 327 |         return result.TestResult() | 
 | 328 |  | 
 | 329 |     def shortDescription(self): | 
| Michael Foord | 34c9462 | 2010-02-10 15:51:42 +0000 | [diff] [blame] | 330 |         """Returns a one-line description of the test, or None if no | 
 | 331 |         description has been provided. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 332 |  | 
| Michael Foord | 34c9462 | 2010-02-10 15:51:42 +0000 | [diff] [blame] | 333 |         The default implementation of this method returns the first line of | 
 | 334 |         the specified test method's docstring. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 335 |         """ | 
| Michael Foord | 34c9462 | 2010-02-10 15:51:42 +0000 | [diff] [blame] | 336 |         doc = self._testMethodDoc | 
 | 337 |         return doc and doc.split("\n")[0].strip() or None | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 338 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 339 |  | 
 | 340 |     def id(self): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 341 |         return "%s.%s" % (strclass(self.__class__), self._testMethodName) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 342 |  | 
 | 343 |     def __eq__(self, other): | 
 | 344 |         if type(self) is not type(other): | 
 | 345 |             return NotImplemented | 
 | 346 |  | 
 | 347 |         return self._testMethodName == other._testMethodName | 
 | 348 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 349 |     def __hash__(self): | 
 | 350 |         return hash((type(self), self._testMethodName)) | 
 | 351 |  | 
 | 352 |     def __str__(self): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 353 |         return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 354 |  | 
 | 355 |     def __repr__(self): | 
 | 356 |         return "<%s testMethod=%s>" % \ | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 357 |                (strclass(self.__class__), self._testMethodName) | 
 | 358 |  | 
 | 359 |     def _addSkip(self, result, reason): | 
 | 360 |         addSkip = getattr(result, 'addSkip', None) | 
 | 361 |         if addSkip is not None: | 
 | 362 |             addSkip(self, reason) | 
 | 363 |         else: | 
 | 364 |             warnings.warn("TestResult has no addSkip method, skips not reported", | 
 | 365 |                           RuntimeWarning, 2) | 
 | 366 |             result.addSuccess(self) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 367 |  | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 368 |     def _executeTestPart(self, function, outcome, isTest=False): | 
 | 369 |         try: | 
 | 370 |             function() | 
 | 371 |         except KeyboardInterrupt: | 
 | 372 |             raise | 
 | 373 |         except SkipTest as e: | 
 | 374 |             outcome.success = False | 
 | 375 |             outcome.skipped = str(e) | 
 | 376 |         except _UnexpectedSuccess: | 
 | 377 |             exc_info = sys.exc_info() | 
 | 378 |             outcome.success = False | 
 | 379 |             if isTest: | 
 | 380 |                 outcome.unexpectedSuccess = exc_info | 
 | 381 |             else: | 
 | 382 |                 outcome.errors.append(exc_info) | 
 | 383 |         except _ExpectedFailure: | 
 | 384 |             outcome.success = False | 
 | 385 |             exc_info = sys.exc_info() | 
 | 386 |             if isTest: | 
 | 387 |                 outcome.expectedFailure = exc_info | 
 | 388 |             else: | 
 | 389 |                 outcome.errors.append(exc_info) | 
 | 390 |         except self.failureException: | 
 | 391 |             outcome.success = False | 
 | 392 |             outcome.failures.append(sys.exc_info()) | 
 | 393 |             exc_info = sys.exc_info() | 
 | 394 |         except: | 
 | 395 |             outcome.success = False | 
 | 396 |             outcome.errors.append(sys.exc_info()) | 
 | 397 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 398 |     def run(self, result=None): | 
 | 399 |         orig_result = result | 
 | 400 |         if result is None: | 
 | 401 |             result = self.defaultTestResult() | 
 | 402 |             startTestRun = getattr(result, 'startTestRun', None) | 
 | 403 |             if startTestRun is not None: | 
 | 404 |                 startTestRun() | 
 | 405 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 406 |         result.startTest(self) | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 407 |  | 
 | 408 |         testMethod = getattr(self, self._testMethodName) | 
 | 409 |         if (getattr(self.__class__, "__unittest_skip__", False) or | 
 | 410 |             getattr(testMethod, "__unittest_skip__", False)): | 
 | 411 |             # If the class or method was skipped. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 412 |             try: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 413 |                 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') | 
 | 414 |                             or getattr(testMethod, '__unittest_skip_why__', '')) | 
 | 415 |                 self._addSkip(result, skip_why) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 416 |             finally: | 
 | 417 |                 result.stopTest(self) | 
 | 418 |             return | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 419 |         try: | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 420 |             outcome = _Outcome() | 
 | 421 |             self._outcomeForDoCleanups = outcome | 
 | 422 |  | 
 | 423 |             self._executeTestPart(self.setUp, outcome) | 
 | 424 |             if outcome.success: | 
 | 425 |                 self._executeTestPart(testMethod, outcome, isTest=True) | 
 | 426 |                 self._executeTestPart(self.tearDown, outcome) | 
 | 427 |  | 
 | 428 |             self.doCleanups() | 
 | 429 |             if outcome.success: | 
 | 430 |                 result.addSuccess(self) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 431 |             else: | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 432 |                 if outcome.skipped is not None: | 
 | 433 |                     self._addSkip(result, outcome.skipped) | 
 | 434 |                 for exc_info in outcome.errors: | 
 | 435 |                     result.addError(self, exc_info) | 
 | 436 |                 for exc_info in outcome.failures: | 
 | 437 |                     result.addFailure(self, exc_info) | 
 | 438 |                 if outcome.unexpectedSuccess is not None: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 439 |                     addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None) | 
 | 440 |                     if addUnexpectedSuccess is not None: | 
 | 441 |                         addUnexpectedSuccess(self) | 
 | 442 |                     else: | 
 | 443 |                         warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures", | 
 | 444 |                                       RuntimeWarning) | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 445 |                         result.addFailure(self, outcome.unexpectedSuccess) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 446 |  | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 447 |                 if outcome.expectedFailure is not None: | 
 | 448 |                     addExpectedFailure = getattr(result, 'addExpectedFailure', None) | 
 | 449 |                     if addExpectedFailure is not None: | 
 | 450 |                         addExpectedFailure(self, outcome.expectedFailure) | 
 | 451 |                     else: | 
 | 452 |                         warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", | 
 | 453 |                                       RuntimeWarning) | 
 | 454 |                         result.addSuccess(self) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 455 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 456 |         finally: | 
 | 457 |             result.stopTest(self) | 
 | 458 |             if orig_result is None: | 
 | 459 |                 stopTestRun = getattr(result, 'stopTestRun', None) | 
 | 460 |                 if stopTestRun is not None: | 
 | 461 |                     stopTestRun() | 
 | 462 |  | 
 | 463 |     def doCleanups(self): | 
 | 464 |         """Execute all cleanup functions. Normally called for you after | 
 | 465 |         tearDown.""" | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 466 |         outcome = self._outcomeForDoCleanups or _Outcome() | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 467 |         while self._cleanups: | 
| Michael Foord | b3468f7 | 2010-12-19 03:19:47 +0000 | [diff] [blame] | 468 |             function, args, kwargs = self._cleanups.pop() | 
 | 469 |             part = lambda: function(*args, **kwargs) | 
 | 470 |             self._executeTestPart(part, outcome) | 
 | 471 |  | 
 | 472 |         # return this for backwards compatibility | 
 | 473 |         # even though we no longer us it internally | 
 | 474 |         return outcome.success | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 475 |  | 
 | 476 |     def __call__(self, *args, **kwds): | 
 | 477 |         return self.run(*args, **kwds) | 
 | 478 |  | 
 | 479 |     def debug(self): | 
 | 480 |         """Run the test without collecting errors in a TestResult""" | 
 | 481 |         self.setUp() | 
 | 482 |         getattr(self, self._testMethodName)() | 
 | 483 |         self.tearDown() | 
| Michael Foord | b874874 | 2010-06-10 16:16:08 +0000 | [diff] [blame] | 484 |         while self._cleanups: | 
 | 485 |             function, args, kwargs = self._cleanups.pop(-1) | 
 | 486 |             function(*args, **kwargs) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 487 |  | 
 | 488 |     def skipTest(self, reason): | 
 | 489 |         """Skip this test.""" | 
 | 490 |         raise SkipTest(reason) | 
 | 491 |  | 
 | 492 |     def fail(self, msg=None): | 
 | 493 |         """Fail immediately, with the given message.""" | 
 | 494 |         raise self.failureException(msg) | 
 | 495 |  | 
 | 496 |     def assertFalse(self, expr, msg=None): | 
| Ezio Melotti | 3044fa7 | 2010-12-18 17:31:58 +0000 | [diff] [blame] | 497 |         """Check that the expression is false.""" | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 498 |         if expr: | 
| Ezio Melotti | 3044fa7 | 2010-12-18 17:31:58 +0000 | [diff] [blame] | 499 |             msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 500 |             raise self.failureException(msg) | 
 | 501 |  | 
 | 502 |     def assertTrue(self, expr, msg=None): | 
| Ezio Melotti | 3044fa7 | 2010-12-18 17:31:58 +0000 | [diff] [blame] | 503 |         """Check that the expression is true.""" | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 504 |         if not expr: | 
| Ezio Melotti | 3044fa7 | 2010-12-18 17:31:58 +0000 | [diff] [blame] | 505 |             msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 506 |             raise self.failureException(msg) | 
 | 507 |  | 
 | 508 |     def _formatMessage(self, msg, standardMsg): | 
 | 509 |         """Honour the longMessage attribute when generating failure messages. | 
 | 510 |         If longMessage is False this means: | 
 | 511 |         * Use only an explicit message if it is provided | 
 | 512 |         * Otherwise use the standard message for the assert | 
 | 513 |  | 
 | 514 |         If longMessage is True: | 
 | 515 |         * Use the standard message | 
 | 516 |         * If an explicit message is provided, plus ' : ' and the explicit message | 
 | 517 |         """ | 
 | 518 |         if not self.longMessage: | 
 | 519 |             return msg or standardMsg | 
 | 520 |         if msg is None: | 
 | 521 |             return standardMsg | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 522 |         try: | 
 | 523 |             # don't switch to '{}' formatting in Python 2.X | 
 | 524 |             # it changes the way unicode input is handled | 
 | 525 |             return '%s : %s' % (standardMsg, msg) | 
 | 526 |         except UnicodeDecodeError: | 
 | 527 |             return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 528 |  | 
 | 529 |  | 
 | 530 |     def assertRaises(self, excClass, callableObj=None, *args, **kwargs): | 
 | 531 |         """Fail unless an exception of class excClass is thrown | 
 | 532 |            by callableObj when invoked with arguments args and keyword | 
 | 533 |            arguments kwargs. If a different type of exception is | 
 | 534 |            thrown, it will not be caught, and the test case will be | 
 | 535 |            deemed to have suffered an error, exactly as for an | 
 | 536 |            unexpected exception. | 
 | 537 |  | 
 | 538 |            If called with callableObj omitted or None, will return a | 
 | 539 |            context object used like this:: | 
 | 540 |  | 
| Michael Foord | 1c42b12 | 2010-02-05 22:58:21 +0000 | [diff] [blame] | 541 |                 with self.assertRaises(SomeException): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 542 |                     do_something() | 
| Michael Foord | 1c42b12 | 2010-02-05 22:58:21 +0000 | [diff] [blame] | 543 |  | 
 | 544 |            The context manager keeps a reference to the exception as | 
| Ezio Melotti | 4900823 | 2010-02-08 21:57:48 +0000 | [diff] [blame] | 545 |            the 'exception' attribute. This allows you to inspect the | 
| Michael Foord | 1c42b12 | 2010-02-05 22:58:21 +0000 | [diff] [blame] | 546 |            exception after the assertion:: | 
 | 547 |  | 
 | 548 |                with self.assertRaises(SomeException) as cm: | 
 | 549 |                    do_something() | 
| Ezio Melotti | 4900823 | 2010-02-08 21:57:48 +0000 | [diff] [blame] | 550 |                the_exception = cm.exception | 
| Michael Foord | b57ac6d | 2010-02-05 23:26:29 +0000 | [diff] [blame] | 551 |                self.assertEqual(the_exception.error_code, 3) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 552 |         """ | 
 | 553 |         context = _AssertRaisesContext(excClass, self, callableObj) | 
 | 554 |         if callableObj is None: | 
 | 555 |             return context | 
 | 556 |         with context: | 
 | 557 |             callableObj(*args, **kwargs) | 
 | 558 |  | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 559 |     def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs): | 
 | 560 |         """Fail unless a warning of class warnClass is triggered | 
 | 561 |            by callableObj when invoked with arguments args and keyword | 
 | 562 |            arguments kwargs.  If a different type of warning is | 
 | 563 |            triggered, it will not be handled: depending on the other | 
 | 564 |            warning filtering rules in effect, it might be silenced, printed | 
 | 565 |            out, or raised as an exception. | 
 | 566 |  | 
 | 567 |            If called with callableObj omitted or None, will return a | 
 | 568 |            context object used like this:: | 
 | 569 |  | 
 | 570 |                 with self.assertWarns(SomeWarning): | 
 | 571 |                     do_something() | 
 | 572 |  | 
 | 573 |            The context manager keeps a reference to the first matching | 
 | 574 |            warning as the 'warning' attribute; similarly, the 'filename' | 
 | 575 |            and 'lineno' attributes give you information about the line | 
 | 576 |            of Python code from which the warning was triggered. | 
 | 577 |            This allows you to inspect the warning after the assertion:: | 
 | 578 |  | 
 | 579 |                with self.assertWarns(SomeWarning) as cm: | 
 | 580 |                    do_something() | 
 | 581 |                the_warning = cm.warning | 
 | 582 |                self.assertEqual(the_warning.some_attribute, 147) | 
 | 583 |         """ | 
 | 584 |         context = _AssertWarnsContext(expected_warning, self, callable_obj) | 
 | 585 |         if callable_obj is None: | 
 | 586 |             return context | 
 | 587 |         with context: | 
 | 588 |             callable_obj(*args, **kwargs) | 
 | 589 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 590 |     def _getAssertEqualityFunc(self, first, second): | 
 | 591 |         """Get a detailed comparison function for the types of the two args. | 
 | 592 |  | 
 | 593 |         Returns: A callable accepting (first, second, msg=None) that will | 
 | 594 |         raise a failure exception if first != second with a useful human | 
 | 595 |         readable error message for those types. | 
 | 596 |         """ | 
 | 597 |         # | 
 | 598 |         # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) | 
 | 599 |         # and vice versa.  I opted for the conservative approach in case | 
 | 600 |         # subclasses are not intended to be compared in detail to their super | 
 | 601 |         # class instances using a type equality func.  This means testing | 
 | 602 |         # subtypes won't automagically use the detailed comparison.  Callers | 
 | 603 |         # should use their type specific assertSpamEqual method to compare | 
 | 604 |         # subclasses if the detailed comparison is desired and appropriate. | 
 | 605 |         # See the discussion in http://bugs.python.org/issue2578. | 
 | 606 |         # | 
 | 607 |         if type(first) is type(second): | 
 | 608 |             asserter = self._type_equality_funcs.get(type(first)) | 
 | 609 |             if asserter is not None: | 
| Benjamin Peterson | 34b2b26 | 2011-07-12 19:21:42 -0500 | [diff] [blame] | 610 |                 if isinstance(asserter, str): | 
 | 611 |                     asserter = getattr(self, asserter) | 
| Benjamin Peterson | 8f326b2 | 2009-12-13 02:10:36 +0000 | [diff] [blame] | 612 |                 return asserter | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 613 |  | 
 | 614 |         return self._baseAssertEqual | 
 | 615 |  | 
 | 616 |     def _baseAssertEqual(self, first, second, msg=None): | 
 | 617 |         """The default assertEqual implementation, not type specific.""" | 
 | 618 |         if not first == second: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 619 |             standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 620 |             msg = self._formatMessage(msg, standardMsg) | 
 | 621 |             raise self.failureException(msg) | 
 | 622 |  | 
 | 623 |     def assertEqual(self, first, second, msg=None): | 
 | 624 |         """Fail if the two objects are unequal as determined by the '==' | 
 | 625 |            operator. | 
 | 626 |         """ | 
 | 627 |         assertion_func = self._getAssertEqualityFunc(first, second) | 
 | 628 |         assertion_func(first, second, msg=msg) | 
 | 629 |  | 
 | 630 |     def assertNotEqual(self, first, second, msg=None): | 
 | 631 |         """Fail if the two objects are equal as determined by the '==' | 
 | 632 |            operator. | 
 | 633 |         """ | 
 | 634 |         if not first != second: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 635 |             msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), | 
 | 636 |                                                           safe_repr(second))) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 637 |             raise self.failureException(msg) | 
 | 638 |  | 
| Michael Foord | 321d059 | 2010-11-02 13:44:51 +0000 | [diff] [blame] | 639 |     def assertAlmostEqual(self, first, second, places=None, msg=None, | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 640 |                           delta=None): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 641 |         """Fail if the two objects are unequal as determined by their | 
 | 642 |            difference rounded to the given number of decimal places | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 643 |            (default 7) and comparing to zero, or by comparing that the | 
 | 644 |            between the two objects is more than the given delta. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 645 |  | 
 | 646 |            Note that decimal places (from zero) are usually not the same | 
 | 647 |            as significant digits (measured from the most signficant digit). | 
| Benjamin Peterson | 4ac9ce4 | 2009-10-04 14:49:41 +0000 | [diff] [blame] | 648 |  | 
 | 649 |            If the two objects compare equal then they will automatically | 
 | 650 |            compare almost equal. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 651 |         """ | 
| Benjamin Peterson | 4ac9ce4 | 2009-10-04 14:49:41 +0000 | [diff] [blame] | 652 |         if first == second: | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 653 |             # shortcut | 
| Benjamin Peterson | 4ac9ce4 | 2009-10-04 14:49:41 +0000 | [diff] [blame] | 654 |             return | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 655 |         if delta is not None and places is not None: | 
 | 656 |             raise TypeError("specify delta or places not both") | 
 | 657 |  | 
 | 658 |         if delta is not None: | 
 | 659 |             if abs(first - second) <= delta: | 
 | 660 |                 return | 
 | 661 |  | 
 | 662 |             standardMsg = '%s != %s within %s delta' % (safe_repr(first), | 
 | 663 |                                                         safe_repr(second), | 
 | 664 |                                                         safe_repr(delta)) | 
 | 665 |         else: | 
 | 666 |             if places is None: | 
 | 667 |                 places = 7 | 
 | 668 |  | 
 | 669 |             if round(abs(second-first), places) == 0: | 
 | 670 |                 return | 
 | 671 |  | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 672 |             standardMsg = '%s != %s within %r places' % (safe_repr(first), | 
 | 673 |                                                           safe_repr(second), | 
 | 674 |                                                           places) | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 675 |         msg = self._formatMessage(msg, standardMsg) | 
 | 676 |         raise self.failureException(msg) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 677 |  | 
| Michael Foord | 321d059 | 2010-11-02 13:44:51 +0000 | [diff] [blame] | 678 |     def assertNotAlmostEqual(self, first, second, places=None, msg=None, | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 679 |                              delta=None): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 680 |         """Fail if the two objects are equal as determined by their | 
 | 681 |            difference rounded to the given number of decimal places | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 682 |            (default 7) and comparing to zero, or by comparing that the | 
 | 683 |            between the two objects is less than the given delta. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 684 |  | 
 | 685 |            Note that decimal places (from zero) are usually not the same | 
 | 686 |            as significant digits (measured from the most signficant digit). | 
| Benjamin Peterson | 4ac9ce4 | 2009-10-04 14:49:41 +0000 | [diff] [blame] | 687 |  | 
 | 688 |            Objects that are equal automatically fail. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 689 |         """ | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 690 |         if delta is not None and places is not None: | 
 | 691 |             raise TypeError("specify delta or places not both") | 
 | 692 |         if delta is not None: | 
 | 693 |             if not (first == second) and abs(first - second) > delta: | 
 | 694 |                 return | 
 | 695 |             standardMsg = '%s == %s within %s delta' % (safe_repr(first), | 
 | 696 |                                                         safe_repr(second), | 
 | 697 |                                                         safe_repr(delta)) | 
 | 698 |         else: | 
 | 699 |             if places is None: | 
 | 700 |                 places = 7 | 
 | 701 |             if not (first == second) and round(abs(second-first), places) != 0: | 
 | 702 |                 return | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 703 |             standardMsg = '%s == %s within %r places' % (safe_repr(first), | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 704 |                                                          safe_repr(second), | 
 | 705 |                                                          places) | 
 | 706 |  | 
 | 707 |         msg = self._formatMessage(msg, standardMsg) | 
 | 708 |         raise self.failureException(msg) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 709 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 710 |  | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 711 |     def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 712 |         """An equality assertion for ordered sequences (like lists and tuples). | 
 | 713 |  | 
| R. David Murray | ad13f22 | 2010-01-29 22:17:58 +0000 | [diff] [blame] | 714 |         For the purposes of this function, a valid ordered sequence type is one | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 715 |         which can be indexed, has a length, and has an equality operator. | 
 | 716 |  | 
 | 717 |         Args: | 
 | 718 |             seq1: The first sequence to compare. | 
 | 719 |             seq2: The second sequence to compare. | 
 | 720 |             seq_type: The expected datatype of the sequences, or None if no | 
 | 721 |                     datatype should be enforced. | 
 | 722 |             msg: Optional message to use on failure instead of a list of | 
 | 723 |                     differences. | 
 | 724 |         """ | 
 | 725 |         if seq_type != None: | 
 | 726 |             seq_type_name = seq_type.__name__ | 
 | 727 |             if not isinstance(seq1, seq_type): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 728 |                 raise self.failureException('First sequence is not a %s: %s' | 
 | 729 |                                         % (seq_type_name, safe_repr(seq1))) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 730 |             if not isinstance(seq2, seq_type): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 731 |                 raise self.failureException('Second sequence is not a %s: %s' | 
 | 732 |                                         % (seq_type_name, safe_repr(seq2))) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 733 |         else: | 
 | 734 |             seq_type_name = "sequence" | 
 | 735 |  | 
 | 736 |         differing = None | 
 | 737 |         try: | 
 | 738 |             len1 = len(seq1) | 
 | 739 |         except (TypeError, NotImplementedError): | 
 | 740 |             differing = 'First %s has no length.    Non-sequence?' % ( | 
 | 741 |                     seq_type_name) | 
 | 742 |  | 
 | 743 |         if differing is None: | 
 | 744 |             try: | 
 | 745 |                 len2 = len(seq2) | 
 | 746 |             except (TypeError, NotImplementedError): | 
 | 747 |                 differing = 'Second %s has no length.    Non-sequence?' % ( | 
 | 748 |                         seq_type_name) | 
 | 749 |  | 
 | 750 |         if differing is None: | 
 | 751 |             if seq1 == seq2: | 
 | 752 |                 return | 
 | 753 |  | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 754 |             seq1_repr = safe_repr(seq1) | 
 | 755 |             seq2_repr = safe_repr(seq2) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 756 |             if len(seq1_repr) > 30: | 
 | 757 |                 seq1_repr = seq1_repr[:30] + '...' | 
 | 758 |             if len(seq2_repr) > 30: | 
 | 759 |                 seq2_repr = seq2_repr[:30] + '...' | 
 | 760 |             elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr) | 
 | 761 |             differing = '%ss differ: %s != %s\n' % elements | 
 | 762 |  | 
 | 763 |             for i in range(min(len1, len2)): | 
 | 764 |                 try: | 
 | 765 |                     item1 = seq1[i] | 
 | 766 |                 except (TypeError, IndexError, NotImplementedError): | 
 | 767 |                     differing += ('\nUnable to index element %d of first %s\n' % | 
 | 768 |                                  (i, seq_type_name)) | 
 | 769 |                     break | 
 | 770 |  | 
 | 771 |                 try: | 
 | 772 |                     item2 = seq2[i] | 
 | 773 |                 except (TypeError, IndexError, NotImplementedError): | 
 | 774 |                     differing += ('\nUnable to index element %d of second %s\n' % | 
 | 775 |                                  (i, seq_type_name)) | 
 | 776 |                     break | 
 | 777 |  | 
 | 778 |                 if item1 != item2: | 
 | 779 |                     differing += ('\nFirst differing element %d:\n%s\n%s\n' % | 
 | 780 |                                  (i, item1, item2)) | 
 | 781 |                     break | 
 | 782 |             else: | 
 | 783 |                 if (len1 == len2 and seq_type is None and | 
 | 784 |                     type(seq1) != type(seq2)): | 
 | 785 |                     # The sequences are the same, but have differing types. | 
 | 786 |                     return | 
 | 787 |  | 
 | 788 |             if len1 > len2: | 
 | 789 |                 differing += ('\nFirst %s contains %d additional ' | 
 | 790 |                              'elements.\n' % (seq_type_name, len1 - len2)) | 
 | 791 |                 try: | 
 | 792 |                     differing += ('First extra element %d:\n%s\n' % | 
 | 793 |                                   (len2, seq1[len2])) | 
 | 794 |                 except (TypeError, IndexError, NotImplementedError): | 
 | 795 |                     differing += ('Unable to index element %d ' | 
 | 796 |                                   'of first %s\n' % (len2, seq_type_name)) | 
 | 797 |             elif len1 < len2: | 
 | 798 |                 differing += ('\nSecond %s contains %d additional ' | 
 | 799 |                              'elements.\n' % (seq_type_name, len2 - len1)) | 
 | 800 |                 try: | 
 | 801 |                     differing += ('First extra element %d:\n%s\n' % | 
 | 802 |                                   (len1, seq2[len1])) | 
 | 803 |                 except (TypeError, IndexError, NotImplementedError): | 
 | 804 |                     differing += ('Unable to index element %d ' | 
 | 805 |                                   'of second %s\n' % (len1, seq_type_name)) | 
| Michael Foord | 2034d9a | 2010-06-05 11:27:52 +0000 | [diff] [blame] | 806 |         standardMsg = differing | 
 | 807 |         diffMsg = '\n' + '\n'.join( | 
| Benjamin Peterson | 6e8c757 | 2009-10-04 20:19:21 +0000 | [diff] [blame] | 808 |             difflib.ndiff(pprint.pformat(seq1).splitlines(), | 
 | 809 |                           pprint.pformat(seq2).splitlines())) | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 810 |  | 
 | 811 |         standardMsg = self._truncateMessage(standardMsg, diffMsg) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 812 |         msg = self._formatMessage(msg, standardMsg) | 
 | 813 |         self.fail(msg) | 
 | 814 |  | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 815 |     def _truncateMessage(self, message, diff): | 
 | 816 |         max_diff = self.maxDiff | 
 | 817 |         if max_diff is None or len(diff) <= max_diff: | 
 | 818 |             return message + diff | 
| Michael Foord | 9dad32e | 2010-06-05 13:49:56 +0000 | [diff] [blame] | 819 |         return message + (DIFF_OMITTED % len(diff)) | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 820 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 821 |     def assertListEqual(self, list1, list2, msg=None): | 
 | 822 |         """A list-specific equality assertion. | 
 | 823 |  | 
 | 824 |         Args: | 
 | 825 |             list1: The first list to compare. | 
 | 826 |             list2: The second list to compare. | 
 | 827 |             msg: Optional message to use on failure instead of a list of | 
 | 828 |                     differences. | 
 | 829 |  | 
 | 830 |         """ | 
 | 831 |         self.assertSequenceEqual(list1, list2, msg, seq_type=list) | 
 | 832 |  | 
 | 833 |     def assertTupleEqual(self, tuple1, tuple2, msg=None): | 
 | 834 |         """A tuple-specific equality assertion. | 
 | 835 |  | 
 | 836 |         Args: | 
 | 837 |             tuple1: The first tuple to compare. | 
 | 838 |             tuple2: The second tuple to compare. | 
 | 839 |             msg: Optional message to use on failure instead of a list of | 
 | 840 |                     differences. | 
 | 841 |         """ | 
 | 842 |         self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) | 
 | 843 |  | 
 | 844 |     def assertSetEqual(self, set1, set2, msg=None): | 
 | 845 |         """A set-specific equality assertion. | 
 | 846 |  | 
 | 847 |         Args: | 
 | 848 |             set1: The first set to compare. | 
 | 849 |             set2: The second set to compare. | 
 | 850 |             msg: Optional message to use on failure instead of a list of | 
 | 851 |                     differences. | 
 | 852 |  | 
| Michael Foord | 91c9da3 | 2010-03-20 17:21:27 +0000 | [diff] [blame] | 853 |         assertSetEqual uses ducktyping to support different types of sets, and | 
 | 854 |         is optimized for sets specifically (parameters must support a | 
 | 855 |         difference method). | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 856 |         """ | 
 | 857 |         try: | 
 | 858 |             difference1 = set1.difference(set2) | 
 | 859 |         except TypeError as e: | 
 | 860 |             self.fail('invalid type when attempting set difference: %s' % e) | 
 | 861 |         except AttributeError as e: | 
 | 862 |             self.fail('first argument does not support set difference: %s' % e) | 
 | 863 |  | 
 | 864 |         try: | 
 | 865 |             difference2 = set2.difference(set1) | 
 | 866 |         except TypeError as e: | 
 | 867 |             self.fail('invalid type when attempting set difference: %s' % e) | 
 | 868 |         except AttributeError as e: | 
 | 869 |             self.fail('second argument does not support set difference: %s' % e) | 
 | 870 |  | 
 | 871 |         if not (difference1 or difference2): | 
 | 872 |             return | 
 | 873 |  | 
 | 874 |         lines = [] | 
 | 875 |         if difference1: | 
 | 876 |             lines.append('Items in the first set but not the second:') | 
 | 877 |             for item in difference1: | 
 | 878 |                 lines.append(repr(item)) | 
 | 879 |         if difference2: | 
 | 880 |             lines.append('Items in the second set but not the first:') | 
 | 881 |             for item in difference2: | 
 | 882 |                 lines.append(repr(item)) | 
 | 883 |  | 
 | 884 |         standardMsg = '\n'.join(lines) | 
 | 885 |         self.fail(self._formatMessage(msg, standardMsg)) | 
 | 886 |  | 
 | 887 |     def assertIn(self, member, container, msg=None): | 
 | 888 |         """Just like self.assertTrue(a in b), but with a nicer default message.""" | 
 | 889 |         if member not in container: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 890 |             standardMsg = '%s not found in %s' % (safe_repr(member), | 
 | 891 |                                                   safe_repr(container)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 892 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 893 |  | 
 | 894 |     def assertNotIn(self, member, container, msg=None): | 
 | 895 |         """Just like self.assertTrue(a not in b), but with a nicer default message.""" | 
 | 896 |         if member in container: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 897 |             standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), | 
 | 898 |                                                         safe_repr(container)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 899 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 900 |  | 
 | 901 |     def assertIs(self, expr1, expr2, msg=None): | 
 | 902 |         """Just like self.assertTrue(a is b), but with a nicer default message.""" | 
 | 903 |         if expr1 is not expr2: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 904 |             standardMsg = '%s is not %s' % (safe_repr(expr1), | 
 | 905 |                                              safe_repr(expr2)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 906 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 907 |  | 
 | 908 |     def assertIsNot(self, expr1, expr2, msg=None): | 
 | 909 |         """Just like self.assertTrue(a is not b), but with a nicer default message.""" | 
 | 910 |         if expr1 is expr2: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 911 |             standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 912 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 913 |  | 
 | 914 |     def assertDictEqual(self, d1, d2, msg=None): | 
| Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 915 |         self.assertIsInstance(d1, dict, 'First argument is not a dictionary') | 
 | 916 |         self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 917 |  | 
 | 918 |         if d1 != d2: | 
| Michael Foord | cb11b25 | 2010-06-05 13:14:43 +0000 | [diff] [blame] | 919 |             standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) | 
| Michael Foord | 085dfd3 | 2010-06-05 12:17:02 +0000 | [diff] [blame] | 920 |             diff = ('\n' + '\n'.join(difflib.ndiff( | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 921 |                            pprint.pformat(d1).splitlines(), | 
 | 922 |                            pprint.pformat(d2).splitlines()))) | 
| Michael Foord | cb11b25 | 2010-06-05 13:14:43 +0000 | [diff] [blame] | 923 |             standardMsg = self._truncateMessage(standardMsg, diff) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 924 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 925 |  | 
| Ezio Melotti | addc6f5 | 2010-12-18 20:00:04 +0000 | [diff] [blame] | 926 |     def assertDictContainsSubset(self, subset, dictionary, msg=None): | 
 | 927 |         """Checks whether dictionary is a superset of subset.""" | 
| Raymond Hettinger | 8ebe27f | 2010-12-21 19:24:26 +0000 | [diff] [blame] | 928 |         warnings.warn('assertDictContainsSubset is deprecated', | 
 | 929 |                       DeprecationWarning) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 930 |         missing = [] | 
 | 931 |         mismatched = [] | 
| Ezio Melotti | addc6f5 | 2010-12-18 20:00:04 +0000 | [diff] [blame] | 932 |         for key, value in subset.items(): | 
 | 933 |             if key not in dictionary: | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 934 |                 missing.append(key) | 
| Ezio Melotti | addc6f5 | 2010-12-18 20:00:04 +0000 | [diff] [blame] | 935 |             elif value != dictionary[key]: | 
| Benjamin Peterson | 6e8c757 | 2009-10-04 20:19:21 +0000 | [diff] [blame] | 936 |                 mismatched.append('%s, expected: %s, actual: %s' % | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 937 |                                   (safe_repr(key), safe_repr(value), | 
| Ezio Melotti | addc6f5 | 2010-12-18 20:00:04 +0000 | [diff] [blame] | 938 |                                    safe_repr(dictionary[key]))) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 939 |  | 
 | 940 |         if not (missing or mismatched): | 
 | 941 |             return | 
 | 942 |  | 
 | 943 |         standardMsg = '' | 
 | 944 |         if missing: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 945 |             standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in | 
 | 946 |                                                     missing) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 947 |         if mismatched: | 
 | 948 |             if standardMsg: | 
 | 949 |                 standardMsg += '; ' | 
 | 950 |             standardMsg += 'Mismatched values: %s' % ','.join(mismatched) | 
 | 951 |  | 
 | 952 |         self.fail(self._formatMessage(msg, standardMsg)) | 
 | 953 |  | 
 | 954 |     def assertSameElements(self, expected_seq, actual_seq, msg=None): | 
 | 955 |         """An unordered sequence specific comparison. | 
 | 956 |  | 
 | 957 |         Raises with an error message listing which elements of expected_seq | 
 | 958 |         are missing from actual_seq and vice versa if any. | 
| Michael Foord | 1c42b12 | 2010-02-05 22:58:21 +0000 | [diff] [blame] | 959 |  | 
 | 960 |         Duplicate elements are ignored when comparing *expected_seq* and | 
 | 961 |         *actual_seq*. It is the equivalent of ``assertEqual(set(expected), | 
 | 962 |         set(actual))`` but it works with sequences of unhashable objects as | 
 | 963 |         well. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 964 |         """ | 
| Michael Foord | 91c9da3 | 2010-03-20 17:21:27 +0000 | [diff] [blame] | 965 |         warnings.warn('assertSameElements is deprecated', | 
 | 966 |                       DeprecationWarning) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 967 |         try: | 
 | 968 |             expected = set(expected_seq) | 
 | 969 |             actual = set(actual_seq) | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 970 |             missing = sorted(expected.difference(actual)) | 
 | 971 |             unexpected = sorted(actual.difference(expected)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 972 |         except TypeError: | 
 | 973 |             # Fall back to slower list-compare if any of the objects are | 
 | 974 |             # not hashable. | 
 | 975 |             expected = list(expected_seq) | 
 | 976 |             actual = list(actual_seq) | 
 | 977 |             try: | 
 | 978 |                 expected.sort() | 
 | 979 |                 actual.sort() | 
 | 980 |             except TypeError: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 981 |                 missing, unexpected = unorderable_list_difference(expected, | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 982 |                                                                   actual) | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 983 |             else: | 
 | 984 |                 missing, unexpected = sorted_list_difference(expected, actual) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 985 |         errors = [] | 
 | 986 |         if missing: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 987 |             errors.append('Expected, but missing:\n    %s' % | 
 | 988 |                           safe_repr(missing)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 989 |         if unexpected: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 990 |             errors.append('Unexpected, but present:\n    %s' % | 
 | 991 |                           safe_repr(unexpected)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 992 |         if errors: | 
 | 993 |             standardMsg = '\n'.join(errors) | 
 | 994 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 995 |  | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 996 |  | 
| Raymond Hettinger | 57bd00a | 2010-12-24 21:51:48 +0000 | [diff] [blame] | 997 |     def assertCountEqual(self, first, second, msg=None): | 
 | 998 |         """An unordered sequence comparison asserting that the same elements, | 
 | 999 |         regardless of order.  If the same element occurs more than once, | 
 | 1000 |         it verifies that the elements occur the same number of times. | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1001 |  | 
| Raymond Hettinger | 57bd00a | 2010-12-24 21:51:48 +0000 | [diff] [blame] | 1002 |             self.assertEqual(Counter(list(first)), | 
 | 1003 |                              Counter(list(second))) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1004 |  | 
| Raymond Hettinger | 57bd00a | 2010-12-24 21:51:48 +0000 | [diff] [blame] | 1005 |          Example: | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1006 |             - [0, 1, 1] and [1, 0, 1] compare equal. | 
 | 1007 |             - [0, 0, 1] and [0, 1] compare unequal. | 
| Raymond Hettinger | 57bd00a | 2010-12-24 21:51:48 +0000 | [diff] [blame] | 1008 |  | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1009 |         """ | 
| Michael Foord | e180d39 | 2011-01-28 19:51:48 +0000 | [diff] [blame] | 1010 |         first_seq, second_seq = list(first), list(second) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1011 |         try: | 
| Michael Foord | e180d39 | 2011-01-28 19:51:48 +0000 | [diff] [blame] | 1012 |             first = collections.Counter(first_seq) | 
 | 1013 |             second = collections.Counter(second_seq) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1014 |         except TypeError: | 
| Raymond Hettinger | 6518f5e | 2010-12-24 00:52:54 +0000 | [diff] [blame] | 1015 |             # Handle case with unhashable elements | 
| Michael Foord | e180d39 | 2011-01-28 19:51:48 +0000 | [diff] [blame] | 1016 |             differences = _count_diff_all_purpose(first_seq, second_seq) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1017 |         else: | 
| Michael Foord | e180d39 | 2011-01-28 19:51:48 +0000 | [diff] [blame] | 1018 |             if first == second: | 
| Raymond Hettinger | 6e165b3 | 2010-11-27 09:31:37 +0000 | [diff] [blame] | 1019 |                 return | 
| Michael Foord | e180d39 | 2011-01-28 19:51:48 +0000 | [diff] [blame] | 1020 |             differences = _count_diff_hashable(first_seq, second_seq) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1021 |  | 
| Raymond Hettinger | 93e233d | 2010-12-24 10:02:22 +0000 | [diff] [blame] | 1022 |         if differences: | 
 | 1023 |             standardMsg = 'Element counts were not equal:\n' | 
| Raymond Hettinger | 57bd00a | 2010-12-24 21:51:48 +0000 | [diff] [blame] | 1024 |             lines = ['First has %d, Second has %d:  %r' % diff for diff in differences] | 
| Raymond Hettinger | 93e233d | 2010-12-24 10:02:22 +0000 | [diff] [blame] | 1025 |             diffMsg = '\n'.join(lines) | 
 | 1026 |             standardMsg = self._truncateMessage(standardMsg, diffMsg) | 
 | 1027 |             msg = self._formatMessage(msg, standardMsg) | 
 | 1028 |             self.fail(msg) | 
| Michael Foord | 8442a60 | 2010-03-20 16:58:04 +0000 | [diff] [blame] | 1029 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1030 |     def assertMultiLineEqual(self, first, second, msg=None): | 
 | 1031 |         """Assert that two multi-line strings are equal.""" | 
| Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame] | 1032 |         self.assertIsInstance(first, str, 'First argument is not a string') | 
 | 1033 |         self.assertIsInstance(second, str, 'Second argument is not a string') | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1034 |  | 
 | 1035 |         if first != second: | 
| Ezio Melotti | edd117f | 2011-04-27 10:20:38 +0300 | [diff] [blame] | 1036 |             # don't use difflib if the strings are too long | 
 | 1037 |             if (len(first) > self._diffThreshold or | 
 | 1038 |                 len(second) > self._diffThreshold): | 
 | 1039 |                 self._baseAssertEqual(first, second, msg) | 
| Michael Foord | c653ce3 | 2010-07-10 13:52:22 +0000 | [diff] [blame] | 1040 |             firstlines = first.splitlines(True) | 
 | 1041 |             secondlines = second.splitlines(True) | 
 | 1042 |             if len(firstlines) == 1 and first.strip('\r\n') == first: | 
 | 1043 |                 firstlines = [first + '\n'] | 
 | 1044 |                 secondlines = [second + '\n'] | 
 | 1045 |             standardMsg = '%s != %s' % (safe_repr(first, True), | 
 | 1046 |                                         safe_repr(second, True)) | 
 | 1047 |             diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) | 
| Michael Foord | cb11b25 | 2010-06-05 13:14:43 +0000 | [diff] [blame] | 1048 |             standardMsg = self._truncateMessage(standardMsg, diff) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1049 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1050 |  | 
 | 1051 |     def assertLess(self, a, b, msg=None): | 
 | 1052 |         """Just like self.assertTrue(a < b), but with a nicer default message.""" | 
 | 1053 |         if not a < b: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1054 |             standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1055 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1056 |  | 
 | 1057 |     def assertLessEqual(self, a, b, msg=None): | 
 | 1058 |         """Just like self.assertTrue(a <= b), but with a nicer default message.""" | 
 | 1059 |         if not a <= b: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1060 |             standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1061 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1062 |  | 
 | 1063 |     def assertGreater(self, a, b, msg=None): | 
 | 1064 |         """Just like self.assertTrue(a > b), but with a nicer default message.""" | 
 | 1065 |         if not a > b: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1066 |             standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1067 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1068 |  | 
 | 1069 |     def assertGreaterEqual(self, a, b, msg=None): | 
 | 1070 |         """Just like self.assertTrue(a >= b), but with a nicer default message.""" | 
 | 1071 |         if not a >= b: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1072 |             standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1073 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1074 |  | 
 | 1075 |     def assertIsNone(self, obj, msg=None): | 
 | 1076 |         """Same as self.assertTrue(obj is None), with a nicer default message.""" | 
 | 1077 |         if obj is not None: | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1078 |             standardMsg = '%s is not None' % (safe_repr(obj),) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1079 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1080 |  | 
 | 1081 |     def assertIsNotNone(self, obj, msg=None): | 
 | 1082 |         """Included for symmetry with assertIsNone.""" | 
 | 1083 |         if obj is None: | 
 | 1084 |             standardMsg = 'unexpectedly None' | 
 | 1085 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1086 |  | 
| Benjamin Peterson | 6e8c757 | 2009-10-04 20:19:21 +0000 | [diff] [blame] | 1087 |     def assertIsInstance(self, obj, cls, msg=None): | 
 | 1088 |         """Same as self.assertTrue(isinstance(obj, cls)), with a nicer | 
 | 1089 |         default message.""" | 
 | 1090 |         if not isinstance(obj, cls): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1091 |             standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) | 
| Benjamin Peterson | 6e8c757 | 2009-10-04 20:19:21 +0000 | [diff] [blame] | 1092 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1093 |  | 
 | 1094 |     def assertNotIsInstance(self, obj, cls, msg=None): | 
 | 1095 |         """Included for symmetry with assertIsInstance.""" | 
 | 1096 |         if isinstance(obj, cls): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1097 |             standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) | 
| Benjamin Peterson | 6e8c757 | 2009-10-04 20:19:21 +0000 | [diff] [blame] | 1098 |             self.fail(self._formatMessage(msg, standardMsg)) | 
 | 1099 |  | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1100 |     def assertRaisesRegex(self, expected_exception, expected_regex, | 
 | 1101 |                           callable_obj=None, *args, **kwargs): | 
 | 1102 |         """Asserts that the message in a raised exception matches a regex. | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1103 |  | 
 | 1104 |         Args: | 
 | 1105 |             expected_exception: Exception class expected to be raised. | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1106 |             expected_regex: Regex (re pattern object or string) expected | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1107 |                     to be found in error message. | 
 | 1108 |             callable_obj: Function to be called. | 
 | 1109 |             args: Extra args. | 
 | 1110 |             kwargs: Extra kwargs. | 
 | 1111 |         """ | 
 | 1112 |         context = _AssertRaisesContext(expected_exception, self, callable_obj, | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1113 |                                        expected_regex) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1114 |         if callable_obj is None: | 
 | 1115 |             return context | 
 | 1116 |         with context: | 
 | 1117 |             callable_obj(*args, **kwargs) | 
 | 1118 |  | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1119 |     def assertWarnsRegex(self, expected_warning, expected_regex, | 
 | 1120 |                          callable_obj=None, *args, **kwargs): | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 1121 |         """Asserts that the message in a triggered warning matches a regexp. | 
 | 1122 |         Basic functioning is similar to assertWarns() with the addition | 
 | 1123 |         that only warnings whose messages also match the regular expression | 
 | 1124 |         are considered successful matches. | 
 | 1125 |  | 
 | 1126 |         Args: | 
 | 1127 |             expected_warning: Warning class expected to be triggered. | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1128 |             expected_regex: Regex (re pattern object or string) expected | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 1129 |                     to be found in error message. | 
 | 1130 |             callable_obj: Function to be called. | 
 | 1131 |             args: Extra args. | 
 | 1132 |             kwargs: Extra kwargs. | 
 | 1133 |         """ | 
 | 1134 |         context = _AssertWarnsContext(expected_warning, self, callable_obj, | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1135 |                                       expected_regex) | 
| Antoine Pitrou | 4bc12ef | 2010-09-06 19:25:46 +0000 | [diff] [blame] | 1136 |         if callable_obj is None: | 
 | 1137 |             return context | 
 | 1138 |         with context: | 
 | 1139 |             callable_obj(*args, **kwargs) | 
 | 1140 |  | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1141 |     def assertRegex(self, text, expected_regex, msg=None): | 
| Michael Foord | e3ef5f1 | 2010-05-08 16:46:14 +0000 | [diff] [blame] | 1142 |         """Fail the test unless the text matches the regular expression.""" | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1143 |         if isinstance(expected_regex, (str, bytes)): | 
| Gregory P. Smith | ed16bf4 | 2010-12-16 19:23:05 +0000 | [diff] [blame] | 1144 |             assert expected_regex, "expected_regex must not be empty." | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1145 |             expected_regex = re.compile(expected_regex) | 
 | 1146 |         if not expected_regex.search(text): | 
 | 1147 |             msg = msg or "Regex didn't match" | 
 | 1148 |             msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text) | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1149 |             raise self.failureException(msg) | 
 | 1150 |  | 
| Ezio Melotti | 8f77630 | 2010-12-10 02:32:05 +0000 | [diff] [blame] | 1151 |     def assertNotRegex(self, text, unexpected_regex, msg=None): | 
| Michael Foord | e3ef5f1 | 2010-05-08 16:46:14 +0000 | [diff] [blame] | 1152 |         """Fail the test if the text matches the regular expression.""" | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1153 |         if isinstance(unexpected_regex, (str, bytes)): | 
 | 1154 |             unexpected_regex = re.compile(unexpected_regex) | 
 | 1155 |         match = unexpected_regex.search(text) | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 1156 |         if match: | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1157 |             msg = msg or "Regex matched" | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 1158 |             msg = '%s: %r matches %r in %r' % (msg, | 
 | 1159 |                                                text[match.start():match.end()], | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1160 |                                                unexpected_regex.pattern, | 
| Benjamin Peterson | b48af54 | 2010-04-11 20:43:16 +0000 | [diff] [blame] | 1161 |                                                text) | 
 | 1162 |             raise self.failureException(msg) | 
 | 1163 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1164 |  | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1165 |     def _deprecate(original_func): | 
 | 1166 |         def deprecated_func(*args, **kwargs): | 
 | 1167 |             warnings.warn( | 
 | 1168 |                 'Please use {0} instead.'.format(original_func.__name__), | 
 | 1169 |                 DeprecationWarning, 2) | 
 | 1170 |             return original_func(*args, **kwargs) | 
 | 1171 |         return deprecated_func | 
 | 1172 |  | 
| Ezio Melotti | 361467e | 2011-04-03 17:37:58 +0300 | [diff] [blame] | 1173 |     # see #9424 | 
| Ezio Melotti | ed3a7d2 | 2010-12-01 02:32:32 +0000 | [diff] [blame] | 1174 |     failUnlessEqual = assertEquals = _deprecate(assertEqual) | 
 | 1175 |     failIfEqual = assertNotEquals = _deprecate(assertNotEqual) | 
 | 1176 |     failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual) | 
 | 1177 |     failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual) | 
 | 1178 |     failUnless = assert_ = _deprecate(assertTrue) | 
 | 1179 |     failUnlessRaises = _deprecate(assertRaises) | 
 | 1180 |     failIf = _deprecate(assertFalse) | 
 | 1181 |     assertRaisesRegexp = _deprecate(assertRaisesRegex) | 
 | 1182 |     assertRegexpMatches = _deprecate(assertRegex) | 
 | 1183 |  | 
 | 1184 |  | 
 | 1185 |  | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1186 | class FunctionTestCase(TestCase): | 
 | 1187 |     """A test case that wraps a test function. | 
 | 1188 |  | 
 | 1189 |     This is useful for slipping pre-existing test functions into the | 
 | 1190 |     unittest framework. Optionally, set-up and tidy-up functions can be | 
 | 1191 |     supplied. As with TestCase, the tidy-up ('tearDown') function will | 
 | 1192 |     always be called if the set-up ('setUp') function ran successfully. | 
 | 1193 |     """ | 
 | 1194 |  | 
 | 1195 |     def __init__(self, testFunc, setUp=None, tearDown=None, description=None): | 
 | 1196 |         super(FunctionTestCase, self).__init__() | 
 | 1197 |         self._setUpFunc = setUp | 
 | 1198 |         self._tearDownFunc = tearDown | 
 | 1199 |         self._testFunc = testFunc | 
 | 1200 |         self._description = description | 
 | 1201 |  | 
 | 1202 |     def setUp(self): | 
 | 1203 |         if self._setUpFunc is not None: | 
 | 1204 |             self._setUpFunc() | 
 | 1205 |  | 
 | 1206 |     def tearDown(self): | 
 | 1207 |         if self._tearDownFunc is not None: | 
 | 1208 |             self._tearDownFunc() | 
 | 1209 |  | 
 | 1210 |     def runTest(self): | 
 | 1211 |         self._testFunc() | 
 | 1212 |  | 
 | 1213 |     def id(self): | 
 | 1214 |         return self._testFunc.__name__ | 
 | 1215 |  | 
 | 1216 |     def __eq__(self, other): | 
 | 1217 |         if not isinstance(other, self.__class__): | 
 | 1218 |             return NotImplemented | 
 | 1219 |  | 
 | 1220 |         return self._setUpFunc == other._setUpFunc and \ | 
 | 1221 |                self._tearDownFunc == other._tearDownFunc and \ | 
 | 1222 |                self._testFunc == other._testFunc and \ | 
 | 1223 |                self._description == other._description | 
 | 1224 |  | 
 | 1225 |     def __ne__(self, other): | 
 | 1226 |         return not self == other | 
 | 1227 |  | 
 | 1228 |     def __hash__(self): | 
 | 1229 |         return hash((type(self), self._setUpFunc, self._tearDownFunc, | 
 | 1230 |                      self._testFunc, self._description)) | 
 | 1231 |  | 
 | 1232 |     def __str__(self): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1233 |         return "%s (%s)" % (strclass(self.__class__), | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1234 |                             self._testFunc.__name__) | 
 | 1235 |  | 
 | 1236 |     def __repr__(self): | 
| Benjamin Peterson | 847a411 | 2010-03-14 15:04:17 +0000 | [diff] [blame] | 1237 |         return "<%s tec=%s>" % (strclass(self.__class__), | 
| Benjamin Peterson | bed7d04 | 2009-07-19 21:01:52 +0000 | [diff] [blame] | 1238 |                                      self._testFunc) | 
 | 1239 |  | 
 | 1240 |     def shortDescription(self): | 
 | 1241 |         if self._description is not None: | 
 | 1242 |             return self._description | 
 | 1243 |         doc = self._testFunc.__doc__ | 
 | 1244 |         return doc and doc.split("\n")[0].strip() or None |