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 copy import copy
from tiramisu import setting from tiramisu import setting
setting.expires_time = 1 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.config import Config
from tiramisu.error import PropertiesOptionError, RequirementError from tiramisu.error import PropertiesOptionError, RequirementError
from py.test import raises from py.test import raises
@ -59,6 +59,65 @@ def test_requires_same_action():
assert props == ['disabled'] 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(): def test_requires_transitive():
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True, b = BoolOption('activate_service_web', '', True,

View File

@ -869,8 +869,19 @@ def validate_requires_arg(requires, name):
" action: {1}").format(name, action)) " action: {1}").format(name, action))
else: else:
config_action[action] = inverse 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, ret = []
inverse, transitive, same_action)) for opt_requires in ret_requires.values():
ret_action = []
return tuple(tuple(ret) for ret in ret_requires.values()) 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: " raise RequirementError(_("option '{0}' has requirement's property error: "
"{1} {2}").format(opt._name, path, properties)) "{1} {2}").format(opt._name, path, properties))
#transitive action, force expected #transitive action, force expected
value = expected value = expected[0]
inverse = False inverse = False
except AttributeError: except AttributeError:
raise AttributeError(_("required option not found: " raise AttributeError(_("required option not found: "
"{0}").format(path)) "{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 matches = True
setting.append(action) setting.append(action)
## the calculation cannot be carried out ## the calculation cannot be carried out