valid properties for slaves when set or append a master's value
authorEmmanuel Garette <egarette@cadoles.com>
Mon, 26 Oct 2015 14:39:07 +0000 (15:39 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Mon, 26 Oct 2015 14:39:07 +0000 (15:39 +0100)
test/test_option_calculation.py
tiramisu/option/masterslave.py

index 694e524..6e6bb5f 100644 (file)
@@ -236,6 +236,7 @@ def test_callback_invalid():
     raises(ValueError, 'val1 = StrOption("val1", "", callback="string")')
     raises(ValueError, 'val1 = StrOption("val1", "", callback=return_val, callback_params="string")')
     val1 = StrOption('val1', "", 'val')
+    val1
     raises(ValueError, "StrOption('val2', '', callback=return_value, callback_params={'': 'string'})")
     raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': (('string', False),)})")
     raises(ValueError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, 'string'),)})")
@@ -739,10 +740,116 @@ def test_callback_master_and_slaves_value():
     assert cfg.val1.val6 == ['val2', 'val2', 'val12']
 
 
+def test_callback_master_and_slaves_disabled():
+    val = BoolOption('val', '', multi=True)
+    val1 = StrOption('val1', "", multi=True)
+    val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val, False),)})
+    interface1 = OptionDescription('val1', '', [val1, val2])
+    interface1.impl_set_group_type(groups.master)
+    maconfig = OptionDescription('rootconfig', '', [val, interface1])
+    cfg = Config(maconfig)
+    cfg.read_write()
+    #
+    assert cfg.val == []
+    assert cfg.val1.val1 == []
+    assert cfg.val1.val2 == []
+    cfg.val1.val1.append('val1')
+    assert cfg.val == []
+    assert cfg.val1.val1 == ['val1']
+    assert cfg.val1.val2 == [None]
+    #
+    cfg.val.append(True)
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].append('disabled')
+    assert cfg.val == [True]
+    assert cfg.val1.val1 == ['val1']
+    raises(PropertiesOptionError, 'cfg.val1.val2')
+    #
+    cfg.val1.val1.append('val1_1')
+    assert cfg.val == [True]
+    assert cfg.val1.val1 == ['val1', 'val1_1']
+    raises(PropertiesOptionError, 'cfg.val1.val2')
+    #
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].remove('disabled')
+    assert cfg.val == [True]
+    assert cfg.val1.val1 == ['val1', 'val1_1']
+    raises(ValueError, 'cfg.val1.val2')
+    #
+    cfg.val = []
+    assert cfg.val1.val1 == ['val1', 'val1_1']
+    assert cfg.val1.val2 == [None, None]
+    #
+    cfg.val1.val2 = [None, None]
+    cfg.val = [True, True]
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].append('disabled')
+    cfg.val1.val1.pop(1)
+    assert cfg.val == [True, True]
+    assert cfg.val1.val1 == ['val1']
+    raises(PropertiesOptionError, 'cfg.val1.val2')
+    #
+    cfg.val1.val1.append('val1_2')
+    assert cfg.val == [True, True]
+    assert cfg.val1.val1 == ['val1', 'val1_2']
+    raises(PropertiesOptionError, 'cfg.val1.val2')
+    #
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].remove('disabled')
+    assert cfg.val == [True, True]
+    assert cfg.val1.val1 == ['val1', 'val1_2']
+    #[None, None] + pop() + append() => [None, True]
+    raises(ValueError, 'assert cfg.val1.val2')
+
+
+def test_callback_master_and_slaves_requires():
+    val = StrOption('val', '', 'val')
+    valreq = StrOption('valreq', '', 'val')
+    val1 = StrOption('val1', "", multi=True)
+    val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
+    val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
+    val4 = StrOption('val4', '', multi=True, default=[])
+    val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params={'': ((val4, False),)})
+    val6 = StrOption('val6', "", multi=True, callback=return_value, callback_params={'': ((val, False),)},
+                     requires=({'option': valreq, 'expected': 'val_disabled', 'action': 'disabled'},))
+    interface1 = OptionDescription('val1', '', [val1, val2, val3, val5, val6])
+    interface1.impl_set_group_type(groups.master)
+    maconfig = OptionDescription('rootconfig', '', [val, valreq, interface1, val4])
+    cfg = Config(maconfig)
+    cfg.read_write()
+    assert cfg.val1.val1 == []
+    assert cfg.val1.val2 == []
+    assert cfg.val1.val3 == []
+    assert cfg.val1.val5 == []
+    assert cfg.val1.val6 == []
+    #
+    cfg.val1.val1 = ['val1']
+    assert cfg.val1.val1 == ['val1']
+    assert cfg.val1.val2 == ['val1']
+    assert cfg.val1.val3 == ['yes']
+    assert cfg.val1.val5 == [None]
+    assert cfg.val1.val6 == ['val']
+    cfg.val4 = ['val10']
+    assert cfg.val1.val5 == ['val10']
+    #
+    cfg.valreq = 'val_disabled'
+    assert cfg.val1.val1 == ['val1']
+    assert cfg.val1.val2 == ['val1']
+    assert cfg.val1.val3 == ['yes']
+    assert cfg.val1.val5 == ['val10']
+    raises(PropertiesOptionError, 'cfg.val1.val6')
+    assert cfg.make_dict() == {'val1.val2': ['val1'], 'val1.val3': ['yes'], 'val1.val1': ['val1'], 'val1.val5': ['val10'], 'val': 'val', 'valreq': 'val_disabled', 'val4': ['val10']}
+    #
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val].append('disabled')
+    cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val3].append('disabled')
+    raises(PropertiesOptionError, 'cfg.val1.val6')
+    assert cfg.make_dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val5': ['val10'], 'val4': ['val10'], 'valreq': 'val_disabled'}
+    #
+    cfg.valreq = 'val'
+    raises(ConfigError, 'cfg.val1.val6')
+
+
 def test_callback_master():
     val2 = StrOption('val2', "", multi=True, callback=return_value)
     val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val2, False),)})
     interface1 = OptionDescription('val1', '', [val1, val2])
