Add MatchesException matcher.

This commit is contained in:
Robert Collins
2010-11-11 15:22:43 +13:00
parent 9dde40dfa2
commit 2d8b3f785b
4 changed files with 77 additions and 2 deletions

View File

@@ -16,15 +16,20 @@ clean:
rm -f TAGS tags
find testtools -name "*.pyc" -exec rm '{}' \;
release:
prerelease:
# An existing MANIFEST breaks distutils sometimes. Avoid that.
-rm MANIFEST
release:
./setup.py sdist upload --sign
snapshot: prerelease
./setup.py sdist
apidocs:
pydoctor --make-html --add-package testtools \
--docformat=restructuredtext --project-name=testtools \
--project-url=https://launchpad.net/testtools
.PHONY: check clean release apidocs
.PHONY: check clean prerelease release apidocs

3
NEWS
View File

@@ -21,6 +21,9 @@ Improvements
* Malformed SyntaxErrors no longer blow up the test suite. (Martin [gz])
* ``MatchesException`` added to the ``testtools.matchers`` module - matches
an exception class and parameters. (Robert Collins)
* addUnexpectedSuccess is translated to addFailure for test results that don't
know about addUnexpectedSuccess. (Jonathan Lange, #654474)

View File

@@ -20,6 +20,7 @@ __all__ = [
'LessThan',
'MatchesAll',
'MatchesAny',
'MatchesException',
'NotEquals',
'Not',
'StartsWith',
@@ -323,6 +324,33 @@ class MatchedUnexpectedly(Mismatch):
return "%r matches %s" % (self.other, self.matcher)
class MatchesException(Matcher):
"""Match an exc_info tuple against an exception."""
def __init__(self, exception):
"""Create a MatchesException that will match exc_info's for exception.
:param exception: An exception to check against an exc_info tuple. The
traceback object is not inspected, only the type and arguments of
the exception.
"""
Matcher.__init__(self)
self.expected = exception
def match(self, other):
if type(other) != tuple:
return Mismatch('%r is not an exc_info tuple' % other)
if not issubclass(other[0], type(self.expected)):
return Mismatch('%r is not a %r' % (
other[0], type(self.expected)))
if other[1].args != self.expected.args:
return Mismatch('%r has different arguments to %r.' % (
other[1], self.expected))
def __str__(self):
return "MatchesException(%r)" % self.expected
class StartsWith(Matcher):
"""Checks whether one string starts with another."""

View File

@@ -3,6 +3,7 @@
"""Tests for matchers."""
import doctest
import sys
from testtools import (
Matcher, # check that Matcher is exposed at the top level for docs.
@@ -18,6 +19,7 @@ from testtools.matchers import (
LessThan,
MatchesAny,
MatchesAll,
MatchesException,
Mismatch,
Not,
NotEquals,
@@ -155,6 +157,43 @@ class TestLessThanInterface(TestCase, TestMatchersInterface):
describe_examples = [('4 is >= 4', 4, LessThan(4))]
class TestMatchesException(TestCase):
def test_does_not_match_different_exception_class(self):
matcher = MatchesException(ValueError("foo"))
try:
raise Exception("foo")
except Exception:
error = sys.exc_info()
mismatch = matcher.match(error)
self.assertNotEqual(None, mismatch)
self.assertEqual(
"<type 'exceptions.Exception'> is not a "
"<type 'exceptions.ValueError'>",
mismatch.describe())
def test_does_not_match_different_args(self):
matcher = MatchesException(Exception("foo"))
try:
raise Exception("bar")
except Exception:
error = sys.exc_info()
mismatch = matcher.match(error)
self.assertNotEqual(None, mismatch)
self.assertEqual(
"Exception('bar',) has different arguments to Exception('foo',).",
mismatch.describe())
def test_matches_same_args(self):
matcher = MatchesException(Exception("foo"))
try:
raise Exception("foo")
except Exception:
error = sys.exc_info()
mismatch = matcher.match(error)
self.assertEqual(None, mismatch)
class TestNotInterface(TestCase, TestMatchersInterface):
matches_matcher = Not(Equals(1))