2
Tests for L{epsilon.descriptor}.
5
from twisted.trial import unittest
7
from epsilon import descriptor
10
class a(descriptor.attribute):
20
class a(descriptor.attribute):
26
class DescriptorTest(unittest.TestCase):
29
self.assertEquals(t.a, 1)
31
self.assertEquals(t.a, 1)
33
self.assertEquals(t.a, 1)
38
self.assertEquals(Test2.a.__doc__, 'stuff')
39
self.assertEquals(t.a, 10)
40
self.assertRaises(AttributeError, setattr, t, 'a', 1)
41
self.assertRaises(AttributeError, delattr, t, 'a')
45
class AbstractClassic:
47
Toy classic class used by L{RequiredAttributeTestCase}.
49
foo = descriptor.requiredAttribute('foo')
50
bar = descriptor.requiredAttribute('bar')
53
class ManifestClassic(AbstractClassic):
55
Toy classic class used by L{RequiredAttributeTestCase}.
61
class AbstractNewStyle(object):
63
Toy new-style class used by L{RequiredAttributeTestCase}.
65
foo = descriptor.requiredAttribute('foo')
66
bar = descriptor.requiredAttribute('bar')
70
class ManifestNewStyle(AbstractNewStyle):
72
Toy classic class used by L{RequiredAttributeTestCase}.
78
class RequiredAttributeTestCase(unittest.TestCase):
80
Tests for L{descriptor.requiredAttribute}.
82
def _defaultAccess(self, abstractFoo):
83
exception = self.assertRaises(AttributeError, getattr, abstractFoo, 'foo')
84
self.assertEqual(len(exception.args), 1)
87
("Required attribute 'foo' has not been changed"
88
" from its default value on %r" % (abstractFoo,)))
90
def test_defaultAccessClassic(self):
92
Accessing a L{descriptor.requiredAttribute} on a classic class raises
93
an C{AttributeError} if its value has not been overridden.
95
abstractFoo = AbstractClassic()
96
self._defaultAccess(abstractFoo)
99
def test_defaultAccessNewStyle(self):
101
Accessing a L{descriptor.requiredAttribute} on a new-style class raises
102
an C{AttributeError} if its value has not been overridden.
104
abstractFoo = AbstractNewStyle()
105
self._defaultAccess(abstractFoo)
108
def _derivedAccess(self, manifestFoo):
109
self.assertEqual(manifestFoo.foo, 'bar')
112
def test_derivedAccessClassic(self):
114
If a derived classic class sets a new value for a
115
L{descriptor.requiredAttribute}, things should work fine.
117
manifestFoo = ManifestClassic()
118
self._derivedAccess(manifestFoo)
121
def test_derivedAccessNewStyle(self):
123
If a new-style derived class sets a new value for a
124
L{descriptor.requiredAttribute}, things should work fine.
126
manifestFoo = ManifestNewStyle()
127
self._derivedAccess(manifestFoo)
130
def _instanceAccess(self, abstractMadeManifest):
131
abstractMadeManifest.foo = 123
132
self.assertEqual(abstractMadeManifest.foo, 123)
135
def test_instanceAccessClassic(self):
137
Accessing a L{descriptor.requiredAttribute} after setting a value for
138
it on an instance of a classic class evaluates to that value.
140
abstractMadeManifest = AbstractClassic()
141
self._instanceAccess(abstractMadeManifest)
144
def test_instanceAccessNewStyle(self):
146
Accessing a L{descriptor.requiredAttribute} after setting a value for
147
it on an instance of a new-style class evaluates to that value.
149
abstractMadeManifest = AbstractNewStyle()
150
self._instanceAccess(abstractMadeManifest)
153
def test_instanceAttributesUnrelatedClassic(self):
155
Accessing one L{descriptor.requiredAttribute} after setting a value for
156
a different L{descriptor.requiredAttribute} raises an
159
partiallyAbstract = AbstractClassic()
160
partiallyAbstract.bar = 123
161
self._defaultAccess(partiallyAbstract)
164
def test_instanceAttributesUnrelatedNewStyle(self):
166
Accessing one L{descriptor.requiredAttribute} after setting a value for
167
a different L{descriptor.requiredAttribute} raises an
170
partiallyAbstract = AbstractNewStyle()
171
partiallyAbstract.bar = 123
172
self._defaultAccess(partiallyAbstract)