From 8a6041b7978d370418e99df8b9fc06b2055a39e6 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 7 Aug 2008 04:51:21 +0000 Subject: [PATCH] 73: Started work on validation rules for opt; added corresponding unit tests --- ipalib/public.py | 26 ++++++++ ipalib/tests/test_public.py | 116 ++++++++++++++++++++++++++---------- ipalib/tests/tstutil.py | 7 +++ 3 files changed, 118 insertions(+), 31 deletions(-) diff --git a/ipalib/public.py b/ipalib/public.py index 5806d0eb6..b43e0af97 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -27,6 +27,19 @@ import plugable import errors +RULE_FLAG = 'validation_rule' + +def rule(obj): + assert not hasattr(obj, RULE_FLAG) + setattr(obj, RULE_FLAG, True) + return obj + +def is_rule(obj): + return getattr(obj, RULE_FLAG, False) is True + + + + class opt(plugable.ReadOnly): __public__ = frozenset(( 'normalize', @@ -35,6 +48,7 @@ class opt(plugable.ReadOnly): 'required', 'type', )) + __rules = None def normalize(self, value): try: @@ -44,6 +58,18 @@ class opt(plugable.ReadOnly): self.__class__.__name__, value, self.type ) + def __get_rules(self): + if self.__rules is None: + self.__rules = tuple(self.__rules_iter()) + return self.__rules + rules = property(__get_rules) + + def __rules_iter(self): + pass + + def validate(self, value): + pass + diff --git a/ipalib/tests/test_public.py b/ipalib/tests/test_public.py index faffd02e9..122f489d4 100644 --- a/ipalib/tests/test_public.py +++ b/ipalib/tests/test_public.py @@ -25,40 +25,94 @@ from tstutil import raises, getitem, no_set, no_del, read_only from ipalib import public, plugable, errors -def test_opt(): - cls = public.opt - assert issubclass(cls, plugable.ReadOnly) +def test_RULE_FLAG(): + assert public.RULE_FLAG == 'validation_rule' - class int_opt(cls): - type = int - i = int_opt() +def test_rule(): + flag = public.RULE_FLAG + rule = public.rule + def my_func(): + pass + assert not hasattr(my_func, flag) + rule(my_func) + assert getattr(my_func, flag) is True + @rule + def my_func2(): + pass + assert getattr(my_func2, flag) is True - # Test with values that can't be converted: - nope = ( - '7.0' - 'whatever', - object, - None, - ) - for val in nope: - e = raises(errors.NormalizationError, i.normalize, val) - assert isinstance(e, errors.ValidationError) - assert e.name == 'int_opt' - assert e.value == val - assert e.error == "not " - assert e.type is int - # Test with values that can be converted: - okay = ( - 7, - 7.0, - 7.2, - 7L, - '7', - ' 7 ', - ) - for val in okay: - assert i.normalize(val) == 7 + +def test_is_rule(): + is_rule = public.is_rule + flag = public.RULE_FLAG + + class example(object): + def __init__(self, value): + if value is not None: + assert value in (True, False) + setattr(self, flag, value) + + obj = example(True) + assert getattr(obj, flag) is True + assert is_rule(obj) + + obj = example(False) + assert getattr(obj, flag) is False + assert not is_rule(obj) + + obj = example(None) + assert not hasattr(obj, flag) + assert not is_rule(obj) + + + + + + +class test_opt(): + def cls(self): + return public.opt + + def sub(self): + class int_opt(self.cls()): + type = int + return int_opt + + def test_class(self): + cls = self.cls() + assert issubclass(cls, plugable.ReadOnly) + + def test_normalize(self): + sub = self.sub() + + i = sub() + + # Test with values that can't be converted: + nope = ( + '7.0' + 'whatever', + object, + None, + ) + for val in nope: + e = raises(errors.NormalizationError, i.normalize, val) + assert isinstance(e, errors.ValidationError) + assert e.name == 'int_opt' + assert e.value == val + assert e.error == "not " + assert e.type is int + # Test with values that can be converted: + okay = ( + 7, + 7.0, + 7.2, + 7L, + '7', + ' 7 ', + ) + for val in okay: + assert i.normalize(val) == 7 def test_cmd(): cls = public.cmd diff --git a/ipalib/tests/tstutil.py b/ipalib/tests/tstutil.py index cdac45474..d2de3b861 100644 --- a/ipalib/tests/tstutil.py +++ b/ipalib/tests/tstutil.py @@ -86,7 +86,14 @@ def read_only(obj, name, value='some_new_obj'): return getattr(obj, name) +def is_prop(prop): + return type(prop) is property + + class ClassChecker(object): def new(self, *args, **kw): return self.cls(*args, **kw) + + def get_sub(self): + raise NotImplementedError('get_sub()')