diff options
Diffstat (limited to 'lib/testtools/testtools/tests/matchers/test_exception.py')
-rw-r--r-- | lib/testtools/testtools/tests/matchers/test_exception.py | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/testtools/testtools/tests/matchers/test_exception.py b/lib/testtools/testtools/tests/matchers/test_exception.py new file mode 100644 index 0000000000..ef7185f19a --- /dev/null +++ b/lib/testtools/testtools/tests/matchers/test_exception.py @@ -0,0 +1,192 @@ +# Copyright (c) 2008-2012 testtools developers. See LICENSE for details. + +import sys + +from testtools import TestCase +from testtools.matchers import ( + AfterPreprocessing, + Equals, + ) +from testtools.matchers._exception import ( + MatchesException, + Raises, + raises, + ) +from testtools.tests.helpers import FullStackRunTest +from testtools.tests.matchers.helpers import TestMatchersInterface + + +def make_error(type, *args, **kwargs): + try: + raise type(*args, **kwargs) + except type: + return sys.exc_info() + + +class TestMatchesExceptionInstanceInterface(TestCase, TestMatchersInterface): + + matches_matcher = MatchesException(ValueError("foo")) + error_foo = make_error(ValueError, 'foo') + error_bar = make_error(ValueError, 'bar') + error_base_foo = make_error(Exception, 'foo') + matches_matches = [error_foo] + matches_mismatches = [error_bar, error_base_foo] + + str_examples = [ + ("MatchesException(Exception('foo',))", + MatchesException(Exception('foo'))) + ] + describe_examples = [ + ("%r is not a %r" % (Exception, ValueError), + error_base_foo, + MatchesException(ValueError("foo"))), + ("ValueError('bar',) has different arguments to ValueError('foo',).", + error_bar, + MatchesException(ValueError("foo"))), + ] + + +class TestMatchesExceptionTypeInterface(TestCase, TestMatchersInterface): + + matches_matcher = MatchesException(ValueError) + error_foo = make_error(ValueError, 'foo') + error_sub = make_error(UnicodeError, 'bar') + error_base_foo = make_error(Exception, 'foo') + matches_matches = [error_foo, error_sub] + matches_mismatches = [error_base_foo] + + str_examples = [ + ("MatchesException(%r)" % Exception, + MatchesException(Exception)) + ] + describe_examples = [ + ("%r is not a %r" % (Exception, ValueError), + error_base_foo, + MatchesException(ValueError)), + ] + + +class TestMatchesExceptionTypeReInterface(TestCase, TestMatchersInterface): + + matches_matcher = MatchesException(ValueError, 'fo.') + error_foo = make_error(ValueError, 'foo') + error_sub = make_error(UnicodeError, 'foo') + error_bar = make_error(ValueError, 'bar') + matches_matches = [error_foo, error_sub] + matches_mismatches = [error_bar] + + str_examples = [ + ("MatchesException(%r)" % Exception, + MatchesException(Exception, 'fo.')) + ] + describe_examples = [ + ("'bar' does not match /fo./", + error_bar, MatchesException(ValueError, "fo.")), + ] + + +class TestMatchesExceptionTypeMatcherInterface(TestCase, TestMatchersInterface): + + matches_matcher = MatchesException( + ValueError, AfterPreprocessing(str, Equals('foo'))) + error_foo = make_error(ValueError, 'foo') + error_sub = make_error(UnicodeError, 'foo') + error_bar = make_error(ValueError, 'bar') + matches_matches = [error_foo, error_sub] + matches_mismatches = [error_bar] + + str_examples = [ + ("MatchesException(%r)" % Exception, + MatchesException(Exception, Equals('foo'))) + ] + describe_examples = [ + ("5 != %r" % (error_bar[1],), + error_bar, MatchesException(ValueError, Equals(5))), + ] + + +class TestRaisesInterface(TestCase, TestMatchersInterface): + + matches_matcher = Raises() + def boom(): + raise Exception('foo') + matches_matches = [boom] + matches_mismatches = [lambda:None] + + # Tricky to get function objects to render constantly, and the interfaces + # helper uses assertEqual rather than (for instance) DocTestMatches. + str_examples = [] + + describe_examples = [] + + +class TestRaisesExceptionMatcherInterface(TestCase, TestMatchersInterface): + + matches_matcher = Raises( + exception_matcher=MatchesException(Exception('foo'))) + def boom_bar(): + raise Exception('bar') + def boom_foo(): + raise Exception('foo') + matches_matches = [boom_foo] + matches_mismatches = [lambda:None, boom_bar] + + # Tricky to get function objects to render constantly, and the interfaces + # helper uses assertEqual rather than (for instance) DocTestMatches. + str_examples = [] + + describe_examples = [] + + +class TestRaisesBaseTypes(TestCase): + + run_tests_with = FullStackRunTest + + def raiser(self): + raise KeyboardInterrupt('foo') + + def test_KeyboardInterrupt_matched(self): + # When KeyboardInterrupt is matched, it is swallowed. + matcher = Raises(MatchesException(KeyboardInterrupt)) + self.assertThat(self.raiser, matcher) + + def test_KeyboardInterrupt_propogates(self): + # The default 'it raised' propogates KeyboardInterrupt. + match_keyb = Raises(MatchesException(KeyboardInterrupt)) + def raise_keyb_from_match(): + matcher = Raises() + matcher.match(self.raiser) + self.assertThat(raise_keyb_from_match, match_keyb) + + def test_KeyboardInterrupt_match_Exception_propogates(self): + # If the raised exception isn't matched, and it is not a subclass of + # Exception, it is propogated. + match_keyb = Raises(MatchesException(KeyboardInterrupt)) + def raise_keyb_from_match(): + if sys.version_info > (2, 5): + matcher = Raises(MatchesException(Exception)) + else: + # On Python 2.4 KeyboardInterrupt is a StandardError subclass + # but should propogate from less generic exception matchers + matcher = Raises(MatchesException(EnvironmentError)) + matcher.match(self.raiser) + self.assertThat(raise_keyb_from_match, match_keyb) + + +class TestRaisesConvenience(TestCase): + + run_tests_with = FullStackRunTest + + def test_exc_type(self): + self.assertThat(lambda: 1/0, raises(ZeroDivisionError)) + + def test_exc_value(self): + e = RuntimeError("You lose!") + def raiser(): + raise e + self.assertThat(raiser, raises(e)) + + +def test_suite(): + from unittest import TestLoader + return TestLoader().loadTestsFromName(__name__) |