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