diff --git a/ipalib/base.py b/ipalib/base.py index 96dd300dd..c7a0cf99f 100644 --- a/ipalib/base.py +++ b/ipalib/base.py @@ -26,18 +26,31 @@ import exceptions class Named(object): - #def __init__(self, prefix): - # clsname = self.__class__.__name__ + prefix = None + + @classmethod + def clsname(cls): + return cls.__name__ + + def __init__(self): + clsname = self.clsname() + assert type(self.prefix) is str + prefix = self.prefix + '_' + if not clsname.startswith(prefix): + raise exceptions.PrefixError(clsname, prefix) + self.__name = clsname[len(prefix):] + self.__name_cli = self.__name.replace('_', '-') + def __get_name(self): - return self.__class__.__name__ + return self.__name name = property(__get_name) - def __get_cli_name(self): - return self.name.replace('_', '-') - cli_name = property(__get_cli_name) + def __get_name_cli(self): + return self.__name_cli + name_cli = property(__get_name_cli) -class Command(Named): +class Command(object): def normalize(self, kw): raise NotImplementedError diff --git a/ipalib/exceptions.py b/ipalib/exceptions.py index 752a1e20f..4150d7124 100644 --- a/ipalib/exceptions.py +++ b/ipalib/exceptions.py @@ -55,3 +55,7 @@ class OverrideError(IPAError): class RegistrationError(IPAError): msg = '%r is not a subclass of %s' + + +class PrefixError(IPAError): + msg = 'class name %r must start with %r' diff --git a/ipalib/tests/test_base.py b/ipalib/tests/test_base.py index 7a998f3cd..e0e2d8e88 100644 --- a/ipalib/tests/test_base.py +++ b/ipalib/tests/test_base.py @@ -40,6 +40,77 @@ def read_only(obj, name): return getattr(obj, name) +class ClassChecker(object): + cls = None # Override this is subclasses + + def new(self, *args, **kw): + return self.cls(*args, **kw) + + def args(self): + return [] + + def kw(self): + return {} + + def std(self): + return self.new(*self.args(), **self.kw()) + + +class test_Named: + """ + Unit tests for `Named` class. + """ + cls = base.Named + + def new(self): + class tst_verb_object(self.cls): + prefix = 'tst' + return tst_verb_object() + + def test_prefix(self): + """ + Test prefix exception. + """ + # Test Example class: + class Example(self.cls): + prefix = 'eg' + + # Two test subclasses: + class do_stuff(Example): + pass + class eg_do_stuff(Example): + pass + + # Test that PrefixError is raised with incorrectly named subclass: + raised = False + try: + do_stuff() + except exceptions.PrefixError: + raised = True + assert raised + + # Test that correctly named subclass works: + eg_do_stuff() + + def test_name(self): + """ + Test Named.name property. + """ + obj = self.new() + assert read_only(obj, 'name') == 'verb_object' + + def test_name_cli(self): + """ + Test Named.name_cli property. + """ + obj = self.new() + assert read_only(obj, 'name_cli') == 'verb-object' + + + + + + class test_NameSpace: """ Unit tests for `NameSpace` class.