~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_registry.py

  • Committer: Vincent Ladeuil
  • Date: 2009-09-16 10:37:29 UTC
  • mto: (4695.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4696.
  • Revision ID: v.ladeuil+lp@free.fr-20090916103729-m6h1pyvjprm6puvm
Respect items() protocol for registry objects.

* bzrlib/tests/test_registry.py:
(TestRegistryIter): Test some corner cases where object are
registered while the registry is iterated.

* bzrlib/registry.py:
(Registry): iteritems() and items() have different intents, don't
mix them under the covers or devs get tricked (see bug #277048
which seemed to have fixed the issue).

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
from bzrlib import (
23
23
    errors,
 
24
    osutils,
24
25
    registry,
25
 
    osutils,
 
26
    tests,
26
27
    )
27
 
from bzrlib.tests import TestCase, TestCaseInTempDir
28
 
 
29
 
 
30
 
class TestRegistry(TestCase):
 
28
 
 
29
 
 
30
class TestRegistry(tests.TestCase):
31
31
 
32
32
    def register_stuff(self, a_registry):
33
33
        a_registry.register('one', 1)
202
202
        self.assertIs(sftp_object, found_object)
203
203
 
204
204
 
205
 
class TestRegistryWithDirs(TestCaseInTempDir):
 
205
class TestRegistryIter(tests.TestCase):
 
206
    """Test registry iteration behaviors.
 
207
 
 
208
    There are dark corner cases here when the registered objects trigger
 
209
    addition in the iterated registry.
 
210
    """
 
211
 
 
212
    def setUp(self):
 
213
        super(TestRegistryIter, self).setUp()
 
214
 
 
215
        # We create a registry with "official" objects and "hidden"
 
216
        # objects. The later represent the side effects that led to bug #277048
 
217
        # and #430510
 
218
        self.registry =  registry.Registry()
 
219
 
 
220
        def register_more():
 
221
            self.registry.register('hidden', None)
 
222
 
 
223
        self.registry.register('passive', None)
 
224
        self.registry.register('active', register_more)
 
225
        self.registry.register('passive-too', None)
 
226
 
 
227
        class InvasiveGetter(registry._ObjectGetter):
 
228
 
 
229
            def get_obj(inner_self):
 
230
                # Surprise ! Getting a registered object (think lazy loaded
 
231
                # module) register yet another object !
 
232
                self.registry.register('more hidden', None)
 
233
                return inner_self._obj
 
234
 
 
235
        self.registry.register('hacky', None)
 
236
        # We peek under the covers because the alternative is to use lazy
 
237
        # registration and create a module that can reference our test registry
 
238
        # it's too much work for such a corner case -- vila 090916
 
239
        self.registry._dict['hacky'] = InvasiveGetter(None)
 
240
 
 
241
    def _iter_them(self, iter_func_name):
 
242
        iter_func = getattr(self.registry, iter_func_name, None)
 
243
        self.assertIsNot(None, iter_func)
 
244
        count = 0
 
245
        for name, func in iter_func():
 
246
            count += 1
 
247
            self.assertFalse(name in ('hidden', 'more hidden'))
 
248
            if func is not None:
 
249
                # Using an object register another one as a side effect
 
250
                func()
 
251
        self.assertEqual(4, count)
 
252
 
 
253
    def test_iteritems(self):
 
254
        # the dict is modified during the iteration
 
255
        self.assertRaises(RuntimeError, self._iter_them, 'iteritems')
 
256
 
 
257
    def test_items(self):
 
258
        # we should be able to iterate even if one item modify the dict
 
259
        self._iter_them('items')
 
260
 
 
261
 
 
262
class TestRegistryWithDirs(tests.TestCaseInTempDir):
206
263
    """Registry tests that require temporary dirs"""
207
264
 
208
265
    def create_plugin_file(self, contents):