[Zope-Checkins] CVS: Zope3/src/persistent/tests
- test_persistent.py:1.5 persistent.txt:1.2
Chris Withers
lists at simplistix.co.uk
Thu Mar 4 03:56:09 EST 2004
Is there a summary of where the decision was made to use DocTests rather than
real tests with comments or docstrings in the test code?
Personally, I think the doctests below are in danger of looking butt ugly :-S
Chris
Jeremy Hylton wrote:
> 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)
>
>
> _______________________________________________
> Zope-Checkins maillist - Zope-Checkins at zope.org
> http://mail.zope.org/mailman/listinfo/zope-checkins
>
--
Simplistix - Content Management, Zope & Python Consulting
- http://www.simplistix.co.uk
More information about the Zope-Checkins
mailing list