80b1b66a17f97f7e5cf6bdd70e7442a497df1bf3
[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
169
170 def test_config_impl_get_path_by_opt():
171     descr = make_description()
172     config = Config(descr)
173     dummy = config.unwrap_from_path('gc.dummy')
174     boo = config.unwrap_from_path('bool')
175     unknown = IntOption('test', '')
176     unknown
177     assert config.cfgimpl_get_description().impl_get_path_by_opt(boo) == 'bool'
178     assert config.cfgimpl_get_description().impl_get_path_by_opt(dummy) == 'gc.dummy'
179     raises(AttributeError, "config.cfgimpl_get_description().impl_get_path_by_opt(unknown)")
180
181
182 def test_config_impl_get_path_by_opt_od():
183     descr = make_description()
184     config = Config(descr)
185     dummy = config.unwrap_from_path('gc.dummy')
186     dummy
187     raises(ConfigError, "config.cfgimpl_get_description().gc.impl_get_path_by_opt(dummy)")
188
189
190 def test_config_impl_get_opt_by_path():
191     descr = make_description()
192     config = Config(descr)
193     dummy = config.unwrap_from_path('gc.dummy')
194     boo = config.unwrap_from_path('bool')
195     if 'id' in dir(boo):
196         assert config.cfgimpl_get_description().impl_get_opt_by_path('bool').id == boo.id
197         assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy').id == dummy.id
198     else:
199         assert config.cfgimpl_get_description().impl_get_opt_by_path('bool') == boo
200         assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy') == dummy
201     raises(AttributeError, "config.cfgimpl_get_description().impl_get_opt_by_path('gc.unknown')")
202
203
204 def test_information_display():
205     g1 = IntOption('g1', '', 1)
206     g2 = StrOption('g2', '', 'héhé')
207     g3 = UnicodeOption('g3', '', u'héhé')
208     g4 = BoolOption('g4', '', True)
209     g5 = StrOption('g5', '')
210     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
211     root = OptionDescription('root', '', [d1])
212     config = Config(root)
213     config.od == """g1 = 1
214 g2 = héhé
215 g3 = héhé
216 g4 = True
217 g5 = None"""
218     config == '[od]'
219
220
221 def test_get_modified_values():
222     g1 = IntOption('g1', '', 1)
223     g2 = StrOption('g2', '', 'héhé')
224     g3 = UnicodeOption('g3', '', u'héhé')
225     g4 = BoolOption('g4', '', True)
226     g5 = StrOption('g5', '')
227     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
228     root = OptionDescription('root', '', [d1])
229     config = Config(root)
230     assert config.cfgimpl_get_values().get_modified_values() == {}
231     config.od.g5 = 'yes'
232     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes')}
233     config.od.g4 = True
234     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g4': ('user', True)}
235
236
237 def test_has_value():
238     g1 = IntOption('g1', '', 1)
239     g2 = StrOption('g2', '', 'héhé')
240     g3 = UnicodeOption('g3', '', u'héhé')
241     g4 = BoolOption('g4', '', True)
242     g5 = StrOption('g5', '')
243     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
244     root = OptionDescription('root', '', [d1])
245     config = Config(root)
246     assert not g5 in config.cfgimpl_get_values()
247     config.od.g5 = 'yes'
248     assert g5 in config.cfgimpl_get_values()
249
250
251 def test_values_not_setitem():
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     config
261     raises(ConfigError, "config.cfgimpl_get_values()[g1] = 2")
262
263
264 def test_duplicated_option():
265     g1 = IntOption('g1', '', 1)
266     g1
267     #in same OptionDescription
268     raises(ConflictError, "d1 = OptionDescription('od', '', [g1, g1])")
269
270
271 def test_duplicated_option_diff_od():
272     g1 = IntOption('g1', '', 1)
273     d1 = OptionDescription('od1', '', [g1])
274     #in different OptionDescription
275     d2 = OptionDescription('od2', '', [g1, d1])
276     d2
277     raises(ConflictError, 'Config(d2)')
278
279
280 def test_cannot_assign_value_to_option_description():
281     descr = make_description()
282     cfg = Config(descr)
283     cfg
284     raises(TypeError, "cfg.gc = 3")
285
286
287 def test_config_multi():
288     i1 = IntOption('test1', '', multi=True)
289     i2 = IntOption('test2', '', multi=True, default_multi=1)
290     i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1)
291     od = OptionDescription('test', '', [i1, i2, i3])
292     config = Config(od)
293     assert config.test1 == []
294     assert config.test2 == []
295     config.test2.append()
296     assert config.test2 == [1]
297     assert config.test3 == [2]
298     config.test3.append()
299     assert config.test3 == [2, 1]
300
301
302 def test_no_validation():
303     i1 = IntOption('test1', '')
304     od = OptionDescription('test', '', [i1])
305     c = Config(od)
306     setting = c.cfgimpl_get_settings()
307     c.test1 = 1
308     raises(ValueError, 'c.test1 = "yes"')
309     assert c.test1 == 1
310     setting.remove('validator')
311     c.test1 = "yes"
312     assert c.test1 == "yes"
313     setting.append('validator')
314     raises(ValueError, 'c.test1')
315     del(c.test1)
316     assert c.test1 is None
317
318
319 def test_delete_config_with_subconfig():
320     test = IntOption('test', '')
321     multi = IntOption('multi', '', multi=True)
322     od = OptionDescription('od', '', [test, multi])
323     odroot = OptionDescription('odroot', '', [od])
324     c = Config(odroot)
325     sub = c.od
326     val = c.cfgimpl_get_values()
327     setting = c.cfgimpl_get_settings()
328     val[test]
329     val[multi]
330     setting[test]
331     sub.make_dict()
332     del(c)
333     raises(ConfigError, 'val[test]')
334     raises(ConfigError, 'val[multi]')
335     raises(ConfigError, 'setting[test]')
336     raises(ConfigError, 'sub.make_dict()')
337
338
339 def test_subconfig():
340     i = IntOption('i', '')
341     o = OptionDescription('val', '', [i])
342     o2 = OptionDescription('val', '', [o])
343     c = Config(o2)
344     c
345     raises(TypeError, "SubConfig(i, weakref.ref(c))")
346     pass
347
348
349 def test_config_weakref():
350     o = OptionDescription('val', '', [])
351     o2 = OptionDescription('val', '', [o])
352     c = Config(o2)
353     SubConfig(o, weakref.ref(c))
354     raises(ValueError, "SubConfig(o, c)")
355     s = SubConfig(o, weakref.ref(c))
356     assert s._cfgimpl_get_context() == c
357     del(c)
358     raises(ConfigError, "s._cfgimpl_get_context()")
359
360
361 def test_config_str():
362     gcdummy = BoolOption('dummy', 'dummy', default=False)
363     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
364     o = OptionDescription('o', '', [gcdummy, gcdummy1])
365     descr = OptionDescription('tiramisu', '', [o])
366     cfg = Config(descr)
367     cfg.read_only()
368     str(cfg)
369     str(cfg.o)
370
371
372 def test_config_od_function():
373     gcdummy = BoolOption('dummy', 'dummy', default=False)
374     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
375     o = OptionDescription('o', '', [gcdummy, gcdummy1])
376     descr = OptionDescription('tiramisu', '', [o])
377     cfg = Config(descr)
378     try:
379         print(cfg.impl_get_opt_by_path())
380     except AttributeError as err:
381         assert str(err) == _('unknown Option {0} in OptionDescription {1}'
382                              '').format('impl_get_opt_by_path', descr.impl_getname())
383
384
385 def test_config_subconfig():
386     i1 = IntOption('i1', '')
387     i2 = IntOption('i2', '', default=1)
388     i3 = IntOption('i3', '')
389     i4 = IntOption('i4', '', default=2)
390     od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
391     od2 = OptionDescription('od2', '', [od1])
392     conf1 = Config(od2, name='conf1')
393     conf1
394     raises(ConfigError, "conf2 = Config(od1, name='conf2')")