def test_order_events(self): # Prepare the setup:: from zope.container.contained import ContainerModifiedEvent # Prepare some objects:: from zope.container.ordered import OrderedContainer oc = OrderedContainer() oc['foo'] = 'bar' oc['baz'] = 'quux' oc['zork'] = 'grue' self.assertEqual(oc.keys(), ['foo', 'baz', 'zork']) # Now change the order:: clearEvents() oc.updateOrder(['baz', 'foo', 'zork']) self.assertEqual(oc.keys(), ['baz', 'foo', 'zork']) # Check what events have been sent:: events = getEvents() self.assertEqual(1, len(events)) self.assertIsInstance(events[0], ContainerModifiedEvent) # This is in fact a specialized modification event:: from zope.lifecycleevent.interfaces import IObjectModifiedEvent self.assertTrue(IObjectModifiedEvent.providedBy(events[0]))
def test_order_updateOrder_bytes(self): # https://github.com/zopefoundation/zope.container/issues/21 from zope.container.ordered import OrderedContainer keys = [u'a', u'b'] oc = OrderedContainer() oc[keys[0]] = 0 oc[keys[1]] = 1 self.assertEqual(keys, oc.keys()) # Updating with bytes keys... oc.updateOrder((b'b', b'a')) # still produces text keys text_type = str if str is not bytes else unicode self.assertEqual(list(reversed(keys)), oc.keys()) self.assertIsInstance(oc.keys()[0], text_type)
def test_namechooser_rename_preserve_order(self): # Test for OrderedContainerItemRenamer.renameItem # This is a regression test for # http://www.zope.org/Collectors/Zope3-dev/658 # Also: https://bugs.launchpad.net/zope.copypastemove/+bug/98385 provideAdapter(ObjectMover) # There's an ordered container from zope.container.ordered import OrderedContainer container = OrderedContainer() class Obj(Contained): def __init__(self, title): self.title = title objects = [Obj('Foo'), Obj('Bar'), Obj('Baz')] container['foo'] = objects[0] container['bar'] = objects[1] container['baz'] = objects[2] # with a custom name chooser import codecs from zope.interface import implementer, Interface from zope.container.interfaces import INameChooser class IMyContainer(Interface): "An interface" @adapter(IMyContainer) @implementer(INameChooser) class MyNameChooser(object): def __init__(self, container): self.container = container def chooseName(self, name, obj): return codecs.getencoder('rot-13')(name)[0] provideAdapter(MyNameChooser) from zope.interface import alsoProvides alsoProvides(container, IMyContainer) # OrderedContainerItemRenamer renames and preserves the order of items from zope.copypastemove import OrderedContainerItemRenamer renamer = OrderedContainerItemRenamer(container) self.assertEqual(renamer.renameItem('bar', 'quux'), u'dhhk') self.assertEqual(list(container.keys()), [u'foo', u'dhhk', u'baz']) self.assertEqual(container.values(), objects)
def test_order_adding_none(self): # This is a regression test: adding None to an OrderedContainer # used to corrupt its internal data structure (_order and _data # would get out of sync, causing KeyErrors when you tried to iterate). from zope.container.ordered import OrderedContainer oc = OrderedContainer() oc['foo'] = None self.assertEqual(oc.keys(), ['foo']) self.assertEqual(oc.values(), [None]) self.assertEqual(oc.items(), [('foo', None)]) # None got proxied, so 'is None is not true self.assertIsNotNone(oc['foo']) self.assertEqual(None, oc['foo'])