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