03ab670abe5c2d38f5690e7fd3b1528e0ce96e94
[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 _get_slots(opt):
7     slots = set()
8     for subclass in opt.__class__.__mro__:
9         if subclass is not object:
10             slots.update(subclass.__slots__)
11     return slots
12
13
14 def _no_state(opt):
15     for attr in _get_slots(opt):
16         if 'state' in attr:
17             try:
18                 getattr(opt, attr)
19             except:
20                 pass
21             else:
22                 raise Exception('opt should have already attribute {0}'.format(attr))
23
24
25 def _diff_opt(opt1, opt2):
26     attr1 = set(_get_slots(opt1))
27     attr2 = set(_get_slots(opt2))
28     diff1 = attr1 - attr2
29     diff2 = attr2 - attr1
30     if diff1 != set():
31         raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
32     if diff2 != set():
33         raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
34     for attr in attr1:
35         if attr in ['_cache_paths']:
36             continue
37         err1 = False
38         err2 = False
39         val1 = None
40         val2 = None
41         try:
42             val1 = getattr(opt1, attr)
43         except:
44             err1 = True
45
46         try:
47             val2 = getattr(opt2, attr)
48         except:
49             err2 = True
50         assert err1 == err2
51         if val1 is None:
52             assert val1 == val2
53         elif attr == '_children':
54             assert val1[0] == val2[0]
55             for index, _opt in enumerate(val1[1]):
56                 assert _opt._name == val2[1][index]._name
57         elif attr == '_requires':
58             assert val1[0][0][0]._name == val2[0][0][0]._name
59             assert val1[0][0][1:] == val2[0][0][1:]
60         elif attr == '_opt':
61             assert val1._name == val2._name
62         elif attr == '_consistencies':
63             # dict is only a cache
64             if isinstance(val1, list):
65                 for index, consistency in enumerate(val1):
66                     assert consistency[0] == val2[index][0]
67                     assert consistency[1]._name == val2[index][1]._name
68         else:
69             assert val1 == val2
70
71
72 def test_diff_opt():
73     b = BoolOption('b', '')
74     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
75     #u.impl_add_consistency('not_equal', b)
76     s = SymLinkOption('s', u)
77     o = OptionDescription('o', '', [b, u, s])
78     o1 = OptionDescription('o1', '', [o])
79
80     a = dumps(o1)
81     q = loads(a)
82     _diff_opt(o1, q)
83     _diff_opt(o1.o, q.o)
84     _diff_opt(o1.o.b, q.o.b)
85     _diff_opt(o1.o.u, q.o.u)
86     _diff_opt(o1.o.s, q.o.s)
87
88
89 def test_diff_opt_cache():
90     b = BoolOption('b', '')
91     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
92     u.impl_add_consistency('not_equal', b)
93     s = SymLinkOption('s', u)
94     o = OptionDescription('o', '', [b, u, s])
95     o1 = OptionDescription('o1', '', [o])
96     o1.impl_build_cache()
97
98     a = dumps(o1)
99     q = loads(a)
100     _diff_opt(o1, q)
101     _diff_opt(o1.o, q.o)
102     _diff_opt(o1.o.b, q.o.b)
103     _diff_opt(o1.o.u, q.o.u)
104     _diff_opt(o1.o.s, q.o.s)
105
106
107 def test_no_state_attr():
108     # all _state_xxx attributes should be deleted
109     b = BoolOption('b', '')
110     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
111     s = SymLinkOption('s', u)
112     o = OptionDescription('o', '', [b, u, s])
113     o1 = OptionDescription('o1', '', [o])
114
115     a = dumps(o1)
116     q = loads(a)
117     _no_state(q)
118     _no_state(q.o)
119     _no_state(q.o.b)
120     _no_state(q.o.u)
121     _no_state(q.o.s)