add some tests
authorEmmanuel Garette <egarette@cadoles.com>
Tue, 4 Feb 2014 20:14:30 +0000 (21:14 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Tue, 4 Feb 2014 20:14:30 +0000 (21:14 +0100)
test/test_config_api.py
test/test_metaconfig.py
test/test_option_owner.py
tiramisu/config.py
tiramisu/option.py
tiramisu/value.py

index 75920eb..f5bc2c1 100644 (file)
@@ -4,7 +4,8 @@ from py.test import raises
 
 from tiramisu.config import Config
 from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
-    BoolOption, FilenameOption, OptionDescription
+    BoolOption, FilenameOption, UnicodeOption, SymLinkOption, IPOption, \
+    PortOption, OptionDescription
 
 
 def make_description():
@@ -150,6 +151,7 @@ def test_find_in_config():
     # not OptionDescription
     raises(AttributeError, "conf.find_first(byname='gc')")
     raises(AttributeError, "conf.gc.find_first(byname='gc2')")
+    raises(ValueError, "conf.find(byname='bool', type_='unknown')")
 
 
 def test_find_multi():
@@ -208,3 +210,18 @@ def test_iter_all_prop():
     config = Config(descr)
     config.read_only()
     assert list(config.iter_all()) == [('string2', 'string2')]
+
+
+def test_invalid_option():
+    raises(TypeError, "ChoiceOption('a', '', [1, 2])")
+    raises(TypeError, "ChoiceOption('a', '', 1)")
+    raises(TypeError, "ChoiceOption('a', '', (1,), open_values='string')")
+    raises(ValueError, "ChoiceOption('a', '', (1,), 3)")
+    raises(ValueError, "FloatOption('a', '', 'string')")
+    raises(ValueError, "UnicodeOption('a', '', 1)")
+    raises(ValueError, "SymLinkOption('a', 'string')")
+    raises(ValueError, "IPOption('a', '', 1)")
+    raises(ValueError, "IPOption('a', '', 'string')")
+    raises(ValueError, "PortOption('a', '', 'string')")
+    raises(ValueError, "PortOption('a', '', '11:12:13', allow_range=True)")
+    raises(ValueError, "PortOption('a', '', 11111111111111111111)")
index 9409d85..a8fc395 100644 (file)
@@ -5,7 +5,7 @@ from py.test import raises
 from tiramisu.setting import owners
 from tiramisu.config import Config, GroupConfig, MetaConfig
 from tiramisu.option import IntOption, OptionDescription
-from tiramisu.error import ConfigError
+from tiramisu.error import ConfigError, PropertiesOptionError
 
 owners.addowner('meta')
 
@@ -15,10 +15,14 @@ def make_description():
     i2 = IntOption('i2', '', default=1)
     i3 = IntOption('i3', '')
     i4 = IntOption('i4', '', default=2)
-    od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
+    i5 = IntOption('i5', '', default=[2], multi=True)
+    i6 = IntOption('i6', '', properties=('disabled',))
+    od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6])
     od2 = OptionDescription('od2', '', [od1])
     conf1 = Config(od2)
     conf2 = Config(od2)
+    conf1.read_write()
+    conf2.read_write()
     meta = MetaConfig([conf1, conf2])
     meta.cfgimpl_get_settings().setowner(owners.meta)
     return meta
@@ -29,7 +33,7 @@ def make_description():
 #FIXME serialization
 def test_none():
     meta = make_description()
-    conf1, conf2 = meta._impl_children
+    conf1, conf2 = meta.cfgimpl_get_children()
     assert conf1.od1.i3 is conf2.od1.i3 is None
     assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
     meta.od1.i3 = 3
@@ -58,7 +62,7 @@ def test_none():
 
 def test_default():
     meta = make_description()
-    conf1, conf2 = meta._impl_children
+    conf1, conf2 = meta.cfgimpl_get_children()
     assert conf1.od1.i2 == conf2.od1.i2 == 1
     assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
     meta.od1.i2 = 3
@@ -87,7 +91,7 @@ def test_default():
 
 def test_contexts():
     meta = make_description()
-    conf1, conf2 = meta._impl_children
+    conf1, conf2 = meta.cfgimpl_get_children()
     assert conf1.od1.i2 == conf2.od1.i2 == 1
     assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
     meta.setattrs('od1.i2', 6)
@@ -101,14 +105,15 @@ def test_find():
     i2 = meta.unwrap_from_path('od1.i2')
     assert [i2] == meta.find(byname='i2')
     assert i2 == meta.find_first(byname='i2')
-    assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1}
+    assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None,
+                                'od1.i2': 1, 'od1.i5': [2], 'od1.i6': None}
 
 
 def test_meta_meta():
     meta1 = make_description()
     meta2 = MetaConfig([meta1])
     meta2.cfgimpl_get_settings().setowner(owners.meta)
-    conf1, conf2 = meta1._impl_children
+    conf1, conf2 = meta1.cfgimpl_get_children()
     assert conf1.od1.i2 == conf2.od1.i2 == 1
     assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
     meta2.od1.i2 = 3
@@ -142,15 +147,21 @@ def test_meta_meta_set():
     meta1 = make_description()
     meta2 = MetaConfig([meta1])
     meta2.cfgimpl_get_settings().setowner(owners.meta)
-    conf1, conf2 = meta1._impl_children
+    conf1, conf2 = meta1.cfgimpl_get_children()
     meta2.setattrs('od1.i1', 7)
+    #PropertiesOptionError
+    meta2.setattrs('od1.i6', 7)
     assert conf1.od1.i1 == conf2.od1.i1 == 7
     assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
     assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7)
     conf1.od1.i1 = 8
