Esempio n. 1
0
def test_wrong_source():
    p = Publisher()
    on_emit_future = OnEmitFuture()
    p | on_emit_future

    with pytest.raises(ValueError):
        on_emit_future.emit(0, who=Publisher())
Esempio n. 2
0
    def __init__(
        self,
        publisher: Publisher,
        coro_with_args,
        mode=AsyncMode.CONCURRENT,
        error_callback=default_error_handler,
    ) -> None:
        Operator.__init__(self, publisher)

        self._coro = coro_with_args
        self._mode = mode
        self._error_callback = error_callback

        # ._future is the reference to a running coroutine encapsulated as task
        self._future = None  # type: Optional[asyncio.Future]

        # ._last_emit is used for LAST_DISTINCT and keeps the last emit from
        # source publisher
        self._last_emit = NONE  # type: Any

        # .scheduled is a Publisher which is emitting the value of the source
        # publisher when the coroutine is actually started
        self.scheduled = Publisher()

        # queue is initialized with following sizes:
        # Mode:                size:
        # QUEUE                unlimited
        # LAST, LAST_DISTINCT  1
        # all others           no queue used
        self._queue = None  # type: Optional[MutableSequence]

        if mode in (AsyncMode.QUEUE, AsyncMode.LAST, AsyncMode.LAST_DISTINCT):
            maxlen = (None if mode is AsyncMode.QUEUE else 1)
            self._queue = deque(maxlen=maxlen)
Esempio n. 3
0
def check_get_method(operator, input_vector, output_vector):
    input_value, output_value = input_vector[0], output_vector[0]

    p = Publisher()
    p.get = mock.MagicMock(return_value=input_value)
    o = p | operator

    with pytest.raises(ValueError):
        o.emit(input_value, who=None)

    assert o.get() == output_value

    disposable = o.subscribe(Sink())

    if input_value is not NONE:
        o.emit(input_value, who=p)  # simulate emit on subscribe

    p.get = None  # .get should not be called when operator has a subscription

    assert o.get() == output_value  # this should retrieve the internal state

    # after unsubscription it should remove the internal state and retrieve it
    # directly from orignator publisher via get
    disposable.dispose()

    p.get = mock.MagicMock(return_value=input_value)

    assert o.get() == output_value

    p.get.assert_called_once_with()
Esempio n. 4
0
 def get(self):
     for publisher in self._publishers:
         try:
             return publisher.get()
         except ValueError:
             pass
     Publisher.get(self)  # raises ValueError
def test_wrong_comparision():
    p1 = Publisher()
    p2 = Publisher()

    with pytest.raises(ValueError):
        assert p1 == p2

    with pytest.raises(ValueError):
        if p1 == p2: pass

    with pytest.raises(ValueError):
        if p1 != p2: pass

    with pytest.raises(ValueError):
        assert p2 in (p1, p2)

    with pytest.raises(ValueError):
        p1 in (p2, p2)

    with pytest.raises(ValueError):
        assert p1 not in (p2, p2)

    l = [p1, p2]
    with pytest.raises(ValueError):
        l.remove(p2)
Esempio n. 6
0
 def get(self):
     try:
         return self._publisher.get()  # may raise ValueError
     except ValueError:
         if self._state is not NONE:
             return self._state
     Publisher.get(self)  # raises ValueError
Esempio n. 7
0
async def test_cancel():
    p = Publisher()
    future = p | OnEmitFuture(timeout=0.01)
    future.cancel()
    p.notify(1)

    with pytest.raises(asyncio.CancelledError):
        future.result()
Esempio n. 8
0
 def _done(self, future: asyncio.Future):
     try:
         result = future.result()
     except Exception:  # pylint: disable=broad-except
         self._error_callback(*sys.exc_info())
     else:
         if result != NONE:
             Publisher.notify(self, result)
Esempio n. 9
0
 def __init__(
         self,
         hub: 'Hub',  # pylint: disable=unused-argument
         path: str) -> None:
     Publisher.__init__(self)
     self._subject = None  # type: Publisher
     self._path = path
     self._hub = hub
     self._pre_assign_emit = None  # type: list
Esempio n. 10
0
    def emit(self, value: Any_, who: Publisher) -> None:
        if who is not self._orginator:
            raise ValueError('Emit from non assigned publisher')

        attribute = getattr(value, self._attribute_name)

        if self._args is None:
            return Publisher.notify(self, attribute)

        return Publisher.notify(self, attribute(*self._args, **self._kwargs))
Esempio n. 11
0
    def emit(self, value: Any, who: Publisher) -> None:
        if who is not self._orginator:
            raise ValueError('Emit from non assigned publisher')

        if self._unpack:
            if self._predicate(*value):
                return Publisher.notify(self, value)
        elif self._predicate(value):
            return Publisher.notify(self, value)
        return None
