Browse Source

Some modifications + tests update for settings loader

Yann Weber 8 years ago
parent
commit
3ed55fdc29

+ 7
- 0
globconf.d/global.ini View File

@@ -1,3 +1,10 @@
1 1
 [lodel2]
2 2
 lib_path = /home/yannweb/dev/lodel2/lodel2-git
3 3
 plugins_path = /home/yannweb/dev/lodel2/lodel2-git/plugins
4
+
5
+[lodel2.editorialmodel]
6
+emfile = examples/em_test.pickle
7
+emtranslator = picklefile
8
+dyncode = lodel/leapi/dyncode.py
9
+editormode = True
10
+groups = 

+ 3
- 1
lodel/editorial_model/components.py View File

@@ -72,6 +72,7 @@ class EmClass(EmComponent):
72 72
         self.__fields = dict() 
73 73
     
74 74
     ##@brief Property that represent a dict of all fields (the EmField defined in this class and all its parents)
75
+    # @todo use Settings.editorialmodel.groups to determine wich fields should be returned
75 76
     @property
76 77
     def __all_fields(self):
77 78
         res = dict()
@@ -97,6 +98,7 @@ class EmClass(EmComponent):
97 98
     # @param uid None | str : If None returns an iterator on EmField instances else return an EmField instance
98 99
     # @param no_parents bool : If True returns only fields defined is this class and not the one defined in parents classes
99 100
     # @return A list on EmFields instances (if uid is None) else return an EmField instance
101
+    # @todo use Settings.editorialmodel.groups to determine wich fields should be returned
100 102
     def fields(self, uid = None, no_parents = False):
101 103
         fields = self.__fields if no_parents else self.__all_fields
102 104
         try:
@@ -253,7 +255,7 @@ class EmGroup(object):
253 255
                     res[new_app.uid] = new_app
254 256
         return res
255 257
     
256
-	##@brief Returns EmGroup components
258
+    ##@brief Returns EmGroup components
257 259
     # @returns a copy of the set of components
258 260
     def components(self):
259 261
         return (self.__components).copy()

+ 45
- 0
lodel/leapi/datahandlers/base_classes.py View File

@@ -256,3 +256,48 @@ class MultipleRef(Reference):
256 256
             if self.max_item < len(value):
257 257
                 return None, FieldValidationError("To many items")
258 258
 
259
+## @brief Class designed to handle datas access will fieldtypes are constructing datas
260
+#
261
+# This class is designed to allow automatic scheduling of construct_data calls. 
262
+#
263
+# In theory it's able to detect circular dependencies
264
+# @todo test circular deps detection
265
+# @todo test circulat deps false positiv
266
+class DatasConstructor(object):
267
+    
268
+    ## @brief Init a DatasConstructor
269
+    # @param lec LeCrud : @ref LeObject child class 
270
+    # @param datas dict : dict with field name as key and field values as value
271
+    # @param fields_handler dict : dict with field name as key and data handler instance as value
272
+    def __init__(self, leobject, datas, fields_handler):
273
+        ## Stores concerned class
274
+        self._leobject = leobject
275
+        ## Stores datas and constructed datas
276
+        self._datas = copy.copy(datas)
277
+        ## Stores fieldtypes
278
+        self._fields_handler = fields_handler
279
+        ## Stores list of fieldname for constructed datas
280
+        self._constructed = []
281
+        ## Stores construct calls list
282
+        self._construct_calls = []
283
+    
284
+    ## @brief Implements the dict.keys() method on instance
285
+    def keys(self):
286
+        return self._datas.keys()
287
+    
288
+    ## @brief Allows to access the instance like a dict
289
+    def __getitem__(self, fname):
290
+        if fname not in self._constructed:
291
+            if fname in self._construct_calls:
292
+                raise RuntimeError('Probably circular dependencies in fieldtypes')
293
+            cur_value = self._datas[fname] if fname in self._datas else None
294
+            self._datas[fname] = self._fields_handler[fname].construct_data(self._leobject, fname, self, cur_value)
295
+            self._constructed.append(fname)
296
+        return self._datas[fname]
297
+    
298
+    ## @brief Allows to set instance values like a dict
299
+    # @warning Should not append in theory
300
+    def __setitem__(self, fname, value):
301
+        self._datas[fname] = value
302
+        warnings.warn("Setting value of an DatasConstructor instance")
303
+ 

+ 2
- 0
lodel/settings/settings.py View File

