* to "reset" a value, now you just have to delete it
[tiramisu.git] / test / test_option_setting.py
1 "config.set() or config.setoption() or option.setoption()"
2 import autopath
3 from py.test import raises
4
5 from tiramisu.setting import owners
6 from tiramisu.config import Config
7 from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
8     StrOption, OptionDescription, SymLinkOption
9 from tiramisu.error import ConflictOptionError, PropertiesOptionError
10
11
12 def make_description():
13     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
14     gcdummy = BoolOption('dummy', 'dummy', default=False)
15     objspaceoption = ChoiceOption('objspace', 'Object space',
16                                   ('std', 'thunk'), 'std')
17     booloption = BoolOption('bool', 'Test boolean option', default=True)
18     intoption = IntOption('int', 'Test int option', default=0)
19     floatoption = FloatOption('float', 'Test float option', default=2.3)
20     stroption = StrOption('str', 'Test string option', default="abc")
21     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
22     wantref_option = BoolOption('wantref', 'Test requires', default=False)
23     wantframework_option = BoolOption('wantframework', 'Test requires',
24                                       default=False)
25     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
26     descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
27                                                wantref_option, stroption,
28                                                wantframework_option,
29                                                intoption, boolop])
30     return descr
31
32
33 #____________________________________________________________
34 # change with __setattr__
35 def test_attribute_access():
36     "Once set, option values can't be changed again by attribute access"
37     s = StrOption("string", "", default="string")
38     descr = OptionDescription("options", "", [s])
39     config = Config(descr)
40     # let's try to change it again
41     config.string = "foo"
42     assert config.string == "foo"
43
44
45 def test_setitem():
46     s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
47     descr = OptionDescription("options", "", [s])
48     config = Config(descr)
49     config.string[1] = "titi"
50
51
52 def test_reset():
53     "if value is None, resets to default owner"
54     s = StrOption("string", "", default="string")
55     descr = OptionDescription("options", "", [s])
56     config = Config(descr)
57     config.string = "foo"
58     assert config.string == "foo"
59     assert config.cfgimpl_get_values().getowner(s) == owners.user
60     del(config.string)
61     assert config.string == 'string'
62     assert config.cfgimpl_get_values().getowner(s) == owners.default
63
64
65 def test_reset_with_multi():
66     s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
67     descr = OptionDescription("options", "", [s])
68     config = Config(descr)
69 #    config.string = []
70     del(config.string)
71     assert config.string == ["string"]
72     assert config.cfgimpl_get_values().getowner(s) == 'default'
73     config.string = ["eggs", "spam", "foo"]
74     assert config.cfgimpl_get_values().getowner(s) == 'user'
75     config.string = []
76     del(config.string)
77 #    assert config.string == ["string"]
78     assert config.cfgimpl_get_values().getowner(s) == 'default'
79     raises(ValueError, "config.string = None")
80
81
82 def test_default_with_multi():
83     "default with multi is a list"
84     s = StrOption("string", "", default=[], default_multi="string", multi=True)
85     descr = OptionDescription("options", "", [s])
86     config = Config(descr)
87     assert config.string == []
88     s = StrOption("string", "", default=None, default_multi="string", multi=True)
89     descr = OptionDescription("options", "", [s])
90     config = Config(descr)
91     assert config.string == []
92
93
94 def test_idontexist():
95     descr = make_description()
96     cfg = Config(descr)
97     raises(AttributeError, "cfg.idontexist")
98
99
100 # ____________________________________________________________
101 def test_attribute_access_with_multi():
102     s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
103     descr = OptionDescription("options", "", [s])
104     config = Config(descr)
105     config.string = ["foo", "bar"]
106     assert config.string == ["foo", "bar"]
107
108
109 def test_item_access_with_multi():
110     s = StrOption("string", "", default=["string"], multi=True)
111     descr = OptionDescription("options", "", [s])
112     config = Config(descr)
113     config.string = ["foo", "bar"]
114     assert config.string == ["foo", "bar"]
115     assert config.string[0] == "foo"
116     # FIXME
117     config.string[0] = 'changetest'
118 #    assert config.string[0] == 'changetest'
119 #    assert config.string[
120
121
122 def test_access_with_multi_default():
123     s = StrOption("string", "", default=["string"], multi=True)
124     descr = OptionDescription("options", "", [s])
125     config = Config(descr)
126     assert config._cfgimpl_values.getowner(s) == 'default'
127     config.string = ["foo", "bar"]
128     assert config.string == ["foo", "bar"]
129     assert config._cfgimpl_values.getowner(s) == 'user'
130
131 #def test_attribute_access_with_multi2():
132 #    s = StrOption("string", "", default="string", multi=True)
133 #    descr = OptionDescription("options", "", [s])
134 #    config = Config(descr)
135 #    config.string = ["foo", "bar"]
136 #    assert config.string == ["foo", "bar"]
137
138
139 def test_multi_with_requires():
140     s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
141     intoption = IntOption('int', 'Test int option', default=0)
142     stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
143                           requires=[('int', 1, 'hidden')], multi=True)
144     descr = OptionDescription("options", "", [s, intoption, stroption])
145     config = Config(descr)
146     setting = config.cfgimpl_get_settings()
147     setting.read_write()
148     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
149     config.int = 1
150     raises(PropertiesOptionError, "config.str = ['a', 'b']")
151     assert config.cfgimpl_get_settings().has_property('hidden', stroption)
152
153
154 def test__requires_with_inverted():
155     s = StrOption("string", "", default=["string"], multi=True)
156     intoption = IntOption('int', 'Test int option', default=0)
157     stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
158                           requires=[('int', 1, 'hide', 'inverted')], multi=True)
159     descr = OptionDescription("options", "", [s, intoption, stroption])
160     config = Config(descr)
161     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
162     config.int = 1
163     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
164
165
166 def test_multi_with_requires_in_another_group():
167     s = StrOption("string", "", default=["string"], multi=True)
168     intoption = IntOption('int', 'Test int option', default=0)
169     descr = OptionDescription("options", "", [intoption])
170     stroption = StrOption('str', 'Test string option', default=["abc"],
171                           requires=[('int', 1, 'hidden')], multi=True)
172     descr = OptionDescription("opt", "", [stroption])
173     descr2 = OptionDescription("opt2", "", [intoption, s, descr])
174     config = Config(descr2)
175     setting = config.cfgimpl_get_settings()
176     setting.read_write()
177     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
178     config.int = 1
179     raises(PropertiesOptionError,  "config.opt.str = ['a', 'b']")
180     assert config.cfgimpl_get_settings().has_property('hidden', stroption)
181
182
183 def test_apply_requires_from_config():
184     s = StrOption("string", "", default=["string"], multi=True)
185     intoption = IntOption('int', 'Test int option', default=0)
186     descr = OptionDescription("options", "", [intoption])
187     stroption = StrOption('str', 'Test string option', default=["abc"],
188                           requires=[('int', 1, 'hidden')], multi=True)
189     descr = OptionDescription("opt", "", [stroption])
190     descr2 = OptionDescription("opt2", "", [intoption, s, descr])
191     config = Config(descr2)
192     setting = config.cfgimpl_get_settings()
193     setting.read_write()
194     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
195     config.int = 1
196     raises(PropertiesOptionError, 'config.opt.str')
197     assert config.cfgimpl_get_settings().has_property('hidden', stroption)
198
199
200 def test_apply_requires_with_disabled():
201     s = StrOption("string", "", default=["string"], multi=True)
202     intoption = IntOption('int', 'Test int option', default=0)
203     descr = OptionDescription("options", "", [intoption])
204     stroption = StrOption('str', 'Test string option', default=["abc"],
205                           requires=[('int', 1, 'disabled')], multi=True)
206     descr = OptionDescription("opt", "", [stroption])
207     descr2 = OptionDescription("opt2", "", [intoption, s, descr])
208     config = Config(descr2)
209     setting = config.cfgimpl_get_settings()
210     setting.read_write()
211     assert not config.cfgimpl_get_settings().has_property('disabled', stroption)
212     config.int = 1
213     raises(PropertiesOptionError, 'config.opt.str')
214     assert config.cfgimpl_get_settings().has_property('disabled', stroption)
215
216
217 def test_multi_with_requires_with_disabled_in_another_group():
218     s = StrOption("string", "", default=["string"], multi=True)
219     intoption = IntOption('int', 'Test int option', default=0)
220     descr = OptionDescription("options", "", [intoption])
221     stroption = StrOption('str', 'Test string option', default=["abc"],
222                           requires=[('int', 1, 'disabled')], multi=True)
223     descr = OptionDescription("opt", "", [stroption])
224     descr2 = OptionDescription("opt2", "", [intoption, s, descr])
225     config = Config(descr2)
226     setting = config.cfgimpl_get_settings()
227     setting.read_write()
228     assert not config.cfgimpl_get_settings().has_property('disabled', stroption)
229     config.int = 1
230     raises(PropertiesOptionError,  "config.opt.str = ['a', 'b']")
231     assert config.cfgimpl_get_settings().has_property('disabled', stroption)
232
233
234 def test_multi_with_requires_that_is_multi():
235     s = StrOption("string", "", default=["string"], multi=True)
236     intoption = IntOption('int', 'Test int option', default=[0], multi=True)
237     stroption = StrOption('str', 'Test string option', default=["abc"],
238                           requires=[('int', [1, 1], 'hidden')], multi=True)
239     descr = OptionDescription("options", "", [s, intoption, stroption])
240     config = Config(descr)
241     setting = config.cfgimpl_get_settings()
242     setting.read_write()
243     assert not config.cfgimpl_get_settings().has_property('hidden', stroption)
244     config.int = [1, 1]
245     raises(PropertiesOptionError, "config.str = ['a', 'b']")
246     assert config.cfgimpl_get_settings().has_property('hidden', stroption)
247
248
249 def test_multi_with_bool():
250     s = BoolOption("bool", "", default=[False], multi=True)
251     descr = OptionDescription("options", "", [s])
252     config = Config(descr)
253     assert descr.bool.is_multi() is True
254     config.bool = [True, False]
255     assert config.cfgimpl_get_values()[s] == [True, False]
256     assert config.bool == [True, False]
257
258
259 def test_multi_with_bool_two():
260     s = BoolOption("bool", "", default=[False], multi=True)
261     descr = OptionDescription("options", "", [s])
262     config = Config(descr)
263     assert descr.bool.is_multi() is True
264     raises(ValueError, "config.bool = True")
265
266
267 def test_choice_access_with_multi():
268     ch = ChoiceOption("t1", "", ("a", "b"), default=["a"], multi=True)
269     descr = OptionDescription("options", "", [ch])
270     config = Config(descr)
271     config.t1 = ["a", "b", "a", "b"]
272     assert config.t1 == ["a", "b", "a", "b"]
273 # ____________________________________________________________
274
275 #def test_setoption_from_option():
276 #    "a setoption directly from the option is **not** a good practice"
277 #    booloption = BoolOption('bool', 'Test boolean option', default=True)
278 #    descr = OptionDescription('descr', '', [booloption])
279 #    cfg = Config(descr)
280 #    booloption.setoption(cfg, False)
281 #    assert cfg.bool == False
282
283
284 #____________________________________________________________
285 def test_dwim_set():
286     descr = OptionDescription("opt", "", [
287         OptionDescription("sub", "", [
288             BoolOption("b1", ""),
289             ChoiceOption("c1", "", ('a', 'b', 'c'), 'a'),
290             BoolOption("d1", ""),
291         ]),
292         BoolOption("b2", ""),
293         BoolOption("d1", ""),
294     ])
295     c = Config(descr)
296     c.set(b1=False, c1='b')
297     assert not c.sub.b1
298     assert c.sub.c1 == 'b'
299     # new config, because you cannot change values once they are set
300     c = Config(descr)
301     c.set(b2=False, **{'sub.c1': 'c'})
302     assert not c.b2
303     assert c.sub.c1 == 'c'
304     raises(ConflictOptionError, "c.set(d1=True)")
305     raises(AttributeError, "c.set(unknown='foo')")
306
307
308 def test_more_set():
309     descr = OptionDescription("opt", "", [
310         OptionDescription("s1", "", [
311             BoolOption("a", "", default=False)]),
312         IntOption("int", "", default=42)])
313     d = {'s1.a': True, 'int': 23}
314     config = Config(descr)
315     config.set(**d)
316     assert config.s1.a
317     assert config.int == 23
318
319
320 def test_set_with_hidden_option():
321     boolopt = BoolOption("a", "", default=False, properties=(('hidden'),))
322     descr = OptionDescription("opt", "", [
323         OptionDescription("s1", "", [boolopt]),
324         IntOption("int", "", default=42)])
325     d = {'s1.a': True, 'int': 23}
326     config = Config(descr)
327     setting = config.cfgimpl_get_settings()
328     setting.read_write()
329     raises(PropertiesOptionError, "config.set(**d)")
330
331
332 def test_set_with_unknown_option():
333     boolopt = BoolOption("b", "", default=False)
334     descr = OptionDescription("opt", "", [
335         OptionDescription("s1", "", [boolopt]),
336         IntOption("int", "", default=42)])
337     d = {'s1.a': True, 'int': 23}
338     config = Config(descr)
339     raises(AttributeError, "config.set(**d)")
340
341
342 def test_set_symlink_option():
343     boolopt = BoolOption("b", "", default=False)
344     linkopt = SymLinkOption("c", "s1.b", opt=boolopt)
345     descr = OptionDescription("opt", "",
346                               [linkopt, OptionDescription("s1", "", [boolopt])])
347     config = Config(descr)
348     setattr(config, "s1.b", True)
349     setattr(config, "s1.b", False)
350     assert config.s1.b is False
351     assert config.c is False
352     config.c = True
353     assert config.s1.b is True
354     assert config.c is True
355     config.c = False
356     assert config.s1.b is False
357     assert config.c is False
358
359 ##____________________________________________________________
360 #def test_config_impl_values():
361 #    descr = make_description()
362 #    config = Config(descr)
363 #    config.bool = False
364 ##    gcdummy.setoption(config, True, "user")
365 ##    config.setoption("gc.dummy", True, "user")
366 #    #config.gc.dummy = True
367 ##    config.setoption("bool", False, "user")
368 #    config.set(dummy=False)
369 #    assert config.gc._cfgimpl_context._cfgimpl_values.values == {'dummy': False, 'float': 2.3, 'name': 'ref'}
370 #    ## acces to the option object
371 ##    config.gc._cfgimpl_descr.dummy.setoption(config, True, "user")
372 #    assert config.gc.dummy == False
373 ##    config.set(dummy=True)
374 ##    assert config.gc.dummy == True
375
376 #____________________________________________________________
377 #def test_accepts_multiple_changes_from_option():
378 #    s = StrOption("string", "", default="string")
379 #    descr = OptionDescription("options", "", [s])
380 #    config = Config(descr)
381 #    config.string = "egg"
382 #    assert s.getdefault() == "string"
383 #    assert config.string == "egg"
384 #    s.setoption(config, 'blah')
385 #    assert s.getdefault() == "string"
386 #    assert config.string == "blah"
387 #    s.setoption(config, 'bol')
388 #    assert config.string == 'bol'
389
390
391 def test_allow_multiple_changes_from_config():
392     """
393     a `setoption` from the config object is much like the attribute access,
394     except the fact that value owner can bet set
395     """
396     s = StrOption("string", "", default="string")
397     s2 = StrOption("string2", "", default="string")
398     suboption = OptionDescription("bip", "", [s2])
399     descr = OptionDescription("options", "", [s, suboption])
400     config = Config(descr)
401     config.string = "oh"
402     assert config.string == "oh"
403     config.set(string2='blah')
404     assert config.bip.string2 == 'blah'
405
406
407 # ____________________________________________________________
408 # accessing a value by the get method
409 def test_access_by_get():
410     descr = make_description()
411     cfg = Config(descr)
412     raises(AttributeError, "cfg.find(byname='idontexist')")
413     assert cfg.find_first(byname='wantref', type_='value') is False
414     assert cfg.gc.dummy is False
415     assert cfg.find_first(byname='dummy', type_='value') is False
416
417
418 def test_access_by_get_whith_hide():
419     b1 = BoolOption("b1", "", properties=(('hidden'),))
420     descr = OptionDescription("opt", "",
421                               [OptionDescription("sub", "",
422                                                  [b1, ChoiceOption("c1", "", ('a', 'b', 'c'), 'a'),
423                                                   BoolOption("d1", "")]),
424                                BoolOption("b2", ""),
425                                BoolOption("d1", "")])
426     c = Config(descr)
427     setting = c.cfgimpl_get_settings()
428     setting.read_write()
429     raises(AttributeError, "c.find(byname='b1')")