~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/testing/matchers.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2010-08-04 16:44:19 UTC
  • mfrom: (11265.1.15 no-more-sampledata-0)
  • Revision ID: launchpad@pqm.canonical.com-20100804164419-5e6x1beuy6f2kzto
[r=jml][ui=none][no-qa] Some cleanup of soyuz test code,
        including use of lp.testing.sampledata,
        factory improvements and addition of some matchers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
__metaclass__ = type
 
5
__all__ = [
 
6
    'DoesNotProvide',
 
7
    'DoesNotCorrectlyProvide',
 
8
    'IsNotProxied',
 
9
    'IsProxied',
 
10
    'Provides',
 
11
    'ProvidesAndIsProxied',
 
12
    ]
 
13
 
 
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
 
18
 
 
19
from testtools.matchers import Matcher, Mismatch
 
20
 
 
21
 
 
22
class DoesNotProvide(Mismatch):
 
23
    """An object does not provide an interface."""
 
24
 
 
25
    def __init__(self, obj, interface):
 
26
        """Create a DoesNotProvide Mismatch.
 
27
 
 
28
        :param obj: the object that does not match.
 
29
        :param interface: the Interface that the object was supposed to match.
 
30
        """
 
31
        self.obj = obj
 
32
        self.interface = interface
 
33
 
 
34
    def describe(self):
 
35
        return "%r does not provide %r." % (self.obj, self.interface)
 
36
 
 
37
 
 
38
class DoesNotCorrectlyProvide(DoesNotProvide):
 
39
    """An object does not correctly provide an interface."""
 
40
 
 
41
    def __init__(self, obj, interface, extra=None):
 
42
        """Create a DoesNotCorrectlyProvide Mismatch.
 
43
 
 
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,
 
47
            or None
 
48
        """
 
49
        super(DoesNotCorrectlyProvide, self).__init__(obj, interface)
 
50
        self.extra = extra
 
51
 
 
52
    def describe(self):
 
53
        if self.extra is not None:
 
54
            extra = ": %s" % self.extra
 
55
        else:
 
56
            extra = "."
 
57
        return ("%r claims to provide %r, but does not do so correctly%s"
 
58
                % (self.obj, self.interface, extra))
 
59
 
 
60
 
 
61
class Provides(Matcher):
 
62
    """Test that an object provides a certain interface."""
 
63
 
 
64
    def __init__(self, interface):
 
65
        """Create a Provides Matcher.
 
66
 
 
67
        :param interface: the Interface that the object should provide.
 
68
        """
 
69
        self.interface = interface
 
70
 
 
71
    def __str__(self):
 
72
        return "provides %r." % self.interface
 
73
 
 
74
    def match(self, matchee):
 
75
        if not self.interface.providedBy(matchee):
 
76
            return DoesNotProvide(matchee, self.interface)
 
77
        passed = True
 
78
        extra = None
 
79
        try:
 
80
            if not verifyObject(self.interface, matchee):
 
81
                passed = False
 
82
        except (BrokenImplementation, BrokenMethodImplementation,
 
83
                DoesNotImplement), e:
 
84
            passed = False
 
85
            extra = str(e)
 
86
        if not passed:
 
87
            return DoesNotCorrectlyProvide(
 
88
                matchee, self.interface, extra=extra)
 
89
        return None
 
90
 
 
91
 
 
92
class IsNotProxied(Mismatch):
 
93
    """An object is not proxied."""
 
94
 
 
95
    def __init__(self, obj):
 
96
        """Create an IsNotProxied Mismatch.
 
97
 
 
98
        :param obj: the object that is not proxied.
 
99
        """
 
100
        self.obj = obj
 
101
 
 
102
    def describe(self):
 
103
        return "%r is not proxied." % self.obj
 
104
 
 
105
 
 
106
class IsProxied(Matcher):
 
107
    """Check that an object is proxied."""
 
108
 
 
109
    def __str__(self):
 
110
        return "Is proxied."
 
111
 
 
112
    def match(self, matchee):
 
113
        if not builtin_isinstance(matchee, Proxy):
 
114
            return IsNotProxied(matchee)
 
115
        return None
 
116
 
 
117
 
 
118
class ProvidesAndIsProxied(Matcher):
 
119
    """Test that an object implements an interface, and is proxied."""
 
120
 
 
121
    def __init__(self, interface):
 
122
        """Create a ProvidesAndIsProxied matcher.
 
123
 
 
124
        :param interface: the Interface the object must provide.
 
125
        """
 
126
        self.interface = interface
 
127
 
 
128
    def __str__(self):
 
129
        return "Provides %r and is proxied." % self.interface
 
130
 
 
131
    def match(self, matchee):
 
132
        mismatch = Provides(self.interface).match(matchee)
 
133
        if mismatch is not None:
 
134
            return mismatch
 
135
        return IsProxied().match(matchee)