Add MatchesException matcher.
This commit is contained in:
9
Makefile
9
Makefile
@@ -16,15 +16,20 @@ clean:
|
|||||||
rm -f TAGS tags
|
rm -f TAGS tags
|
||||||
find testtools -name "*.pyc" -exec rm '{}' \;
|
find testtools -name "*.pyc" -exec rm '{}' \;
|
||||||
|
|
||||||
release:
|
prerelease:
|
||||||
# An existing MANIFEST breaks distutils sometimes. Avoid that.
|
# An existing MANIFEST breaks distutils sometimes. Avoid that.
|
||||||
-rm MANIFEST
|
-rm MANIFEST
|
||||||
|
|
||||||
|
release:
|
||||||
./setup.py sdist upload --sign
|
./setup.py sdist upload --sign
|
||||||
|
|
||||||
|
snapshot: prerelease
|
||||||
|
./setup.py sdist
|
||||||
|
|
||||||
apidocs:
|
apidocs:
|
||||||
pydoctor --make-html --add-package testtools \
|
pydoctor --make-html --add-package testtools \
|
||||||
--docformat=restructuredtext --project-name=testtools \
|
--docformat=restructuredtext --project-name=testtools \
|
||||||
--project-url=https://launchpad.net/testtools
|
--project-url=https://launchpad.net/testtools
|
||||||
|
|
||||||
|
|
||||||
.PHONY: check clean release apidocs
|
.PHONY: check clean prerelease release apidocs
|
||||||
|
|||||||
3
NEWS
3
NEWS
@@ -21,6 +21,9 @@ Improvements
|
|||||||
|
|
||||||
* Malformed SyntaxErrors no longer blow up the test suite. (Martin [gz])
|
* 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
|
* addUnexpectedSuccess is translated to addFailure for test results that don't
|
||||||
know about addUnexpectedSuccess. (Jonathan Lange, #654474)
|
know about addUnexpectedSuccess. (Jonathan Lange, #654474)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ __all__ = [
|
|||||||
'LessThan',
|
'LessThan',
|
||||||
'MatchesAll',
|
'MatchesAll',
|
||||||
'MatchesAny',
|
'MatchesAny',
|
||||||
|
'MatchesException',
|
||||||
'NotEquals',
|
'NotEquals',
|
||||||
'Not',
|
'Not',
|
||||||
'StartsWith',
|
'StartsWith',
|
||||||
@@ -323,6 +324,33 @@ class MatchedUnexpectedly(Mismatch):
|
|||||||
return "%r matches %s" % (self.other, self.matcher)
|
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):
|
class StartsWith(Matcher):
|
||||||
"""Checks whether one string starts with another."""
|
"""Checks whether one string starts with another."""
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"""Tests for matchers."""
|
"""Tests for matchers."""
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
|
import sys
|
||||||
|
|
||||||
from testtools import (
|
from testtools import (
|
||||||
Matcher, # check that Matcher is exposed at the top level for docs.
|
Matcher, # check that Matcher is exposed at the top level for docs.
|
||||||
@@ -18,6 +19,7 @@ from testtools.matchers import (
|
|||||||
LessThan,
|
LessThan,
|
||||||
MatchesAny,
|
MatchesAny,
|
||||||
MatchesAll,
|
MatchesAll,
|
||||||
|
MatchesException,
|
||||||
Mismatch,
|
Mismatch,
|
||||||
Not,
|
Not,
|
||||||
NotEquals,
|
NotEquals,
|
||||||
@@ -155,6 +157,43 @@ class TestLessThanInterface(TestCase, TestMatchersInterface):
|
|||||||
describe_examples = [('4 is >= 4', 4, LessThan(4))]
|
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):
|
class TestNotInterface(TestCase, TestMatchersInterface):
|
||||||
|
|
||||||
matches_matcher = Not(Equals(1))
|
matches_matcher = Not(Equals(1))
|
||||||
|
|||||||
Reference in New Issue
Block a user