Esempio n. 1
0
def test_literal_parse_num():
    e = parse(None, '16384')
    assert isinstance(e, literalvalues.LiteralValue)
    assert e.value == 16384

    e = parse(None, '-3.14')
    assert isinstance(e, literalvalues.LiteralValue)
    assert e.value == -3.14
Esempio n. 2
0
def test_literal_parse_bool():
    e = parse(None, 'false')
    assert isinstance(e, literalvalues.LiteralValue)
    assert e.value == 0

    e = parse(None, 'true')
    assert isinstance(e, literalvalues.LiteralValue)
    assert e.value == 1
Esempio n. 3
0
async def test_parse_complex_expression(num_mock_port1, num_mock_port2):
    num_mock_port1.set_last_read_value(5)
    num_mock_port2.set_last_read_value(-4)

    e = parse('nid1', 'ADD(10, MUL($, 3.14), $nid2)')
    assert round(await e.eval(), 1) == 21.7

    e = parse('nid1', 'ADD(10, MUL($, 3.14), DIV(10, 2), MIN($nid2, 10, $))')
    assert round(await e.eval(), 1) == 26.7
Esempio n. 4
0
    async def enable(self) -> None:
        if self._enabled:
            return

        self.debug('enabling')
        self._enabled = True
        self.invalidate_attr('enabled')

        # Reset port expression
        if self._expression:
            sexpression = str(self._expression)
            self.debug('resetting expression "%s"', sexpression)
            self._expression = core_expressions.parse(self.get_id(),
                                                      sexpression)

            main.force_eval_expressions(self)

        try:
            await self.handle_enable()

        except Exception:
            self.error('failed to enable')
            self._enabled = False

            raise
Esempio n. 5
0
    async def attr_set_transform_write(self, stransform_write: str) -> None:
        if not stransform_write:
            self._transform_write = None
            return

        try:
            self.debug('parsing expression "%s"', stransform_write)
            transform_write = core_expressions.parse(self.get_id(),
                                                     stransform_write)

            deps = transform_write.get_deps()
            for dep in deps:
                if not dep.startswith('$'):
                    continue

                if dep != f'${self._id}':
                    raise core_expressions.ExternalDependency(
                        port_id=dep[1:], pos=stransform_write.index(dep))

            self.debug('setting write transform "%s"', transform_write)
            self._transform_write = transform_write

        except core_expressions.ExpressionParseError as e:
            self.error('failed to set transform write expression "%s": %s',
                       stransform_write, e)

            raise InvalidAttributeValue('transform_write',
                                        details=e.to_json()) from e
Esempio n. 6
0
    async def attr_set_expression(self, sexpression: str) -> None:
        if not await self.is_writable():
            self.error('refusing to set expression on non-writable port')
            raise PortError('Cannot set expression on non-writable port')

        if self._sequence:
            self.debug('canceling current sequence')
            await self._sequence.cancel()
            self._sequence = None

        if not sexpression:
            self._expression = None
            return

        try:
            self.debug('parsing expression "%s"', sexpression)
            expression = core_expressions.parse(self.get_id(), sexpression)

            self.debug('checking for expression circular dependencies')
            await core_expressions.check_loops(self, expression)

        except core_expressions.ExpressionParseError as e:
            self.error('failed to set expression "%s": %s', sexpression, e)

            raise InvalidAttributeValue('expression',
                                        details=e.to_json()) from e

        self.debug('setting expression "%s"', expression)
        self._expression = expression

        main.force_eval_expressions(self)
Esempio n. 7
0
async def test_port_value_circular_dependency(num_mock_port1, num_mock_port2):
    num_mock_port1.set_writable(True)
    num_mock_port2.set_writable(True)

    await num_mock_port1.set_attr('expression', 'ADD($nid2, 10)')
    e2 = parse('nid2', 'ADD($nid1, 10)')
    with pytest.raises(CircularDependency):
        await check_loops(num_mock_port2, e2)
Esempio n. 8
0
async def test_parse_whitespace(num_mock_port1, num_mock_port2):
    num_mock_port1.set_last_read_value(5)
    num_mock_port2.set_last_read_value(-4)

    context = {
        'port_values': {
            'nid1': num_mock_port1.get_last_read_value(),
            'nid2': num_mock_port2.get_last_read_value()
        }
    }

    e = parse('nid1', '  ADD  (\t10,  MUL  (  $,  3.14  )  ,  $nid2  )  ')
    assert round(await e.eval(context=context), 1) == 21.7
Esempio n. 9
0
    async def attr_set_transform_write(self, stransform_write: str) -> None:
        if not stransform_write:
            self._transform_write = None
            return

        try:
            self.debug('parsing expression "%s"', stransform_write)
            transform_write = core_expressions.parse(self.get_id(), stransform_write)

            deps = transform_write.get_deps()
            for dep in deps:
                if not dep.startswith('$'):
                    continue

                if dep != f'${self._id}':
                    raise core_expressions.ExpressionError('Transform expression depends other ports')

            self.debug('setting write transform "%s"', transform_write)
            self._transform_write = transform_write

        except core_expressions.ExpressionError as e:
            self.error('failed to set transform write expression "%s": %s', stransform_write, e)

            raise InvalidAttributeValue('transform_write') from e
