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