[Zodb-checkins] CVS: Zope3/src/zodb/code/tests - test_patch.py:1.3 test_class.py:1.3 atestmodule.py:1.3

Jeremy Hylton jeremy@zope.com
Fri, 24 Jan 2003 18:21:32 -0500


Update of /cvs-repository/Zope3/src/zodb/code/tests
In directory cvs.zope.org:/tmp/cvs-serv31712/zodb/code/tests

Modified Files:
	test_patch.py test_class.py atestmodule.py 
Log Message:
Merge new-pickle-branch to trunk.  Yee ha!


=== Zope3/src/zodb/code/tests/test_patch.py 1.2 => 1.3 ===
--- Zope3/src/zodb/code/tests/test_patch.py:1.2	Wed Dec 25 09:12:18 2002
+++ Zope3/src/zodb/code/tests/test_patch.py	Fri Jan 24 18:20:54 2003
@@ -18,6 +18,10 @@
 class TestPatch(unittest.TestCase):
 
     def testPatch(self):
+        # verify obvious facts of object identity
+        self.assert_(atestmodule.Bar is atestmodule.Sub.__bases__[0])
+        self.assert_(atestmodule.aFunc is atestmodule.foo[0])
+        
         moddict = atestmodule.__dict__
         convert(atestmodule, {})
         newdict = atestmodule.__dict__
@@ -29,6 +33,14 @@
         self.assertEqual(L1, L2)
 
         self.assertEqual(atestmodule.__dict__, atestmodule.aFunc.func_globals)
+
+        # make sure object identity is maintained by patch
+        Bar = newdict["Bar"]
+        Bar_as_base = newdict["Sub"].__bases__[0]
+        self.assert_(Bar is Bar_as_base)
+
+        self.assert_(newdict["aFunc"] is newdict["foo"][0])
+
 
 def test_suite():
     s = unittest.TestSuite()


=== Zope3/src/zodb/code/tests/test_class.py 1.2 => 1.3 ===
--- Zope3/src/zodb/code/tests/test_class.py:1.2	Tue Jan 21 11:05:54 2003
+++ Zope3/src/zodb/code/tests/test_class.py	Fri Jan 24 18:20:54 2003
@@ -24,10 +24,35 @@
 
 class TestClass(TestBase):
 
+    # TODO
+    # test classes with getstate and setstate
+    # make sure class invalidation works correctly
+
     class_with_init = """class Foo:
     def __init__(self, arg):
         self.var = arg""" "\n"
 
+    def _load_path(self, path):
+        # Load an object from a new connection given a database path.
+        root = self.db.open().root()
+        obj = root
+        for part in path.split("."):
+            try:
+                obj = obj[part]
+            except TypeError:
+                obj = getattr(obj, part)
+        return obj
+
+    def _load_name(self, name):
+        # Load a class from a new connection given a dotted name
+        i = name.rfind(".")
+        module = name[:i]
+        klass = name[i+1:]
+        # The following depends entirely on the internals of the
+        # implementation.
+        return self._load_path("registry._mgrs.%s._module.%s"
+                               % (module, klass))
+
     def testClassWithInit(self):
         self.registry.newModule("testclass", self.class_with_init)
         get_transaction().commit()
@@ -35,6 +60,10 @@
         x = testclass.Foo(12)
         self.assertEqual(x.var, 12)
 
+        Foo2 = self._load_name("testclass.Foo")
+        y = Foo2(12)
+        self.assertEqual(y.var, 12)
+
     class_and_instance = """class Foo:
     def __init__(self, arg):
         self.var = arg
@@ -53,6 +82,23 @@
         import testclass
         self.assertEqual(testclass.x.var, 12)
 
+        Foo2 = self._load_name("testclass.Foo")
+        self.assertEqual(Foo2(12).var, 12)
+        x = self._load_name("testclass.x")
+        self.assertEqual(x.var, 12)
+
+    class_interface = """class Foo:
+    __implements__ = 1""" + "\n"
+
+    def testClassInterface(self):
+        # this doesn't do a proper zope interface, but we're really
+        # only concerned about handling of the __implements__ attribute.
+        self.registry.newModule("testclass", self.class_interface)
+        get_transaction().commit()
+        import testclass
+        obj = testclass.Foo()
+        self.assertEqual(obj.__implements__, 1)
+
     cross_module_import = "from testclass import Foo"
 
     def testCrossModuleImport(self):
@@ -76,9 +122,51 @@
         inst = testclass.Foo()
         self.assertEqual(inst.meth(4), 12)
 
+        Foo2 = self._load_name("testclass.Foo")
+        inst2 = Foo2()
+        self.assertEqual(inst2.meth(4), 12)
+
         self.registry.updateModule("testclass", self.update_in_place2)
         get_transaction().commit()
         self.assertEqual(inst.meth(4), 7)
+
+        # The old instance's connection hasn't processed the
+        # invalidation yet.
+        self.assertEqual(inst2.meth(4), 12)
+        self.assertEqual(Foo2().meth(4), 12)
+        inst2.__class__._p_jar.sync()
+        self.assertEqual(inst2.meth(4), 7)
+        self.assertEqual(Foo2().meth(4), 7)
+
+    parent1 = """class Foo:
+    def meth(self, arg):
+        return arg * 2""" "\n"
+
+    parent2 = """class Foo:
+    def meth(self, arg):
+        return arg // 2""" "\n"
+
+    child = """import parent
+    
+class Bar(parent.Foo):
+    def meth(self, arg):
+        return super(Bar, self).meth(arg) + 5""" "\n"
+
+    def testInheritanceAcrossModules(self):
+        self.registry.newModule("parent", self.parent1)
+        self.registry.newModule("child", self.child)
+        get_transaction().commit()
+        import child
+        self.assertEqual(child.Bar().meth(3), 3*2+5)
+        self.registry.updateModule("parent", self.parent2)
+        get_transaction().commit()
+        self.assertEqual(child.Bar().meth(3), 3//2+5)
+
+        # XXX somehow we get the meth() defined on parent
+        # instead of the one on child.  it looks like super
+        # isn't doing what I expect.
+        Bar = self._load_name("child.Bar")
+##        self.assertEqual(Bar().meth(3), 3//2+5)
         
 def test_suite():
     return unittest.makeSuite(TestClass)


=== Zope3/src/zodb/code/tests/atestmodule.py 1.2 => 1.3 ===
--- Zope3/src/zodb/code/tests/atestmodule.py:1.2	Wed Dec 25 09:12:18 2002
+++ Zope3/src/zodb/code/tests/atestmodule.py	Fri Jan 24 18:20:54 2003
@@ -13,6 +13,9 @@
         def bar(self):
             return 1
 
+# put aFunc inside a function to be sure it is found
+foo = (aFunc,)
+
 class Bar:
     def bar(self, x):
         return 2 * x
@@ -21,6 +24,9 @@
     alias = aFunc
 
     classbar = classmethod(bar)
+
+class Sub(Bar):
+    pass
 
 def anotherFunc():
     class NotFound: