support multi requirement with inverse for same option

This commit is contained in:
Emmanuel Garette 2013-07-03 15:04:15 +02:00
parent b80bef0f7e
commit 0afb521766
3 changed files with 77 additions and 7 deletions

View File

@ -3,7 +3,7 @@ import autopath
from copy import copy
from tiramisu import setting
setting.expires_time = 1
from tiramisu.option import IPOption, OptionDescription, BoolOption, IntOption
from tiramisu.option import IPOption, OptionDescription, BoolOption, IntOption, StrOption
from tiramisu.config import Config
from tiramisu.error import PropertiesOptionError, RequirementError
from py.test import raises
@ -59,6 +59,65 @@ def test_requires_same_action():
assert props == ['disabled']
def test_multiple_requires():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled'},
{'option': a, 'expected': 'ok', 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
c = Config(od)
c.read_write()
c.ip_address_service
c.activate_service = 'yes'
props = []
try:
c.ip_address_service
except PropertiesOptionError, err:
props = err.proptype
assert props == ['disabled']
c.activate_service = 'ok'
props = []
try:
c.ip_address_service
except PropertiesOptionError, err:
props = err.proptype
assert props == ['disabled']
c.activate_service = 'no'
c.ip_address_service
def test_multiple_requires_inverse():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': 'ok', 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
c = Config(od)
c.read_write()
props = []
try:
c.ip_address_service
except PropertiesOptionError, err:
props = err.proptype
assert props == ['disabled']
c.activate_service = 'yes'
c.ip_address_service
c.activate_service = 'ok'
c.ip_address_service
c.activate_service = 'no'
props = []
try:
c.ip_address_service
except PropertiesOptionError, err:
props = err.proptype
assert props == ['disabled']
def test_requires_transitive():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,

View File

@ -869,8 +869,19 @@ def validate_requires_arg(requires, name):
" action: {1}").format(name, action))
else:
config_action[action] = inverse
if action not in ret_requires:
ret_requires[action] = {}
if option not in ret_requires[action]:
ret_requires[action][option] = (option, [expected], action,
inverse, transitive, same_action)
else:
ret_requires[action][option][1].append(expected)
ret_requires.setdefault(action, []).append((option, expected, action,
inverse, transitive, same_action))
return tuple(tuple(ret) for ret in ret_requires.values())
ret = []
for opt_requires in ret_requires.values():
ret_action = []
for require in opt_requires.values():
req = (require[0], tuple(require[1]), require[2], require[3], require[4], require[5])
ret_action.append(req)
ret.append(tuple(ret_action))
return tuple(ret)

View File

@ -360,12 +360,12 @@ class Setting(object):
raise RequirementError(_("option '{0}' has requirement's property error: "
"{1} {2}").format(opt._name, path, properties))
#transitive action, force expected
value = expected
value = expected[0]
inverse = False
except AttributeError:
raise AttributeError(_("required option not found: "
"{0}").format(path))
if not inverse and value == expected or inverse and value != expected:
if not inverse and value in expected or inverse and value not in expected:
matches = True
setting.append(action)
## the calculation cannot be carried out