Esempio n. 10
0
async def test_parse_whitespace(num_mock_port1, num_mock_port2):
    num_mock_port1.set_last_read_value(5)
    num_mock_port2.set_last_read_value(-4)

    e = parse('nid1', '  ADD  (\t10,  MUL  (  $,  3.14  )  ,  $nid2  )  ')
    assert round(await e.eval(), 1) == 21.7
    def _prepare_filter(self) -> None:
        event_types = self._filter.get('type')
        if event_types:
            if not isinstance(event_types, list):
                event_types = (event_types, )
            self._filter_event_types = set(event_types)

        port_value = self._filter.get('port_value')
        if port_value is not None:
            if isinstance(port_value, str):  # An expression
                try:
                    self.debug('using value expression "%s"', port_value)
                    self._filter_port_value = core_expressions.parse(
                        self_port_id=None, sexpression=port_value)

                except core_expressions.ExpressionParseError as e:
                    self.error('failed to parse port expression "%s": %s',
                               port_value, e)

                    raise

            else:
                if not isinstance(port_value, list):
                    port_value = (port_value, )

                self._filter_port_value = port_value

        self._filter_port_value_transition = self._filter.get(
            'port_value_transition')

        self._filter_device_attrs = {
            n[7:]: v
            for n, v in self._filter.items()
            if n.startswith('device_') and not n.endswith('_transition')
        }

        self._filter_device_attr_transitions = {
            n[7:-11]: v
            for n, v in self._filter.items()
            if n.startswith('device_') and n.endswith('_transition')
        }

        self._filter_port_attrs = {
            n[5:]: v
            for n, v in self._filter.items() if n.startswith('port_')
            and n != 'port_value' and not n.endswith('_transition')
        }

        self._filter_port_attr_transitions = {
            n[5:-11]: v
            for n, v in self._filter.items() if n.startswith('port_')
            and n != 'port_value_transition' and n.endswith('_transition')
        }

        self._filter_slave_attrs = {
            n[6:]: v
            for n, v in self._filter.items()
            if n.startswith('slave_') and not n.endswith('_transition')
        }

        self._filter_slave_attr_transitions = {
            n[6:-11]: v
            for n, v in self._filter.items()
            if n.startswith('slave_') and n.endswith('_transition')
        }

        self._filter_device_attr_names.update(self._filter_device_attrs.keys())
        self._filter_device_attr_names.update(
            self._filter_device_attr_transitions.keys())

        self._filter_port_attr_names.update(self._filter_port_attrs.keys())
        self._filter_port_attr_names.update(
            self._filter_port_attr_transitions.keys())

        self._filter_slave_attr_names.update(self._filter_slave_attrs.keys())
        self._filter_slave_attr_names.update(
            self._filter_slave_attr_transitions.keys())

        self._filter_prepared = True
        self.debug('filter prepared')
Esempio n. 12
0
def test_port_value_parse(num_mock_port1, num_mock_port2):
    e = parse('nid1', '$nid2')
    assert isinstance(e, port.PortValue)
    assert e.port_id == 'nid2'
    assert e.get_port() == num_mock_port2
Esempio n. 13
0
async def test_parse_unknown_function():
    with pytest.raises(UnknownFunction) as exc_info:
        parse(None, 'ADD(10, UNKNOWN_FUNC(3, 14))')

    assert exc_info.value.name == 'UNKNOWN_FUNC'
    assert exc_info.value.pos == 9
Esempio n. 14
0
def test_port_ref_parse(num_mock_port1, num_mock_port2):
    e = parse('nid1', '@nid2')
    assert isinstance(e, port.PortRef)
    assert e.port_id == 'nid2'
    assert e.get_port() == num_mock_port2
Esempio n. 15
0
def test_port_ref_inexistent(num_mock_port1):
    e = parse('nid1', '@nid2')
    assert isinstance(e, port.PortRef)
    assert e.port_id == 'nid2'
    assert e.get_port() is None
Esempio n. 16
0
async def test_parse_unbalanced_parentheses():
    with pytest.raises(UnbalancedParentheses) as exc_info:
        parse(None, 'ADD(10)), MUL(3, 14))')

    assert exc_info.value.pos == 8
Esempio n. 17
0
def test_port_value_inexistent(num_mock_port1):
    e = parse('nid1', '$nid2')
    assert isinstance(e, port.PortValue)
    assert e.port_id == 'nid2'
    assert e.get_port() is None
Esempio n. 18
0
async def test_parse_unexpected_end():
    with pytest.raises(UnexpectedEnd):
        parse(None, 'ADD(10, MUL(3, 14)')
Esempio n. 19
0
async def test_parse_unexpected_character():
    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, '-ADD(10, $)')

    assert exc_info.value.c == '-'
    assert exc_info.value.pos == 1

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, 'ADD#(10, $)')

    assert exc_info.value.c == '#'
    assert exc_info.value.pos == 4

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, 'ADD(%$port, 10)')

    assert exc_info.value.c == '%'
    assert exc_info.value.pos == 5

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, 'ADD($%port, 10)')

    assert exc_info.value.c == '%'
    assert exc_info.value.pos == 7

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, 'ADD($port*, 10)')

    assert exc_info.value.c == '*'
    assert exc_info.value.pos == 11

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, 'ADD(#, 10, $)')

    assert exc_info.value.c == '#'
    assert exc_info.value.pos == 5

    with pytest.raises(UnexpectedCharacter) as exc_info:
        parse(None, '3+4')

    assert exc_info.value.c == '+'
    assert exc_info.value.pos == 2
Esempio n. 20
0
async def test_parse_empty():
    with pytest.raises(EmptyExpression):
        parse(None, '    ')