python 3.5 support
[tiramisu.git] / test / test_config.py
1 # -*- coding: utf-8 -*-
2
3 """theses tests are much more to test that config, option description, vs...
4 **it's there** and answers via attribute access"""
5 from .autopath import do_autopath
6 do_autopath()
7
8 from py.test import raises
9
10 from tiramisu.config import Config, SubConfig
11 from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
12     BoolOption, UnicodeOption, OptionDescription
13 from tiramisu.i18n import _
14 from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError
15 import weakref
16
17
18 def make_description():
19     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
20     gcdummy = BoolOption('dummy', 'dummy', default=False)
21     objspaceoption = ChoiceOption('objspace', 'Object space',
22                                   ('std', 'thunk'), 'std')
23     booloption = BoolOption('bool', 'Test boolean option', default=True)
24     intoption = IntOption('int', 'Test int option', default=0)
25     floatoption = FloatOption('float', 'Test float option', default=2.3)
26     stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', ))
27     boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',))
28     wantref_option = BoolOption('wantref', 'Test requires', default=False)
29     wantframework_option = BoolOption('wantframework', 'Test requires',
30                                       default=False)
31
32     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
33     descr = OptionDescription('tiram', '', [gcgroup, booloption, objspaceoption,
34                                             wantref_option, stroption,
35                                             wantframework_option,
36                                             intoption, boolop])
37     return descr
38
39
40 #def test_base_config():
41 #    """making a :class:`tiramisu.config.Config()` object
42 #    and a :class:`tiramisu.option.OptionDescription()` object
43 #    """
44 #    gcdummy = BoolOption('dummy', 'dummy', default=False)
45 #    descr = OptionDescription('tiramisu', '', [gcdummy])
46 #    cfg = Config(descr)
47 #    assert cfg.dummy is False
48 #    dm = cfg.unwrap_from_path('dummy')
49 #    assert dm.impl_getname() == 'dummy'
50
51
52 def test_base_config_name():
53     gcdummy = BoolOption('dummy', 'dummy', default=False)
54     descr = OptionDescription('tiramisu', '', [gcdummy])
55     cfg = Config(descr, name='cfg')
56     cfg.impl_getname() == 'cfg'
57     raises(ValueError, "Config(descr, name='unvalid name')")
58
59
60 def test_not_config():
61     assert raises(TypeError, "Config('str')")
62
63
64 def test_base_path():
65     gcdummy = BoolOption('dummy', 'dummy', default=False)
66     descr = OptionDescription('tiramisu', '', [gcdummy])
67     cfg = Config(descr)
68     assert cfg._impl_path is None
69     base = OptionDescription('config', '', [descr])
70     cfg = Config(base)
71     assert cfg._impl_path is None
72     assert cfg.tiramisu._impl_path == 'tiramisu'
73     nbase = OptionDescription('baseconfig', '', [base])
74     cfg = Config(nbase)
75     assert cfg._impl_path is None
76     assert cfg.config._impl_path == 'config'
77     assert cfg.config.tiramisu._impl_path == 'config.tiramisu'
78 #
79 #
80 #def test_reset_value():
81 #    descr = make_description()
82 #    cfg = Config(descr)
83 #    assert cfg.gc.dummy is False
84 #    cfg.gc.dummy = True
85 #    assert cfg.gc.dummy is True
86 #
87 #
88 #def test_base_config_and_groups():
89 #    descr = make_description()
90 #    # overrides the booloption default value
91 #    config = Config(descr)
92 #    config.bool = False
93 #    assert config.gc.name == 'ref'
94 #    assert config.bool is False
95 #    nm = config.unwrap_from_path('gc.name')
96 #    assert nm.impl_getname() == 'name'
97 #    gc = config.unwrap_from_path('gc')
98 #    assert gc.impl_getname() == 'gc'
99 #    #nm = config.unwrap_from_name('name')
100 #    #assert nm.impl_getname() == 'name'
101
102
103 def test_base_config_force_permissive():
104     descr = make_description()
105     config = Config(descr)
106     config.read_write()
107     config.cfgimpl_get_settings().setpermissive(('hidden',))
108     raises(PropertiesOptionError, "config.getattr('boolop')")
109     assert config.getattr('boolop', force_permissive=True) is True
110
111
112 def test_base_config_in_a_tree():
113     "how options are organized into a tree, see :ref:`tree`"
114     descr = make_description()
115     config = Config(descr)
116     config.bool = False
117     assert config.gc.name == 'ref'
118     config.gc.name = 'framework'
119     assert config.gc.name == 'framework'
120     assert getattr(config, "gc.name") == 'framework'
121
122     assert config.objspace == 'std'
123     config.objspace = 'thunk'
124     assert config.objspace == 'thunk'
125
126     assert config.gc.float == 2.3
127     assert config.int == 0
128     config.gc.float = 3.4
129     config.int = 123
130     assert config.gc.float == 3.4
131     assert config.int == 123
132
133     assert not config.wantref
134
135     assert config.str == "abc"
136     config.str = "def"
137     assert config.str == "def"
138
139     raises(AttributeError, 'config.gc.foo = "bar"')
140
141     config = Config(descr)
142     config.bool = False
143     assert config.gc.name == 'ref'
144     config.wantframework = True
145
146
147 def test_cfgimpl_get_home_by_path():
148     " :meth:`tiramisu.config.SubConfig.cfgimpl_get_home_by_path()` to retrieve a path"
149     descr = make_description()
150     config = Config(descr)
151     config.bool = False
152     assert config.cfgimpl_get_home_by_path('gc.dummy')[1] == 'dummy'
153     assert config.cfgimpl_get_home_by_path('dummy')[1] == 'dummy'
154
155
156 def test_not_valid_properties():
157     raises(TypeError, "stroption = StrOption('str', 'Test string option', default='abc', properties=['mandatory',])")
158
159
160 def test_information_config():
161     descr = make_description()
162     config = Config(descr)
163     string = 'some informations'
164     config.impl_set_information('info', string)
165     assert config.impl_get_information('info') == string
166     raises(ValueError, "config.impl_get_information('noinfo')")
167     assert config.impl_get_information('noinfo', 'default') == 'default'
168     config.impl_del_information('info')
169     raises(ValueError, "config.impl_get_information('info')")
170     raises(ValueError, "config.impl_del_information('noinfo')")
171
172
173 def test_config_impl_get_path_by_opt():
174     descr = make_description()
175     config = Config(descr)
176     dummy = config.unwrap_from_path('gc.dummy')
177     boo = config.unwrap_from_path('bool')
178     unknown = IntOption('test', '')
179     unknown
180     assert config.cfgimpl_get_description().impl_get_path_by_opt(boo) == 'bool'
181     assert config.cfgimpl_get_description().impl_get_path_by_opt(dummy) == 'gc.dummy'
182     raises(AttributeError, "config.cfgimpl_get_description().impl_get_path_by_opt(unknown)")
183
184
185 def test_config_impl_get_path_by_opt_od():
186     descr = make_description()
187     config = Config(descr)
188     dummy = config.unwrap_from_path('gc.dummy')
189     dummy
190     raises(ConfigError, "config.cfgimpl_get_description().gc.impl_get_path_by_opt(dummy)")
191
192
193 def test_config_impl_get_opt_by_path():
194     descr = make_description()
195     config = Config(descr)
196     dummy = config.unwrap_from_path('gc.dummy')
197     boo = config.unwrap_from_path('bool')
198     if 'id' in dir(boo):
199         assert config.cfgimpl_get_description().impl_get_opt_by_path('bool').id == boo.id
200         assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy').id == dummy.id
201     else:
202         assert config.cfgimpl_get_description().impl_get_opt_by_path('bool') == boo
203         assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy') == dummy
204     raises(AttributeError, "config.cfgimpl_get_description().impl_get_opt_by_path('gc.unknown')")
205
206
207 def test_information_display():
208     g1 = IntOption('g1', '', 1)
209     g2 = StrOption('g2', '', 'héhé')
210     g3 = UnicodeOption('g3', '', u'héhé')
211     g4 = BoolOption('g4', '', True)
212     g5 = StrOption('g5', '')
213     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
214     root = OptionDescription('root', '', [d1])
215     config = Config(root)
216     config.od == """g1 = 1
217 g2 = héhé
218 g3 = héhé
219 g4 = True
220 g5 = None"""
221     config == '[od]'
222
223
224 def test_get_modified_values():
225     g1 = IntOption('g1', '', 1)
226     g2 = StrOption('g2', '', 'héhé')
227     g3 = UnicodeOption('g3', '', u'héhé')
228     g4 = BoolOption('g4', '', True)
229     g5 = StrOption('g5', '')
230     g6 = StrOption('g6', '', multi=True)
231     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5, g6])
232     root = OptionDescription('root', '', [d1])
233     config = Config(root)
234     assert config.cfgimpl_get_values().get_modified_values() == {}
235     config.od.g5 = 'yes'
236     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes')}
237     config.od.g4 = True
238     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g4': ('user', True)}
239     del config.od.g4
240     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes')}
241     config.od.g6.append()
242     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g6': ('user', (None,))}
243     config.od.g6.pop(0)
244     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g6': ('user', tuple())}
245     config.od.g6.append('3')
246     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g6': ('user', ('3',))}
247     del config.od.g6[0]
248     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g6': ('user', tuple())}
249
250
251 def test_has_value():
252     g1 = IntOption('g1', '', 1)
253     g2 = StrOption('g2', '', 'héhé')
254     g3 = UnicodeOption('g3', '', u'héhé')
255     g4 = BoolOption('g4', '', True)
256     g5 = StrOption('g5', '')
257     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
258     root = OptionDescription('root', '', [d1])
259     config = Config(root)
260     assert not g5 in config.cfgimpl_get_values()
261     config.od.g5 = 'yes'
262     assert g5 in config.cfgimpl_get_values()
263
264
265 def test_values_not_setitem():
266     g1 = IntOption('g1', '', 1)
267     g2 = StrOption('g2', '', 'héhé')
268     g3 = UnicodeOption('g3', '', u'héhé')
269     g4 = BoolOption('g4', '', True)
270     g5 = StrOption('g5', '')
271     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
272     root = OptionDescription('root', '', [d1])
273     config = Config(root)
274     config
275     raises(ConfigError, "config.cfgimpl_get_values()[g1] = 2")
276
277
278 def test_duplicated_option():
279     g1 = IntOption('g1', '', 1)
280     g1
281     #in same OptionDescription
282     raises(ConflictError, "d1 = OptionDescription('od', '', [g1, g1])")
283
284
285 def test_duplicated_option_diff_od():
286     g1 = IntOption('g1', '', 1)
287     d1 = OptionDescription('od1', '', [g1])
288     #in different OptionDescription
289     d2 = OptionDescription('od2', '', [g1, d1])
290     d2
291     raises(ConflictError, 'Config(d2)')
292
293
294 def test_cannot_assign_value_to_option_description():
295     descr = make_description()
296     cfg = Config(descr)
297     cfg
298     raises(TypeError, "cfg.gc = 3")
299
300
301 def test_config_multi():
302     i1 = IntOption('test1', '', multi=True)
303     i2 = IntOption('test2', '', multi=True, default_multi=1)
304     i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1)
305     od = OptionDescription('test', '', [i1, i2, i3])
306     config = Config(od)
307     assert config.test1 == []
308     assert config.test2 == []
309     config.test2.append()
310     assert config.test2 == [1]
311     assert config.test3 == [2]
312     config.test3.append()
313     assert config.test3 == [2, 1]
314
315
316 def test_no_validation():
317     i1 = IntOption('test1', '')
318     od = OptionDescription('test', '', [i1])
319     c = Config(od)
320     setting = c.cfgimpl_get_settings()
321     c.test1 = 1
322     raises(ValueError, 'c.test1 = "yes"')
323     assert c.test1 == 1
324     setting.remove('validator')
325     c.test1 = "yes"
326     assert c.test1 == "yes"
327     setting.append('validator')
328     raises(ValueError, 'c.test1')
329     del(c.test1)
330     assert c.test1 is None
331
332
333 def test_delete_config_with_subconfig():
334     test = IntOption('test', '')
335     multi = IntOption('multi', '', multi=True)
336     od = OptionDescription('od', '', [test, multi])
337     odroot = OptionDescription('odroot', '', [od])
338     c = Config(odroot)
339     sub = c.od
340     val = c.cfgimpl_get_values()
341     setting = c.cfgimpl_get_settings()
342     val[test]
343     val[multi]
344     setting[test]
345     sub.make_dict()
346     del(c)
347     raises(ConfigError, 'val[test]')
348     raises(ConfigError, 'val[multi]')
349     raises(ConfigError, 'setting[test]')
350     raises(ConfigError, 'sub.make_dict()')
351
352
353 def test_subconfig():
354     i = IntOption('i', '')
355     o = OptionDescription('val', '', [i])
356     o2 = OptionDescription('val', '', [o])
357     c = Config(o2)
358     c
359     raises(TypeError, "SubConfig(i, weakref.ref(c))")
360     pass
361
362
363 def test_config_weakref():
364     o = OptionDescription('val', '', [])
365     o2 = OptionDescription('val', '', [o])
366     c = Config(o2)
367     SubConfig(o, weakref.ref(c))
368     raises(ValueError, "SubConfig(o, c)")
369     s = SubConfig(o, weakref.ref(c))
370     assert s._cfgimpl_get_context() == c
371     del(c)
372     raises(ConfigError, "s._cfgimpl_get_context()")
373
374
375 def test_config_str():
376     gcdummy = BoolOption('dummy', 'dummy', default=False)
377     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
378     o = OptionDescription('o', '', [gcdummy, gcdummy1])
379     descr = OptionDescription('tiramisu', '', [o])
380     cfg = Config(descr)
381     cfg.read_only()
382     str(cfg)
383     str(cfg.o)
384
385
386 def test_config_od_function():
387     gcdummy = BoolOption('dummy', 'dummy', default=False)
388     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
389     o = OptionDescription('o', '', [gcdummy, gcdummy1])
390     descr = OptionDescription('tiramisu', '', [o])
391     cfg = Config(descr)
392     try:
393         print(cfg.impl_get_opt_by_path())
394     except AttributeError as err:
395         assert str(err) == _('unknown Option {0} in OptionDescription {1}'
396                              '').format('impl_get_opt_by_path', descr.impl_getname())
397
398
399 def test_config_subconfig():
400     i1 = IntOption('i1', '')
401     i2 = IntOption('i2', '', default=1)
402     i3 = IntOption('i3', '')
403     i4 = IntOption('i4', '', default=2)
404     od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
405     od2 = OptionDescription('od2', '', [od1])
406     conf1 = Config(od2, name='conf1')
407     conf1
408     raises(ConfigError, "conf2 = Config(od1, name='conf2')")