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