support multi requirement with inverse for same option
authorEmmanuel Garette <egarette@cadoles.com>
Wed, 3 Jul 2013 13:04:15 +0000 (15:04 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Wed, 3 Jul 2013 13:04:15 +0000 (15:04 +0200)
test/test_requires.py
tiramisu/option.py
tiramisu/setting.py

index 61dfdee..9fa3837 100644 (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,
index 9937a6e..e645a31 100644 (file)
@@ -869,8 +869,19 @@ def validate_requires_arg(requires, name):
                                    " action: {1}").format(name, action))
         else:
             config_action[action] = inverse
-
-        ret_requires.setdefault(action, []).append((option, expected, action,
-                                                    inverse, transitive, same_action))
-
-    return tuple(tuple(ret) for ret in ret_requires.values())
+        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 = []
+    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)
index 05e8013..a20f88a 100644 (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