@@ -59,6 +59,8 @@ PYTHON_SYS_LIB_PATH = '/usr/local/lib/python{major}.{minor}/'.format(
59 59
 #
60 60
 # @todo handles default sections for variable sections (sections ending with 
61 61
 # '.*')
62
+# @todo delete the first stage, the lib path HAVE TO BE HARDCODED. In fact
63
+#when we will run lodel in production the lodel2 lib will be in the python path
62 64
 class Settings(object):
63 65
     
64 66
     ##@brief global conf specsification (default_value + validator)

+ 14
- 0
lodel/settings/validator.py View File

@@ -210,6 +210,8 @@ LODEL2_CONF_SPECS = {
210 210
                     SettingValidator('bool')),
211 211
         'plugins': (    "",
212 212
                         SettingValidator('list')),
213
+        'sitename': (   'noname',
214
+                        SettingValidator('strip')),
213 215
     },
214 216
     'lodel2.logging.*' : {
215 217
         'level': (  'ERROR',
@@ -222,5 +224,17 @@ LODEL2_CONF_SPECS = {
222 224
                             SettingValidator('int', none_is_valid = True)),
223 225
         'maxbytes': (   None,
224 226
                         SettingValidator('int', none_is_valid = True)),
227
+    },
228
+    'lodel2.editorialmodel': {
229
+        'emfile': ( 'em.pickle',
230
+                    SettingValidator('strip')),
231
+        'emtranslator': (   'picklefile',
232
+                            SettingValidator('strip')),
233
+        'dyncode': (    'leapi_dyncode.py',
234
+                        SettingValidator('strip')),
235
+        'groups': ( '',
236
+                    SettingValidator('list')),
237
+        'editormode': ( False,
238
+                        SettingValidator('bool')),
225 239
     }
226 240
 }

+ 8
- 0
tests/settings/settings_examples/complex.conf.d/file1.ini View File

@@ -0,0 +1,8 @@
1
+[lodel2.editorialmodel]
2
+lib_path=/tmp
3
+foo_bar=42
4
+foo.bar=1337
5
+[lodel2.bar.foo]
6
+barfoo=42
7
+[lodel2.bar.bar]
8
+toto=tata

+ 9
- 0
tests/settings/settings_examples/complex.conf.d/file2.ini View File

@@ -0,0 +1,9 @@
1
+[lodel2.editorialmodel]
2
+example=foobar
3
+
4
+[lodel2.conf1]
5
+conf_key=woot
6
+conf_value=42
7
+
8
+[lodel2.conf2]
9
+conf_foo=bar

+ 6
- 0
tests/settings/settings_examples/complex.conf.d/file3.ini View File

@@ -0,0 +1,6 @@
1
+[lodel2.foo.bar]
2
+barfoo=42
3
+[lodel2.foo.foo]
4
+foobar=barfoo
5
+[lodel2.bar.foo]
6
+foobar=barfoo

+ 1
- 0
tests/settings/test_settings.py View File

@@ -8,6 +8,7 @@ from lodel.settings.settings import Settings
8 8
 
9 9
 class SettingsTestCase(unittest.TestCase):
10 10
     
11
+    @unittest.skip('todo : write it')
11 12
     def test_init(self):
12 13
         settings = Settings('tests/settings/settings_tests.ini', 'tests/settings/settings_tests_conf.d')
13 14
         pass

+ 39
- 0
tests/settings/test_settings_loader.py View File

@@ -59,6 +59,45 @@ class SettingsLoaderTestCase(unittest.TestCase):
59 59
         value = loader.getoption('lodel2.foo.bar', 'foobar', dummy_validator)
60 60
         self.assertEqual(value, "hello world")
61 61
 
62
+    def test_getoption_complex(self):
63
+        """ Testing behavior of getoption with less simple files & confs """
64
+
65
+        expected = {
66
+            'lodel2.editorialmodel': {
67
+                'lib_path': '/tmp',
68
+                'foo_bar': '42',
69
+                'foo.bar': '1337',
70
+                'example': 'foobar',
71
+            },
72
+            'lodel2.conf1': {
73
+                'conf_key': 'woot',
74
+                'conf_value': '42',
75
+            },
76
+            'lodel2.conf2': {
77
+                'conf_foo': 'bar',
78
+            },
79
+            'lodel2.foo.foo': {
80
+                'foobar': 'barfoo',
81
+            },
82
+            'lodel2.bar.foo': {
83
+                'foobar': 'barfoo',
84
+                'barfoo': '42',
85
+            },
86
+            'lodel2.bar.bar': {
87
+                'toto': 'tata',
88
+            }
89
+        }
90
+
91
+        loader = SettingsLoader('tests/settings/settings_examples/complex.conf.d')
92
+        for section in expected:
93
+            for key, expected_value in expected[section].items():
94
+                value = loader.getoption(   section,
95
+                                            key,
96
+                                            dummy_validator)
97
+                self.assertEqual(value, expected_value)
98
+
99
+                
100
+
62 101
     def test_variable_sections(self):
63 102
         """ Testing variable section recognition """
64 103
         loader = SettingsLoader('tests/settings/settings_examples/var_sections.conf.d')

Loading…
Cancel
Save