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