[Zope3-checkins] CVS: Zope3/src/zope/app/services/tests - test_objecthub.py:1.16

Garrett Smith garrett at mojave-corp.com
Tue Dec 16 17:05:41 EST 2003


Update of /cvs-repository/Zope3/src/zope/app/services/tests
In directory cvs.zope.org:/tmp/cvs-serv10567/src/zope/app/services/tests

Modified Files:
	test_objecthub.py 
Log Message:
Provided a stop-gap fix for a couple of problems with the object hub:

- When an object is moved or renamed, its descendants' paths in the
hub become invalid.

- When an object is removed, its descendants are left registered.

Tests have been added to document the expected behavior.

While this fix isn't terrible (it does keep the hub state current), it glosses
over some issues:

- Developers that rely on an object path receive no notification that the
object path has changed. Arguably, no one should rely on a path (hub ids
should be used instead) but we should probably have a discussion on this
to see if we need to publish 'path changed' events.

- The removal of descendants is a result of not receiving object 'removed'
events for all of the objects deleted in an operation. I believe this is
still the right thing to do, since there's no assurance that *all* of the
deleted objects will have corresponding 'removed' events. Nonetheless,
it looks a bit defensive to me.

- These changes infer ancestor/descendant relationships from path
strings. I don't see this as a viable long term approach :-) Another item
to discuss.


=== Zope3/src/zope/app/services/tests/test_objecthub.py 1.15 => 1.16 ===
--- Zope3/src/zope/app/services/tests/test_objecthub.py:1.15	Fri Nov 21 12:12:13 2003
+++ Zope3/src/zope/app/services/tests/test_objecthub.py	Tue Dec 16 17:05:40 2003
@@ -41,6 +41,7 @@
 from zope.app.services.hub import ObjectModifiedHubEvent, ObjectRemovedHubEvent
 from zope.app.services.hub import ObjectMovedHubEvent, ObjectRegisteredHubEvent
 from zope.app.services.hub import ObjectUnregisteredHubEvent
+from zope.app.services.hub import canonicalSlash, userPath
 
 from zope.app.interfaces.traversing import IContainmentRoot
 from zope.app.location import Location
@@ -264,7 +265,6 @@
                 (IObjectAddedEvent, location),
             ])
 
-
 class TestObjectCreatedEvent(BasicHubTest):
     def setUp(self):
         ObjectHubSetup.setUp(self)
@@ -407,6 +407,33 @@
             ])
 
 
+    def testRemoveDescendants(self):
+        # Test that removing an object also removes its descendants
+        locations = (
+            '/',
+            '/1',
+            '/1/1_1',
+            '/1/1_1/1_1_1',
+            '/2',
+            '/2/2_1',
+            '/2/2_2' )
+        hub = self.object_hub
+        for path in locations:
+            hub.register(path)
+        removed_event = self.removed_event
+        removed_event.oldParent = '/'
+        removed_event.oldName = '1'
+        hub.notify(removed_event)
+        newLocations = [path for (path, oid) in hub.iterRegistrations()]
+        newLocations.sort()
+        self.assertEqual([
+            '/', 
+            '/2', 
+            '/2/2_1', 
+            '/2/2_2'], 
+            newLocations)
+
+
 class TestObjectModifiedEvent(BasicHubTest):
     def setUp(self):
         ObjectHubSetup.setUp(self)
@@ -561,6 +588,84 @@
                 (IObjectMovedEvent, new_location),
             ])
 
+    def testRepathDescendantsOnRename(self):
+        # Test that the paths of descendants of renamed objects are updated
+        locations = (
+            '/',
+            '/1',
+            '/1/1_1',
+            '/1/1_1/1_1_1',
+            '/2',
+            '/2/2_1',
+            '/2/2_2' )
+        hub = self.object_hub
+        for path in locations:
+            hub.register(path)
+        moved_event = self.moved_event
+        moved_event.oldParent = '/'
+        moved_event.oldName = '1'
+        moved_event.newParent = '/'
+        moved_event.newName = '3'
+        hub.notify(moved_event)
+        newLocations = [path for (path, oid) in hub.iterRegistrations()]
+        newLocations.sort()
+        self.assertEqual([
+            '/',
+            '/2',
+            '/2/2_1',
+            '/2/2_2',
+            '/3',
+            '/3/1_1',
+            '/3/1_1/1_1_1'],
+            newLocations)
+
+    def testRepathDescendantsOnMove(self):
+        # Test that the paths of descendants of moved objects are updated
+        locations = (
+            '/',
+            '/1',
+            '/1/1_1',
+            '/1/1_1/1_1_1',
+            '/2',
+            '/2/2_1',
+            '/2/2_2' )
+        hub = self.object_hub
+        for path in locations:
+            hub.register(path)
+        moved_event = self.moved_event
+        moved_event.oldParent = '/'
+        moved_event.oldName = '1'
+        moved_event.newParent = '/2/2_1'
+        moved_event.newName = '1'
+        hub.notify(moved_event)
+        newLocations = [path for (path, oid) in hub.iterRegistrations()]
+        newLocations.sort()
+        self.assertEqual([
+            '/',
+            '/2',
+            '/2/2_1',
+            '/2/2_1/1',
+            '/2/2_1/1/1_1',
+            '/2/2_1/1/1_1/1_1_1',
+            '/2/2_2'],
+            newLocations)
+
+class TestPathFunctions(BasicHubTest):
+
+    def testCanonicalSlash(self):
+        self.assertEqual(canonicalSlash('/'), '/')
+        self.assertEqual(canonicalSlash('/', 'bar'), '/bar/')
+        self.assertEqual(canonicalSlash('/foo'), '/foo/')
+        self.assertEqual(canonicalSlash('/foo', 'bar'), '/foo/bar/')
+        self.assertRaises(ValueError, canonicalSlash, '\\')
+        self.assertRaises(ValueError, canonicalSlash, '')
+
+    def testUserPath(self):
+        self.assertEqual(userPath('/'), '/')
+        self.assertEqual(userPath('/foo'), '/foo')
+        self.assertEqual(userPath('/foo/'), '/foo')
+        self.assertEqual(userPath('/foo/bar'), '/foo/bar')
+        self.assertEqual(userPath('/foo/bar/'), '/foo/bar')
 
 def test_suite():
     return unittest.TestSuite((
@@ -576,6 +681,7 @@
         unittest.makeSuite(TestObjectRemovedEvent),
         unittest.makeSuite(TestObjectModifiedEvent),
         unittest.makeSuite(TestObjectMovedEvent),
+        unittest.makeSuite(TestPathFunctions),
         ))
 
 if __name__=='__main__':




More information about the Zope3-Checkins mailing list