1
#############################################################################
3
# Copyright (c) 2003 Zope Corporation and Contributors.
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
13
##############################################################################
18
from persistent import Persistent, GHOST, UPTODATE, CHANGED, STICKY
19
from persistent.cPickleCache import PickleCache
20
from persistent.TimeStamp import TimeStamp
21
from ZODB.utils import p64
24
"""Testing stub for _p_jar attribute."""
27
self.cache = PickleCache(self)
32
obj._p_oid = p64(self.oid)
35
self.cache[obj._p_oid] = obj
40
# the following methods must be implemented to be a jar
42
def setklassstate(self):
43
# I don't know what this method does, but the pickle cache
44
# constructor calls it.
47
def register(self, obj):
48
self.registered[obj] = 1
50
def setstate(self, obj):
51
# Trivial setstate() implementation that just re-initializes
52
# the object. This isn't what setstate() is supposed to do,
53
# but it suffices for the tests.
54
obj.__class__.__init__(obj)
64
def __getattr__(self, attr):
73
def __getattribute__(self, attr):
74
supergetattr = super(H2, self).__getattribute__
76
return supergetattr(attr)
77
except AttributeError:
82
class PersistenceTest(unittest.TestCase):
90
def testOidAndJarAttrs(self):
92
self.assertEqual(obj._p_oid, None)
94
self.assertEqual(obj._p_oid, 12)
99
# Can't change oid of cache object.
102
self.assertRaises(ValueError, deloid)
105
self.assertRaises(ValueError, setoid)
109
self.assertRaises(ValueError, deloid)
112
self.assertRaises(ValueError, setoid)
114
def testChangedAndState(self):
118
# The value returned for _p_changed can be one of:
119
# 0 -- it is not changed
121
# None -- it is a ghost
124
self.assertEqual(obj._p_changed, 1)
125
self.assertEqual(obj._p_state, CHANGED)
126
self.assert_(obj in self.jar.registered)
129
self.assertEqual(obj._p_changed, 0)
130
self.assertEqual(obj._p_state, UPTODATE)
131
self.jar.registered.clear()
134
self.assertEqual(obj._p_changed, 1)
135
self.assertEqual(obj._p_state, CHANGED)
136
self.assert_(obj in self.jar.registered)
138
# setting obj._p_changed to None ghostifies if the
139
# object is in the up-to-date state, but not otherwise.
140
obj._p_changed = None
141
self.assertEqual(obj._p_changed, 1)
142
self.assertEqual(obj._p_state, CHANGED)
145
obj._p_changed = None
146
self.assertEqual(obj._p_changed, None)
147
self.assertEqual(obj._p_state, GHOST)
152
# You can transition directly from modified to ghost if
153
# you delete the _p_changed attribute.
155
self.assertEqual(obj._p_changed, None)
156
self.assertEqual(obj._p_state, GHOST)
158
def testStateReadonly(self):
159
# make sure we can't write to _p_state; we don't want yet
160
# another way to change state!
164
self.assertRaises(TypeError, setstate, GHOST)
165
self.assertRaises(TypeError, setstate, UPTODATE)
166
self.assertRaises(TypeError, setstate, CHANGED)
167
self.assertRaises(TypeError, setstate, STICKY)
169
def testInvalidate(self):
173
self.assertEqual(obj._p_changed, 0)
174
self.assertEqual(obj._p_state, UPTODATE)
176
self.assertEqual(obj._p_changed, None)
177
self.assertEqual(obj._p_state, GHOST)
182
self.assertEqual(obj._p_changed, None)
183
self.assertEqual(obj._p_state, GHOST)
185
def testSerial(self):
186
noserial = "\000" * 8
188
self.assertEqual(obj._p_serial, noserial)
192
self.assertRaises(ValueError, set, 1)
193
self.assertRaises(ValueError, set, "0123")
194
self.assertRaises(ValueError, set, "012345678")
195
self.assertRaises(ValueError, set, u"01234567")
197
obj._p_serial = "01234567"
199
self.assertEqual(obj._p_serial, noserial)
203
self.assertEqual(obj._p_mtime, None)
206
ts = TimeStamp(*time.gmtime(t)[:6])
207
obj._p_serial = repr(ts)
208
self.assertEqual(obj._p_mtime, t)
209
self.assert_(isinstance(obj._p_mtime, float))
211
def testPicklable(self):
214
s = pickle.dumps(obj)
215
obj2 = pickle.loads(s)
216
self.assertEqual(obj.attr, obj2.attr)
218
def testGetattr(self):
220
self.assertEqual(obj.larry, 1)
221
self.assertEqual(obj.curly, 2)
222
self.assertEqual(obj.moe, 3)
227
# The simple Jar used for testing re-initializes the object.
228
self.assertEqual(obj.larry, 1)
229
# The getattr hook modified the object, so it should now be
230
# in the changed state.
231
self.assertEqual(obj._p_changed, 1)
232
self.assertEqual(obj._p_state, CHANGED)
233
self.assertEqual(obj.curly, 2)
234
self.assertEqual(obj.moe, 3)
236
def testGetattribute(self):
238
self.assertEqual(obj.larry, 1)
239
self.assertEqual(obj.curly, 2)
240
self.assertEqual(obj.moe, 3)
245
# The simple Jar used for testing re-initializes the object.
246
self.assertEqual(obj.larry, 1)
247
# The getattr hook modified the object, so it should now be
248
# in the changed state.
249
self.assertEqual(obj._p_changed, 1)
250
self.assertEqual(obj._p_state, CHANGED)
251
self.assertEqual(obj.curly, 2)
252
self.assertEqual(obj.moe, 3)
254
# TODO: Need to decide how __setattr__ and __delattr__ should work,
259
return unittest.makeSuite(PersistenceTest)