From 7acf12e988f45d503d7d93f03f706618f7696504 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Sun, 20 Jul 2008 01:29:59 +0000 Subject: 10: Updated base.API to reflect the fact that base.Object is now the new unit of plugin functionality; updated corresponding unit tests --- ipalib/__init__.py | 4 -- ipalib/base.py | 67 ++++++++++++++---------------- ipalib/crud.py | 24 +++++------ ipalib/tests/test_base.py | 101 +++++++++++++++++++++++----------------------- 4 files changed, 90 insertions(+), 106 deletions(-) (limited to 'ipalib') diff --git a/ipalib/__init__.py b/ipalib/__init__.py index 1337d812..ddce3ac9 100644 --- a/ipalib/__init__.py +++ b/ipalib/__init__.py @@ -20,7 +20,3 @@ """ IPA library. """ - -import base - -api = base.API() diff --git a/ipalib/base.py b/ipalib/base.py index cac6797f..3cadc70e 100644 --- a/ipalib/base.py +++ b/ipalib/base.py @@ -112,6 +112,14 @@ class NameSpace(object): for key in self.__keys: yield key + def __call__(self): + """ + Iterates through the values in this NameSpace in the same order as + the keys. + """ + for key in self.__keys: + yield self.__kw[key] + def __len__(self): """ Returns number of items in this NameSpace. @@ -172,57 +180,42 @@ class Object(Named): return NameSpace(d) def get_commands(self): - raise NotImplementedError + return [] def get_attributes(self): - raise NotImplementedError + return [] class API(object): - __cmd = None __objects = None - __locked = False + __commands = None def __init__(self): - self.__classes = set() - self.__names = set() - self.__stage = {} + self.__obj_d = {} def __get_objects(self): return self.__objects objects = property(__get_objects) - def __get_cmd(self): - return self.__cmd - cmd = property(__get_cmd) + def __get_commands(self): + return self.__commands + commands = property(__get_commands) - def __merge(self, base, cls, override): - assert issubclass(base, Named) + def register_object(self, cls, override=False): assert type(override) is bool - if not (inspect.isclass(cls) and issubclass(cls, base)): - raise exceptions.RegistrationError(cls, base.__name__) - if cls in self.__classes: - raise exceptions.DuplicateError(cls.__name__, id(cls)) - if cls.__name__ in self.__names and not override: - raise exceptions.OverrideError(cls.__name__) - prefix = base.prefix - assert cls.__name__.startswith(prefix) - self.__classes.add(cls) - self.__names.add(cls.__name__) - if prefix not in self.__stage: - self.__stage[prefix] = {} - self.__stage[prefix][cls.__name__] = cls - - - def register_command(self, cls, override=False): - self.__merge(Command, cls, override) + if not (inspect.isclass(cls) and issubclass(cls, Object)): + raise exceptions.RegistrationError(cls, 'Object') + obj = cls() + if obj.name in self.__obj_d and not override: + raise exceptions.OverrideError(obj.name) + self.__obj_d[obj.name] = obj def finalize(self): - for (prefix, d) in self.__stage.items(): - n = {} - for cls in d.values(): - i = cls() - assert cls.__name__ == (prefix + '_' + i.name) - n[i.name] = i - if prefix == 'cmd': - self.__cmd = NameSpace(n) + cmd_d = {} + for obj in self.__obj_d.values(): + for cmd in obj.commands(): + assert cmd.full_name not in cmd_d + cmd_d[cmd.full_name] = cmd + self.__commands = NameSpace(cmd_d) + self.__objects = NameSpace(self.__obj_d) + self.__obj_d = None diff --git a/ipalib/crud.py b/ipalib/crud.py index afbad47a..c20b4cc1 100644 --- a/ipalib/crud.py +++ b/ipalib/crud.py @@ -23,15 +23,15 @@ Base classes for objects with CRUD functionality. import base -class create(base.Command): +class add(base.Command): pass -class retrieve(base.Command): +class get(base.Command): pass -class update(base.Command): +class edit(base.Command): pass @@ -39,22 +39,16 @@ class delete(base.Command): pass -class search(base.Command): +class find(base.Command): pass -class user(base.Object): +class CrudLike(base.Object): def get_commands(self): return [ - create, - retrieve, - update, + add, + get, + edit, delete, - ] - - def get_attributes(self): - return [ - givenName, - sn, - login, + find, ] diff --git a/ipalib/tests/test_base.py b/ipalib/tests/test_base.py index 31b10994..aefe4fa3 100644 --- a/ipalib/tests/test_base.py +++ b/ipalib/tests/test_base.py @@ -21,7 +21,7 @@ Unit tests for `ipalib.base` module. """ -from ipalib import base, exceptions +from ipalib import base, exceptions, crud def read_only(obj, name): @@ -225,7 +225,6 @@ def test_Object(): class login(base.Attribute): pass - class user(base.Object): def get_commands(self): return [ @@ -283,79 +282,81 @@ class test_API: """ return base.API() - def dont_fresh(self): + def test_fresh(self): """ Test expectations of a fresh API instance. """ api = self.new() - assert read_only(api, 'cmd') is None + assert read_only(api, 'objects') is None + assert read_only(api, 'commands') is None - def dont_register_command(self): + def test_register_exception(self): + """ + Check that RegistrationError is raised when registering anything + other than a subclass of Command. + """ api = self.new() - class cmd_my_command(base.Command): - pass - class cmd_another_command(base.Command): + class my_command(base.Command): pass - # Check that RegistrationError is raised when registering anything - # other than a subclass of Command: - for obj in [object, cmd_my_command()]: + for obj in [object, my_command]: raised = False try: - api.register_command(obj) + api.register_object(obj) except exceptions.RegistrationError: raised = True assert raised - # Check that command registration works: - api.register_command(cmd_my_command) - api.register_command(cmd_another_command) - - # Check that DuplicateError is raised when registering the same class - # twice: - raised = False - try: - api.register_command(cmd_my_command) - except exceptions.DuplicateError: - raised = True - assert raised + def test_override_exception(self): + class some_object(base.Object): + def get_commands(self): + return [] + def get_attributes(self): + return [] - # Check that OverrideError is raised when registering same name - # without override = True: - class cmd_my_command(base.Command): - pass + api = self.new() + api.register_object(some_object) raised = False try: - api.register_command(cmd_my_command) + api.register_object(some_object) except exceptions.OverrideError: raised = True assert raised + api.register_object(some_object, override=True) - # Check that override=True works: - api.register_command(cmd_my_command, override=True) - - def dont_finalize(self): - api = self.new() - assert read_only(api, 'cmd') is None - - class cmd_my_command(base.Command): + def test_finalize(self): + class user(crud.CrudLike): pass - class cmd_another_command(base.Command): + class group(crud.CrudLike): + pass + class service(crud.CrudLike): pass - api.register_command(cmd_my_command) - api.register_command(cmd_another_command) + names = list(user().commands) + assert len(names) == 5 + full_names = set() + for o in ['user', 'group', 'service']: + full_names.update('%s_%s' % (v, o) for v in names) + assert len(full_names) == 15 - api.finalize() - cmd = read_only(api, 'cmd') - assert isinstance(cmd, base.NameSpace) - assert api.cmd is cmd + api = self.new() + api.register_object(user) + api.register_object(group) + api.register_object(service) + api.finalize() - assert len(cmd) == 2 - assert list(cmd) == ['another_command', 'my_command'] - assert isinstance(cmd.my_command, cmd_my_command) - assert cmd.my_command is cmd['my_command'] - assert isinstance(cmd.another_command, cmd_another_command) - assert cmd.another_command is cmd['another_command'] + # Test API.objects property: + objects = read_only(api, 'objects') + assert type(objects) is base.NameSpace + assert objects is api.objects # Same instance must be returned + assert len(objects) is 3 + assert list(objects) == ['group', 'service', 'user'] + + # Test API.commands property: + commands = read_only(api, 'commands') + assert type(commands) is base.NameSpace + assert commands is api.commands # Same instance must be returned + assert len(commands) is 15 + assert list(commands) == sorted(full_names) -- cgit