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