1
# Copyright 2010 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
7
'DoesNotCorrectlyProvide',
11
'ProvidesAndIsProxied',
14
from zope.interface.verify import verifyObject
15
from zope.interface.exceptions import (
16
BrokenImplementation, BrokenMethodImplementation, DoesNotImplement)
17
from zope.security.proxy import builtin_isinstance, Proxy
19
from testtools.matchers import Matcher, Mismatch
22
class DoesNotProvide(Mismatch):
23
"""An object does not provide an interface."""
25
def __init__(self, obj, interface):
26
"""Create a DoesNotProvide Mismatch.
28
:param obj: the object that does not match.
29
:param interface: the Interface that the object was supposed to match.
32
self.interface = interface
35
return "%r does not provide %r." % (self.obj, self.interface)
38
class DoesNotCorrectlyProvide(DoesNotProvide):
39
"""An object does not correctly provide an interface."""
41
def __init__(self, obj, interface, extra=None):
42
"""Create a DoesNotCorrectlyProvide Mismatch.
44
:param obj: the object that does not match.
45
:param interface: the Interface that the object was supposed to match.
46
:param extra: any extra information about the mismatch as a string,
49
super(DoesNotCorrectlyProvide, self).__init__(obj, interface)
53
if self.extra is not None:
54
extra = ": %s" % self.extra
57
return ("%r claims to provide %r, but does not do so correctly%s"
58
% (self.obj, self.interface, extra))
61
class Provides(Matcher):
62
"""Test that an object provides a certain interface."""
64
def __init__(self, interface):
65
"""Create a Provides Matcher.
67
:param interface: the Interface that the object should provide.
69
self.interface = interface
72
return "provides %r." % self.interface
74
def match(self, matchee):
75
if not self.interface.providedBy(matchee):
76
return DoesNotProvide(matchee, self.interface)
80
if not verifyObject(self.interface, matchee):
82
except (BrokenImplementation, BrokenMethodImplementation,
87
return DoesNotCorrectlyProvide(
88
matchee, self.interface, extra=extra)
92
class IsNotProxied(Mismatch):
93
"""An object is not proxied."""
95
def __init__(self, obj):
96
"""Create an IsNotProxied Mismatch.
98
:param obj: the object that is not proxied.
103
return "%r is not proxied." % self.obj
106
class IsProxied(Matcher):
107
"""Check that an object is proxied."""
112
def match(self, matchee):
113
if not builtin_isinstance(matchee, Proxy):
114
return IsNotProxied(matchee)
118
class ProvidesAndIsProxied(Matcher):
119
"""Test that an object implements an interface, and is proxied."""
121
def __init__(self, interface):
122
"""Create a ProvidesAndIsProxied matcher.
124
:param interface: the Interface the object must provide.
126
self.interface = interface
129
return "Provides %r and is proxied." % self.interface
131
def match(self, matchee):
132
mismatch = Provides(self.interface).match(matchee)
133
if mismatch is not None:
135
return IsProxied().match(matchee)