+    interface1
     raises(ValueError, "interface1.impl_set_group_type(groups.master)")
 
 
index c3d2890..3462f70 100644 (file)
@@ -189,7 +189,7 @@ class MasterSlaves(object):
         value = values._get_validated_value(opt, path, validate,
                                             force_permissive,
                                             force_properties,
-                                            False,
+                                            validate_properties,
                                             None,  # not undefined
                                             with_meta=master_is_meta,
                                             settings=settings)
@@ -211,21 +211,23 @@ class MasterSlaves(object):
                              setitem=False,
                              force=True,
                              validate=validate)
-        if validate_properties:
-            context.cfgimpl_get_settings().validate_properties(opt, False,
-                                                               False,
-                                                               value=value,
-                                                               path=path,
-                                                               force_permissive=force_permissive,
-                                                               force_properties=force_properties,
-                                                               self_properties=setting_properties)
+            if validate_properties:
+                context.cfgimpl_get_settings().validate_properties(opt, False,
+                                                                   False,
+                                                                   value=value,
+                                                                   path=path,
+                                                                   force_permissive=force_permissive,
+                                                                   force_properties=force_properties,
+                                                                   self_properties=setting_properties)
         return value
 
     def setitem(self, values, opt, value, path):
         if self.is_master(opt):
             masterlen = len(value)
+            #for regen slave path
+            base_path = '.'.join(path.split('.')[:-1]) + '.'
             for slave in self.getslaves(opt):
-                slave_path = slave.impl_getpath(values._getcontext())
+                slave_path = base_path + slave.impl_getname()
                 slave_value = values._get_validated_value(slave,
                                                           slave_path,
                                                           False,