diff options
-rw-r--r-- | ipalib/public.py | 66 | ||||
-rw-r--r-- | ipalib/tests/test_public.py | 64 |
2 files changed, 86 insertions, 44 deletions
diff --git a/ipalib/public.py b/ipalib/public.py index d97f519b..564f6c8b 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -168,8 +168,8 @@ class Command(plugable.Plugin): 'get_doc', 'options', )) - __options = None - option_classes = tuple() + __Option = None + options = tuple() def get_doc(self, _): """ @@ -183,26 +183,18 @@ class Command(plugable.Plugin): raise NotImplementedError('%s.get_doc()' % self.name) def get_options(self): - """ - Returns iterable with option proxy objects used to create the option - NameSpace when __get_option() is called. - """ - for cls in self.option_classes: - assert inspect.isclass(cls) - o = cls() - o.__lock__() - yield plugable.PluginProxy(Option, o) + return self.options - def __get_options(self): + def __get_Option(self): """ - Returns the NameSpace containing the option proxy objects. + Returns the NameSpace containing the Option instances. """ - if self.__options is None: - object.__setattr__(self, '_Command__options', + if self.__Option is None: + object.__setattr__(self, '_Command__Option', plugable.NameSpace(self.get_options()), ) - return self.__options - options = property(__get_options) + return self.__Option + Option = property(__get_Option) def normalize_iter(self, kw): for (key, value) in kw.items(): @@ -332,11 +324,11 @@ class Method(Attribute, Command): __public__ = Attribute.__public__.union(Command.__public__) def get_options(self): - for proxy in Command.get_options(self): - yield proxy + for option in Command.options: + yield option if self.obj is not None and self.obj.Property is not None: for proxy in self.obj.Property(): - yield proxy + yield proxy.option class Property(Attribute): @@ -346,19 +338,27 @@ class Property(Attribute): 'type', )).union(Attribute.__public__) - def __get_rules(self): - """ - Returns the tuple of rule methods used for input validation. This - tuple is lazily initialized the first time the property is accessed. - """ - if self.__rules is None: - rules = tuple(sorted( - self.__rules_iter(), - key=lambda f: getattr(f, '__name__'), - )) - object.__setattr__(self, '_Property__rules', rules) - return self.__rules - rules = property(__get_rules) + type = ipa_types.Unicode() + required = False + multivalue = False + default = None + default_from = None + normalize = None + + def __init__(self): + super(Property, self).__init__() + self.rules = tuple(sorted( + self.__rules_iter(), + key=lambda f: getattr(f, '__name__'), + )) + self.option = Option(self.attr_name, self.doc, self.type, + required=self.required, + multivalue=self.multivalue, + default=self.default, + default_from=self.default_from, + rules=self.rules, + normalize=self.normalize, + ) def __rules_iter(self): """ diff --git a/ipalib/tests/test_public.py b/ipalib/tests/test_public.py index 2e732179..3000cfe3 100644 --- a/ipalib/tests/test_public.py +++ b/ipalib/tests/test_public.py @@ -304,30 +304,47 @@ class test_Option(ClassChecker): assert o.get_values() == values -class test_Command(ClassChecker): +class dont_Command(ClassChecker): """ Tests the `public.Command` class. """ _cls = public.Command def get_subcls(self): - class my_option(public.Option): - def normalize(self, value): - return super(my_option, self).normalize(value).lower() - @public.rule - def my_rule(self, value): + class Rule(object): + def __init__(self, name): + self.name = name + + def __call__(self, value): if value != self.name: return 'must equal %r' % self.name - default_from = public.DefaultFrom( - lambda arg: arg, 'default_from' - ) + + default_from = public.DefaultFrom( + lambda arg: arg, + 'default_from' + ) + normalize = lambda value: value.lower() + type_ = ipa_types.Unicode() class option0(my_option): pass class option1(my_option): required = True + class example(self.cls): - option_classes = (option0, option1) + options = ( + public.Option('option0', 'Option zero', type_, + normalize=normalize, + default_from=default_from, + rules=(Rule('option0'),) + ), + public.Option('option1', 'Option one', type_, + normalize=normalize, + default_from=default_from, + rules=(Rule('option1'),), + required=True, + ), + ) return example def test_class(self): @@ -550,7 +567,7 @@ class test_Attribute(ClassChecker): assert read_only(o, 'obj') is user_obj -class test_Method(ClassChecker): +class dont_Method(ClassChecker): """ Tests the `public.Method` class. """ @@ -608,5 +625,30 @@ class test_Property(ClassChecker): """ _cls = public.Property + def get_subcls(self): + class user_givenname(self.cls): + 'User first name' + + @public.rule + def rule0_lowercase(self, value): + if not value.islower(): + return 'Must be lowercase' + return user_givenname + def test_class(self): assert self.cls.__bases__ == (public.Attribute,) + assert isinstance(self.cls.type, ipa_types.Unicode) + assert self.cls.required is False + assert self.cls.multivalue is False + assert self.cls.default is None + assert self.cls.default_from is None + assert self.cls.normalize is None + + def test_init(self): + o = self.subcls() + assert len(o.rules) == 1 + assert o.rules[0].__name__ == 'rule0_lowercase' + opt = o.option + assert isinstance(opt, public.Option) + assert opt.name == 'givenname' + assert opt.doc == 'User first name' |