1#!/usr/bin/env python3
2
3"""Implementation of widget <cond> elements
4
5Allow setting up tests such as:
6
7<widget>
8 <cond><sid>M01</sid></cond>
9 <class>Paragraph</class>
10 <text>Hello</text>
11</widget>
12
13."""
14
15import logging
16
17from chart.project import SID
18
19
20class Clause:
21 """Base for conditions."""
22
23 def test(self, _):
24 """Test if context matches this clause."""
25 raise NotImplementedError
26
27
28# class SCIDClause(Clause):
29 # """Test if the `scid` in a context matches."""
30
31 # def __init__(self, elem):
32 # self.cond = elem.text.strip()
33
34 # def test(self, config):
35 # """Test if the `scid` in `config` matches us."""
36 # logging.debug('SID clause testing {got} against {cond}'.format(
37 # got=config['sid'], cond=self.cond))
38
39 # if config['sid'] != self.cond:
40 # return False
41
42 # return True
43
44 # def brief_description(self):
45 # """Quick description of this clause."""
46 # return 'SID {cond}'.format(cond=self.cond)
47
48
49class SIDClause(Clause):
50 """Test if the report `sid` matches."""
51
52 def __init__(self, elem=None, sid=None):
53 if elem is not None:
54 self.cond = SID.from_xml(elem)
55
56 elif sid is not None:
57 self.cond = sid
58
59 def test(self, config):
60 """Test if the `sid` in `config` matches us."""
61 return config['sid'] == self.cond
62
63 def brief_description(self):
64 """Quick description of this clause."""
65 return 'SID is {c}'.format(c=self.cond)
66
67
68class Condition:
69 """Build up a list of clauses and allow widgets to be tested against all of them."""
70
71 def __init__(self):
72 # Currently the code allows multiple <cond> elements from a single widget
73 # this is probably wrong
74 self.clauses = []
75
76 def append(self, elem):
77 """Allow the `Widget` constructor to configure us with an additional clause."""
78 if elem.tag != 'cond':
79 raise ValueError('Condition object is constructed using the <cond> element')
80
81 for subelem in elem:
82 if subelem.tag == 'scid':
83 self.clauses.append(SIDClause(sid=SID(subelem.text.strip())))
84
85 elif subelem.tag == 'sid':
86 self.clauses.append(SIDClause(subelem))
87
88 else:
89 raise ValueError('Unknown condition {typ}'.format(typ=subelem.tag))
90
91 def test(self, config):
92 """Test if all of our conditions match (boolean AND test)."""
93 for clause in self.clauses:
94 if not clause.test(config):
95 return False
96
97 return True
98
99 def brief_description(self):
100 """Output for the 'report --show-template' command."""
101 return ' and '.join(c.brief_description() for c in self.clauses)