+    assert [conf1, conf2] == meta2.find_firsts(byname='i1')
     assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7)
     assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8)
+    assert [conf1, conf2] == meta2.find_firsts(byname='i5', byvalue=2)
     raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
+    raises(AttributeError, "meta2.find_firsts(byname='not', byvalue=10)")
+    raises(AttributeError, "meta2.find_firsts(byname='i6')")
 
 
 def test_not_meta():
@@ -159,9 +170,10 @@ def test_not_meta():
     od2 = OptionDescription('od2', '', [od1])
     conf1 = Config(od2)
     conf2 = Config(od2)
+    raises(ValueError, "GroupConfig(conf1)")
     meta = GroupConfig([conf1, conf2])
     raises(ConfigError, 'meta.od1.i1')
-    conf1, conf2 = meta._impl_children
+    conf1, conf2 = meta.cfgimpl_get_children()
     meta.setattrs('od1.i1', 7)
     assert conf1.od1.i1 == conf2.od1.i1 == 7
     assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
index b758e91..d4c3f6b 100644 (file)
@@ -36,6 +36,7 @@ def test_default_owner():
     cfg = Config(descr)
     assert cfg.dummy is False
     assert cfg.getowner(gcdummy) == 'default'
+    raises(TypeError, "cfg.getowner('gcdummy')")
     cfg.dummy = True
     assert cfg.getowner(gcdummy) == owners.user
 
index e3ac94f..c9fb992 100644 (file)
@@ -296,12 +296,9 @@ class SubConfig(object):
         :return: find list or an exception if nothing has been found
         """
         def _filter_by_name():
-            try:
-                if byname is None or path == byname or \
-                        path.endswith('.' + byname):
-                    return True
-            except IndexError:
-                pass
+            if byname is None or path == byname or \
+                    path.endswith('.' + byname):
+                return True
             return False
 
         def _filter_by_value():
@@ -452,22 +449,16 @@ class SubConfig(object):
 
     def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten):
         if isinstance(opt, OptionDescription):
-            try:
-                pathsvalues += getattr(self, path).make_dict(flatten,
-                                                             _currpath +
-                                                             path.split('.'))
-            except PropertiesOptionError:
-                pass  # this just a hidden or disabled option
+            pathsvalues += getattr(self, path).make_dict(flatten,
+                                                         _currpath +
+                                                         path.split('.'))
         else:
-            try:
-                value = self._getattr(opt._name)
-                if flatten:
-                    name = opt._name
-                else:
-                    name = '.'.join(_currpath + [opt._name])
-                pathsvalues.append((name, value))
-            except PropertiesOptionError:
-                pass  # this just a hidden or disabled option
+            value = self._getattr(opt._name)
+            if flatten:
+                name = opt._name
+            else:
+                name = '.'.join(_currpath + [opt._name])
+            pathsvalues.append((name, value))
 
     def cfgimpl_get_path(self):
         descr = self.cfgimpl_get_description()
index ad99416..409d6eb 100644 (file)
@@ -662,7 +662,7 @@ class ChoiceOption(Option):
         return self._open_values
 
     def _validate(self, value):
-        if not self._open_values and not value in self._values:
+        if not self.impl_is_openvalues() and not value in self.impl_get_values():
             raise ValueError(_('value {0} is not permitted, '
                                'only {1} is allowed'
                                '').format(value, self._values))
@@ -782,9 +782,13 @@ class IPOption(Option):
     def _validate(self, value):
         # sometimes an ip term starts with a zero
         # but this does not fit in some case, for example bind does not like it
-        for val in value.split('.'):
-            if val.startswith("0") and len(val) > 1:
-                raise ValueError(_('invalid IP'))
+        try:
+            for val in value.split('.'):
+                if val.startswith("0") and len(val) > 1:
+                    raise ValueError(_('invalid IP'))
+        except AttributeError:
+            #if integer for example
+            raise ValueError(_('invalid IP'))
         # 'standard' validation
         try:
             IP('{0}/32'.format(value))
@@ -856,18 +860,22 @@ class PortOption(Option):
         if self._allow_range and ":" in str(value):
             value = str(value).split(':')
             if len(value) != 2:
-                raise ValueError('invalid part, range must have two values '
-                                 'only')
+                raise ValueError(_('invalid part, range must have two values '
+                                 'only'))
             if not value[0] < value[1]:
-                raise ValueError('invalid port, first port in range must be'
-                                 ' smaller than the second one')
+                raise ValueError(_('invalid port, first port in range must be'
+                                 ' smaller than the second one'))
         else:
             value = [value]
 
         for val in value:
-            if not self._min_value <= int(val) <= self._max_value:
-                raise ValueError('invalid port, must be an between {0} and {1}'
-                                 ''.format(self._min_value, self._max_value))
+            try:
+                if not self._min_value <= int(val) <= self._max_value:
+                    raise ValueError(_('invalid port, must be an between {0} '
+                                     'and {1}').format(self._min_value,
+                                                      self._max_value))
+            except ValueError:
+                raise ValueError(_('invalid port'))
 
 
 class NetworkOption(Option):
index 863f2a1..ed70f90 100644 (file)
@@ -66,6 +66,8 @@ class Values(object):
         meta = self._getcontext().cfgimpl_get_meta()
         if meta is not None:
             value = meta.cfgimpl_get_values()[opt]
+            if isinstance(value, Multi):
+                value = list(value)
         else:
             value = opt.impl_getdefault()
         if opt.impl_is_multi():