def test_unregister(self): """ Removing a class from the registry. This is not used that often outside of unit tests (e.g., to remove artifacts when a test has to add a class to a global registry). """ registry = ClassRegistry(attr_name='element') registry.register(Charmander) registry.register(Squirtle) # Don't feel bad Bulbasaur! Actually, you're my favorite! self.assertIs(registry.unregister('fire'), Charmander) with self.assertRaises(RegistryKeyError): registry.get('fire') # Note that you must unregister the KEY, not the CLASS. with self.assertRaises(KeyError): # noinspection PyTypeChecker registry.unregister(Squirtle) # If you try to unregister a key that isn't registered, you'll # get an error. with self.assertRaises(KeyError): registry.unregister('fire')
class RegistryPatcherTestCase(TestCase): def setUp(self): super(RegistryPatcherTestCase, self).setUp() self.registry = ClassRegistry(attr_name='element', unique=True) def test_patch_detect_keys(self): """ Patching a registry in a context, with registry keys detected automatically. """ self.registry.register(Charmander) self.registry.register(Squirtle) with RegistryPatcher(self.registry, Charmeleon, Bulbasaur): self.assertIsInstance(self.registry['fire'], Charmeleon) self.assertIsInstance(self.registry['water'], Squirtle) # Nesting contexts? You betcha! with RegistryPatcher(self.registry, Ivysaur): self.assertIsInstance(self.registry['grass'], Ivysaur) self.assertIsInstance(self.registry['grass'], Bulbasaur) # Save file corrupted. Restoring previous save... self.assertIsInstance(self.registry['fire'], Charmander) self.assertIsInstance(self.registry['water'], Squirtle) with self.assertRaises(RegistryKeyError): self.registry.get('grass') def test_patch_manual_keys(self): """ Patching a registry in a context, specifying registry keys manually. """ self.registry.register('sparky')(Charmander) self.registry.register('chad')(Squirtle) with RegistryPatcher(self.registry, sparky=Charmeleon, rex=Bulbasaur): self.assertIsInstance(self.registry['sparky'], Charmeleon) self.assertIsInstance(self.registry['chad'], Squirtle) # Don't worry Chad; your day will come! with RegistryPatcher(self.registry, rex=Ivysaur): self.assertIsInstance(self.registry['rex'], Ivysaur) self.assertIsInstance(self.registry['rex'], Bulbasaur) # Save file corrupted. Restoring previous save... self.assertIsInstance(self.registry['sparky'], Charmander) self.assertIsInstance(self.registry['chad'], Squirtle) with self.assertRaises(RegistryKeyError): self.registry.get('jodie')
def test_constructor_params(self): """ Params can be passed to the registered class' constructor. """ registry = ClassRegistry(attr_name='element') registry.register(Bulbasaur) # Goofus uses positional arguments, which are magical and # make his code more difficult to read. goofus = registry.get('grass', 'goofus') # Gallant uses keyword arguments, producing self-documenting # code and being courteous to his fellow developers. # He still names his pokémon after himself, though. Narcissist. gallant = registry.get('grass', name='gallant') self.assertIsInstance(goofus, Bulbasaur) self.assertEqual(goofus.name, 'goofus') self.assertIsInstance(gallant, Bulbasaur) self.assertEqual(gallant.name, 'gallant')
def test_register_function(self): """ Functions can be registered as well (so long as they walk, talk and quack like a class). """ registry = ClassRegistry() @registry.register('fire') def pokemon_factory(name=None): return Charmeleon(name=name) poke = registry.get('fire', name='trogdor') self.assertIsInstance(poke, Charmeleon) self.assertEqual(poke.name, 'trogdor')