[Zope-Checkins] CVS: Zope3/src/persistent/tests -
test_persistent.py:1.5 persistent.txt:1.2
Jeremy Hylton
jeremy at zope.com
Wed Mar 3 13:59:43 EST 2004
Update of /cvs-repository/Zope3/src/persistent/tests
In directory cvs.zope.org:/tmp/cvs-serv7824/persistent/tests
Modified Files:
test_persistent.py persistent.txt
Log Message:
Restructure relationship between persistent.txt and test_persistent.py.
Move some of the test framework code from .py to .txt, and add a more
detailed comment at the top about the contract between .txt and the
.py file that uses it.
Move the interface test into .txt. I guess it's not so bad.
Change some tests that displayed the contents of __dict__. Other
persistent implementations may have extra state in __dict__.
Remove B, it is unused.
Change DocFileSuite() to accept an explicit set of globals.
Remove the pickling/P2 test, because it was too hard to make work with
the framework. Include comment explaining how such a test should be
added.
=== Zope3/src/persistent/tests/test_persistent.py 1.4 => 1.5 ===
--- Zope3/src/persistent/tests/test_persistent.py:1.4 Wed Mar 3 07:18:50 2004
+++ Zope3/src/persistent/tests/test_persistent.py Wed Mar 3 13:59:42 2004
@@ -12,23 +12,12 @@
#
##############################################################################
import doctest
-import new
import os
import sys
import unittest
-from persistent import Persistent
-from persistent.interfaces import IPersistent
import persistent.tests
-
-try:
- import zope.interface
-except ImportError:
- interfaces = False
-else:
- interfaces = True
-
-oid = "\0\0\0\0\0\0hi"
+from persistent import Persistent
class P(Persistent):
def __init__(self):
@@ -36,72 +25,16 @@
def inc(self):
self.x += 1
-class P2(P):
- def __getstate__(self):
- return 42
- def __setstate__(self, v):
- self.v = v
-
-class B(Persistent):
-
- __slots__ = ["x", "_p_serial"]
-
- def __init__(self):
- self.x = 0
-
- def inc(self):
- self.x += 1
-
- def __getstate__(self):
- return {'x': self.x}
-
- def __setstate__(self, state):
- self.x = state['x']
-
-class DM:
- def __init__(self):
- self.called = 0
- def register(self, ob):
- self.called += 1
- def setstate(self, ob):
- ob.__setstate__({'x': 42})
-
-class BrokenDM(DM):
-
- def register(self,ob):
- self.called += 1
- raise NotImplementedError
-
- def setstate(self,ob):
- raise NotImplementedError
-
-class Test(unittest.TestCase):
-
- # XXX This is the only remaining unittest. Figure out how to move
- # this into doctest?
-
- if interfaces:
- def testInterface(self):
- self.assert_(IPersistent.isImplementedByInstancesOf(Persistent),
- "%s does not implement IPersistent" % Persistent)
- p = Persistent()
- self.assert_(IPersistent.isImplementedBy(p),
- "%s does not implement IPersistent" % p)
-
- self.assert_(IPersistent.isImplementedByInstancesOf(P),
- "%s does not implement IPersistent" % P)
- p = P()
- self.assert_(IPersistent.isImplementedBy(p),
- "%s does not implement IPersistent" % p)
-
-def DocFileSuite(path):
+def DocFileSuite(path, globs=None):
# It's not entirely obvious how to connection this single string
# with unittest. For now, re-use the _utest() function that comes
# standard with doctest in Python 2.3. One problem is that the
# error indicator doesn't point to the line of the doctest file
# that failed.
source = open(path).read()
- t = doctest.Tester(globs=sys._getframe(1).f_globals)
+ if globs is None:
+ globs = sys._getframe(1).f_globals
+ t = doctest.Tester(globs=globs)
def runit():
doctest._utest(t, path, source, path, 0)
f = unittest.FunctionTestCase(runit, description="doctest from %s" % path)
@@ -110,7 +43,5 @@
return suite
def test_suite():
- p = os.path.join(persistent.tests.__path__[0], "persistent.txt")
- s = unittest.makeSuite(Test)
- s.addTest(DocFileSuite(p))
- return s
+ path = os.path.join(persistent.tests.__path__[0], "persistent.txt")
+ return DocFileSuite(path, {"P": P})
=== Zope3/src/persistent/tests/persistent.txt 1.1 => 1.2 ===
--- Zope3/src/persistent/tests/persistent.txt:1.1 Tue Mar 2 17:15:14 2004
+++ Zope3/src/persistent/tests/persistent.txt Wed Mar 3 13:59:42 2004
@@ -2,8 +2,42 @@
===============================
This document is an extended doc test that covers the basics of the
-Persistent base class. It depends on a few base classes defined in
-test_persistent.py.
+Persistent base class. The test expects a class named 'P' to be
+provided in its globals. The P class implements the Persistent
+interface.
+
+Test framework
+--------------
+
+The class P needs to behave like ExampleP. (Note that the code below
+is *not* part of the tests.)
+
+class ExampleP(Persistent):
+ def __init__(self):
+ self.x = 0
+ def inc(self):
+ self.x += 1
+
+The tests use stub data managers. A data manager is responsible for
+loading and storing the state of a persistent object. It's stored in
+the _p_jar attribute of a persistent object.
+
+>>> class DM:
+... def __init__(self):
+... self.called = 0
+... def register(self, ob):
+... self.called += 1
+... def setstate(self, ob):
+... ob.__setstate__({'x': 42})
+
+>>> class BrokenDM(DM):
+... def register(self,ob):
+... self.called += 1
+... raise NotImplementedError
+... def setstate(self,ob):
+... raise NotImplementedError
+
+>>> from persistent import Persistent
Test Persistent without Data Manager
------------------------------------
@@ -56,7 +90,7 @@
>>> p = P()
>>> dm = DM()
->>> p._p_oid = oid
+>>> p._p_oid = "00000012"
>>> p._p_jar = dm
>>> p._p_changed
0
@@ -127,8 +161,11 @@
implementations.
>>> p = P()
->>> p.__getstate__()
-{'x': 0}
+>>> state = p.__getstate__()
+>>> isinstance(state, dict)
+True
+>>> state['x']
+0
>>> p._p_state
0
@@ -255,8 +292,8 @@
>>> p = P()
>>> p.inc()
>>> p.inc()
->>> p.__dict__
-{'x': 2}
+>>> 'x' in p.__dict__
+True
>>> p._p_jar
@@ -360,8 +397,8 @@
>>> p_shouldHaveDict.__dictoffset__ > 0
True
>>> x = p_shouldHaveDict()
->>> x.__dict__
-{}
+>>> isinstance(x.__dict__, dict)
+True
Pickling
@@ -381,11 +418,31 @@
>>> p2.x == p.x
True
-The P2 class has a custom __getstate__ and __setstate__.
-
->>> p = P2()
->>> p2 = pickle.loads(pickle.dumps(p))
->>> p2.__class__ is P2
-True
->>> p2.__dict__
-{'v': 42}
+We should also test that pickle works with custom getstate and
+setstate. Perhaps even reduce. The problem is that pickling depends
+on finding the class in a particular module, and classes defined here
+won't appear in any module. We could require each user of the tests
+to define a base class, but that might be tedious.
+
+Interfaces
+----------
+
+Some versions of Zope and ZODB have the zope.interfaces package
+available. If it is available, then persistent will be associated
+with several interfaces. It's hard to write a doctest test that runs
+the tests only if zope.interface is available, so this test looks a
+little unusual. One problem is that the assert statements won't do
+anything if you run with -O.
+
+>>> try:
+... import zope.interface
+... except ImportError:
+... pass
+... else:
+... from persistent.interfaces import IPersistent
+... assert IPersistent.isImplementedByInstancesOf(Persistent)
+... p = Persistent()
+... assert IPersistent.isImplementedBy(p)
+... assert IPersistent.isImplementedByInstancesOf(P)
+... p = P()
+... assert IPersistent.isImplementedBy(p)
More information about the Zope-Checkins
mailing list