testtools: Update to latest version.
[metze/samba/wip.git] / lib / testtools / testtools / tests / test_testcase.py
1 # Copyright (c) 2008-2012 testtools developers. See LICENSE for details.
2
3 """Tests for extensions to the base test library."""
4
5 from doctest import ELLIPSIS
6 from pprint import pformat
7 import sys
8 import unittest
9
10 from testtools import (
11     ErrorHolder,
12     MultipleExceptions,
13     PlaceHolder,
14     TestCase,
15     clone_test_with_new_id,
16     content,
17     skip,
18     skipIf,
19     skipUnless,
20     testcase,
21     )
22 from testtools.compat import (
23     _b,
24     _u,
25     )
26 from testtools.content import TracebackContent
27 from testtools.matchers import (
28     Annotate,
29     DocTestMatches,
30     Equals,
31     MatchesException,
32     Raises,
33     )
34 from testtools.testcase import Nullary
35 from testtools.testresult.doubles import (
36     Python26TestResult,
37     Python27TestResult,
38     ExtendedTestResult,
39     )
40 from testtools.tests.helpers import (
41     an_exc_info,
42     FullStackRunTest,
43     LoggingResult,
44     )
45 try:
46     exec('from __future__ import with_statement')
47 except SyntaxError:
48     pass
49 else:
50     from testtools.tests.test_with_with import *
51
52
53 class TestPlaceHolder(TestCase):
54
55     run_test_with = FullStackRunTest
56
57     def makePlaceHolder(self, test_id="foo", short_description=None):
58         return PlaceHolder(test_id, short_description)
59
60     def test_id_comes_from_constructor(self):
61         # The id() of a PlaceHolder is whatever you pass into the constructor.
62         test = PlaceHolder("test id")
63         self.assertEqual("test id", test.id())
64
65     def test_shortDescription_is_id(self):
66         # The shortDescription() of a PlaceHolder is the id, by default.
67         test = PlaceHolder("test id")
68         self.assertEqual(test.id(), test.shortDescription())
69
70     def test_shortDescription_specified(self):
71         # If a shortDescription is provided to the constructor, then
72         # shortDescription() returns that instead.
73         test = PlaceHolder("test id", "description")
74         self.assertEqual("description", test.shortDescription())
75
76     def test_repr_just_id(self):
77         # repr(placeholder) shows you how the object was constructed.
78         test = PlaceHolder("test id")
79         self.assertEqual(
80             "<testtools.testcase.PlaceHolder('addSuccess', %s, {})>" % repr(
81             test.id()), repr(test))
82
83     def test_repr_with_description(self):
84         # repr(placeholder) shows you how the object was constructed.
85         test = PlaceHolder("test id", "description")
86         self.assertEqual(
87             "<testtools.testcase.PlaceHolder('addSuccess', %r, {}, %r)>" % (
88             test.id(), test.shortDescription()), repr(test))
89
90     def test_repr_custom_outcome(self):
91         test = PlaceHolder("test id", outcome='addSkip')
92         self.assertEqual(
93             "<testtools.testcase.PlaceHolder('addSkip', %r, {})>" % (
94             test.id()), repr(test))
95
96     def test_counts_as_one_test(self):
97         # A placeholder test counts as one test.
98         test = self.makePlaceHolder()
99         self.assertEqual(1, test.countTestCases())
100
101     def test_str_is_id(self):
102         # str(placeholder) is always the id(). We are not barbarians.
103         test = self.makePlaceHolder()
104         self.assertEqual(test.id(), str(test))
105
106     def test_runs_as_success(self):
107         # When run, a PlaceHolder test records a success.
108         test = self.makePlaceHolder()
109         log = []
110         test.run(LoggingResult(log))
111         self.assertEqual(
112             [('startTest', test), ('addSuccess', test), ('stopTest', test)],
113             log)
114
115     def test_supplies_details(self):
116         details = {'quux':None}
117         test = PlaceHolder('foo', details=details)
118         result = ExtendedTestResult()
119         test.run(result)
120         self.assertEqual(
121             [('startTest', test),
122              ('addSuccess', test, details),
123              ('stopTest', test)],
124             result._events)
125
126     def test_call_is_run(self):
127         # A PlaceHolder can be called, in which case it behaves like run.
128         test = self.makePlaceHolder()
129         run_log = []
130         test.run(LoggingResult(run_log))
131         call_log = []
132         test(LoggingResult(call_log))
133         self.assertEqual(run_log, call_log)
134
135     def test_runs_without_result(self):
136         # A PlaceHolder can be run without a result, in which case there's no
137         # way to actually get at the result.
138         self.makePlaceHolder().run()
139
140     def test_debug(self):
141         # A PlaceHolder can be debugged.
142         self.makePlaceHolder().debug()
143
144
145 class TestErrorHolder(TestCase):
146     # Note that these tests exist because ErrorHolder exists - it could be
147     # deprecated and dropped at this point.
148
149     run_test_with = FullStackRunTest
150
151     def makeException(self):
152         try:
153             raise RuntimeError("danger danger")
154         except:
155             return sys.exc_info()
156
157     def makePlaceHolder(self, test_id="foo", error=None,
158                         short_description=None):
159         if error is None:
160             error = self.makeException()
161         return ErrorHolder(test_id, error, short_description)
162
163     def test_id_comes_from_constructor(self):
164         # The id() of a PlaceHolder is whatever you pass into the constructor.
165         test = ErrorHolder("test id", self.makeException())
166         self.assertEqual("test id", test.id())
167
168     def test_shortDescription_is_id(self):
169         # The shortDescription() of a PlaceHolder is the id, by default.
170         test = ErrorHolder("test id", self.makeException())
171         self.assertEqual(test.id(), test.shortDescription())
172
173     def test_shortDescription_specified(self):
174         # If a shortDescription is provided to the constructor, then
175         # shortDescription() returns that instead.
176         test = ErrorHolder("test id", self.makeException(), "description")
177         self.assertEqual("description", test.shortDescription())
178
179     def test_counts_as_one_test(self):
180         # A placeholder test counts as one test.
181         test = self.makePlaceHolder()
182         self.assertEqual(1, test.countTestCases())
183
184     def test_str_is_id(self):
185         # str(placeholder) is always the id(). We are not barbarians.
186         test = self.makePlaceHolder()
187         self.assertEqual(test.id(), str(test))
188
189     def test_runs_as_error(self):
190         # When run, an ErrorHolder test records an error.
191         error = self.makeException()
192         test = self.makePlaceHolder(error=error)
193         result = ExtendedTestResult()
194         log = result._events
195         test.run(result)
196         self.assertEqual(
197             [('startTest', test),
198              ('addError', test, test._details),
199              ('stopTest', test)], log)
200
201     def test_call_is_run(self):
202         # A PlaceHolder can be called, in which case it behaves like run.
203         test = self.makePlaceHolder()
204         run_log = []
205         test.run(LoggingResult(run_log))
206         call_log = []
207         test(LoggingResult(call_log))
208         self.assertEqual(run_log, call_log)
209
210     def test_runs_without_result(self):
211         # A PlaceHolder can be run without a result, in which case there's no
212         # way to actually get at the result.
213         self.makePlaceHolder().run()
214
215     def test_debug(self):
216         # A PlaceHolder can be debugged.
217         self.makePlaceHolder().debug()
218
219
220 class TestEquality(TestCase):
221     """Test ``TestCase``'s equality implementation."""
222
223     run_test_with = FullStackRunTest
224
225     def test_identicalIsEqual(self):
226         # TestCase's are equal if they are identical.
227         self.assertEqual(self, self)
228
229     def test_nonIdenticalInUnequal(self):
230         # TestCase's are not equal if they are not identical.
231         self.assertNotEqual(TestCase(methodName='run'),
232             TestCase(methodName='skip'))
233
234
235 class TestAssertions(TestCase):
236     """Test assertions in TestCase."""
237
238     run_test_with = FullStackRunTest
239
240     def raiseError(self, exceptionFactory, *args, **kwargs):
241         raise exceptionFactory(*args, **kwargs)
242
243     def test_formatTypes_single(self):
244         # Given a single class, _formatTypes returns the name.
245         class Foo(object):
246             pass
247         self.assertEqual('Foo', self._formatTypes(Foo))
248
249     def test_formatTypes_multiple(self):
250         # Given multiple types, _formatTypes returns the names joined by
251         # commas.
252         class Foo(object):
253             pass
254         class Bar(object):
255             pass
256         self.assertEqual('Foo, Bar', self._formatTypes([Foo, Bar]))
257
258     def test_assertRaises(self):
259         # assertRaises asserts that a callable raises a particular exception.
260         self.assertRaises(RuntimeError, self.raiseError, RuntimeError)
261
262     def test_assertRaises_fails_when_no_error_raised(self):
263         # assertRaises raises self.failureException when it's passed a
264         # callable that raises no error.
265         ret = ('orange', 42)
266         self.assertFails(
267             "<function ...<lambda> at ...> returned ('orange', 42)",
268             self.assertRaises, RuntimeError, lambda: ret)
269
270     def test_assertRaises_fails_when_different_error_raised(self):
271         # assertRaises re-raises an exception that it didn't expect.
272         self.assertThat(lambda: self.assertRaises(RuntimeError,
273             self.raiseError, ZeroDivisionError),
274             Raises(MatchesException(ZeroDivisionError)))
275
276     def test_assertRaises_returns_the_raised_exception(self):
277         # assertRaises returns the exception object that was raised. This is
278         # useful for testing that exceptions have the right message.
279
280         # This contraption stores the raised exception, so we can compare it
281         # to the return value of assertRaises.
282         raisedExceptions = []
283         def raiseError():
284             try:
285                 raise RuntimeError('Deliberate error')
286             except RuntimeError:
287                 raisedExceptions.append(sys.exc_info()[1])
288                 raise
289
290         exception = self.assertRaises(RuntimeError, raiseError)
291         self.assertEqual(1, len(raisedExceptions))
292         self.assertTrue(
293             exception is raisedExceptions[0],
294             "%r is not %r" % (exception, raisedExceptions[0]))
295
296     def test_assertRaises_with_multiple_exceptions(self):
297         # assertRaises((ExceptionOne, ExceptionTwo), function) asserts that
298         # function raises one of ExceptionTwo or ExceptionOne.
299         expectedExceptions = (RuntimeError, ZeroDivisionError)
300         self.assertRaises(
301             expectedExceptions, self.raiseError, expectedExceptions[0])
302         self.assertRaises(
303             expectedExceptions, self.raiseError, expectedExceptions[1])
304
305     def test_assertRaises_with_multiple_exceptions_failure_mode(self):
306         # If assertRaises is called expecting one of a group of exceptions and
307         # a callable that doesn't raise an exception, then fail with an
308         # appropriate error message.
309         expectedExceptions = (RuntimeError, ZeroDivisionError)
310         self.assertRaises(
311             self.failureException,
312             self.assertRaises, expectedExceptions, lambda: None)
313         self.assertFails('<function ...<lambda> at ...> returned None',
314             self.assertRaises, expectedExceptions, lambda: None)
315
316     def test_assertRaises_function_repr_in_exception(self):
317         # When assertRaises fails, it includes the repr of the invoked
318         # function in the error message, so it's easy to locate the problem.
319         def foo():
320             """An arbitrary function."""
321             pass
322         self.assertThat(
323             lambda: self.assertRaises(Exception, foo),
324             Raises(
325                 MatchesException(self.failureException, '.*%r.*' % (foo,))))
326
327     def assertFails(self, message, function, *args, **kwargs):
328         """Assert that function raises a failure with the given message."""
329         failure = self.assertRaises(
330             self.failureException, function, *args, **kwargs)
331         self.assertThat(failure, DocTestMatches(message, ELLIPSIS))
332
333     def test_assertIn_success(self):
334         # assertIn(needle, haystack) asserts that 'needle' is in 'haystack'.
335         self.assertIn(3, range(10))
336         self.assertIn('foo', 'foo bar baz')
337         self.assertIn('foo', 'foo bar baz'.split())
338
339     def test_assertIn_failure(self):
340         # assertIn(needle, haystack) fails the test when 'needle' is not in
341         # 'haystack'.
342         self.assertFails('3 not in [0, 1, 2]', self.assertIn, 3, [0, 1, 2])
343         self.assertFails(
344             '%r not in %r' % ('qux', 'foo bar baz'),
345             self.assertIn, 'qux', 'foo bar baz')
346
347     def test_assertNotIn_success(self):
348         # assertNotIn(needle, haystack) asserts that 'needle' is not in
349         # 'haystack'.
350         self.assertNotIn(3, [0, 1, 2])
351         self.assertNotIn('qux', 'foo bar baz')
352
353     def test_assertNotIn_failure(self):
354         # assertNotIn(needle, haystack) fails the test when 'needle' is in
355         # 'haystack'.
356         self.assertFails('[1, 2, 3] matches Contains(3)', self.assertNotIn,
357             3, [1, 2, 3])
358         self.assertFails(
359             "'foo bar baz' matches Contains('foo')",
360             self.assertNotIn, 'foo', 'foo bar baz')
361
362     def test_assertIsInstance(self):
363         # assertIsInstance asserts that an object is an instance of a class.
364
365         class Foo(object):
366             """Simple class for testing assertIsInstance."""
367
368         foo = Foo()
369         self.assertIsInstance(foo, Foo)
370
371     def test_assertIsInstance_multiple_classes(self):
372         # assertIsInstance asserts that an object is an instance of one of a
373         # group of classes.
374
375         class Foo(object):
376             """Simple class for testing assertIsInstance."""
377
378         class Bar(object):
379             """Another simple class for testing assertIsInstance."""
380
381         foo = Foo()
382         self.assertIsInstance(foo, (Foo, Bar))
383         self.assertIsInstance(Bar(), (Foo, Bar))
384
385     def test_assertIsInstance_failure(self):
386         # assertIsInstance(obj, klass) fails the test when obj is not an
387         # instance of klass.
388
389         class Foo(object):
390             """Simple class for testing assertIsInstance."""
391
392         self.assertFails(
393             "'42' is not an instance of %s" % self._formatTypes(Foo),
394             self.assertIsInstance, 42, Foo)
395
396     def test_assertIsInstance_failure_multiple_classes(self):
397         # assertIsInstance(obj, (klass1, klass2)) fails the test when obj is
398         # not an instance of klass1 or klass2.
399
400         class Foo(object):
401             """Simple class for testing assertIsInstance."""
402
403         class Bar(object):
404             """Another simple class for testing assertIsInstance."""
405
406         self.assertFails(
407             "'42' is not an instance of any of (%s)" % self._formatTypes([Foo, Bar]),
408             self.assertIsInstance, 42, (Foo, Bar))
409
410     def test_assertIsInstance_overridden_message(self):
411         # assertIsInstance(obj, klass, msg) permits a custom message.
412         self.assertFails("'42' is not an instance of str: foo",
413             self.assertIsInstance, 42, str, "foo")
414
415     def test_assertIs(self):
416         # assertIs asserts that an object is identical to another object.
417         self.assertIs(None, None)
418         some_list = [42]
419         self.assertIs(some_list, some_list)
420         some_object = object()
421         self.assertIs(some_object, some_object)
422
423     def test_assertIs_fails(self):
424         # assertIs raises assertion errors if one object is not identical to
425         # another.
426         self.assertFails('None is not 42', self.assertIs, None, 42)
427         self.assertFails('[42] is not [42]', self.assertIs, [42], [42])
428
429     def test_assertIs_fails_with_message(self):
430         # assertIs raises assertion errors if one object is not identical to
431         # another, and includes a user-supplied message, if it's provided.
432         self.assertFails(
433             'None is not 42: foo bar', self.assertIs, None, 42, 'foo bar')
434
435     def test_assertIsNot(self):
436         # assertIsNot asserts that an object is not identical to another
437         # object.
438         self.assertIsNot(None, 42)
439         self.assertIsNot([42], [42])
440         self.assertIsNot(object(), object())
441
442     def test_assertIsNot_fails(self):
443         # assertIsNot raises assertion errors if one object is identical to
444         # another.
445         self.assertFails('None matches Is(None)', self.assertIsNot, None, None)
446         some_list = [42]
447         self.assertFails(
448             '[42] matches Is([42])', self.assertIsNot, some_list, some_list)
449
450     def test_assertIsNot_fails_with_message(self):
451         # assertIsNot raises assertion errors if one object is identical to
452         # another, and includes a user-supplied message if it's provided.
453         self.assertFails(
454             'None matches Is(None): foo bar', self.assertIsNot, None, None,
455             "foo bar")
456
457     def test_assertThat_matches_clean(self):
458         class Matcher(object):
459             def match(self, foo):
460                 return None
461         self.assertThat("foo", Matcher())
462
463     def test_assertThat_mismatch_raises_description(self):
464         calls = []
465         class Mismatch(object):
466             def __init__(self, thing):
467                 self.thing = thing
468             def describe(self):
469                 calls.append(('describe_diff', self.thing))
470                 return "object is not a thing"
471             def get_details(self):
472                 return {}
473         class Matcher(object):
474             def match(self, thing):
475                 calls.append(('match', thing))
476                 return Mismatch(thing)
477             def __str__(self):
478                 calls.append(('__str__',))
479                 return "a description"
480         class Test(TestCase):
481             def test(self):
482                 self.assertThat("foo", Matcher())
483         result = Test("test").run()
484         self.assertEqual([
485             ('match', "foo"),
486             ('describe_diff', "foo"),
487             ], calls)
488         self.assertFalse(result.wasSuccessful())
489
490     def test_assertThat_output(self):
491         matchee = 'foo'
492         matcher = Equals('bar')
493         expected = matcher.match(matchee).describe()
494         self.assertFails(expected, self.assertThat, matchee, matcher)
495
496     def test_assertThat_message_is_annotated(self):
497         matchee = 'foo'
498         matcher = Equals('bar')
499         expected = Annotate('woo', matcher).match(matchee).describe()
500         self.assertFails(expected, self.assertThat, matchee, matcher, 'woo')
501
502     def test_assertThat_verbose_output(self):
503         matchee = 'foo'
504         matcher = Equals('bar')
505         expected = (
506             'Match failed. Matchee: %r\n'
507             'Matcher: %s\n'
508             'Difference: %s\n' % (
509                 matchee,
510                 matcher,
511                 matcher.match(matchee).describe(),
512                 ))
513         self.assertFails(
514             expected, self.assertThat, matchee, matcher, verbose=True)
515
516     def get_error_string(self, e):
517         """Get the string showing how 'e' would be formatted in test output.
518
519         This is a little bit hacky, since it's designed to give consistent
520         output regardless of Python version.
521
522         In testtools, TestResult._exc_info_to_unicode is the point of dispatch
523         between various different implementations of methods that format
524         exceptions, so that's what we have to call. However, that method cares
525         about stack traces and formats the exception class. We don't care
526         about either of these, so we take its output and parse it a little.
527         """
528         error = TracebackContent((e.__class__, e, None), self).as_text()
529         # We aren't at all interested in the traceback.
530         if error.startswith('Traceback (most recent call last):\n'):
531             lines = error.splitlines(True)[1:]
532             for i, line in enumerate(lines):
533                 if not line.startswith(' '):
534                     break
535             error = ''.join(lines[i:])
536         # We aren't interested in how the exception type is formatted.
537         exc_class, error = error.split(': ', 1)
538         return error
539
540     def test_assertThat_verbose_unicode(self):
541         # When assertThat is given matchees or matchers that contain non-ASCII
542         # unicode strings, we can still provide a meaningful error.
543         matchee = _u('\xa7')
544         matcher = Equals(_u('a'))
545         expected = (
546             'Match failed. Matchee: %s\n'
547             'Matcher: %s\n'
548             'Difference: %s\n\n' % (
549                 repr(matchee).replace("\\xa7", matchee),
550                 matcher,
551                 matcher.match(matchee).describe(),
552                 ))
553         e = self.assertRaises(
554             self.failureException, self.assertThat, matchee, matcher,
555             verbose=True)
556         self.assertEqual(expected, self.get_error_string(e))
557
558     def test_assertEqual_nice_formatting(self):
559         message = "These things ought not be equal."
560         a = ['apple', 'banana', 'cherry']
561         b = {'Thatcher': 'One who mends roofs of straw',
562              'Major': 'A military officer, ranked below colonel',
563              'Blair': 'To shout loudly',
564              'Brown': 'The colour of healthy human faeces'}
565         expected_error = '\n'.join([
566             '!=:',
567             'reference = %s' % pformat(a),
568             'actual    = %s' % pformat(b),
569             ': ' + message,
570             ])
571         self.assertFails(expected_error, self.assertEqual, a, b, message)
572         self.assertFails(expected_error, self.assertEquals, a, b, message)
573         self.assertFails(expected_error, self.failUnlessEqual, a, b, message)
574
575     def test_assertEqual_formatting_no_message(self):
576         a = "cat"
577         b = "dog"
578         expected_error = "'cat' != 'dog'"
579         self.assertFails(expected_error, self.assertEqual, a, b)
580         self.assertFails(expected_error, self.assertEquals, a, b)
581         self.assertFails(expected_error, self.failUnlessEqual, a, b)
582
583     def test_assertEqual_non_ascii_str_with_newlines(self):
584         message = _u("Be careful mixing unicode and bytes")
585         a = "a\n\xa7\n"
586         b = "Just a longish string so the more verbose output form is used."
587         expected_error = '\n'.join([
588             '!=:',
589             "reference = '''\\",
590             'a',
591             repr('\xa7')[1:-1],
592             "'''",
593             'actual    = %r' % (b,),
594             ': ' + message,
595             ])
596         self.assertFails(expected_error, self.assertEqual, a, b, message)
597
598     def test_assertIsNone(self):
599         self.assertIsNone(None)
600
601         expected_error = 'None is not 0'
602         self.assertFails(expected_error, self.assertIsNone, 0)
603
604     def test_assertIsNotNone(self):
605         self.assertIsNotNone(0)
606         self.assertIsNotNone("0")
607
608         expected_error = 'None matches Is(None)'
609         self.assertFails(expected_error, self.assertIsNotNone, None)
610
611
612 class TestAddCleanup(TestCase):
613     """Tests for TestCase.addCleanup."""
614
615     run_test_with = FullStackRunTest
616
617     class LoggingTest(TestCase):
618         """A test that logs calls to setUp, runTest and tearDown."""
619
620         def setUp(self):
621             TestCase.setUp(self)
622             self._calls = ['setUp']
623
624         def brokenSetUp(self):
625             # A tearDown that deliberately fails.
626             self._calls = ['brokenSetUp']
627             raise RuntimeError('Deliberate Failure')
628
629         def runTest(self):
630             self._calls.append('runTest')
631
632         def brokenTest(self):
633             raise RuntimeError('Deliberate broken test')
634
635         def tearDown(self):
636             self._calls.append('tearDown')
637             TestCase.tearDown(self)
638
639     def setUp(self):
640         TestCase.setUp(self)
641         self._result_calls = []
642         self.test = TestAddCleanup.LoggingTest('runTest')
643         self.logging_result = LoggingResult(self._result_calls)
644
645     def assertErrorLogEqual(self, messages):
646         self.assertEqual(messages, [call[0] for call in self._result_calls])
647
648     def assertTestLogEqual(self, messages):
649         """Assert that the call log equals 'messages'."""
650         case = self._result_calls[0][1]
651         self.assertEqual(messages, case._calls)
652
653     def logAppender(self, message):
654         """A cleanup that appends 'message' to the tests log.
655
656         Cleanups are callables that are added to a test by addCleanup. To
657         verify that our cleanups run in the right order, we add strings to a
658         list that acts as a log. This method returns a cleanup that will add
659         the given message to that log when run.
660         """
661         self.test._calls.append(message)
662
663     def test_fixture(self):
664         # A normal run of self.test logs 'setUp', 'runTest' and 'tearDown'.
665         # This test doesn't test addCleanup itself, it just sanity checks the
666         # fixture.
667         self.test.run(self.logging_result)
668         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
669
670     def test_cleanup_run_before_tearDown(self):
671         # Cleanup functions added with 'addCleanup' are called before tearDown
672         # runs.
673         self.test.addCleanup(self.logAppender, 'cleanup')
674         self.test.run(self.logging_result)
675         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown', 'cleanup'])
676
677     def test_add_cleanup_called_if_setUp_fails(self):
678         # Cleanup functions added with 'addCleanup' are called even if setUp
679         # fails. Note that tearDown has a different behavior: it is only
680         # called when setUp succeeds.
681         self.test.setUp = self.test.brokenSetUp
682         self.test.addCleanup(self.logAppender, 'cleanup')
683         self.test.run(self.logging_result)
684         self.assertTestLogEqual(['brokenSetUp', 'cleanup'])
685
686     def test_addCleanup_called_in_reverse_order(self):
687         # Cleanup functions added with 'addCleanup' are called in reverse
688         # order.
689         #
690         # One of the main uses of addCleanup is to dynamically create
691         # resources that need some sort of explicit tearDown. Often one
692         # resource will be created in terms of another, e.g.,
693         #     self.first = self.makeFirst()
694         #     self.second = self.makeSecond(self.first)
695         #
696         # When this happens, we generally want to clean up the second resource
697         # before the first one, since the second depends on the first.
698         self.test.addCleanup(self.logAppender, 'first')
699         self.test.addCleanup(self.logAppender, 'second')
700         self.test.run(self.logging_result)
701         self.assertTestLogEqual(
702             ['setUp', 'runTest', 'tearDown', 'second', 'first'])
703
704     def test_tearDown_runs_after_cleanup_failure(self):
705         # tearDown runs even if a cleanup function fails.
706         self.test.addCleanup(lambda: 1/0)
707         self.test.run(self.logging_result)
708         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
709
710     def test_cleanups_continue_running_after_error(self):
711         # All cleanups are always run, even if one or two of them fail.
712         self.test.addCleanup(self.logAppender, 'first')
713         self.test.addCleanup(lambda: 1/0)
714         self.test.addCleanup(self.logAppender, 'second')
715         self.test.run(self.logging_result)
716         self.assertTestLogEqual(
717             ['setUp', 'runTest', 'tearDown', 'second', 'first'])
718
719     def test_error_in_cleanups_are_captured(self):
720         # If a cleanup raises an error, we want to record it and fail the the
721         # test, even though we go on to run other cleanups.
722         self.test.addCleanup(lambda: 1/0)
723         self.test.run(self.logging_result)
724         self.assertErrorLogEqual(['startTest', 'addError', 'stopTest'])
725
726     def test_keyboard_interrupt_not_caught(self):
727         # If a cleanup raises KeyboardInterrupt, it gets reraised.
728         def raiseKeyboardInterrupt():
729             raise KeyboardInterrupt()
730         self.test.addCleanup(raiseKeyboardInterrupt)
731         self.assertThat(lambda:self.test.run(self.logging_result),
732             Raises(MatchesException(KeyboardInterrupt)))
733
734     def test_all_errors_from_MultipleExceptions_reported(self):
735         # When a MultipleExceptions exception is caught, all the errors are
736         # reported.
737         def raiseMany():
738             try:
739                 1/0
740             except Exception:
741                 exc_info1 = sys.exc_info()
742             try:
743                 1/0
744             except Exception:
745                 exc_info2 = sys.exc_info()
746             raise MultipleExceptions(exc_info1, exc_info2)
747         self.test.addCleanup(raiseMany)
748         self.logging_result = ExtendedTestResult()
749         self.test.run(self.logging_result)
750         self.assertEqual(['startTest', 'addError', 'stopTest'],
751             [event[0] for event in self.logging_result._events])
752         self.assertEqual(set(['traceback', 'traceback-1']),
753             set(self.logging_result._events[1][2].keys()))
754
755     def test_multipleCleanupErrorsReported(self):
756         # Errors from all failing cleanups are reported as separate backtraces.
757         self.test.addCleanup(lambda: 1/0)
758         self.test.addCleanup(lambda: 1/0)
759         self.logging_result = ExtendedTestResult()
760         self.test.run(self.logging_result)
761         self.assertEqual(['startTest', 'addError', 'stopTest'],
762             [event[0] for event in self.logging_result._events])
763         self.assertEqual(set(['traceback', 'traceback-1']),
764             set(self.logging_result._events[1][2].keys()))
765
766     def test_multipleErrorsCoreAndCleanupReported(self):
767         # Errors from all failing cleanups are reported, with stopTest,
768         # startTest inserted.
769         self.test = TestAddCleanup.LoggingTest('brokenTest')
770         self.test.addCleanup(lambda: 1/0)
771         self.test.addCleanup(lambda: 1/0)
772         self.logging_result = ExtendedTestResult()
773         self.test.run(self.logging_result)
774         self.assertEqual(['startTest', 'addError', 'stopTest'],
775             [event[0] for event in self.logging_result._events])
776         self.assertEqual(set(['traceback', 'traceback-1', 'traceback-2']),
777             set(self.logging_result._events[1][2].keys()))
778
779
780 class TestWithDetails(TestCase):
781
782     run_test_with = FullStackRunTest
783
784     def assertDetailsProvided(self, case, expected_outcome, expected_keys):
785         """Assert that when case is run, details are provided to the result.
786
787         :param case: A TestCase to run.
788         :param expected_outcome: The call that should be made.
789         :param expected_keys: The keys to look for.
790         """
791         result = ExtendedTestResult()
792         case.run(result)
793         case = result._events[0][1]
794         expected = [
795             ('startTest', case),
796             (expected_outcome, case),
797             ('stopTest', case),
798             ]
799         self.assertEqual(3, len(result._events))
800         self.assertEqual(expected[0], result._events[0])
801         self.assertEqual(expected[1], result._events[1][0:2])
802         # Checking the TB is right is rather tricky. doctest line matching
803         # would help, but 'meh'.
804         self.assertEqual(sorted(expected_keys),
805             sorted(result._events[1][2].keys()))
806         self.assertEqual(expected[-1], result._events[-1])
807
808     def get_content(self):
809         return content.Content(
810             content.ContentType("text", "foo"), lambda: [_b('foo')])
811
812
813 class TestExpectedFailure(TestWithDetails):
814     """Tests for expected failures and unexpected successess."""
815
816     run_test_with = FullStackRunTest
817
818     def make_unexpected_case(self):
819         class Case(TestCase):
820             def test(self):
821                 raise testcase._UnexpectedSuccess
822         case = Case('test')
823         return case
824
825     def test_raising__UnexpectedSuccess_py27(self):
826         case = self.make_unexpected_case()
827         result = Python27TestResult()
828         case.run(result)
829         case = result._events[0][1]
830         self.assertEqual([
831             ('startTest', case),
832             ('addUnexpectedSuccess', case),
833             ('stopTest', case),
834             ], result._events)
835
836     def test_raising__UnexpectedSuccess_extended(self):
837         case = self.make_unexpected_case()
838         result = ExtendedTestResult()
839         case.run(result)
840         case = result._events[0][1]
841         self.assertEqual([
842             ('startTest', case),
843             ('addUnexpectedSuccess', case, {}),
844             ('stopTest', case),
845             ], result._events)
846
847     def make_xfail_case_xfails(self):
848         content = self.get_content()
849         class Case(TestCase):
850             def test(self):
851                 self.addDetail("foo", content)
852                 self.expectFailure("we are sad", self.assertEqual,
853                     1, 0)
854         case = Case('test')
855         return case
856
857     def make_xfail_case_succeeds(self):
858         content = self.get_content()
859         class Case(TestCase):
860             def test(self):
861                 self.addDetail("foo", content)
862                 self.expectFailure("we are sad", self.assertEqual,
863                     1, 1)
864         case = Case('test')
865         return case
866
867     def test_expectFailure_KnownFailure_extended(self):
868         case = self.make_xfail_case_xfails()
869         self.assertDetailsProvided(case, "addExpectedFailure",
870             ["foo", "traceback", "reason"])
871
872     def test_expectFailure_KnownFailure_unexpected_success(self):
873         case = self.make_xfail_case_succeeds()
874         self.assertDetailsProvided(case, "addUnexpectedSuccess",
875             ["foo", "reason"])
876
877
878 class TestUniqueFactories(TestCase):
879     """Tests for getUniqueString and getUniqueInteger."""
880
881     run_test_with = FullStackRunTest
882
883     def test_getUniqueInteger(self):
884         # getUniqueInteger returns an integer that increments each time you
885         # call it.
886         one = self.getUniqueInteger()
887         self.assertEqual(1, one)
888         two = self.getUniqueInteger()
889         self.assertEqual(2, two)
890
891     def test_getUniqueString(self):
892         # getUniqueString returns the current test id followed by a unique
893         # integer.
894         name_one = self.getUniqueString()
895         self.assertEqual('%s-%d' % (self.id(), 1), name_one)
896         name_two = self.getUniqueString()
897         self.assertEqual('%s-%d' % (self.id(), 2), name_two)
898
899     def test_getUniqueString_prefix(self):
900         # If getUniqueString is given an argument, it uses that argument as
901         # the prefix of the unique string, rather than the test id.
902         name_one = self.getUniqueString('foo')
903         self.assertThat(name_one, Equals('foo-1'))
904         name_two = self.getUniqueString('bar')
905         self.assertThat(name_two, Equals('bar-2'))
906
907
908 class TestCloneTestWithNewId(TestCase):
909     """Tests for clone_test_with_new_id."""
910
911     run_test_with = FullStackRunTest
912
913     def test_clone_test_with_new_id(self):
914         class FooTestCase(TestCase):
915             def test_foo(self):
916                 pass
917         test = FooTestCase('test_foo')
918         oldName = test.id()
919         newName = self.getUniqueString()
920         newTest = clone_test_with_new_id(test, newName)
921         self.assertEqual(newName, newTest.id())
922         self.assertEqual(oldName, test.id(),
923             "the original test instance should be unchanged.")
924
925     def test_cloned_testcase_does_not_share_details(self):
926         """A cloned TestCase does not share the details dict."""
927         class Test(TestCase):
928             def test_foo(self):
929                 self.addDetail(
930                     'foo', content.Content('text/plain', lambda: 'foo'))
931         orig_test = Test('test_foo')
932         cloned_test = clone_test_with_new_id(orig_test, self.getUniqueString())
933         orig_test.run(unittest.TestResult())
934         self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
935         self.assertEqual(None, cloned_test.getDetails().get('foo'))
936
937
938 class TestDetailsProvided(TestWithDetails):
939
940     run_test_with = FullStackRunTest
941
942     def test_addDetail(self):
943         mycontent = self.get_content()
944         self.addDetail("foo", mycontent)
945         details = self.getDetails()
946         self.assertEqual({"foo": mycontent}, details)
947
948     def test_addError(self):
949         class Case(TestCase):
950             def test(this):
951                 this.addDetail("foo", self.get_content())
952                 1/0
953         self.assertDetailsProvided(Case("test"), "addError",
954             ["foo", "traceback"])
955
956     def test_addFailure(self):
957         class Case(TestCase):
958             def test(this):
959                 this.addDetail("foo", self.get_content())
960                 self.fail('yo')
961         self.assertDetailsProvided(Case("test"), "addFailure",
962             ["foo", "traceback"])
963
964     def test_addSkip(self):
965         class Case(TestCase):
966             def test(this):
967                 this.addDetail("foo", self.get_content())
968                 self.skip('yo')
969         self.assertDetailsProvided(Case("test"), "addSkip",
970             ["foo", "reason"])
971
972     def test_addSucccess(self):
973         class Case(TestCase):
974             def test(this):
975                 this.addDetail("foo", self.get_content())
976         self.assertDetailsProvided(Case("test"), "addSuccess",
977             ["foo"])
978
979     def test_addUnexpectedSuccess(self):
980         class Case(TestCase):
981             def test(this):
982                 this.addDetail("foo", self.get_content())
983                 raise testcase._UnexpectedSuccess()
984         self.assertDetailsProvided(Case("test"), "addUnexpectedSuccess",
985             ["foo"])
986
987     def test_addDetails_from_Mismatch(self):
988         content = self.get_content()
989         class Mismatch(object):
990             def describe(self):
991                 return "Mismatch"
992             def get_details(self):
993                 return {"foo": content}
994         class Matcher(object):
995             def match(self, thing):
996                 return Mismatch()
997             def __str__(self):
998                 return "a description"
999         class Case(TestCase):
1000             def test(self):
1001                 self.assertThat("foo", Matcher())
1002         self.assertDetailsProvided(Case("test"), "addFailure",
1003             ["foo", "traceback"])
1004
1005     def test_multiple_addDetails_from_Mismatch(self):
1006         content = self.get_content()
1007         class Mismatch(object):
1008             def describe(self):
1009                 return "Mismatch"
1010             def get_details(self):
1011                 return {"foo": content, "bar": content}
1012         class Matcher(object):
1013             def match(self, thing):
1014                 return Mismatch()
1015             def __str__(self):
1016                 return "a description"
1017         class Case(TestCase):
1018             def test(self):
1019                 self.assertThat("foo", Matcher())
1020         self.assertDetailsProvided(Case("test"), "addFailure",
1021             ["bar", "foo", "traceback"])
1022
1023     def test_addDetails_with_same_name_as_key_from_get_details(self):
1024         content = self.get_content()
1025         class Mismatch(object):
1026             def describe(self):
1027                 return "Mismatch"
1028             def get_details(self):
1029                 return {"foo": content}
1030         class Matcher(object):
1031             def match(self, thing):
1032                 return Mismatch()
1033             def __str__(self):
1034                 return "a description"
1035         class Case(TestCase):
1036             def test(self):
1037                 self.addDetail("foo", content)
1038                 self.assertThat("foo", Matcher())
1039         self.assertDetailsProvided(Case("test"), "addFailure",
1040             ["foo", "foo-1", "traceback"])
1041
1042
1043 class TestSetupTearDown(TestCase):
1044
1045     run_test_with = FullStackRunTest
1046
1047     def test_setUpNotCalled(self):
1048         class DoesnotcallsetUp(TestCase):
1049             def setUp(self):
1050                 pass
1051             def test_method(self):
1052                 pass
1053         result = unittest.TestResult()
1054         DoesnotcallsetUp('test_method').run(result)
1055         self.assertEqual(1, len(result.errors))
1056
1057     def test_tearDownNotCalled(self):
1058         class DoesnotcalltearDown(TestCase):
1059             def test_method(self):
1060                 pass
1061             def tearDown(self):
1062                 pass
1063         result = unittest.TestResult()
1064         DoesnotcalltearDown('test_method').run(result)
1065         self.assertEqual(1, len(result.errors))
1066
1067
1068 class TestSkipping(TestCase):
1069     """Tests for skipping of tests functionality."""
1070
1071     run_test_with = FullStackRunTest
1072
1073     def test_skip_causes_skipException(self):
1074         self.assertThat(lambda:self.skip("Skip this test"),
1075             Raises(MatchesException(self.skipException)))
1076
1077     def test_can_use_skipTest(self):
1078         self.assertThat(lambda:self.skipTest("Skip this test"),
1079             Raises(MatchesException(self.skipException)))
1080
1081     def test_skip_without_reason_works(self):
1082         class Test(TestCase):
1083             def test(self):
1084                 raise self.skipException()
1085         case = Test("test")
1086         result = ExtendedTestResult()
1087         case.run(result)
1088         self.assertEqual('addSkip', result._events[1][0])
1089         self.assertEqual('no reason given.',
1090             result._events[1][2]['reason'].as_text())
1091
1092     def test_skipException_in_setup_calls_result_addSkip(self):
1093         class TestThatRaisesInSetUp(TestCase):
1094             def setUp(self):
1095                 TestCase.setUp(self)
1096                 self.skip("skipping this test")
1097             def test_that_passes(self):
1098                 pass
1099         calls = []
1100         result = LoggingResult(calls)
1101         test = TestThatRaisesInSetUp("test_that_passes")
1102         test.run(result)
1103         case = result._events[0][1]
1104         self.assertEqual([('startTest', case),
1105             ('addSkip', case, "skipping this test"), ('stopTest', case)],
1106             calls)
1107
1108     def test_skipException_in_test_method_calls_result_addSkip(self):
1109         class SkippingTest(TestCase):
1110             def test_that_raises_skipException(self):
1111                 self.skip("skipping this test")
1112         result = Python27TestResult()
1113         test = SkippingTest("test_that_raises_skipException")
1114         test.run(result)
1115         case = result._events[0][1]
1116         self.assertEqual([('startTest', case),
1117             ('addSkip', case, "skipping this test"), ('stopTest', case)],
1118             result._events)
1119
1120     def test_skip__in_setup_with_old_result_object_calls_addSuccess(self):
1121         class SkippingTest(TestCase):
1122             def setUp(self):
1123                 TestCase.setUp(self)
1124                 raise self.skipException("skipping this test")
1125             def test_that_raises_skipException(self):
1126                 pass
1127         result = Python26TestResult()
1128         test = SkippingTest("test_that_raises_skipException")
1129         test.run(result)
1130         self.assertEqual('addSuccess', result._events[1][0])
1131
1132     def test_skip_with_old_result_object_calls_addError(self):
1133         class SkippingTest(TestCase):
1134             def test_that_raises_skipException(self):
1135                 raise self.skipException("skipping this test")
1136         result = Python26TestResult()
1137         test = SkippingTest("test_that_raises_skipException")
1138         test.run(result)
1139         self.assertEqual('addSuccess', result._events[1][0])
1140
1141     def test_skip_decorator(self):
1142         class SkippingTest(TestCase):
1143             @skip("skipping this test")
1144             def test_that_is_decorated_with_skip(self):
1145                 self.fail()
1146         result = Python26TestResult()
1147         test = SkippingTest("test_that_is_decorated_with_skip")
1148         test.run(result)
1149         self.assertEqual('addSuccess', result._events[1][0])
1150
1151     def test_skipIf_decorator(self):
1152         class SkippingTest(TestCase):
1153             @skipIf(True, "skipping this test")
1154             def test_that_is_decorated_with_skipIf(self):
1155                 self.fail()
1156         result = Python26TestResult()
1157         test = SkippingTest("test_that_is_decorated_with_skipIf")
1158         test.run(result)
1159         self.assertEqual('addSuccess', result._events[1][0])
1160
1161     def test_skipUnless_decorator(self):
1162         class SkippingTest(TestCase):
1163             @skipUnless(False, "skipping this test")
1164             def test_that_is_decorated_with_skipUnless(self):
1165                 self.fail()
1166         result = Python26TestResult()
1167         test = SkippingTest("test_that_is_decorated_with_skipUnless")
1168         test.run(result)
1169         self.assertEqual('addSuccess', result._events[1][0])
1170
1171
1172 class TestOnException(TestCase):
1173
1174     run_test_with = FullStackRunTest
1175
1176     def test_default_works(self):
1177         events = []
1178         class Case(TestCase):
1179             def method(self):
1180                 self.onException(an_exc_info)
1181                 events.append(True)
1182         case = Case("method")
1183         case.run()
1184         self.assertThat(events, Equals([True]))
1185
1186     def test_added_handler_works(self):
1187         events = []
1188         class Case(TestCase):
1189             def method(self):
1190                 self.addOnException(events.append)
1191                 self.onException(an_exc_info)
1192         case = Case("method")
1193         case.run()
1194         self.assertThat(events, Equals([an_exc_info]))
1195
1196     def test_handler_that_raises_is_not_caught(self):
1197         events = []
1198         class Case(TestCase):
1199             def method(self):
1200                 self.addOnException(events.index)
1201                 self.assertThat(lambda: self.onException(an_exc_info),
1202                     Raises(MatchesException(ValueError)))
1203         case = Case("method")
1204         case.run()
1205         self.assertThat(events, Equals([]))
1206
1207
1208 class TestPatchSupport(TestCase):
1209
1210     run_test_with = FullStackRunTest
1211
1212     class Case(TestCase):
1213         def test(self):
1214             pass
1215
1216     def test_patch(self):
1217         # TestCase.patch masks obj.attribute with the new value.
1218         self.foo = 'original'
1219         test = self.Case('test')
1220         test.patch(self, 'foo', 'patched')
1221         self.assertEqual('patched', self.foo)
1222
1223     def test_patch_restored_after_run(self):
1224         # TestCase.patch masks obj.attribute with the new value, but restores
1225         # the original value after the test is finished.
1226         self.foo = 'original'
1227         test = self.Case('test')
1228         test.patch(self, 'foo', 'patched')
1229         test.run()
1230         self.assertEqual('original', self.foo)
1231
1232     def test_successive_patches_apply(self):
1233         # TestCase.patch can be called multiple times per test. Each time you
1234         # call it, it overrides the original value.
1235         self.foo = 'original'
1236         test = self.Case('test')
1237         test.patch(self, 'foo', 'patched')
1238         test.patch(self, 'foo', 'second')
1239         self.assertEqual('second', self.foo)
1240
1241     def test_successive_patches_restored_after_run(self):
1242         # TestCase.patch restores the original value, no matter how many times
1243         # it was called.
1244         self.foo = 'original'
1245         test = self.Case('test')
1246         test.patch(self, 'foo', 'patched')
1247         test.patch(self, 'foo', 'second')
1248         test.run()
1249         self.assertEqual('original', self.foo)
1250
1251     def test_patch_nonexistent_attribute(self):
1252         # TestCase.patch can be used to patch a non-existent attribute.
1253         test = self.Case('test')
1254         test.patch(self, 'doesntexist', 'patched')
1255         self.assertEqual('patched', self.doesntexist)
1256
1257     def test_restore_nonexistent_attribute(self):
1258         # TestCase.patch can be used to patch a non-existent attribute, after
1259         # the test run, the attribute is then removed from the object.
1260         test = self.Case('test')
1261         test.patch(self, 'doesntexist', 'patched')
1262         test.run()
1263         marker = object()
1264         value = getattr(self, 'doesntexist', marker)
1265         self.assertIs(marker, value)
1266
1267
1268 class TestTestCaseSuper(TestCase):
1269
1270     run_test_with = FullStackRunTest
1271
1272     def test_setup_uses_super(self):
1273         class OtherBaseCase(unittest.TestCase):
1274             setup_called = False
1275             def setUp(self):
1276                 self.setup_called = True
1277                 super(OtherBaseCase, self).setUp()
1278         class OurCase(TestCase, OtherBaseCase):
1279             def runTest(self):
1280                 pass
1281         test = OurCase()
1282         test.setUp()
1283         test.tearDown()
1284         self.assertTrue(test.setup_called)
1285
1286     def test_teardown_uses_super(self):
1287         class OtherBaseCase(unittest.TestCase):
1288             teardown_called = False
1289             def tearDown(self):
1290                 self.teardown_called = True
1291                 super(OtherBaseCase, self).tearDown()
1292         class OurCase(TestCase, OtherBaseCase):
1293             def runTest(self):
1294                 pass
1295         test = OurCase()
1296         test.setUp()
1297         test.tearDown()
1298         self.assertTrue(test.teardown_called)
1299
1300
1301 class TestNullary(TestCase):
1302
1303     def test_repr(self):
1304         # The repr() of nullary is the same as the repr() of the wrapped
1305         # function.
1306         def foo():
1307             pass
1308         wrapped = Nullary(foo)
1309         self.assertEqual(repr(wrapped), repr(foo))
1310
1311     def test_called_with_arguments(self):
1312         # The function is called with the arguments given to Nullary's
1313         # constructor.
1314         l = []
1315         def foo(*args, **kwargs):
1316             l.append((args, kwargs))
1317         wrapped = Nullary(foo, 1, 2, a="b")
1318         wrapped()
1319         self.assertEqual(l, [((1, 2), {'a': 'b'})])
1320
1321     def test_returns_wrapped(self):
1322         # Calling Nullary returns whatever the function returns.
1323         ret = object()
1324         wrapped = Nullary(lambda: ret)
1325         self.assertIs(ret, wrapped())
1326
1327     def test_raises(self):
1328         # If the function raises, so does Nullary when called.
1329         wrapped = Nullary(lambda: 1/0)
1330         self.assertRaises(ZeroDivisionError, wrapped)
1331
1332
1333 def test_suite():
1334     from unittest import TestLoader
1335     return TestLoader().loadTestsFromName(__name__)