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)