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