From 0afb5217660a983e1c88e316a8c983d8ccbfc15f Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 3 Jul 2013 15:04:15 +0200 Subject: [PATCH] support multi requirement with inverse for same option --- test/test_requires.py | 61 ++++++++++++++++++++++++++++++++++++++++++- tiramisu/option.py | 19 +++++++++++--- tiramisu/setting.py | 4 +-- 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/test/test_requires.py b/test/test_requires.py index 61dfdee..9fa3837 100644 --- a/test/test_requires.py +++ b/test/test_requires.py @@ -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, diff --git a/tiramisu/option.py b/tiramisu/option.py index 9937a6e..e645a31 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -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) diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 05e8013..a20f88a 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -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