serialize new callback
[tiramisu.git] / test / test_state.py
1 from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
2     OptionDescription
3 from pickle import dumps, loads
4
5
6 def return_value(value=None):
7         return value
8
9
10 def _get_slots(opt):
11     slots = set()
12     for subclass in opt.__class__.__mro__:
13         if subclass is not object:
14             slots.update(subclass.__slots__)
15     return slots
16
17
18 def _no_state(opt):
19     for attr in _get_slots(opt):
20         if 'state' in attr:
21             try:
22                 getattr(opt, attr)
23             except:
24                 pass
25             else:
26                 raise Exception('opt should have already attribute {0}'.format(attr))
27
28
29 def _diff_opt(opt1, opt2):
30     attr1 = set(_get_slots(opt1))
31     attr2 = set(_get_slots(opt2))
32     diff1 = attr1 - attr2
33     diff2 = attr2 - attr1
34     if diff1 != set():
35         raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
36     if diff2 != set():
37         raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
38     for attr in attr1:
39         if attr in ['_cache_paths']:
40             continue
41         err1 = False
42         err2 = False
43         val1 = None
44         val2 = None
45         try:
46             val1 = getattr(opt1, attr)
47         except:
48             err1 = True
49
50         try:
51             val2 = getattr(opt2, attr)
52         except:
53             err2 = True
54         assert err1 == err2
55         if val1 is None:
56             assert val1 == val2
57         elif attr == '_children':
58             assert val1[0] == val2[0]
59             for index, _opt in enumerate(val1[1]):
60                 assert _opt._name == val2[1][index]._name
61         elif attr == '_requires':
62             assert val1[0][0][0]._name == val2[0][0][0]._name
63             assert val1[0][0][1:] == val2[0][0][1:]
64         elif attr == '_opt':
65             assert val1._name == val2._name
66         elif attr == '_consistencies':
67             # dict is only a cache
68             if isinstance(val1, list):
69                 for index, consistency in enumerate(val1):
70                     assert consistency[0] == val2[index][0]
71                     assert consistency[1]._name == val2[index][1]._name
72         elif attr == '_callback':
73             assert val1[0] == val2[0]
74             if val1[1] is not None:
75                 for key, values in val1[1].items():
76                     for idx, value in enumerate(values):
77                         if isinstance(value, tuple):
78                             assert val1[1][key][idx][0]._name == val2[1][key][idx][0]._name
79                             assert val1[1][key][idx][1] == val2[1][key][idx][1]
80                         else:
81                             assert val1[1][key][idx] == val2[1][key][idx]
82             else:
83                 assert val1[1] == val2[1]
84         else:
85             assert val1 == val2
86
87
88 def test_diff_opt():
89     b = BoolOption('b', '')
90     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
91     #u.impl_add_consistency('not_equal', b)
92     s = SymLinkOption('s', u)
93     o = OptionDescription('o', '', [b, u, s])
94     o1 = OptionDescription('o1', '', [o])
95
96     a = dumps(o1)
97     q = loads(a)
98     _diff_opt(o1, q)
99     _diff_opt(o1.o, q.o)
100     _diff_opt(o1.o.b, q.o.b)
101     _diff_opt(o1.o.u, q.o.u)
102     _diff_opt(o1.o.s, q.o.s)
103
104
105 def test_diff_opt_cache():
106     b = BoolOption('b', '')
107     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
108     u.impl_add_consistency('not_equal', b)
109     s = SymLinkOption('s', u)
110     o = OptionDescription('o', '', [b, u, s])
111     o1 = OptionDescription('o1', '', [o])
112     o1.impl_build_cache()
113
114     a = dumps(o1)
115     q = loads(a)
116     _diff_opt(o1, q)
117     _diff_opt(o1.o, q.o)
118     _diff_opt(o1.o.b, q.o.b)
119     _diff_opt(o1.o.u, q.o.u)
120     _diff_opt(o1.o.s, q.o.s)
121
122
123 def test_diff_opt_callback():
124     b = BoolOption('b', '', callback=return_value)
125     b2 = BoolOption('b2', '', callback=return_value, callback_params={'': ('yes',)})
126     b3 = BoolOption('b3', '', callback=return_value, callback_params={'': ('yes', (b, False)), 'value': ('no',)})
127     o = OptionDescription('o', '', [b, b2, b3])
128     o1 = OptionDescription('o1', '', [o])
129     o1.impl_build_cache()
130
131     a = dumps(o1)
132     q = loads(a)
133     _diff_opt(o1, q)
134     _diff_opt(o1.o, q.o)
135     _diff_opt(o1.o.b, q.o.b)
136     _diff_opt(o1.o.b2, q.o.b2)
137     _diff_opt(o1.o.b3, q.o.b3)
138
139
140 def test_no_state_attr():
141     # all _state_xxx attributes should be deleted
142     b = BoolOption('b', '')
143     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
144     s = SymLinkOption('s', u)
145     o = OptionDescription('o', '', [b, u, s])
146     o1 = OptionDescription('o1', '', [o])
147
148     a = dumps(o1)
149     q = loads(a)
150     _no_state(q)
151     _no_state(q.o)
152     _no_state(q.o.b)
153     _no_state(q.o.u)
154     _no_state(q.o.s)