Esempio n. 12
0
 def get(self):
     selection = self._publisher.get()  # may raises ValueError
     try:
         item = self._mapping[selection]
     except (IndexError, KeyError, TypeError):
         if self._default is NONE:
             Publisher.get(self)  # raises ValueError
         item = self._default
     if isinstance(item, Publisher):
         return item.get()  # may raises ValueError
     return item
Esempio n. 13
0
def test_partition():
    mock = Mock()
    p = Publisher()

    dut = p | Partition(3)
    dut | Sink(mock)
    p.notify(1)
    p.notify(2)
    mock.assert_not_called()
    dut.flush()
    mock.assert_called_once_with((1, 2))
Esempio n. 14
0
 def _wait_done_cb(self):
     if self._last_state is not NONE:
         try:
             Publisher.notify(self, self._last_state)
         except Exception:  # pylint: disable=broad-except
             self._error_callback(*sys.exc_info())
         self._last_state = NONE
         self._call_later_handler = self._loop.call_later(
             self._duration, self._wait_done_cb)
     else:
         self._call_later_handler = None
Esempio n. 15
0
    def _delayed_emit_cb(self, value=NONE):
        if value is NONE:
            # since the last emit the given duration has passed without another
            # emit
            return

        try:
            Publisher.notify(self, value)
        except Exception:  # pylint: disable=broad-except
            self._error_callback(*sys.exc_info())

        self._timer.start(self._duration)
Esempio n. 16
0
def test_adding_publisher():
    p1 = Publisher()
    p2 = Publisher()
    dut = Merge(p1, p2)

    assert len(dut.source_publishers) == 2

    p3 = Publisher()
    p3 | dut

    assert len(dut.source_publishers) == 3
    assert p3 in dut.source_publishers
Esempio n. 17
0
    def get(self):
        value = self._publisher.get()  # may raise ValueError

        if self._unpack:
            result = self._function(*value)
        else:
            result = self._function(value)

        if result is NONE:
            Publisher.get(self)  # raises ValueError

        return result
Esempio n. 18
0
    def subscribe(self, subscriber: 'Subscriber',
                  prepend: bool = False) -> SubscriptionDisposable:
        disposable = MultiOperator.subscribe(self, subscriber, prepend)

        if self._missing:
            self._missing.clear()
            if self._state is NONE:
                Publisher.notify(self, self._init)
            else:
                Publisher.notify(self, self._state)

        return disposable
Esempio n. 19
0
async def test_errorhandler():
    mock = Mock(side_effect=ZeroDivisionError)
    mock_errorhandler = Mock()

    p = Publisher()

    dut = p | Delay(0.1, error_callback=mock_errorhandler)
    dut | Sink(mock)

    p.notify(1)
    await asyncio.sleep(0.15)
    mock.assert_called_once_with(1)
    mock_errorhandler.assert_called_once_with(ZeroDivisionError, ANY, ANY)
Esempio n. 20
0
def test_exception():
    source = Publisher()
    dut = source | CatchException(ValueError)

    class _Subscriber(Subscriber):
        exception = None
        results = []

        def emit(self, arg, who: Publisher) -> None:
            if self.exception is not None:
                raise self.exception
            self.results.append(arg)

    subscriber = _Subscriber()
    dut.subscribe(subscriber)

    source.notify(1)
    source.notify(2)
    assert tuple(subscriber.results) == (1, 2)
    subscriber.exception = ValueError()
    source.notify(1)
    assert tuple(subscriber.results) == (1, 2)
    subscriber.exception = ZeroDivisionError()
    with pytest.raises(ZeroDivisionError):
        source.notify(3)

    with pytest.raises(ValueError):
        CatchException()
Esempio n. 21
0
async def test_future_return():
    class S(Subscriber):
        def __init__(self):
            self.future = asyncio.get_event_loop().create_future()

        def emit(self, value, who: Publisher) -> asyncio.Future:
            return self.future

    p = Publisher()
    s1 = S()

    p.subscribe(s1)

    assert p.notify(None) is s1.future

    s2 = S()

    p.subscribe(s2)

    gathered_future = p.notify(None)

    await asyncio.sleep(0)
    assert not gathered_future.done()

    s1.future.set_result(1)
    await asyncio.sleep(0)
    assert not gathered_future.done()

    s2.future.set_result(1)
    await asyncio.sleep(0)
    assert gathered_future.done()
Esempio n. 22
0
def test_stateless_nested():
    source1 = Publisher()
    dut1 = CombineLatest(source1, allow_stateless=True)

    source2 = Publisher()
    dut2 = CombineLatest(dut1, source2, allow_stateless=True)

    assert len(source1.subscriptions) == 0
    assert len(source2.subscriptions) == 0
    assert len(dut1.subscriptions) == 0
    assert len(dut2.subscriptions) == 0

    collector = Collector()
    dut2 | collector
    assert len(source1.subscriptions) == 1
    assert len(source2.subscriptions) == 1
    assert len(dut1.subscriptions) == 1
    assert len(dut2.subscriptions) == 1

    with pytest.raises(ValueError):
        dut2.get()

    assert collector.result_vector == ()

    collector.reset()
    source1.notify(True)
    assert collector.result_vector == (((True, ), NONE), )

    collector.reset()
    source2.notify(False)

    assert collector.result_vector == ((NONE, False), )
Esempio n. 23
0
def test_stateless_map():
    source1 = StatefulPublisher(0)
    source2 = Publisher()

    dut = CombineLatest(source1,
                        source2,
                        map_=lambda a, b: a + (0 if b is NONE else b),
                        allow_stateless=True)

    collector = Collector()
    dut.subscribe(collector)

    with pytest.raises(ValueError):
        dut.get()
    assert collector.result_vector == ()

    collector.reset()
    source1.notify(1)
    assert collector.result_vector == (1, )

    source1.notify(1)
    assert collector.result_vector == (1, )

    source1.notify(1.0)
    assert collector.result_vector == (1, )

    source2.notify(0)
    assert collector.result_vector == (1, 1)

    source2.notify(1)
    assert collector.result_vector == (1, 1, 2)

    source2.notify(1)
    assert collector.result_vector == (1, 1, 2, 2)
def test_getattr_without_inherit():
    p = Publisher()

    class Foo:
        a = None

        def __init__(self, a=5):
            self.a = a

    with pytest.raises(AttributeError):
        dut = p.a

    with pytest.raises(AttributeError):
        p.assnign(5)
Esempio n. 25
0
def test_notify(init, number_of_subscribers):
    """ Testing .notify(v) method """
    p = Publisher(init)
    m = mock.Mock()

    # subscribing Sinks to the publisher and test .notify on subscribe
    subscribers = [Sink(m, i) for i in range(number_of_subscribers)]

    m.assert_not_called()

    for s in subscribers:
        p.subscribe(s)

    if init is not NONE:
        m.assert_has_calls([mock.call(i, init) for i in range(number_of_subscribers)])
    else:
        m.assert_not_called()

    m.reset_mock()

    # test .notify() for listening subscribers
    p.notify(1)

    m.assert_has_calls([mock.call(i, 1) for i in range(number_of_subscribers)])

    m.reset_mock()

    # re- .notify() with the same value
    p.notify(1)

    m.assert_has_calls([mock.call(i, 1) for i in range(number_of_subscribers)])
Esempio n. 26
0
    def __init__(self, interval, poll_func: Callable[[Any], Any], *args,
                 error_callback=default_error_handler, loop=None,
                 **kwargs) -> None:
        Publisher.__init__(self)

        self._interval = interval
        if args or kwargs:
            self._poll_func = \
                partial(poll_func, *args, **kwargs)  # type: Callable
        else:
            self._poll_func = poll_func  # type: Callable
        self._loop = loop or asyncio.get_event_loop()

        self._call_later_handler = None
        self._error_callback = error_callback
Esempio n. 27
0
    def get(self):
        # if all publishers are stateful ._state will be defined
        if self._state is not NONE:
            return self._state

        # get value of all publishers
        values = (p.get() for p in self._publishers)  # may raise ValueError

        if not self._map:
            return tuple(values)

        result = self._map(*values)
        if result is NONE:
            Publisher.get(self)  # raises ValueError
        return result
Esempio n. 28
0
 def get(self):
     queue = list(self._queue)
     value = self._publisher.get()  # may raises ValueError
     queue.append(value)
     if self._size and len(queue) == self._size:
         return tuple(queue)
     return Publisher.get(self)  # raises ValueError
Esempio n. 29
0
def test_bitwise_combine_latest(method, init, bit_value_map, input_vector, output_vector):
    publisher_bit_mapping = OrderedDict([(Publisher(v), b) for b, v in bit_value_map])
    i_vector = [tuple(v for k, v in bit_value_map)] + input_vector

    operator = BitwiseCombineLatest(publisher_bit_mapping, init)

    method(operator, i_vector, output_vector)
Esempio n. 30
0
    def emit(self, value: Any, who: Publisher) -> None:
        if who is not self._orginator:
            raise ValueError('Emit from non assigned publisher')

        if not bool(value):
            return Publisher.notify(self, value)
        return None